From 0cdca3a6364552ad9b957e36387cd5104c514cc0 Mon Sep 17 00:00:00 2001 From: Cosmo Myzrail Gorynych Date: Sun, 21 Aug 2022 19:34:23 +1200 Subject: [PATCH] Merge commit '93db4b9e45393e7dbd5b7d12ad8c5c7be03cc031' --- .eslintrc.json | 495 +- app/data/Wood_End.wav | Bin 0 -> 273724 bytes app/data/Wood_Start.wav | Bin 0 -> 280332 bytes app/data/ct.libs/place/index.js | 3 + .../ct.libs/place/injections/beforedraw.js | 8 +- app/data/ct.release/rooms.js | 33 +- app/data/ct.release/templates.js | 12 +- app/data/ct.release/tilemaps.js | 16 +- app/data/cursorErase.svg | 12 + app/data/cursorRotate.svg | 4 + app/data/i18n/Brazilian Portuguese.json | 147 +- app/data/i18n/Chinese Simplified.json | 149 +- app/data/i18n/Comments.json | 147 +- app/data/i18n/Debug.json | 278 +- app/data/i18n/Dutch.json | 151 +- app/data/i18n/English.json | 56 +- app/data/i18n/French.json | 147 +- app/data/i18n/German.json | 147 +- app/data/i18n/Japanese.json | 147 +- app/data/i18n/Polish.json | 147 +- app/data/i18n/Romanian.json | 147 +- app/data/i18n/Russian.json | 87 +- app/data/i18n/Spanish.json | 147 +- app/data/i18n/Turkish.json | 147 +- app/data/i18n/Ukranian.json | 89 +- app/package-lock.json | 91 +- app/package.json | 3 +- gulpfile.js | 1 - package-lock.json | 4 +- package.json | 2 +- src/examples/DungeonCrawler_tutorial.ict | 11236 ++++++++++------ ...i14d3f53f-a868-4820-84cd-63234ab6e6b9.png} | Bin ...-a868-4820-84cd-63234ab6e6b9.png_prev.png} | Bin ...868-4820-84cd-63234ab6e6b9.png_prev@2.png} | Bin ...ia42e0dff-69c9-46c3-8996-745aaa769698.png} | Bin ...-69c9-46c3-8996-745aaa769698.png_prev.png} | Bin ...9c9-46c3-8996-745aaa769698.png_prev@2.png} | Bin .../img/r127493eb58cf.png | Bin 9594 -> 0 bytes .../r1cd7a8ef-febb-4174-ad90-42846504b06f.png | Bin 0 -> 1664 bytes ...1cd7a8ef-febb-4174-ad90-42846504b06f@r.png | Bin 0 -> 6664 bytes .../r326893eb-b9c2-4616-aaee-bb4641e0423e.png | Bin 0 -> 2045 bytes ...326893eb-b9c2-4616-aaee-bb4641e0423e@r.png | Bin 0 -> 7081 bytes .../img/r342f55fa6324.png | Bin 9594 -> 0 bytes .../img/r3786dc4c7d4c.png | Bin 9594 -> 0 bytes .../img/r42846504b06f.png | Bin 18511 -> 0 bytes .../img/r6569f49f6b80.png | Bin 5192 -> 0 bytes .../img/r7b6ea00c7b7c.png | Bin 10275 -> 0 bytes .../rae6bb30c-9ad9-4390-b632-127493eb58cf.png | Bin 0 -> 1896 bytes ...ae6bb30c-9ad9-4390-b632-127493eb58cf@r.png | Bin 0 -> 8466 bytes .../img/rbb4641e0423e.png | Bin 11936 -> 0 bytes .../ree8b4583-614a-44d6-aacc-6569f49f6b80.png | Bin 0 -> 272 bytes ...ee8b4583-614a-44d6-aacc-6569f49f6b80@r.png | Bin 0 -> 2481 bytes .../reed8a427-1c70-425d-b633-7b6ea00c7b7c.png | Bin 0 -> 904 bytes ...eed8a427-1c70-425d-b633-7b6ea00c7b7c@r.png | Bin 0 -> 6485 bytes .../DungeonCrawler_tutorial/img/splash.png | Bin 10200 -> 6485 bytes src/icons/cursor.svg | 2 + src/icons/lock.svg | 1 + src/icons/redo.svg | 4 + src/icons/undo.svg | 4 + src/icons/unlock.svg | 1 + src/js/3rdparty/alertify.js | 1 + src/js/3rdparty/soundbox.js | 11 - src/js/addMigrationMethod.js | 11 + src/js/loadProject.js | 239 - src/js/projectMigrationScripts/2.1.0.js | 36 + src/js/projectMigrationScripts/2.2.0.js | 24 + src/node_requires/3rdparty/soundbox.ts | 55 + src/node_requires/IMenuItem.d.ts | 5 +- src/node_requires/events/index.ts | 2 +- src/node_requires/exporter/index.ts | 1 + src/node_requires/exporter/rooms.ts | 54 +- src/node_requires/exporter/templates.ts | 1 + src/node_requires/extendGlobals.d.ts | 2 + src/node_requires/hotkeys.js | 19 +- .../resources/emitterTandems/index.ts | 2 +- .../resources/modules/typedefs.ts | 2 +- .../resources/projects/IProject.d.ts | 38 +- .../{defaultProject.js => defaultProject.ts} | 22 +- src/node_requires/resources/projects/index.ts | 250 +- src/node_requires/resources/rooms/IRoom.d.ts | 72 +- .../resources/rooms/defaultRoom.ts | 5 +- src/node_requires/resources/rooms/index.ts | 32 +- .../resources/templates/ITemplate.d.ts | 1 + .../resources/templates/defaultTemplate.ts | 1 + .../resources/templates/index.ts | 14 +- .../resources/textures/ITexture.d.ts | 2 + src/node_requires/resources/textures/index.ts | 87 +- .../roomEditor/IRoomEditorRiotTag.d.ts | 39 + src/node_requires/roomEditor/common.ts | 116 + .../roomEditor/entityClasses/Background.ts | 125 + .../roomEditor/entityClasses/Copy.ts | 104 + .../roomEditor/entityClasses/MarqueeBox.ts | 24 + .../roomEditor/entityClasses/SnapTarget.ts | 95 + .../roomEditor/entityClasses/Tile.ts | 85 + .../roomEditor/entityClasses/TileLayer.ts | 68 + .../roomEditor/entityClasses/Transformer.ts | 289 + .../roomEditor/entityClasses/Viewport.ts | 58 + .../entityClasses/ViewportRestriction.ts | 57 + src/node_requires/roomEditor/history.ts | 290 + src/node_requires/roomEditor/index.ts | 561 + .../roomEditor/interactions/camera/home.ts | 16 + .../roomEditor/interactions/camera/move.ts | 46 + .../roomEditor/interactions/camera/zoom.ts | 48 + .../interactions/copies/deleteCopies.ts | 40 + .../interactions/copies/placeCopy.ts | 148 + .../roomEditor/interactions/copyPaste.ts | 126 + .../roomEditor/interactions/history.ts | 37 + .../roomEditor/interactions/index.ts | 96 + .../roomEditor/interactions/mousePosLabel.ts | 15 + .../interactions/placementCalculator.ts | 136 + .../interactions/tiles/ITilePatch.d.ts | 7 + .../interactions/tiles/deleteTiles.ts | 43 + .../interactions/tiles/placeTile.ts | 192 + .../interactions/transformer/delete.ts | 32 + .../interactions/transformer/move.ts | 57 + .../interactions/transformer/nudge.ts | 66 + .../interactions/transformer/rotate.ts | 46 + .../interactions/transformer/scale.ts | 154 + .../interactions/transformer/select.ts | 162 + src/node_requires/themes/index.ts | 44 +- src/node_requires/{ => utils}/imageUtils.ts | 0 src/node_requires/utils/propUtils.ts | 30 + src/node_requires/utils/trigo.ts | 51 + src/pug/index.pug | 9 + src/riotTags/debugger/debugger-toolbar.tag | 7 +- .../main-menu/export-mobile-panel.tag | 2 +- .../main-menu/main-menu-latest-projects.tag | 3 +- src/riotTags/main-menu/main-menu-project.tag | 3 +- src/riotTags/notepad-panel.tag | 4 +- src/riotTags/project-selector.tag | 9 +- .../tabs/rendering-settings.tag | 8 +- .../rooms/copy-custom-properties-modal.tag | 93 - .../rooms/room-backgrounds-editor.tag | 345 +- src/riotTags/rooms/room-copy-properties.tag | 65 - src/riotTags/rooms/room-editor.tag | 1165 +- .../rooms/room-entities-properties.tag | 482 + src/riotTags/rooms/room-events-editor.tag | 6 +- src/riotTags/rooms/room-properties.tag | 161 + src/riotTags/rooms/room-template-picker.tag | 23 + src/riotTags/rooms/room-tile-editor.tag | 248 +- src/riotTags/rooms/room-type-picker.tag | 89 - src/riotTags/rooms/rooms-panel.tag | 7 +- src/riotTags/shared/asset-input.tag | 5 +- src/riotTags/shared/asset-selector.tag | 4 +- src/riotTags/shared/asset-viewer.tag | 51 +- src/riotTags/shared/collapsible-section.tag | 34 +- src/riotTags/shared/context-menu.tag | 2 +- src/riotTags/shared/error-notice.tag | 21 + src/riotTags/shared/zoom-slider.tag | 7 + src/riotTags/sounds/sound-editor.tag | 5 +- src/riotTags/style-editor.tag | 5 +- src/riotTags/template-editor.tag | 10 +- src/riotTags/textures/texture-editor.tag | 11 +- src/riotTags/textures/texture-generator.tag | 5 +- src/styl/buildingBlocks.styl | 18 + src/styl/common.styl | 8 + src/styl/inputs.styl | 21 + .../tags/rooms/room-backgrounds-editor.styl | 3 + src/styl/tags/rooms/room-copy-properties.styl | 9 - src/styl/tags/rooms/room-editor.styl | 264 +- src/styl/tags/rooms/room-tile-editor.styl | 26 + src/styl/tags/shared/asset-input.styl | 16 + src/styl/tags/shared/asset-viewer.styl | 6 + src/styl/tags/shared/collapsible-section.styl | 35 +- src/styl/tags/shared/error-notice.styl | 6 + src/styl/themeSpringStream.styl | 2 + tsconfig.json | 12 +- 167 files changed, 15165 insertions(+), 6707 deletions(-) create mode 100644 app/data/Wood_End.wav create mode 100644 app/data/Wood_Start.wav create mode 100644 app/data/cursorErase.svg create mode 100644 app/data/cursorRotate.svg rename src/examples/DungeonCrawler_tutorial/img/{i14d3f53f-a868-4820-84cd-63234ab6e6b9.png} => i14d3f53f-a868-4820-84cd-63234ab6e6b9.png} (100%) rename src/examples/DungeonCrawler_tutorial/img/{i14d3f53f-a868-4820-84cd-63234ab6e6b9.png}_prev.png => i14d3f53f-a868-4820-84cd-63234ab6e6b9.png_prev.png} (100%) rename src/examples/DungeonCrawler_tutorial/img/{i14d3f53f-a868-4820-84cd-63234ab6e6b9.png}_prev@2.png => i14d3f53f-a868-4820-84cd-63234ab6e6b9.png_prev@2.png} (100%) rename src/examples/DungeonCrawler_tutorial/img/{ia42e0dff-69c9-46c3-8996-745aaa769698.png} => ia42e0dff-69c9-46c3-8996-745aaa769698.png} (100%) rename src/examples/DungeonCrawler_tutorial/img/{ia42e0dff-69c9-46c3-8996-745aaa769698.png}_prev.png => ia42e0dff-69c9-46c3-8996-745aaa769698.png_prev.png} (100%) rename src/examples/DungeonCrawler_tutorial/img/{ia42e0dff-69c9-46c3-8996-745aaa769698.png}_prev@2.png => ia42e0dff-69c9-46c3-8996-745aaa769698.png_prev@2.png} (100%) delete mode 100644 src/examples/DungeonCrawler_tutorial/img/r127493eb58cf.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/r1cd7a8ef-febb-4174-ad90-42846504b06f.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/r1cd7a8ef-febb-4174-ad90-42846504b06f@r.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/r326893eb-b9c2-4616-aaee-bb4641e0423e.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/r326893eb-b9c2-4616-aaee-bb4641e0423e@r.png delete mode 100644 src/examples/DungeonCrawler_tutorial/img/r342f55fa6324.png delete mode 100644 src/examples/DungeonCrawler_tutorial/img/r3786dc4c7d4c.png delete mode 100644 src/examples/DungeonCrawler_tutorial/img/r42846504b06f.png delete mode 100644 src/examples/DungeonCrawler_tutorial/img/r6569f49f6b80.png delete mode 100644 src/examples/DungeonCrawler_tutorial/img/r7b6ea00c7b7c.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/rae6bb30c-9ad9-4390-b632-127493eb58cf.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/rae6bb30c-9ad9-4390-b632-127493eb58cf@r.png delete mode 100644 src/examples/DungeonCrawler_tutorial/img/rbb4641e0423e.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/ree8b4583-614a-44d6-aacc-6569f49f6b80.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/ree8b4583-614a-44d6-aacc-6569f49f6b80@r.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/reed8a427-1c70-425d-b633-7b6ea00c7b7c.png create mode 100644 src/examples/DungeonCrawler_tutorial/img/reed8a427-1c70-425d-b633-7b6ea00c7b7c@r.png create mode 100644 src/icons/cursor.svg create mode 100644 src/icons/lock.svg create mode 100644 src/icons/redo.svg create mode 100644 src/icons/undo.svg create mode 100644 src/icons/unlock.svg delete mode 100644 src/js/3rdparty/soundbox.js create mode 100644 src/js/addMigrationMethod.js delete mode 100644 src/js/loadProject.js create mode 100644 src/js/projectMigrationScripts/2.2.0.js create mode 100644 src/node_requires/3rdparty/soundbox.ts rename src/node_requires/resources/projects/{defaultProject.js => defaultProject.ts} (75%) create mode 100644 src/node_requires/roomEditor/IRoomEditorRiotTag.d.ts create mode 100644 src/node_requires/roomEditor/common.ts create mode 100644 src/node_requires/roomEditor/entityClasses/Background.ts create mode 100644 src/node_requires/roomEditor/entityClasses/Copy.ts create mode 100644 src/node_requires/roomEditor/entityClasses/MarqueeBox.ts create mode 100644 src/node_requires/roomEditor/entityClasses/SnapTarget.ts create mode 100644 src/node_requires/roomEditor/entityClasses/Tile.ts create mode 100644 src/node_requires/roomEditor/entityClasses/TileLayer.ts create mode 100644 src/node_requires/roomEditor/entityClasses/Transformer.ts create mode 100644 src/node_requires/roomEditor/entityClasses/Viewport.ts create mode 100644 src/node_requires/roomEditor/entityClasses/ViewportRestriction.ts create mode 100644 src/node_requires/roomEditor/history.ts create mode 100644 src/node_requires/roomEditor/index.ts create mode 100644 src/node_requires/roomEditor/interactions/camera/home.ts create mode 100644 src/node_requires/roomEditor/interactions/camera/move.ts create mode 100644 src/node_requires/roomEditor/interactions/camera/zoom.ts create mode 100644 src/node_requires/roomEditor/interactions/copies/deleteCopies.ts create mode 100644 src/node_requires/roomEditor/interactions/copies/placeCopy.ts create mode 100644 src/node_requires/roomEditor/interactions/copyPaste.ts create mode 100644 src/node_requires/roomEditor/interactions/history.ts create mode 100644 src/node_requires/roomEditor/interactions/index.ts create mode 100644 src/node_requires/roomEditor/interactions/mousePosLabel.ts create mode 100644 src/node_requires/roomEditor/interactions/placementCalculator.ts create mode 100644 src/node_requires/roomEditor/interactions/tiles/ITilePatch.d.ts create mode 100644 src/node_requires/roomEditor/interactions/tiles/deleteTiles.ts create mode 100644 src/node_requires/roomEditor/interactions/tiles/placeTile.ts create mode 100644 src/node_requires/roomEditor/interactions/transformer/delete.ts create mode 100644 src/node_requires/roomEditor/interactions/transformer/move.ts create mode 100644 src/node_requires/roomEditor/interactions/transformer/nudge.ts create mode 100644 src/node_requires/roomEditor/interactions/transformer/rotate.ts create mode 100644 src/node_requires/roomEditor/interactions/transformer/scale.ts create mode 100644 src/node_requires/roomEditor/interactions/transformer/select.ts rename src/node_requires/{ => utils}/imageUtils.ts (100%) create mode 100644 src/node_requires/utils/propUtils.ts create mode 100644 src/node_requires/utils/trigo.ts delete mode 100644 src/riotTags/rooms/copy-custom-properties-modal.tag delete mode 100644 src/riotTags/rooms/room-copy-properties.tag create mode 100644 src/riotTags/rooms/room-entities-properties.tag create mode 100644 src/riotTags/rooms/room-properties.tag create mode 100644 src/riotTags/rooms/room-template-picker.tag delete mode 100644 src/riotTags/rooms/room-type-picker.tag create mode 100644 src/riotTags/shared/error-notice.tag create mode 100644 src/styl/tags/rooms/room-backgrounds-editor.styl delete mode 100644 src/styl/tags/rooms/room-copy-properties.styl create mode 100644 src/styl/tags/rooms/room-tile-editor.styl create mode 100644 src/styl/tags/shared/error-notice.styl diff --git a/.eslintrc.json b/.eslintrc.json index a3c6afbb4..21de30d0c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,247 +1,248 @@ -{ - "root": true, - "env": { - "browser": true, - "commonjs": true, - "es6": true, - "node": true - }, - "plugins": ["pug", "@typescript-eslint"], - "globals": { - "alertify": true, - "dragonBones": true, - "monaco": true, - "nw": true, - "PIXI": true, - "QRCode": true, - "riot": true, - "soundbox": true - }, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 2018 - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended" - ], - "rules": { - "@typescript-eslint/no-var-requires": "off", - "accessor-pairs": "error", - "array-bracket-spacing": ["error", "never"], - "array-callback-return": "error", - "array-element-newline": ["error", "consistent"], - "arrow-body-style": "error", - "arrow-parens": "off", - "arrow-spacing": ["error", {"after": true, "before": true}], - "block-scoped-var": "error", - "block-spacing": ["error", "never"], - "brace-style": ["error", "1tbs", {"allowSingleLine": false}], - "callback-return": "off", - "camelcase": "error", - "capitalized-comments": ["off", "always"], - "class-methods-use-this": "error", - "comma-dangle": ["warn", "never"], - "comma-spacing": ["error", {"before": false, "after": true}], - "comma-style": ["error", "last"], - "complexity": "error", - "computed-property-spacing": ["error","never"], - "consistent-return": "error", - "consistent-this": "error", - "curly": "error", - "default-case": "error", - "dot-location": "off", - "dot-notation": "error", - "eol-last": ["error", "always"], - "eqeqeq": "error", - "func-call-spacing": ["error", "never"], - "func-name-matching": "error", - "func-names": ["error", "as-needed"], - "func-style": ["error", "expression"], - "function-paren-newline": ["error", "multiline"], - "generator-star-spacing": "error", - "global-require": "off", - "guard-for-in": "off", - "handle-callback-err": "error", - "id-blacklist": ["error", "data", "tag", "element"], - "id-length": ["error", {"min": 1, "max": 24}], - "id-match": "error", - "indent": ["error", 4, {"VariableDeclarator": "first", "MemberExpression": "off", "ignoreComments": true}], - "init-declarations": "off", - "jsx-quotes": "error", - "key-spacing": ["error", {"beforeColon": false, "afterColon": true, "mode": "strict"}], - "keyword-spacing": ["error", {"after": true, "before": true}], - "line-comment-position": "off", - "linebreak-style": ["error", "unix"], - "lines-around-comment": "off", - "max-depth": ["error", 4], - "max-len": ["error", {"code": 100, "ignoreComments": false, "ignoreUrls": true, "ignoreStrings": true, "ignoreTemplateLiterals": true, "ignoreRegExpLiterals": true}], - "max-lines": "off", - "max-lines-per-function": ["error", {"max": 80, "skipBlankLines": true, "skipComments": true}], - "max-nested-callbacks": ["error", 10], - "max-params": ["error", 5], - "max-statements": "off", - "max-statements-per-line": ["error", {"max": 1}], - "multiline-ternary": ["error", "always-multiline"], - "new-cap": "warn", - "new-parens": "error", - "newline-per-chained-call": ["error", {"ignoreChainWithDepth": 2}], - "no-alert": "error", - "no-array-constructor": "error", - "no-await-in-loop": "error", - "no-bitwise": "warn", - "no-caller": "error", - "no-confusing-arrow": "error", - "no-console": ["warn", { - "allow": ["error"] - }], - "no-continue": "off", - "no-div-regex": "error", - "no-duplicate-imports": "error", - "no-else-return": "error", - "no-empty-function": "error", - "no-eq-null": "error", - "no-eval": "error", - "no-extend-native": "error", - "no-extra-bind": "error", - "no-extra-label": "error", - "no-extra-parens": "off", - "no-floating-decimal": "error", - "no-implicit-coercion": "error", - "no-implicit-globals": "error", - "no-implied-eval": "error", - "no-inline-comments": "off", - "no-inner-declarations": [ - "error", - "functions" - ], - "no-invalid-this": "off", - "no-iterator": "error", - "no-label-var": "error", - "no-labels": "error", - "no-lone-blocks": "error", - "no-lonely-if": "error", - "no-loop-func": "error", - "no-magic-numbers": "off", - "no-mixed-operators": [ - "error", - { - "groups": [ - ["&", "|", "^", "~", "<<", ">>", ">>>"], - ["==", "!=", "===", "!==", ">", ">=", "<", "<="], - ["&&", "||"], - ["in", "instanceof"] - ], - "allowSamePrecedence": true - } - ], - "no-mixed-requires": "error", - "no-mixed-spaces-and-tabs": "error", - "no-multi-spaces": "error", - "no-multi-str": "error", - "no-multiple-empty-lines": ["error", {"max": 2, "maxEOF": 1}], - "no-negated-condition": "off", - "no-nested-ternary": "error", - "no-new": "error", - "no-new-func": "error", - "no-new-object": "error", - "no-new-require": "error", - "no-new-wrappers": "error", - "no-octal-escape": "error", - "no-param-reassign": "off", - "no-path-concat": "error", - "no-plusplus": "off", - "no-process-env": "warn", - "no-process-exit": "error", - "no-proto": "error", - "no-prototype-builtins": "error", - "no-restricted-globals": "error", - "no-restricted-imports": "error", - "no-restricted-modules": "error", - "no-restricted-properties": "error", - "no-restricted-syntax": ["error", "WithStatement"], - "no-return-assign": "error", - "no-return-await": "error", - "no-script-url": "error", - "no-self-compare": "error", - "no-sequences": "error", - "no-shadow": "off", - "no-shadow-restricted-names": "error", - "no-sync": "off", - "no-tabs": "error", - "no-template-curly-in-string": "error", - "no-ternary": "off", - "no-throw-literal": "error", - "no-trailing-spaces": "error", - "no-undef-init": "error", - "no-undefined": "error", - "no-underscore-dangle": ["error", {"allow": ["__dirname"]}], - "no-unmodified-loop-condition": "error", - "no-unneeded-ternary": "error", - "no-unsafe-negation": "error", - "no-unused-expressions": "error", - "no-use-before-define": "error", - "no-useless-call": "error", - "no-useless-computed-key": "error", - "no-useless-concat": "error", - "no-useless-constructor": "error", - "no-useless-escape": "error", - "no-useless-rename": "error", - "no-useless-return": "error", - "no-var": "off", - "no-void": "off", - "no-warning-comments": "warn", - "no-whitespace-before-property": "error", - "no-with": "error", - "object-curly-newline": ["error", { - "ObjectExpression": {"minProperties": 1}, - "ObjectPattern": "never", - "ImportDeclaration": "never", - "ExportDeclaration": {"multiline": true, "minProperties": 2} - }], - "object-curly-spacing": ["error", "never"], - "object-property-newline": ["error", {"allowAllPropertiesOnSameLine": true}], - "object-shorthand": "error", - "one-var": "off", - "one-var-declaration-per-line": ["error", "initializations"], - "operator-assignment": "error", - "operator-linebreak": ["error", "after"], - "padded-blocks": ["error", "never"], - "prefer-arrow-callback": "off", - "prefer-const": "error", - "prefer-destructuring": "error", - "prefer-exponentiation-operator": "warn", - "prefer-numeric-literals": "error", - "prefer-rest-params": "error", - "prefer-spread": "error", - "prefer-template": "off", - "quote-props": ["error", "as-needed"], - "quotes": ["error", "single"], - "radix": "error", - "require-atomic-updates": "error", - "require-await": "error", - "rest-spread-spacing": "error", - "semi": ["error", "always"], - "semi-spacing": "error", - "semi-style": ["error", "last"], - "sort-imports": "off", - "sort-keys": "off", - "sort-vars": "off", - "space-before-blocks": ["error", "always"], - "space-before-function-paren": ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}], - "space-in-parens": ["error", "never"], - "space-infix-ops": "error", - "space-unary-ops": "error", - "spaced-comment": "error", - "strict": "off", - "symbol-description": "error", - "template-curly-spacing": ["error", "never"], - "template-tag-spacing": ["error", "never"], - "unicode-bom": ["error", "never"], - "vars-on-top": "off", - "wrap-regex": "off", - "yield-star-spacing": "error", - "yoda": ["error", "never"] - } -} +{ + "root": true, + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "node": true + }, + "plugins": ["pug", "@typescript-eslint"], + "globals": { + "alertify": true, + "dragonBones": true, + "monaco": true, + "nw": true, + "PIXI": true, + "QRCode": true, + "riot": true, + "soundbox": true + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2018 + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@typescript-eslint/no-var-requires": "off", + "accessor-pairs": "error", + "array-bracket-spacing": ["error", "never"], + "array-callback-return": "error", + "array-element-newline": ["error", "consistent"], + "arrow-body-style": "error", + "arrow-parens": "off", + "arrow-spacing": ["error", {"after": true, "before": true}], + "block-scoped-var": "error", + "block-spacing": ["error", "never"], + "brace-style": ["error", "1tbs", {"allowSingleLine": false}], + "callback-return": "off", + "camelcase": "error", + "capitalized-comments": ["off", "always"], + "class-methods-use-this": "error", + "comma-dangle": ["warn", "never"], + "comma-spacing": ["error", {"before": false, "after": true}], + "comma-style": ["error", "last"], + "complexity": "error", + "computed-property-spacing": ["error","never"], + "consistent-return": "error", + "consistent-this": "error", + "curly": "error", + "default-case": "error", + "dot-location": "off", + "dot-notation": "error", + "eol-last": ["error", "always"], + "eqeqeq": "error", + "func-call-spacing": ["error", "never"], + "func-name-matching": "error", + "func-names": ["error", "as-needed"], + "func-style": ["error", "expression"], + "function-paren-newline": ["error", "multiline"], + "generator-star-spacing": "error", + "global-require": "off", + "guard-for-in": "off", + "handle-callback-err": "error", + "id-blacklist": ["error", "data", "tag", "element"], + "id-length": ["error", {"min": 1, "max": 24}], + "id-match": "error", + "indent": ["error", 4, {"VariableDeclarator": "first", "MemberExpression": "off", "ignoreComments": true}], + "init-declarations": "off", + "jsx-quotes": "error", + "key-spacing": ["error", {"beforeColon": false, "afterColon": true, "mode": "strict"}], + "keyword-spacing": ["error", {"after": true, "before": true}], + "line-comment-position": "off", + "linebreak-style": ["error", "unix"], + "lines-around-comment": "off", + "max-depth": ["error", 4], + "max-len": ["error", {"code": 100, "ignoreComments": false, "ignoreUrls": true, "ignoreStrings": true, "ignoreTemplateLiterals": true, "ignoreRegExpLiterals": true}], + "max-lines": "off", + "max-lines-per-function": ["error", {"max": 80, "skipBlankLines": true, "skipComments": true}], + "max-nested-callbacks": ["error", 10], + "max-params": ["error", 5], + "max-statements": "off", + "max-statements-per-line": ["error", {"max": 1}], + "multiline-ternary": ["error", "always-multiline"], + "new-cap": "warn", + "new-parens": "error", + "newline-per-chained-call": ["error", {"ignoreChainWithDepth": 2}], + "no-alert": "error", + "no-array-constructor": "error", + "no-await-in-loop": "error", + "no-bitwise": "warn", + "no-caller": "error", + "no-confusing-arrow": "error", + "no-console": ["warn", { + "allow": ["error"] + }], + "no-continue": "off", + "no-div-regex": "error", + "no-duplicate-imports": "error", + "no-else-return": "error", + "no-empty-function": "error", + "no-eq-null": "error", + "no-eval": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-extra-parens": "off", + "no-floating-decimal": "error", + "no-implicit-coercion": "error", + "no-implicit-globals": "error", + "no-implied-eval": "error", + "no-inline-comments": "off", + "no-inner-declarations": [ + "error", + "functions" + ], + "no-invalid-this": "off", + "no-iterator": "error", + "no-label-var": "error", + "no-labels": "error", + "no-lone-blocks": "error", + "no-lonely-if": "error", + "no-loop-func": "error", + "no-magic-numbers": "off", + "no-mixed-operators": [ + "error", + { + "groups": [ + ["&", "|", "^", "~", "<<", ">>", ">>>"], + ["==", "!=", "===", "!==", ">", ">=", "<", "<="], + ["&&", "||"], + ["in", "instanceof"] + ], + "allowSamePrecedence": true + } + ], + "no-mixed-requires": "error", + "no-mixed-spaces-and-tabs": "error", + "no-multi-spaces": "error", + "no-multi-str": "error", + "no-multiple-empty-lines": ["error", {"max": 2, "maxEOF": 1}], + "no-negated-condition": "off", + "no-nested-ternary": "error", + "no-new": "error", + "no-new-func": "error", + "no-new-object": "error", + "no-new-require": "error", + "no-new-wrappers": "error", + "no-octal-escape": "error", + "no-param-reassign": "off", + "no-path-concat": "error", + "no-plusplus": "off", + "no-process-env": "warn", + "no-process-exit": "error", + "no-proto": "error", + "no-prototype-builtins": "error", + "no-restricted-globals": "error", + "no-restricted-imports": "error", + "no-restricted-modules": "error", + "no-restricted-properties": "error", + "no-restricted-syntax": ["error", "WithStatement"], + "no-return-assign": "error", + "no-return-await": "error", + "no-script-url": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-shadow": "off", + "no-shadow-restricted-names": "error", + "no-sync": "off", + "no-tabs": "error", + "no-template-curly-in-string": "error", + "no-ternary": "off", + "no-throw-literal": "error", + "no-trailing-spaces": "error", + "no-undef-init": "error", + "no-undefined": "error", + "no-underscore-dangle": ["error", {"allow": ["__dirname"]}], + "no-unmodified-loop-condition": "error", + "no-unneeded-ternary": "error", + "no-unsafe-negation": "error", + "no-unused-expressions": "off", + "@typescript-eslint/no-unused-expressions": "error", + "no-use-before-define": "error", + "no-useless-call": "error", + "no-useless-computed-key": "error", + "no-useless-concat": "error", + "no-useless-constructor": "error", + "no-useless-escape": "error", + "no-useless-rename": "error", + "no-useless-return": "error", + "no-var": "off", + "no-void": "off", + "no-warning-comments": "warn", + "no-whitespace-before-property": "error", + "no-with": "error", + "object-curly-newline": ["error", { + "ObjectExpression": {"minProperties": 1}, + "ObjectPattern": "never", + "ImportDeclaration": "never", + "ExportDeclaration": {"multiline": true, "minProperties": 2} + }], + "object-curly-spacing": ["error", "never"], + "object-property-newline": ["error", {"allowAllPropertiesOnSameLine": true}], + "object-shorthand": "error", + "one-var": "off", + "one-var-declaration-per-line": ["error", "initializations"], + "operator-assignment": "error", + "operator-linebreak": ["error", "after"], + "padded-blocks": ["error", "never"], + "prefer-arrow-callback": "off", + "prefer-const": "error", + "prefer-destructuring": "error", + "prefer-exponentiation-operator": "warn", + "prefer-numeric-literals": "error", + "prefer-rest-params": "error", + "prefer-spread": "error", + "prefer-template": "off", + "quote-props": ["error", "as-needed"], + "quotes": ["error", "single"], + "radix": "error", + "require-atomic-updates": "error", + "require-await": "error", + "rest-spread-spacing": "error", + "semi": ["error", "always"], + "semi-spacing": "error", + "semi-style": ["error", "last"], + "sort-imports": "off", + "sort-keys": "off", + "sort-vars": "off", + "space-before-blocks": ["error", "always"], + "space-before-function-paren": ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}], + "space-in-parens": ["error", "never"], + "space-infix-ops": "error", + "space-unary-ops": "error", + "spaced-comment": "error", + "strict": "off", + "symbol-description": "error", + "template-curly-spacing": ["error", "never"], + "template-tag-spacing": ["error", "never"], + "unicode-bom": ["error", "never"], + "vars-on-top": "off", + "wrap-regex": "off", + "yield-star-spacing": "error", + "yoda": ["error", "never"] + } +} diff --git a/app/data/Wood_End.wav b/app/data/Wood_End.wav new file mode 100644 index 0000000000000000000000000000000000000000..2e0b68c85d982596a46ae313e71bb8bba62263e8 GIT binary patch literal 273724 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

Vf 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 NbTy4MDq(iv{{=s@w-f*X diff --git a/src/icons/cursor.svg b/src/icons/cursor.svg new file mode 100644 index 000000000..56102beca --- /dev/null +++ b/src/icons/cursor.svg @@ -0,0 +1,2 @@ + + diff --git a/src/icons/lock.svg b/src/icons/lock.svg new file mode 100644 index 000000000..de09d9db3 --- /dev/null +++ b/src/icons/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/redo.svg b/src/icons/redo.svg new file mode 100644 index 000000000..996380f66 --- /dev/null +++ b/src/icons/redo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/icons/undo.svg b/src/icons/undo.svg new file mode 100644 index 000000000..4a23bbdef --- /dev/null +++ b/src/icons/undo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/icons/unlock.svg b/src/icons/unlock.svg new file mode 100644 index 000000000..01dc35973 --- /dev/null +++ b/src/icons/unlock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/js/3rdparty/alertify.js b/src/js/3rdparty/alertify.js index c5329270e..d2d0d0222 100644 --- a/src/js/3rdparty/alertify.js +++ b/src/js/3rdparty/alertify.js @@ -395,6 +395,7 @@ _alertify.injectCSS(); + const {soundbox} = require('./data/node_requires/3rdparty/soundbox'); return { _$$alertify: _alertify, parent(elem) { diff --git a/src/js/3rdparty/soundbox.js b/src/js/3rdparty/soundbox.js deleted file mode 100644 index 6148b18e4..000000000 --- a/src/js/3rdparty/soundbox.js +++ /dev/null @@ -1,11 +0,0 @@ -(function () { - 'use strict';class SoundBox{constructor(){this.sounds={};this.instances=[];this.default_volume=1}load(a,b,d){this.sounds[a]=new Audio(b);if("function"==typeof d)this.sounds[a].addEventListener("canplaythrough",d);else return new Promise((c,b)=>{this.sounds[a].addEventListener("canplaythrough",c);this.sounds[a].addEventListener("error",b)})}remove(a){"undefined"!=typeof this.sounds&&delete this.sounds[a]}play(a,b,d=null){if("undefined"==typeof this.sounds[a])return console.error("Can't find sound called '"+ -a+"'."),!1;var c=this.sounds[a].cloneNode(!0);c.volume=d||this.default_volume;c.play();this.instances.push(c);c.addEventListener("ended",()=>{let a=this.instances.indexOf(c);-1!=a&&this.instances.splice(a,1)});return"function"==typeof b?(c.addEventListener("ended",b),!0):new Promise((a,b)=>c.addEventListener("ended",a))}stop_all(){let a=this.instances.slice();for(let b of a)b.pause(),b.dispatchEvent(new Event("ended"))}}SoundBox.version="0.3.4"; - - const soundbox = new SoundBox(); - - soundbox.load('Success', 'data/Success.wav'); - soundbox.load('Failure', 'data/Failure.wav'); - - window.soundbox = soundbox; -})(); diff --git a/src/js/addMigrationMethod.js b/src/js/addMigrationMethod.js new file mode 100644 index 000000000..134239a42 --- /dev/null +++ b/src/js/addMigrationMethod.js @@ -0,0 +1,11 @@ +(function addMigrationMethod(window) { + window.migrationProcess = window.migrationProcess || []; + window.applyMigrationCode = function applyMigrationCode(version) { + const process = window.migrationProcess.find(process => process.version === version); + if (!process) { + throw new Error(`Cannot find migration code for version ${version}`); + } + process.process(global.currentProject) + .then(() => window.alertify.success(`Applied migration code for version ${version}`, 'success', 3000)); + }; +})(this); diff --git a/src/js/loadProject.js b/src/js/loadProject.js deleted file mode 100644 index e012ae300..000000000 --- a/src/js/loadProject.js +++ /dev/null @@ -1,239 +0,0 @@ -(function addLoadProjectMethod(window) { - window.migrationProcess = window.migrationProcess || []; - window.applyMigrationCode = function applyMigrationCode(version) { - const process = window.migrationProcess.find(process => process.version === version); - if (!process) { - throw new Error(`Cannot find migration code for version ${version}`); - } - process.process(global.currentProject) - .then(() => window.alertify.success(`Applied migration code for version ${version}`, 'success', 3000)); - }; - - const fs = require('fs-extra'), - path = require('path'); - // @see https://semver.org/ - const semverRegex = /(\d+)\.(\d+)\.(\d+)(-[A-Za-z.-]*(\d+)?[A-Za-z.-]*)?/; - const semverToArray = string => { - const raw = semverRegex.exec(string); - return [ - raw[1], - raw[2], - raw[3], - // -next- versions and other postfixes will count as a fourth component. - // They all will apply before regular versions - raw[4] ? raw[5] || 1 : null - ]; - }; - - /** - * Applies migration scripts to older projects. - */ - var adapter = async project => { - var version = semverToArray(project.ctjsVersion || '0.2.0'); - - const migrationToExecute = window.migrationProcess - // Sort all the patches chronologically - .sort((m1, m2) => { - const m1Version = semverToArray(m1.version); - const m2Version = semverToArray(m2.version); - - for (let i = 0; i < 4; i++) { - if (m1Version[i] < m2Version[i] || m1Version[i] === null) { - return -1; - } else if (m1Version[i] > m2Version[i]) { - return 1; - } - } - // eslint-disable-next-line no-console - console.warn(`Two equivalent versions found for migration, ${m1.version} and ${m2.version}.`); - return 0; - }) - // Throw out patches for current and previous versions - .filter((migration) => { - const migrationVersion = semverToArray(migration.version); - for (let i = 0; i < 3; i++) { - // if any of the first three version numbers is lower than project's, - // skip the patch - if (migrationVersion[i] < version[i]) { - return false; - } - if (migrationVersion[i] > version[i]) { - return true; - } - } - // a lazy check for equal base versions - if (migrationVersion.slice(0, 3).join('.') === version.slice(0, 3).join('.')) { - // handle the case with two postfixed versions - if (migrationVersion[3] !== null && version[3] !== null) { - return migrationVersion[3] > version[3]; - } - // postfixed source, unpostfixed patch - if (migrationVersion[3] === null && version[3] !== null) { - return true; - } - return false; - } - return true; - }); - - if (migrationToExecute.length) { - // eslint-disable-next-line no-console - console.debug(`Applying migration sequence: patches ${migrationToExecute.map(m => m.version).join(', ')}.`); - } - for (const migration of migrationToExecute) { - // eslint-disable-next-line no-console - console.debug(`Migrating project from version ${project.ctjsVersion || '0.2.0'} to ${migration.version}`); - // We do need to apply updates in a sequence - // eslint-disable-next-line no-await-in-loop - await migration.process(project); - } - - // Unfortunately, recent versions of eslint give false positives on this line - // @see https://github.com/eslint/eslint/issues/11900 - // @see https://github.com/eslint/eslint/issues/11899 - // eslint-disable-next-line require-atomic-updates - project.ctjsVersion = process.versions.ctjs; - }; - - /** - * Opens the project and refreshes the whole app. - * - * @param {Object} projectData Loaded JSON file, in js object form - * @returns {void} - */ - var loadProject = async projectData => { - const glob = require('./data/node_requires/glob'); - global.currentProject = projectData; - window.alertify.log(window.languageJSON.intro.loadingProject); - glob.modified = false; - - try { - await adapter(projectData); - fs.ensureDir(global.projdir); - fs.ensureDir(global.projdir + '/img'); - fs.ensureDir(global.projdir + '/snd'); - - const lastProjects = localStorage.lastProjects ? localStorage.lastProjects.split(';') : []; - if (lastProjects.indexOf(path.normalize(global.projdir + '.ict')) !== -1) { - lastProjects.splice(lastProjects.indexOf(path.normalize(global.projdir + '.ict')), 1); - } - lastProjects.unshift(path.normalize(global.projdir + '.ict')); - if (lastProjects.length > 15) { - lastProjects.pop(); - } - localStorage.lastProjects = lastProjects.join(';'); - - if (global.currentProject.settings.title) { - document.title = global.currentProject.settings.title + ' — ct.js'; - } - - glob.scriptTypings = {}; - for (const script of global.currentProject.scripts) { - glob.scriptTypings[script.name] = [ - monaco.languages.typescript.javascriptDefaults.addExtraLib(script.code), - monaco.languages.typescript.typescriptDefaults.addExtraLib(script.code) - ]; - } - - const {loadAllTypedefs, resetTypedefs} = require('./data/node_requires/resources/modules/typedefs'); - resetTypedefs(); - loadAllTypedefs(); - - const {unloadAllEvents, loadAllModulesEvents} = require('./data/node_requires/events'); - unloadAllEvents(); - await loadAllModulesEvents(); - - window.signals.trigger('projectLoaded'); - setTimeout(() => { - window.riot.update(); - }, 0); - } catch (err) { - window.alertify.alert(window.languageJSON.intro.loadingProjectError + err); - } - }; - - /** - * Checks file format and loads it - * - * @param {String} proj The path to the file. - * @returns {void} - */ - var loadProjectFile = async proj => { - const textProjData = await fs.readFile(proj, 'utf8'); - let projectData; - // Before v1.3, projects were stored in JSON format - try { - if (textProjData.indexOf('{') === 0) { // First, make a silly check for JSON files - projectData = JSON.parse(textProjData); - } else { - try { - const YAML = require('js-yaml'); - projectData = YAML.load(textProjData); - } catch (e) { - // whoopsie, wrong window - // eslint-disable-next-line no-console - console.warn(`Tried to load a file ${proj} as a YAML, but got an error (see below). Falling back to JSON.`); - console.error(e); - projectData = JSON.parse(textProjData); - } - } - } catch (e) { - window.alertify.error(e); - throw e; - } - if (!projectData) { - window.alertify.error(window.languageJSON.common.wrongFormat); - return; - } - try { - loadProject(projectData); - } catch (e) { - window.alertify.error(e); - throw e; - } - }; - - window.loadProject = async proj => { - if (!proj) { - const baseMessage = 'An attempt to open a project with an empty path.'; - alertify.error(baseMessage + ' See the console for the call stack.'); - const err = new Error(baseMessage); - throw err; - } - sessionStorage.projname = path.basename(proj); - global.projdir = path.dirname(proj) + path.sep + path.basename(proj, '.ict'); - - let recoveryStat; - try { - recoveryStat = await fs.stat(proj + '.recovery'); - } catch (err) { - // no recovery file found - void 0; - } - if (recoveryStat && recoveryStat.isFile()) { - const targetStat = await fs.stat(proj); - const voc = window.languageJSON.intro.recovery; - const userResponse = await window.alertify - .okBtn(voc.loadRecovery) - .cancelBtn(voc.loadTarget) - /* {0} — target file date - {1} — target file state (newer/older) - {2} — recovery file date - {3} — recovery file state (newer/older) - */ - .confirm(voc.message - .replace('{0}', targetStat.mtime.toLocaleString()) - .replace('{1}', targetStat.mtime < recoveryStat.mtime ? voc.older : voc.newer) - .replace('{2}', recoveryStat.mtime.toLocaleString()) - .replace('{3}', recoveryStat.mtime < targetStat.mtime ? voc.older : voc.newer)); - window.alertify - .okBtn(window.languageJSON.common.ok) - .cancelBtn(window.languageJSON.common.cancel); - if (userResponse.buttonClicked === 'ok') { - return loadProjectFile(proj + '.recovery'); - } - return loadProjectFile(proj); - } - return loadProjectFile(proj); - }; -})(this); diff --git a/src/js/projectMigrationScripts/2.1.0.js b/src/js/projectMigrationScripts/2.1.0.js index 6f2e915f2..d6ed06abf 100644 --- a/src/js/projectMigrationScripts/2.1.0.js +++ b/src/js/projectMigrationScripts/2.1.0.js @@ -2,6 +2,7 @@ window.migrationProcess = window.migrationProcess || []; window.migrationProcess.push({ version: '2.1.0', + // eslint-disable-next-line max-lines-per-function process: project => new Promise(resolve => { const templateEventMap = { oncreate: 'OnCreate', @@ -36,6 +37,7 @@ window.migrationProcess.push({ } } for (const room of project.rooms) { + room.simulate = true; if (!room.events) { room.events = []; for (const key in roomEventMap) { @@ -52,6 +54,40 @@ window.migrationProcess.push({ } room.type = 'room'; } + // Break up tile chunks into individual tiles + for (const room of project.rooms) { + for (const layer of room.tiles) { + layer.tiles = layer.tiles.reduce((tiles, tile) => { + const tex = project.textures.find(t => t.uid === tile.texture); + if (!tile.grid) { + tiles.push(tile); + return tiles; + } + // grid: [tileX, tileY, tileSpanX, tileSpanY] + // eslint-disable-next-line prefer-destructuring + for (let x = tile.grid[0]; x < tile.grid[0] + tile.grid[2]; x++) { + // eslint-disable-next-line prefer-destructuring + for (let y = tile.grid[1]; y < tile.grid[1] + tile.grid[3]; y++) { + tiles.push({ + x: tile.x + tex.axis[0], + y: tile.y + tex.axis[1], + opacity: tile.opacity ?? 1, + tint: tile.tint ?? 0xffffff, + scale: { + x: tile.scale?.x ?? 1, + y: tile.scale?.y ?? 1 + }, + frame: x + y * tex.grid[0], + rotation: tile.rotation ?? 0, + texture: tile.texture + }); + } + } + delete tile.grid; + return tiles; + }, []); + } + } resolve(); }) }); diff --git a/src/js/projectMigrationScripts/2.2.0.js b/src/js/projectMigrationScripts/2.2.0.js new file mode 100644 index 000000000..f8d8c2117 --- /dev/null +++ b/src/js/projectMigrationScripts/2.2.0.js @@ -0,0 +1,24 @@ +window.migrationProcess = window.migrationProcess || []; + +window.migrationProcess.push({ + version: '2.2.0', + // eslint-disable-next-line max-lines-per-function + process: project => new Promise(resolve => { + for (const room of project.rooms) { + room.isUi = room.extends.isUi; + delete room.extends.isUi; + for (const copy of room.copies) { + copy.exts = copy.exts ?? {}; + copy.customProperties = copy.customProperties ?? {}; + copy.opacity = copy.opacity ?? 1; + copy.tint = copy.tint ?? 0xffffff; + copy.rotation = copy.rotation ?? 0; + copy.scale = copy.scale ?? { + x: 1, + y: 1 + }; + } + } + resolve(); + }) +}); diff --git a/src/node_requires/3rdparty/soundbox.ts b/src/node_requires/3rdparty/soundbox.ts new file mode 100644 index 000000000..9633cd912 --- /dev/null +++ b/src/node_requires/3rdparty/soundbox.ts @@ -0,0 +1,55 @@ +'use strict'; + +type knownSoundNames = 'Success' | 'Failure' | 'Wood_Start' | 'Wood_End'; + +class SoundBox { + static version: string; + sounds: Record = {}; + instances: HTMLAudioElement[] = []; + default_volume = 1; + get mute() { + return localStorage.disableSounds === 'on'; + } + load(name: knownSoundNames, url: string, callback?: (this: HTMLAudioElement, ev: Event) => any) { + this.sounds[name] = new Audio(url); + if ("function" == typeof callback) { + this.sounds[name].addEventListener("canplaythrough", callback); + } else { + return new Promise((c, b) => { + this.sounds[name].addEventListener("canplaythrough", c); + this.sounds[name].addEventListener("error", b) + }) + } + } + remove(name: knownSoundNames) { + "undefined" != typeof this.sounds && delete this.sounds[name] + } + play(name: knownSoundNames, callback?: (this: HTMLAudioElement, ev: Event) => any, volume?: number) { + if (this.mute) { + return; + } + if ("undefined" == typeof this.sounds[name]) { + return console.error(`Can't find sound called '${name}'.`), false; + } + var audioTag = this.sounds[name].cloneNode(true) as HTMLAudioElement; + audioTag.volume = volume ?? this.default_volume; + audioTag.play(); + this.instances.push(audioTag); + audioTag.addEventListener("ended", () => { + let a = this.instances.indexOf(audioTag); - 1 != a && this.instances.splice(a, 1) + }); + return "function" == typeof callback ? (audioTag.addEventListener("ended", callback), !0) : new Promise((a, b) => audioTag.addEventListener("ended", a)) + } + stop_all() { + let a = this.instances.slice(); + for (let b of a) b.pause(), b.dispatchEvent(new Event("ended")) + } +} +SoundBox.version = "0.3.4"; + +export const soundbox = new SoundBox(); + +soundbox.load('Success', 'data/Success.wav'); +soundbox.load('Failure', 'data/Failure.wav'); +soundbox.load('Wood_Start', 'data/Wood_Start.wav'); +soundbox.load('Wood_End', 'data/Wood_End.wav'); diff --git a/src/node_requires/IMenuItem.d.ts b/src/node_requires/IMenuItem.d.ts index 14634b731..91bfca164 100644 --- a/src/node_requires/IMenuItem.d.ts +++ b/src/node_requires/IMenuItem.d.ts @@ -46,11 +46,14 @@ declare interface IMenuItem { submenu?: IMenu, /** - * E.g. 'Control+c' + * E.g. 'Control+c'. Binds the element to hotkey.js library. */ hotkey?: string, /** * A human-readable variant, e.g. 'Ctrl+C'. Fallbacks to `hotkey`. + * If set without `hotkey`, still shows the label but does not + * bind the element to the hotkey.js library. + * The label is wrapped into (parentheses) automatically. */ hotkeyLabel?: string } diff --git a/src/node_requires/events/index.ts b/src/node_requires/events/index.ts index 33097c8da..2422f9e09 100644 --- a/src/node_requires/events/index.ts +++ b/src/node_requires/events/index.ts @@ -278,7 +278,7 @@ const unloadAllEvents = (): void => { } }; -export = { +export { categories, events, bakeCategories, diff --git a/src/node_requires/exporter/index.ts b/src/node_requires/exporter/index.ts index 7417b171f..a123d06e4 100644 --- a/src/node_requires/exporter/index.ts +++ b/src/node_requires/exporter/index.ts @@ -205,6 +205,7 @@ const exportCtProject = async ( projdir: string, production: boolean ): Promise => { + window.signals.trigger('exportProject'); currentProject = project; await removeBrokenModules(project); resetEventsCache(); diff --git a/src/node_requires/exporter/rooms.ts b/src/node_requires/exporter/rooms.ts index c3aee985b..d45477774 100644 --- a/src/node_requires/exporter/rooms.ts +++ b/src/node_requires/exporter/rooms.ts @@ -40,8 +40,16 @@ interface IExportedTile { x: number, y: number, width: number, - height: number + height: number, + opacity: number, + rotation: number, + scale: { + x: number, + y: number + }, + tint: number } +type ExportedCopy = Omit & {template: string}; // eslint-disable-next-line max-lines-per-function const stringifyRooms = (proj: IProject): IScriptablesFragment => { @@ -52,12 +60,14 @@ const stringifyRooms = (proj: IProject): IScriptablesFragment => { let rootRoomOnLeave = ''; for (const r of proj.rooms) { - const roomCopy = JSON.parse(JSON.stringify(r.copies)); - const objs = []; - for (const copy of roomCopy) { - copy.template = proj.templates[glob.templatemap[copy.uid]].name; - delete copy.uid; - objs.push(copy); + const objs: ExportedCopy[] = []; + for (const copy of r.copies) { + const exportableCopy = { + ...copy, + template: proj.templates[glob.templatemap[copy.uid]].name + }; + delete exportableCopy.uid; + objs.push(exportableCopy); } const bgsCopy = JSON.parse(JSON.stringify(r.backgrounds)); for (const bg in bgsCopy) { @@ -75,19 +85,22 @@ const stringifyRooms = (proj: IProject): IScriptablesFragment => { extends: tileLayer.extends ? getUnwrappedExtends(tileLayer.extends) : {} }; for (const tile of tileLayer.tiles) { - for (let x = 0; x < tile.grid[2]; x++) { - for (let y = 0; y < tile.grid[3]; y++) { - const texture = glob.texturemap[tile.texture].g; - layer.tiles.push({ - texture: texture.name, - frame: tile.grid[0] + x + (y + tile.grid[1]) * texture.grid[0], - x: tile.x + x * (texture.width + texture.marginx), - y: tile.y + y * (texture.height + texture.marginy), - width: texture.width, - height: texture.height - }); - } - } + const texture = glob.texturemap[tile.texture].g; + layer.tiles.push({ + texture: texture.name, + frame: tile.frame, + x: tile.x, + y: tile.y, + width: texture.width, + height: texture.height, + opacity: tile.opacity, + rotation: tile.rotation, + scale: { + x: tile.scale.x, + y: tile.scale.y + }, + tint: tile.tint + }); } tileLayers.push(layer); } @@ -119,6 +132,7 @@ ct.rooms.templates['${r.name}'] = { onCreate() { ${scriptableCode.thisOnCreate} }, + isUi: ${r.isUi}, extends: ${r.extends ? JSON.stringify(getUnwrappedExtends(r.extends), null, 4) : '{}'} } `; diff --git a/src/node_requires/exporter/templates.ts b/src/node_requires/exporter/templates.ts index db84234ec..960b09440 100644 --- a/src/node_requires/exporter/templates.ts +++ b/src/node_requires/exporter/templates.ts @@ -17,6 +17,7 @@ const stringifyTemplates = function (proj: IProject): IScriptablesFragment { ct.templates.templates["${template.name}"] = { depth: ${template.depth}, blendMode: PIXI.BLEND_MODES.${template.blendMode?.toUpperCase() ?? 'NORMAL'}, + animationFPS: ${template.animationFPS ?? 60}, playAnimationOnStart: ${Boolean(template.playAnimationOnStart)}, loopAnimation: ${Boolean(template.loopAnimation)}, ${template.texture !== -1 ? 'texture: "' + getTextureFromId(template.texture).name + '",' : ''} diff --git a/src/node_requires/extendGlobals.d.ts b/src/node_requires/extendGlobals.d.ts index 794d1b480..d832d8f3e 100644 --- a/src/node_requires/extendGlobals.d.ts +++ b/src/node_requires/extendGlobals.d.ts @@ -11,6 +11,8 @@ declare global { var monaco: any; var currentProject: IProject; var projdir: string; + var migrationProcess: any[]; + var riot: any; function showOpenDialog(options: any): Promise; function showSaveDialog(options: any): Promise; interface Window { diff --git a/src/node_requires/hotkeys.js b/src/node_requires/hotkeys.js index 116be69a0..057fb9000 100644 --- a/src/node_requires/hotkeys.js +++ b/src/node_requires/hotkeys.js @@ -12,6 +12,13 @@ on key presses in a declarative way, based on HTML markup plus a couple of scopi On each key press, the lib queries the document for the resulting key combination. The selector is `[data-hotkey="Your-Code"]` +Your-Code is in form `Ctrl+Alt+Meta+X`, where X is a pressed letter. +If you need the Shift key modifier, the letter will be an uppercase one. +If not, use the lowercase letter. +The code for Shift+S is just `S`, the code for just S key is `s`. +Every modifier is optional. Examples: `l`, `5`, `Ctrl+1`, `Ctrl+C`. +Do follow the order of modifiers: `Ctrl+Alt+c` is valid, but `Alt+Ctrl+c` is not. + You can narrow the scope of the query by calling `hotkey.push(scope)`. (See more methods below.) The scope is nested, forming a stack. If a scope is specified, it is read from the most recently added part to the outer scope, trying to call the elements that are inside a scoped parent. @@ -67,6 +74,7 @@ const hotkeyRef = Symbol('hotkey'); class Hotkeys { constructor(doc) { + this.isFormField = isFormField; this.document = doc; this.document[hotkeyRef] = this; this.scopeStack = []; @@ -74,8 +82,12 @@ class Hotkeys { this[offDomEventsRef] = new Map(); this[listenerRef] = e => { + // Ignore key events when typing into form fields + if (isFormField(e.target)) { + return; + } const code = getCode(e); - this.trigger(code); + this.trigger(code, e); }; this.document.body.addEventListener('keydown', this[listenerRef]); } @@ -98,12 +110,13 @@ class Hotkeys { this[offDomEventsRef].set(code, []); } } - trigger(code) { + trigger(code, event) { const offDom = this[offDomEventsRef].get(code); if (offDom) { for (const event of offDom) { event(); } + event.preventDefault(); } // querySelectorAll returns a NodeList, which is not a sortable array. Convert by spreading. @@ -128,6 +141,7 @@ class Hotkeys { } else { elt.click(); } + event.preventDefault(); return; } } @@ -143,6 +157,7 @@ class Hotkeys { } else { elt.click(); } + event.preventDefault(); return; } } diff --git a/src/node_requires/resources/emitterTandems/index.ts b/src/node_requires/resources/emitterTandems/index.ts index 885ba209e..0237ec0ac 100644 --- a/src/node_requires/resources/emitterTandems/index.ts +++ b/src/node_requires/resources/emitterTandems/index.ts @@ -2,7 +2,7 @@ const getThumbnail = function getThumbnail(): string { return 'sparkles'; }; const getById = function getById(id: string): ITandem { - const tandem = (window as Window).currentProject.tandems.find((t: ITandem) => t.uid === id); + const tandem = (window as Window).currentProject.emitterTandems.find((t: ITandem) => t.uid === id); if (!tandem) { throw new Error(`Attempt to get a non-existent tandem with ID ${id}`); } diff --git a/src/node_requires/resources/modules/typedefs.ts b/src/node_requires/resources/modules/typedefs.ts index 7dbfd07a1..074afa003 100644 --- a/src/node_requires/resources/modules/typedefs.ts +++ b/src/node_requires/resources/modules/typedefs.ts @@ -55,7 +55,7 @@ const resetTypedefs = function resetTypedefs(): void { } }; -export = { +export { addTypedefs, removeTypedefs, loadAllTypedefs, diff --git a/src/node_requires/resources/projects/IProject.d.ts b/src/node_requires/resources/projects/IProject.d.ts index ba44fc28e..c0d420fd5 100644 --- a/src/node_requires/resources/projects/IProject.d.ts +++ b/src/node_requires/resources/projects/IProject.d.ts @@ -3,8 +3,44 @@ declare interface IProject { templates: ITemplate[]; sounds: ISound[]; rooms: IRoom[]; - tandems: ITandem[]; + emitterTandems: ITandem[]; fonts: IFont[]; styles: IStyle[]; + settings: { + authoring: { + author: string, + site: string, + title: string + version: [number, number, number], + versionPostfix: string, + appId: string + }, + rendering: { + usePixiLegacy: boolean, + maxFPS: 60, + pixelatedrender: boolean, + highDensity: boolean, + desktopMode: 'maximized' | 'fullscreen' | 'windowed', + hideCursor: boolean, + mobileScreenOrientation: 'unspecified' | 'landscape' | 'portrait' + }, + export: { + windows: boolean, + linux: boolean, + mac: boolean, + functionWrap: boolean, + codeModifier: 'none' | 'minify' | 'obfuscate' + }, + branding: { + icon: assetRef, + /** A hex color */ + accent: string, + invertPreloaderScheme: boolean, + splashScreen: assetRef, + forceSmoothIcons: boolean, + forceSmoothSplashScreen: boolean, + hideLoadingLogo: boolean + } + }; [key: string]: any; } diff --git a/src/node_requires/resources/projects/defaultProject.js b/src/node_requires/resources/projects/defaultProject.ts similarity index 75% rename from src/node_requires/resources/projects/defaultProject.js rename to src/node_requires/resources/projects/defaultProject.ts index d41306d80..a8a23f089 100644 --- a/src/node_requires/resources/projects/defaultProject.js +++ b/src/node_requires/resources/projects/defaultProject.ts @@ -1,4 +1,4 @@ -const defaultProjectTemplate = { +const defaultProjectTemplate: IProject = { ctjsVersion: process.versions.ctjs, notes: '/* empty */', libs: { @@ -19,6 +19,7 @@ const defaultProjectTemplate = { templates: [], sounds: [], styles: [], + fonts: [], rooms: [], actions: [], emitterTandems: [], @@ -40,14 +41,17 @@ const defaultProjectTemplate = { site: '', title: '', version: [0, 0, 0], - versionPostfix: '' + versionPostfix: '', + appId: '' }, rendering: { usePixiLegacy: true, maxFPS: 60, pixelatedrender: false, highDensity: true, - desktopMode: 'maximized' + desktopMode: 'maximized', + hideCursor: false, + mobileScreenOrientation: 'unspecified' }, export: { windows: true, @@ -57,15 +61,19 @@ const defaultProjectTemplate = { codeModifier: 'none' }, branding: { - icon: -1, accent: '#446adb', // ct.js' crystal blue - invertPreloaderScheme: true + invertPreloaderScheme: true, + icon: -1, + splashScreen: -1, + forceSmoothIcons: false, + forceSmoothSplashScreen: false, + hideLoadingLogo: false } } }; module.exports = { - get() { - return JSON.parse(JSON.stringify(defaultProjectTemplate)); + get(): IProject { + return JSON.parse(JSON.stringify(defaultProjectTemplate)) as IProject; } }; diff --git a/src/node_requires/resources/projects/index.ts b/src/node_requires/resources/projects/index.ts index 3323e1893..c4484b45e 100644 --- a/src/node_requires/resources/projects/index.ts +++ b/src/node_requires/resources/projects/index.ts @@ -1,3 +1,250 @@ +import {populatePixiTextureCache, setPixelart} from '../textures'; +import {loadAllTypedefs, resetTypedefs} from '../modules/typedefs'; +import {unloadAllEvents, loadAllModulesEvents} from '../../events'; +import * as path from 'path'; + +const fs = require('fs-extra'); + +// @see https://semver.org/ +const semverRegex = /(\d+)\.(\d+)\.(\d+)(-[A-Za-z.-]*(\d+)?[A-Za-z.-]*)?/; +const semverToArray = (string: string) => { + const raw = semverRegex.exec(string); + return [ + raw[1], + raw[2], + raw[3], + // -next- versions and other postfixes will count as a fourth component. + // They all will apply before regular versions + raw[4] ? raw[5] || 1 : null + ]; +}; + +interface IMigrationPlan { + version: string, + process: (project: Partial) => Promise; +} + +/** +* Applies migration scripts to older projects. +*/ +const adapter = async (project: Partial) => { + var version = semverToArray(project.ctjsVersion || '0.2.0'); + + const migrationToExecute = window.migrationProcess + // Sort all the patches chronologically + .sort((m1: IMigrationPlan, m2: IMigrationPlan) => { + const m1Version = semverToArray(m1.version); + const m2Version = semverToArray(m2.version); + + for (let i = 0; i < 4; i++) { + if (m1Version[i] < m2Version[i] || m1Version[i] === null) { + return -1; + } else if (m1Version[i] > m2Version[i]) { + return 1; + } + } + // eslint-disable-next-line no-console + console.warn(`Two equivalent versions found for migration, ${m1.version} and ${m2.version}.`); + return 0; + }) + // Throw out patches for current and previous versions + .filter((migration: IMigrationPlan) => { + const migrationVersion = semverToArray(migration.version); + for (let i = 0; i < 3; i++) { + // if any of the first three version numbers is lower than project's, + // skip the patch + if (migrationVersion[i] < version[i]) { + return false; + } + if (migrationVersion[i] > version[i]) { + return true; + } + } + // a lazy check for equal base versions + if (migrationVersion.slice(0, 3).join('.') === version.slice(0, 3).join('.')) { + // handle the case with two postfixed versions + if (migrationVersion[3] !== null && version[3] !== null) { + return migrationVersion[3] > version[3]; + } + // postfixed source, unpostfixed patch + if (migrationVersion[3] === null && version[3] !== null) { + return true; + } + return false; + } + return true; + }); + + if (migrationToExecute.length) { + // eslint-disable-next-line no-console + console.debug(`Applying migration sequence: patches ${migrationToExecute.map((m: IMigrationPlan) => m.version).join(', ')}.`); + } + for (const migration of migrationToExecute) { + // eslint-disable-next-line no-console + console.debug(`Migrating project from version ${project.ctjsVersion || '0.2.0'} to ${migration.version}`); + // We do need to apply updates in a sequence + // eslint-disable-next-line no-await-in-loop + await migration.process(project); + } + + // Unfortunately, recent versions of eslint give false positives on this line + // @see https://github.com/eslint/eslint/issues/11900 + // @see https://github.com/eslint/eslint/issues/11899 + // eslint-disable-next-line require-atomic-updates + project.ctjsVersion = process.versions.ctjs; +}; + +/** +* Opens the project and refreshes the whole app. +* +* @param {IProject} projectData Loaded JSON file, in js object form +* @returns {Promise} +*/ +const loadProject = async (projectData: IProject): Promise => { + const glob = require('../../glob'); + window.currentProject = projectData; + window.alertify.log(window.languageJSON.intro.loadingProject); + glob.modified = false; + + try { + await adapter(projectData); + fs.ensureDir(global.projdir); + fs.ensureDir(global.projdir + '/img'); + fs.ensureDir(global.projdir + '/snd'); + + const lastProjects = localStorage.lastProjects ? localStorage.lastProjects.split(';') : []; + if (lastProjects.indexOf(path.normalize(global.projdir + '.ict')) !== -1) { + lastProjects.splice(lastProjects.indexOf(path.normalize(global.projdir + '.ict')), 1); + } + lastProjects.unshift(path.normalize(global.projdir + '.ict')); + if (lastProjects.length > 15) { + lastProjects.pop(); + } + localStorage.lastProjects = lastProjects.join(';'); + + if (window.currentProject.settings.authoring.title) { + document.title = window.currentProject.settings.authoring.title + ' — ct.js'; + } + + glob.scriptTypings = {}; + for (const script of window.currentProject.scripts) { + glob.scriptTypings[script.name] = [ + monaco.languages.typescript.javascriptDefaults.addExtraLib(script.code), + monaco.languages.typescript.typescriptDefaults.addExtraLib(script.code) + ]; + } + + resetTypedefs(); + loadAllTypedefs(); + + unloadAllEvents(); + setPixelart(projectData.settings.rendering.pixelatedrender); + await Promise.all([ + loadAllModulesEvents(), + populatePixiTextureCache(projectData) + ]); + + window.signals.trigger('projectLoaded'); + setTimeout(() => { + window.riot.update(); + }, 0); + } catch (err) { + window.alertify.alert(window.languageJSON.intro.loadingProjectError + err); + } +}; + +/** +* Checks file format and loads it +* +* @param {String} proj The path to the file. +* @returns {void} +*/ +const readProjectFile = async (proj: string) => { + const textProjData = await fs.readFile(proj, 'utf8'); + let projectData; + // Before v1.3, projects were stored in JSON format + try { + if (textProjData.indexOf('{') === 0) { // First, make a silly check for JSON files + projectData = JSON.parse(textProjData); + } else { + try { + const YAML = require('js-yaml'); + projectData = YAML.load(textProjData); + } catch (e) { + // whoopsie, wrong window + // eslint-disable-next-line no-console + console.warn(`Tried to load a file ${proj} as a YAML, but got an error (see below). Falling back to JSON.`); + console.error(e); + projectData = JSON.parse(textProjData); + } + } + } catch (e) { + window.alertify.error(e); + throw e; + } + if (!projectData) { + window.alertify.error(window.languageJSON.common.wrongFormat); + return; + } + try { + loadProject(projectData); + } catch (e) { + window.alertify.error(e); + throw e; + } +}; + +/** + * Opens a project file, checking for recovery files and asking + * a user about them if needed. + * This is the method that should be used for opening ct.js projects + * from within UI. + */ +const openProject = async (proj: string): Promise => { + if (!proj) { + const baseMessage = 'An attempt to open a project with an empty path.'; + alertify.error(baseMessage + ' See the console for the call stack.'); + const err = new Error(baseMessage); + throw err; + } + sessionStorage.projname = path.basename(proj); + global.projdir = path.dirname(proj) + path.sep + path.basename(proj, '.ict'); + + // Check for recovery files + let recoveryStat; + try { + recoveryStat = await fs.stat(proj + '.recovery'); + } catch (err) { + // no recovery file found + void 0; + } + if (recoveryStat && recoveryStat.isFile()) { + const targetStat = await fs.stat(proj); + const voc = window.languageJSON.intro.recovery; + const userResponse = await window.alertify + .okBtn(voc.loadRecovery) + .cancelBtn(voc.loadTarget) + /* {0} — target file date + {1} — target file state (newer/older) + {2} — recovery file date + {3} — recovery file state (newer/older) + */ + .confirm(voc.message + .replace('{0}', targetStat.mtime.toLocaleString()) + .replace('{1}', targetStat.mtime < recoveryStat.mtime ? voc.older : voc.newer) + .replace('{2}', recoveryStat.mtime.toLocaleString()) + .replace('{3}', recoveryStat.mtime < targetStat.mtime ? voc.older : voc.newer)); + window.alertify + .okBtn(window.languageJSON.common.ok) + .cancelBtn(window.languageJSON.common.cancel); + if (userResponse.buttonClicked === 'ok') { + return readProjectFile(proj + '.recovery'); + } + return readProjectFile(proj); + } + return readProjectFile(proj); +}; + const defaultProject = require('./defaultProject'); /** @@ -55,7 +302,7 @@ const getProjectDir = function (projPath: string): string { * @param {string} projPath * @param {boolean} [fs] Whether to return a filesystem path (true) or a URL (false; default). */ -const getProjectThumbnail = function (projPath: string, fs?: boolean) { +const getProjectThumbnail = function (projPath: string, fs?: boolean): string { const path = require('path'); projPath = getProjectDir(projPath); if (fs) { @@ -77,6 +324,7 @@ const getProjectIct = function (projPath: string): string { }; export { + openProject, defaultProject, getDefaultProjectDir, getProjectThumbnail, diff --git a/src/node_requires/resources/rooms/IRoom.d.ts b/src/node_requires/resources/rooms/IRoom.d.ts index 5ad1b0330..8dbd837f3 100644 --- a/src/node_requires/resources/rooms/IRoom.d.ts +++ b/src/node_requires/resources/rooms/IRoom.d.ts @@ -3,31 +3,45 @@ type canvasPatternRepeat = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; interface IRoomBackground { depth: number, texture: assetRef, - extends: { - parallaxX?: number, - parallaxY?: number, - shiftX?: number, - shiftY?: number, - repeat: canvasPatternRepeat - [key: string]: unknown - } + parallaxX: number, + parallaxY: number, + shiftX: number, + shiftY: number, + movementX: number, + movementY: number, + scaleX: number, + scaleY: number, + repeat: canvasPatternRepeat } interface IRoomCopy { x: number, y: number, - uid: assetRef, - tx?: number, - ty?: number, + uid: string, + scale: { + x: number, + y: number + }, + rotation?: number, + tint?: number, + opacity?: number, exts: { [key: string]: unknown - } + }, + customProperties: Record } interface ITileTemplate { x: number; y: number; - grid: number[]; + opacity: number; + tint: number; + frame: number; + scale: { + x: number, + y: number + }; + rotation: number; texture: string; } @@ -35,24 +49,28 @@ interface ITileLayerTemplate { depth: number; tiles: Array, extends?: Record + hidden?: boolean; } interface IRoom extends IScriptable { - width: number, - height: number, + width: number; + height: number; /** A CSS color */ - backgroundColor: string, - backgrounds: Array, - copies: Array, - tiles: Array - gridX: number, - gridY: number, - restrictCamera?: boolean, - restrictMinX?: number, - restrictMinY?: number, - restrictMaxX?: number, - restrictMaxY?: number, + backgroundColor: string; + backgrounds: Array; + copies: Array; + tiles: Array; + gridX: number; + gridY: number; + diagonalGrid: boolean; + simulate: boolean; + restrictCamera?: boolean; + restrictMinX?: number; + restrictMinY?: number; + restrictMaxX?: number; + restrictMaxY?: number; + isUi: boolean; extends: { [key: string]: unknown - } + }; } diff --git a/src/node_requires/resources/rooms/defaultRoom.ts b/src/node_requires/resources/rooms/defaultRoom.ts index b5373a7b7..1a1320c9d 100644 --- a/src/node_requires/resources/rooms/defaultRoom.ts +++ b/src/node_requires/resources/rooms/defaultRoom.ts @@ -8,8 +8,11 @@ const room = { onleave: '', gridX: 64, gridY: 64, + diagonalGrid: false, + simulate: true, width: 1280, - height: 720 + height: 720, + isUi: false }; const get = function (): IRoom { diff --git a/src/node_requires/resources/rooms/index.ts b/src/node_requires/resources/rooms/index.ts index ec035a573..85d9460d9 100644 --- a/src/node_requires/resources/rooms/index.ts +++ b/src/node_requires/resources/rooms/index.ts @@ -1,3 +1,5 @@ +import {outputCanvasToFile} from '../../utils/imageUtils'; + const getDefaultRoom = require('./defaultRoom').get; const fs = require('fs-extra'); const path = require('path'); @@ -31,7 +33,6 @@ const getById = getRoomFromId; * Retrieves the full path to a thumbnail of a given room. * @param {string|IRoom} room Either the id of the room, or its ct.js object * @param {boolean} [x2] If set to true, returns a 340x256 image instead of 64x64. - * (Not implemented, actually!) * @param {boolean} [fs] If set to true, returns a file system path, not a URI. * @returns {string} The full path to the thumbnail. */ @@ -44,16 +45,39 @@ const getRoomPreview = (room: assetRef | IRoom, x2: boolean, fs: boolean): strin room = getRoomFromId(room); } if (fs) { - return `${(global as any).projdir}/img/r${room.uid}.png`; + return `${(global as any).projdir}/img/r${room.uid}${x2 ? '@r' : ''}.png`; } - return `file://${(global as any).projdir}/img/r${room.uid}.png?${room.lastmod}`; + return `file://${(global as any).projdir}/img/r${room.uid}${x2 ? '@r' : ''}.png?${room.lastmod}`; }; const getThumbnail = getRoomPreview; +const writeRoomPreview = ( + room: assetRef | IRoom, + canvas: HTMLCanvasElement, + x2: boolean +): Promise | Promise => { + if (typeof room === 'number') { + throw new Error('Cannot write a room preview for a room -1'); + } + if (typeof room === 'string') { + room = getRoomFromId(room); + } + const path = `${(global as any).projdir}/img/r${room.uid}${x2 ? '@r' : ''}.png`; + if (x2) { + const splash = `${(global as any).projdir}/img/splash.png`; + return Promise.all([ + outputCanvasToFile(canvas, path), + outputCanvasToFile(canvas, splash) + ]); + } + return outputCanvasToFile(canvas, path); +}; + export { createNewRoom, getRoomFromId, getById, getRoomPreview, - getThumbnail + getThumbnail, + writeRoomPreview }; diff --git a/src/node_requires/resources/templates/ITemplate.d.ts b/src/node_requires/resources/templates/ITemplate.d.ts index 0a0923480..415fb4448 100644 --- a/src/node_requires/resources/templates/ITemplate.d.ts +++ b/src/node_requires/resources/templates/ITemplate.d.ts @@ -7,6 +7,7 @@ interface ITemplate extends IScriptable { blendMode?: PixiBlendMode, playAnimationOnStart: boolean, loopAnimation: boolean, + animationFPS: number, extends: { [key: string]: unknown } diff --git a/src/node_requires/resources/templates/defaultTemplate.ts b/src/node_requires/resources/templates/defaultTemplate.ts index 24a410f3f..59a0a81de 100644 --- a/src/node_requires/resources/templates/defaultTemplate.ts +++ b/src/node_requires/resources/templates/defaultTemplate.ts @@ -7,6 +7,7 @@ const defaultTemplate = { texture: -1 as assetRef, playAnimationOnStart: false, loopAnimation: true, + animationFPS: 30, visible: true }; diff --git a/src/node_requires/resources/templates/index.ts b/src/node_requires/resources/templates/index.ts index 9df58908e..70ecb62b7 100644 --- a/src/node_requires/resources/templates/index.ts +++ b/src/node_requires/resources/templates/index.ts @@ -1,4 +1,5 @@ const getDefaultTemplate = require('./defaultTemplate').get; +import {getPixiTexture as getTexturePixiTexture} from '../textures'; const createNewTemplate = function createNewTemplate(name: string): ITemplate { const template = getDefaultTemplate(); @@ -47,11 +48,22 @@ const getTemplatePreview = function getTemplatePreview( }; const getThumbnail = getTemplatePreview; +const getPixiTexture = (template: ITemplate | assetRef): PIXI.Texture[] => { + if (typeof template === 'string') { + template = getTemplateFromId(template); + } + if (template === -1) { + throw new Error('Cannot work with -1 assetRefs'); + } + return getTexturePixiTexture(template.texture, void 0, false); +}; + export { getDefaultTemplate, getTemplateFromId, getById, getTemplatePreview, getThumbnail, - createNewTemplate + createNewTemplate, + getPixiTexture }; diff --git a/src/node_requires/resources/textures/ITexture.d.ts b/src/node_requires/resources/textures/ITexture.d.ts index e78d9c212..c02c29149 100644 --- a/src/node_requires/resources/textures/ITexture.d.ts +++ b/src/node_requires/resources/textures/ITexture.d.ts @@ -3,6 +3,7 @@ interface ITexture extends IAsset { uid: string; name: string; origname: string; + /* Number of columns and rows, accordigly */ grid: [number, number]; axis: [number, number]; width: number; @@ -23,4 +24,5 @@ interface ITexture extends IAsset { top?: number; bottom?: number; tiled?: boolean; + ignoreTiledUse?: boolean; } diff --git a/src/node_requires/resources/textures/index.ts b/src/node_requires/resources/textures/index.ts index abaef5b4a..8c7b43b00 100644 --- a/src/node_requires/resources/textures/index.ts +++ b/src/node_requires/resources/textures/index.ts @@ -71,6 +71,7 @@ const baseTextureFromTexture = (texture: ITexture): Promise => }); }); +const unknownTexture = PIXI.Texture.from('data/img/unknown.png'); const pixiTextureCache: Record} An array of PIXI.Textures */ @@ -108,11 +111,20 @@ const texturesFromCtTexture = async function (tex: ITexture) { } } } + pixiTextureCache[tex.name] = { + lastmod: tex.lastmod, + texture: frames + }; return frames; }; - -let defaultTexture: PIXI.Texture; - +const populatePixiTextureCache = async (project: IProject): Promise => { + clearPixiTextureCache(); + const promises = []; + for (const texture of project.textures) { + promises.push(texturesFromCtTexture(texture)); + } + await Promise.all(promises); +}; // async const getDOMImage = function ( texture: assetRef | ITexture, @@ -136,24 +148,36 @@ const getDOMImage = function ( }; /** - * @param {string|-1|any} texture Either a uid of a texture, or a ct.js texture object + * @param {assetRef | ITexture} texture Either a uid of a texture, or a ct.js texture object * @param {number} [frame] The frame to extract. If not defined, will return an array of all frames * @param {boolean} [allowMinusOne] Allows the use of `-1` as a texture uid * @returns {Array|PIXI.Texture} An array of textures, or an individual one. */ -const getPixiTexture = async function ( +function getPixiTexture(texture: assetRef | ITexture): PIXI.Texture[]; +function getPixiTexture( + texture: -1 +): never; +function getPixiTexture( texture: assetRef | ITexture, - frame?: number, + frame: void | null, allowMinusOne?: boolean -): Promise { +): PIXI.Texture[]; +function getPixiTexture( + texture: assetRef | ITexture, + frame: number, + allowMinusOne?: boolean +): PIXI.Texture; +// eslint-disable-next-line func-style +function getPixiTexture( + texture: assetRef | ITexture, + frame?: number | void | null, + allowMinusOne?: boolean +): PIXI.Texture | PIXI.Texture[] { if (allowMinusOne && texture === -1) { - if (!defaultTexture) { - defaultTexture = PIXI.Texture.from('data/img/unknown.png'); - } if (frame || frame === 0) { - return defaultTexture; + return unknownTexture; } - return [defaultTexture]; + return [unknownTexture]; } if (texture === -1) { throw new Error('Cannot turn -1 into a pixi texture in getPixiTexture method unless it is explicitly allowed.'); @@ -161,24 +185,11 @@ const getPixiTexture = async function ( if (typeof texture === 'string') { texture = getTextureFromId(texture); } - const {uid} = texture; - if (!pixiTextureCache[uid] || - pixiTextureCache[uid].lastmod !== texture.lastmod - ) { - const tex = await texturesFromCtTexture(texture); - // Everything is constant, and the key gets overridden. - // Where's the race condition? False positive?? - // eslint-disable-next-line require-atomic-updates - pixiTextureCache[uid] = { - lastmod: texture.lastmod, - texture: tex - }; - } if (frame || frame === 0) { - return pixiTextureCache[uid].texture[frame]; + return pixiTextureCache[texture.name].texture[frame]; } - return pixiTextureCache[uid].texture; -}; + return pixiTextureCache[texture.name].texture; +} /** * Returns a texture object by its name. @@ -330,7 +341,13 @@ const importImageToTexture = async ( const getCleanTextureName = (name: string): string => name.replace(isBgPostfixTester, '').replace(texturePostfixParser, ''); -const getTexturePivot = (texture: string | ITexture, inPixels?: boolean): [number, number] => { +const getTexturePivot = (texture: assetRef | ITexture, inPixels?: boolean): [number, number] => { + if (texture === -1) { + if (inPixels) { + return [16, 16]; + } + return [0.5, 0.5]; + } if (typeof texture === 'string') { texture = getTextureFromId(texture); } @@ -340,8 +357,18 @@ const getTexturePivot = (texture: string | ITexture, inPixels?: boolean): [numbe return [texture.axis[0] / texture.width, texture.axis[1] / texture.height]; }; +const setPixelart = (pixelart: boolean): void => { + PIXI.settings.SCALE_MODE = pixelart ? + PIXI.SCALE_MODES.NEAREST : + PIXI.SCALE_MODES.LINEAR; + for (const tex in pixiTextureCache) { + pixiTextureCache[tex].texture[0].baseTexture.scaleMode = PIXI.settings.SCALE_MODE; + } +}; + export { clearPixiTextureCache, + populatePixiTextureCache, getTextureFromId, getById, getTextureFromName, @@ -350,6 +377,8 @@ export { getThumbnail, getTexturePivot, getTextureOrig, + texturesFromCtTexture as updatePixiTexture, + setPixelart, getPixiTexture, getDOMImage, importImageToTexture, diff --git a/src/node_requires/roomEditor/IRoomEditorRiotTag.d.ts b/src/node_requires/roomEditor/IRoomEditorRiotTag.d.ts new file mode 100644 index 000000000..9d7b9f6b6 --- /dev/null +++ b/src/node_requires/roomEditor/IRoomEditorRiotTag.d.ts @@ -0,0 +1,39 @@ +import {TileLayer} from './entityClasses/TileLayer'; + +import {ITilePatch} from './interactions/tiles/ITilePatch'; +import {RoomEditor} from '.'; + +type tool = 'select' | 'addCopies' | 'addTiles' | 'manageBackgrounds' | 'roomProperties'; + +export interface IRoomEditorRiotTag { + update(): void; + tilePatch: ITilePatch; + currentTileLayer: TileLayer; + opts: { + room: IRoom; + }; + refs: { + propertiesPanel?: { + updatePropList(): void; + applyChanges(): void; + update(): void; + }, + tileEditor?: { + update(): void; + }, + backgroundsEditor?: { + update(): void; + }, + zoomLabel: HTMLSpanElement + }; + root: HTMLElement; + pixiEditor: RoomEditor; + zoom: number; + gridOn: boolean; + freePlacementMode: boolean; + controlMode: boolean; + currentTool: tool; + currentTemplate: ITemplate | -1; + setTool(tool: tool): () => void; + changeSelectedTemplate(templateId: string): void; +} diff --git a/src/node_requires/roomEditor/common.ts b/src/node_requires/roomEditor/common.ts new file mode 100644 index 000000000..ead9589f5 --- /dev/null +++ b/src/node_requires/roomEditor/common.ts @@ -0,0 +1,116 @@ +interface ISimplePoint { + x: number; + y: number; +} + +export const defaultTextStyle = new PIXI.TextStyle({ + dropShadow: true, + dropShadowDistance: 2, + dropShadowAlpha: 0.35, + fill: '#fff', + fontFamily: '\'Open Sans\',sans-serif,serif', + fontSize: 16 +}); + +/** Converts global coordinates to coordinates on a diagonal grid */ +export const toDiagonal = (pos: ISimplePoint, gridX: number, gridY: number): ISimplePoint => ({ + x: pos.y / gridY + pos.x / gridX, + y: -pos.x / gridX + pos.y / gridY +}); +/** Converts coordinates on a diagonal grid to global coordinates */ +export const fromDiagonal = (pos: ISimplePoint, gridX: number, gridY: number): ISimplePoint => ({ + x: 0.5 * gridX * (pos.x - pos.y), + y: 0.5 * gridY * (pos.x + pos.y) +}); +/** Converts global coordinates to coordinates on a rectangular grid */ +export const toRectangular = (pos: ISimplePoint, gridX: number, gridY: number): ISimplePoint => ({ + x: pos.x / gridX, + y: pos.y / gridY +}); +/** Converts coordinates on a rectangular grid to global coordinates */ +export const fromRectangular = (pos: ISimplePoint, gridX: number, gridY: number): ISimplePoint => ({ + x: pos.x * gridX, + y: pos.y * gridY +}); + +export const snapToDiagonalGrid = ( + pos: ISimplePoint, + gridX: number, + gridY: number +): ISimplePoint => { + const diag = toDiagonal({ + x: pos.x, + y: pos.y + }, gridX, gridY); + return fromDiagonal({ + x: Math.round(diag.x), + y: Math.round(diag.y) + }, gridX, gridY); +}; +export const snapToRectangularGrid = ( + pos: ISimplePoint, + gridX: number, + gridY: number +): ISimplePoint => ({ + x: Math.round(pos.x / gridX) * gridX, + y: Math.round(pos.y / gridY) * gridY +}); + +export const eraseCursor = 'url("data/cursorErase.svg") 1 1, default'; +export const rotateCursor = 'url("data/cursorRotate.svg") 12 12, pointer'; + +/** + * Six filters that recolor any DisplayObject to one of the primary+secondary colors. + * The colors: + * + * 0: Red + * 1: Yellow + * 2: Green + * 3: Aqua + * 4: Blue + * 5: Magenta + */ +export const recolorFilters: PIXI.filters.ColorMatrixFilter[] = []; +for (let i = 0; i < 6; i++) { + const filter = new PIXI.filters.ColorMatrixFilter(); + recolorFilters.push(filter); +} +/* eslint-disable array-element-newline, no-underscore-dangle, no-multi-spaces */ +recolorFilters[0]._loadMatrix([ + 1, 1, 1, 0, 0, + 0.1, 0.1, 0.1, 0, 0, + 0.1, 0.1, 0.1, 0, 0, + 0, 0, 0, 1, 0 +], false); +recolorFilters[1]._loadMatrix([ + 0.5, 0.5, 0.5, 0, 0, + 0.5, 0.5, 0.5, 0, 0, + 0.1, 0.1, 0.1, 0, 0, + 0, 0, 0, 1, 0 +], false); +recolorFilters[2]._loadMatrix([ + 0.1, 0.1, 0.1, 0, 0, + 1, 1, 1, 0, 0, + 0.1, 0.1, 0.1, 0, 0, + 0, 0, 0, 1, 0 +], false); +recolorFilters[3]._loadMatrix([ + 0.1, 0.1, 0.1, 0, 0, + 0.5, 0.5, 0.5, 0, 0, + 0.5, 0.5, 0.5, 0, 0, + 0, 0, 0, 1, 0 +], false); +recolorFilters[4]._loadMatrix([ + 0.1, 0.1, 0.1, 0, 0, + 0.1, 0.1, 0.1, 0, 0, + 1, 1, 1, 0, 0, + 0, 0, 0, 1, 0 +], false); +recolorFilters[5]._loadMatrix([ + 0.5, 0.5, 0.5, 0, 0, + 0.1, 0.1, 0.1, 0, 0, + 0.5, 0.5, 0.5, 0, 0, + 0, 0, 0, 1, 0 +], false); +/* eslint-enable array-element-newline, no-underscore-dangle, no-multi-spaces*/ + diff --git a/src/node_requires/roomEditor/entityClasses/Background.ts b/src/node_requires/roomEditor/entityClasses/Background.ts new file mode 100644 index 000000000..e48586aae --- /dev/null +++ b/src/node_requires/roomEditor/entityClasses/Background.ts @@ -0,0 +1,125 @@ +import {getPixiTexture} from '../../resources/textures'; +import {RoomEditor} from '..'; + +class Background extends PIXI.TilingSprite { + bgTexture: assetRef; + editor: RoomEditor; + shiftX = 0; + shiftY = 0; + parallaxX = 1; + parallaxY = 1; + movementX = 0; + movementY = 0; + simulatedMovedX = 0; + simulatedMovedY = 0; + repeat: canvasPatternRepeat = 'repeat'; + + constructor(bgInfo: IRoomBackground, editor: RoomEditor) { + super(getPixiTexture(bgInfo.texture, 0, true)); + this.anchor.x = this.anchor.y = 0; + this.editor = editor; + this.deserialize(bgInfo); + this.tick(0); + } + destroy(): void { + const ind = this.editor.backgrounds.indexOf(this); + if (ind !== -1) { + this.editor.backgrounds.splice(ind, 1); + this.editor.riotEditor.refs.backgroundsEditor.update(); + } + super.destroy(); + } + detach(): this { + const ind = this.editor.backgrounds.indexOf(this); + if (ind === -1) { + throw new Error('Attempt to detach an off-screen background'); + } + this.editor.backgrounds.splice(ind, 1); + this.parent.removeChild(this); + this.editor.riotEditor.refs.backgroundsEditor.update(); + return this; + } + restore(): this { + this.editor.backgrounds.push(this); + this.editor.room.addChild(this); + this.editor.riotEditor.refs.backgroundsEditor.update(); + return this; + } + + changeTexture(id: assetRef): void { + this.texture = getPixiTexture(id, 0, true); + this.anchor.x = this.anchor.y = 0; + this.bgTexture = id; + } + + serialize(): IRoomBackground { + return { + depth: this.zIndex, + texture: this.bgTexture as string, + shiftX: this.shiftX, + shiftY: this.shiftY, + parallaxX: this.parallaxX, + parallaxY: this.parallaxY, + movementX: this.movementX, + movementY: this.movementY, + scaleX: this.tileScale.x, + scaleY: this.tileScale.y, + repeat: this.repeat + }; + } + deserialize(bg: IRoomBackground): void { + this.zIndex = bg.depth; + this.bgTexture = bg.texture; + this.shiftX = bg.shiftX; + this.shiftY = bg.shiftY; + this.parallaxX = bg.parallaxX; + this.parallaxY = bg.parallaxY; + this.movementX = bg.movementX; + this.movementY = bg.movementY; + this.tileScale.set(bg.scaleX, bg.scaleY); + this.repeat = bg.repeat; + } + refreshTexture(): void { + this.texture = getPixiTexture(this.bgTexture, 0); + this.anchor.x = this.anchor.y = 0; + } + tick(deltaTime: number): void { + const {camera, screen} = this.editor; + const cameraBounds = { + x: camera.x - screen.width / 2 * camera.scale.x, + y: camera.y - screen.height / 2 * camera.scale.y, + width: screen.width * camera.scale.x, + height: screen.height * camera.scale.y + }; + if (this.movementX === 0) { + this.simulatedMovedX = 0; + } + if (this.movementY === 0) { + this.simulatedMovedY = 0; + } + if (deltaTime > 0) { + this.simulatedMovedX += deltaTime * this.movementX; + this.simulatedMovedY += deltaTime * this.movementY; + } + if (this.repeat !== 'repeat-x' && this.repeat !== 'no-repeat') { + this.y = cameraBounds.y; + this.tilePosition.y = -this.y * this.parallaxY + this.shiftY + this.simulatedMovedY; + this.height = cameraBounds.height + 1; + } else { + this.y = this.shiftY + this.simulatedMovedY + cameraBounds.y * (this.parallaxY - 1); + this.height = this.texture.height * this.tileScale.y; + this.tilePosition.y = 0; + } + if (this.repeat !== 'repeat-y' && this.repeat !== 'no-repeat') { + this.x = cameraBounds.x; + this.tilePosition.x = -this.x * this.parallaxX + this.shiftX + this.simulatedMovedX; + this.width = cameraBounds.width + 1; + } else { + this.x = this.shiftX + this.simulatedMovedX + cameraBounds.x * (this.parallaxX - 1); + this.width = this.texture.width * this.tileScale.x; + this.tilePosition.x = 0; + } + } +} + +export {Background}; diff --git a/src/node_requires/roomEditor/entityClasses/Copy.ts b/src/node_requires/roomEditor/entityClasses/Copy.ts new file mode 100644 index 000000000..cb53bab6c --- /dev/null +++ b/src/node_requires/roomEditor/entityClasses/Copy.ts @@ -0,0 +1,104 @@ +import {RoomEditor} from '..'; +import {getPixiTexture, getTemplateFromId} from '../../resources/templates'; +import {getTexturePivot} from '../../resources/textures'; + +/** + * @notice This class automatically adds and removes itself from editor's copy list + */ +class Copy extends PIXI.AnimatedSprite { + templateId: string; + copyExts: Record; + copyCustomProps: Record; + cachedTemplate: ITemplate; + isGhost: boolean; + editor: RoomEditor; + autoUpdate: boolean; + update: (deltaTime: number) => void; + + constructor(copyInfo: IRoomCopy, editor: RoomEditor, isGhost?: boolean) { + super(getPixiTexture(copyInfo.uid)); + this.editor = editor; + this.templateId = copyInfo.uid; + this.autoUpdate = false; + const t = getTemplateFromId(this.templateId as string); + this.cachedTemplate = t; + this.deserialize(copyInfo); + this.isGhost = Boolean(isGhost); + this.interactive = !this.isGhost; + if (t.playAnimationOnStart) { + this.play(); + } + if (!this.isGhost) { + editor.copies.add(this); + } + } + destroy(): void { + if (!this.isGhost) { + this.editor.copies.delete(this); + } + super.destroy(); + } + detach(): this { + this.editor.copies.delete(this); + this.editor.room.removeChild(this); + return this; + } + restore(): this { + this.editor.copies.add(this); + this.editor.room.addChild(this); + return this; + } + + get animated(): boolean { + return getTemplateFromId(this.templateId as string).playAnimationOnStart; + } + + serialize(): IRoomCopy { + return { + x: this.x, + y: this.y, + opacity: this.alpha, + tint: this.tint, + scale: { + x: this.scale.x, + y: this.scale.y + }, + rotation: this.rotation, + uid: this.templateId, + exts: this.copyExts, + customProperties: this.copyCustomProps + }; + } + deserialize(copy: IRoomCopy): void { + this.x = copy.x; + this.y = copy.y; + this.zIndex = this.cachedTemplate.depth; + this.alpha = copy.opacity ?? 1; + this.tint = copy.tint ?? 0xffffff; + this.scale.x = copy.scale?.x ?? 1; + this.scale.y = copy.scale?.y ?? 1; + this.rotation = copy.rotation ?? 0; + this.templateId = copy.uid; + this.copyExts = copy.exts ?? {}; + this.copyCustomProps = copy.customProperties ?? {}; + const t = getTemplateFromId(this.templateId as string); + this.animationSpeed = t.animationFPS / 60; + this.loop = t.loopAnimation ?? true; + if (t.texture !== -1) { + [this.anchor.x, this.anchor.y] = getTexturePivot(t.texture); + } else { + this.anchor.x = this.anchor.y = 0.5; + } + } + refreshTexture(): void { + const t = this.cachedTemplate; + this.textures = getPixiTexture(t); + if (t.texture !== -1) { + [this.anchor.x, this.anchor.y] = getTexturePivot(t.texture); + } else { + this.anchor.x = this.anchor.y = 0.5; + } + } +} + +export {Copy}; diff --git a/src/node_requires/roomEditor/entityClasses/MarqueeBox.ts b/src/node_requires/roomEditor/entityClasses/MarqueeBox.ts new file mode 100644 index 000000000..947b9560f --- /dev/null +++ b/src/node_requires/roomEditor/entityClasses/MarqueeBox.ts @@ -0,0 +1,24 @@ +import {RoomEditor} from '..'; +import {getPixiSwatch} from '../../themes'; + +export class MarqueeBox extends PIXI.Graphics { + editor: RoomEditor; + constructor(editor: RoomEditor, x: number, y: number, width: number, height: number) { + super(); + this.editor = editor; + this.redrawBox(x, y, width, height); + } + redrawBox(x: number, y: number, width: number, height: number): void { + const x1 = x, + x2 = x + width, + y1 = y, + y2 = y + height; + this.x = Math.min(x1, x2); + this.y = Math.min(y1, y2); + this.clear(); + this.lineStyle(3 * this.editor.camera.scale.x, getPixiSwatch('act')) + .drawRoundedRect(0, 0, Math.abs(width), Math.abs(height), 0.1); + this.lineStyle(this.editor.camera.scale.x, getPixiSwatch('background')) + .drawRoundedRect(0, 0, Math.abs(width), Math.abs(height), 0.1); + } +} diff --git a/src/node_requires/roomEditor/entityClasses/SnapTarget.ts b/src/node_requires/roomEditor/entityClasses/SnapTarget.ts new file mode 100644 index 000000000..64db149d9 --- /dev/null +++ b/src/node_requires/roomEditor/entityClasses/SnapTarget.ts @@ -0,0 +1,95 @@ +import {getPixiSwatch} from '../../themes'; +import {RoomEditor} from '..'; +import {snapToRectangularGrid, snapToDiagonalGrid} from '../common'; +import {getPixiTexture, getTextureFromId, getTexturePivot} from '../../resources/textures'; +import {createTilePatch} from '../interactions/tiles/placeTile'; + +const unknownTextures = getPixiTexture(-1, void 0, true); + +export class SnapTarget extends PIXI.Container { + editor: RoomEditor; + circle = new PIXI.Graphics(); + ghost = new PIXI.AnimatedSprite(unknownTextures); + ghostCompound = new PIXI.Container(); + prevGhostTex: ITexture; + prevTilePatch: string; + constructor(editor: RoomEditor) { + super(); + this.editor = editor; + this.ghost.visible = false; + this.ghost.alpha = 0.5; + [this.ghost.anchor.x, this.ghost.anchor.y] = [0.5, 0.5]; + this.addChild(this.ghost, this.ghostCompound); + this.circle.beginFill(getPixiSwatch('act')); + this.circle.drawCircle(0, 0, 4); + this.addChild(this.circle); + } + getPatchString(): string { + const {tilePatch} = this.editor.riotEditor; + return `${tilePatch.texture.uid}:${tilePatch.startX}:${tilePatch.startY}:${tilePatch.spanX}:${tilePatch.spanY}`; + } + update(): void { + this.circle.scale.x = this.editor.camera.scale.x; + this.circle.scale.y = this.editor.camera.scale.y; + + const {riotEditor} = this.editor; + const {currentTemplate} = riotEditor; + if (riotEditor.currentTool === 'addCopies' && currentTemplate !== -1) { + this.ghost.visible = true; + if (currentTemplate.texture === -1 && + this.ghost.textures !== unknownTextures + ) { + this.updateGhost(-1); + this.ghost.textures = unknownTextures; + } + if (currentTemplate.texture !== -1 && + this.prevGhostTex !== getTextureFromId(currentTemplate.texture) + ) { + this.updateGhost(currentTemplate.texture); + this.prevGhostTex = getTextureFromId(currentTemplate.texture); + } + } else { + this.ghost.visible = false; + } + if (riotEditor.currentTool === 'addTiles' && riotEditor.tilePatch?.texture) { + if (this.prevTilePatch !== this.getPatchString()) { + this.ghostCompound.removeChildren(); + this.ghostCompound.visible = true; + this.ghostCompound.addChild(...createTilePatch(riotEditor.tilePatch, { + x: 0, + y: 0 + }, this.editor, true)); + this.prevTilePatch = this.getPatchString(); + } + } else { + this.ghostCompound.visible = false; + if (this.ghostCompound.children.length) { + this.ghostCompound.removeChildren(); + } + } + + const {mouse} = this.editor.renderer.plugins.interaction; + mouse.getLocalPosition(this.editor.overlays, this.position); + if (!riotEditor.gridOn || riotEditor.freePlacementMode) { + return; + } + let snappedPos; + if (this.editor.ctRoom.diagonalGrid) { + snappedPos = snapToDiagonalGrid({ + x: this.x, + y: this.y + }, this.editor.ctRoom.gridX, this.editor.ctRoom.gridY); + } else { + snappedPos = snapToRectangularGrid({ + x: this.x, + y: this.y + }, this.editor.ctRoom.gridX, this.editor.ctRoom.gridY); + } + this.x = snappedPos.x; + this.y = snappedPos.y; + } + updateGhost(texture: assetRef | ITexture): void { + this.ghost.textures = getPixiTexture(texture, void 0, true); + [this.ghost.anchor.x, this.ghost.anchor.y] = getTexturePivot(texture); + } +} diff --git a/src/node_requires/roomEditor/entityClasses/Tile.ts b/src/node_requires/roomEditor/entityClasses/Tile.ts new file mode 100644 index 000000000..07b01162c --- /dev/null +++ b/src/node_requires/roomEditor/entityClasses/Tile.ts @@ -0,0 +1,85 @@ +import {getPixiTexture, getTexturePivot} from '../../resources/textures'; +import {RoomEditor} from '..'; +import {TileLayer} from './TileLayer'; + +/** + * @notice This class automatically adds and removes itself from editor's tile list + */ +class Tile extends PIXI.Sprite { + tileTexture: assetRef; + tileFrame: number; + parent: TileLayer | null; + editor: RoomEditor; + isGhost: boolean; + + constructor(tileInfo: ITileTemplate, editor: RoomEditor, isGhost?: boolean) { + super(getPixiTexture(tileInfo.texture, tileInfo.frame, false)); + this.editor = editor; + this.deserialize(tileInfo); + this.isGhost = Boolean(isGhost); + this.interactive = !this.isGhost; + if (this.isGhost) { + this.alpha *= 0.5; + } else { + editor.tiles.add(this); + } + } + destroy(): void { + if (!this.isGhost) { + this.editor.tiles.delete(this); + } + super.destroy(); + } + detach(): this { + this.editor.tiles.delete(this); + this.parent.removeChild(this); + return this; + } + restore(parent: TileLayer): this { + this.editor.tiles.add(this); + parent.addChild(this); + return this; + } + + serialize(): ITileTemplate { + return { + x: this.x, + y: this.y, + opacity: this.alpha, + tint: this.tint, + scale: { + x: this.scale.x, + y: this.scale.y + }, + frame: this.tileFrame, + rotation: this.rotation, + texture: this.tileTexture as string + }; + } + deserialize(tile: ITileTemplate): void { + this.x = tile.x; + this.y = tile.y; + this.alpha = tile.opacity ?? 1; + this.tint = tile.tint ?? 0xffffff; + this.scale.x = tile.scale?.x ?? 1; + this.scale.y = tile.scale?.y ?? 1; + this.rotation = tile.rotation ?? 0; + this.tileTexture = tile.texture; + this.tileFrame = tile.frame; + [this.anchor.x, this.anchor.y] = getTexturePivot(this.tileTexture); + } + refreshTexture(): void { + const frame = getPixiTexture(this.tileTexture, this.tileFrame); + if (frame) { + this.texture = frame; + } else { + // eslint-disable-next-line no-console + console.warn(`Frame ${this.tileFrame} does not exist in the texture ${this.tileTexture}. Removing the tile.`); + // Invalid tile. Desintegrate! + this.destroy(); + } + [this.anchor.x, this.anchor.y] = getTexturePivot(this.tileTexture); + } +} + +export {Tile}; diff --git a/src/node_requires/roomEditor/entityClasses/TileLayer.ts b/src/node_requires/roomEditor/entityClasses/TileLayer.ts new file mode 100644 index 000000000..f773ec73d --- /dev/null +++ b/src/node_requires/roomEditor/entityClasses/TileLayer.ts @@ -0,0 +1,68 @@ +import {Tile} from './Tile'; +import {RoomEditor} from '..'; + +let idCounter = 0; + +export class TileLayer extends PIXI.Container { + extends: Record; + children: Tile[]; + editor: RoomEditor; + id: number; + constructor(tileLayer: ITileLayerTemplate, editor: RoomEditor) { + super(); + this.editor = editor; + this.id = idCounter++; + this.deserialize(tileLayer); + } + destroy(): void { + if (this.parent) { + this.parent.removeChild(this); + } + const ind = this.editor.tileLayers.indexOf(this); + if (ind !== -1) { + this.editor.tileLayers.splice(ind, 1); + } + super.destroy({ + children: true + }); + } + detach(writeToHistory?: boolean): this { + const ind = this.editor.tileLayers.indexOf(this); + if (ind !== -1) { + // eslint-disable-next-line no-console + console.warn('Detaching a layer that was not in the editor\'s tileLayer list', this); + this.editor.tileLayers.splice(ind, 1); + } + for (const tile of this.children) { + this.editor.tiles.delete(tile); + } + this.parent.removeChild(this); + if (writeToHistory) { + this.editor.history.pushChange({ + type: 'tileLayerDeletion', + deleted: this + }); + } + return this; + } + restore(): this { + this.editor.addTileLayer(this); + return this; + } + serialize(): ITileLayerTemplate { + return { + depth: this.zIndex, + tiles: this.children.map(c => c.serialize()), + extends: this.extends, + hidden: !this.visible + }; + } + deserialize(tileLayer: ITileLayerTemplate): void { + this.zIndex = tileLayer.depth; + this.extends = tileLayer.extends || {}; + for (const tile of tileLayer.tiles) { + const pixiTile = new Tile(tile, this.editor); + this.addChild(pixiTile); + } + } +} diff --git a/src/node_requires/roomEditor/entityClasses/Transformer.ts b/src/node_requires/roomEditor/entityClasses/Transformer.ts new file mode 100644 index 000000000..f51cba670 --- /dev/null +++ b/src/node_requires/roomEditor/entityClasses/Transformer.ts @@ -0,0 +1,289 @@ +import {RoomEditor} from '..'; + +import {getPixiSwatch} from '../../themes'; +import {rotateCursor} from '../common'; +import {ease} from 'node_modules/pixi-ease'; + +import {rotateRad, pdc} from '../../utils/trigo'; + +export class Handle extends PIXI.Graphics { + constructor() { + super(); + this.beginFill(getPixiSwatch('act')); + this.drawCircle(0, 0, 6); + this.interactive = true; + this.cursor = 'pointer'; + } +} +type transformSubset = { + x: number; + y: number; + scale: { + x: number; + y: number; + }; + rotation: number; +} + +export class Transformer extends PIXI.Container { + handleTL = new Handle(); + handleTR = new Handle(); + handleT = new Handle(); + handleL = new Handle(); + handleR = new Handle(); + handleCenter = new Handle(); + handleBL = new Handle(); + handleBR = new Handle(); + handleB = new Handle(); + handleRotate = new Handle(); + scaleHandles = [ + this.handleTL, + this.handleTR, + this.handleT, + this.handleL, + this.handleR, + this.handleBL, + this.handleBR, + this.handleB + ]; + frame = new PIXI.Graphics(); + + applyRotation: number; + applyScaleX: number; + applyScaleY: number; + applyTranslateX: number; + applyTranslateY: number; + transformPivotX: number; + transformPivotY: number; + frameWidth: number; + frameHeight: number; + initialTransforms = new Map(); + + editor: RoomEditor; + + constructor(editor: RoomEditor) { + super(); + this.editor = editor; + this.handleRotate.cursor = rotateCursor; + + this.handleCenter.scale.set(1.25, 1.25); + this.handleCenter.cursor = 'move'; + + this.addChild( + this.frame, + this.handleTL, + this.handleTR, + this.handleT, + this.handleL, + this.handleR, + this.handleCenter, + this.handleBL, + this.handleBR, + this.handleB, + this.handleRotate + ); + this.setup(); + } + + setup(skipHistoryUpdate?: boolean): void { + this.initialTransforms.clear(); + this.applyRotation = 0; + this.applyScaleX = this.applyScaleY = 1; + this.applyTranslateX = this.applyTranslateY = 0; + if (this.editor.currentSelection.size === 0) { + this.visible = false; + return; + } + this.visible = true; + + let rect; + for (const elt of this.editor.currentSelection) { + const w = elt.width, + h = elt.height, + // IDK why this works + px = Math.sign(elt.scale.x) === -1 ? 1 - elt.anchor.x : elt.anchor.x, + py = Math.sign(elt.scale.y) === -1 ? 1 - elt.anchor.y : elt.anchor.y; + const tl = rotateRad(-w * px, -h * py, elt.rotation), + tr = rotateRad(w * (1 - px), -h * py, elt.rotation), + bl = rotateRad(-w * px, h * (1 - py), elt.rotation), + br = rotateRad(w * (1 - px), h * (1 - py), elt.rotation); + const x1 = Math.min(tl[0], bl[0], tr[0], br[0]), + x2 = Math.max(tl[0], bl[0], tr[0], br[0]), + y1 = Math.min(tl[1], bl[1], tr[1], br[1]), + y2 = Math.max(tl[1], bl[1], tr[1], br[1]); + if (!rect) { + rect = new PIXI.Rectangle(x1, y1, x2 - x1, y2 - y1); + rect.x += elt.x; + rect.y += elt.y; + } else { + const newRect = new PIXI.Rectangle(x1, y1, x2 - x1, y2 - y1); + newRect.x += elt.x; + newRect.y += elt.y; + rect.enlarge(newRect); + } + this.initialTransforms.set(elt, { + x: elt.x, + y: elt.y, + scale: { + x: elt.scale.x || 1, + y: elt.scale.y || 1 + }, + rotation: elt.rotation + }); + } + this.frameWidth = rect.width; + this.frameHeight = rect.height; + this.transformPivotX = rect.x + rect.width / 2; + this.transformPivotY = rect.y + rect.height / 2; + if (!skipHistoryUpdate) { + this.editor.history.initiateTransformChange(); + } + this.updateFrame(); + } + clear(): void { + this.editor.currentSelection.clear(); + this.setup(true); + } + + applyTransforms(): void { + for (const elt of this.editor.currentSelection) { + const initial = this.initialTransforms.get(elt); + const delta = { + x: ((initial.x + this.applyTranslateX) - this.transformPivotX) * this.applyScaleX, + y: ((initial.y + this.applyTranslateY) - this.transformPivotY) * this.applyScaleY + }; + const rotatedDelta = rotateRad(delta.x, delta.y, this.applyRotation); + elt.x = this.transformPivotX + rotatedDelta[0]; + elt.y = this.transformPivotY + rotatedDelta[1]; + elt.rotation = initial.rotation + this.applyRotation; + + // Skew isn't in ct.js, so something fancy is introduced as an alternative. + // Works great at 0, 90, 180, 270 degrees. + // Works q̴̿ͅu̵͈͑e̵̖͒s̵͈̎t̸̪̽i̶͈͌o̴̳͊ñ̶̪a̵͜͝b̶̮̈́ĺ̸̲y̸͒͜ on other angles. + const flip = Math.sign(this.applyScaleX) !== Math.sign(this.applyScaleY) ? -1 : 1; + const sin = Math.sin(initial.rotation), + cos = Math.cos(initial.rotation); + + elt.scale.set( + initial.scale.x * + (cos ** 2 * this.applyScaleX + sin ** 2 * this.applyScaleY * flip), + initial.scale.y * + (sin ** 2 * this.applyScaleX * flip + cos ** 2 * this.applyScaleY) + ); + } + } + + outlineSelected(): void { + for (const elt of this.editor.currentSelection) { + const w = elt.width, + h = elt.height, + // IDK why this works + px = Math.sign(elt.scale.x) === -1 ? 1 - elt.anchor.x : elt.anchor.x, + py = Math.sign(elt.scale.y) === -1 ? 1 - elt.anchor.y : elt.anchor.y, + {x, y} = this.editor.room.toGlobal(elt.position), + sx = this.editor.camera.scale.x, + sy = this.editor.camera.scale.y; + const tl = rotateRad(-w * px, -h * py, elt.rotation), + tr = rotateRad(w * (1 - px), -h * py, elt.rotation), + bl = rotateRad(-w * px, h * (1 - py), elt.rotation), + br = rotateRad(w * (1 - px), h * (1 - py), elt.rotation); + // this.frame.lineStyle(3, getPixiSwatch('act')); + this.frame.lineStyle(1, getPixiSwatch('background')); + this.frame.beginFill(getPixiSwatch('act'), 0.15); + this.frame.moveTo(x + tl[0] / sx, y + tl[1] / sy); + this.frame.lineTo(x + tr[0] / sx, y + tr[1] / sy); + this.frame.lineTo(x + br[0] / sx, y + br[1] / sy); + this.frame.lineTo(x + bl[0] / sx, y + bl[1] / sy); + this.frame.lineTo(x + tl[0] / sx, y + tl[1] / sy); + this.frame.endFill(); + // this.frame.lineStyle(1, getPixiSwatch('background')); + // this.frame.moveTo(x + tl[0] / sx, y + tl[1] / sy); + // this.frame.lineTo(x + tr[0] / sx, y + tr[1] / sy); + // this.frame.lineTo(x + br[0] / sx, y + br[1] / sy); + // this.frame.lineTo(x + bl[0] / sx, y + bl[1] / sy); + // this.frame.lineTo(x + tl[0] / sx, y + tl[1] / sy); + } + } + updateFrame(): void { + const halfDiagonalScaled = { + x: this.frameWidth / 2 * this.applyScaleX / this.editor.camera.scale.x, + y: this.frameHeight / 2 * this.applyScaleY / this.editor.camera.scale.y + }; + // Compute position of four corners of the selection frame + const TR = rotateRad(halfDiagonalScaled.x, -halfDiagonalScaled.y, this.applyRotation), + TL = rotateRad(-halfDiagonalScaled.x, -halfDiagonalScaled.y, this.applyRotation), + BR = rotateRad(halfDiagonalScaled.x, halfDiagonalScaled.y, this.applyRotation), + BL = rotateRad(-halfDiagonalScaled.x, halfDiagonalScaled.y, this.applyRotation); + const globalFrom = this.editor.room.toGlobal(new PIXI.Point( + this.transformPivotX, + this.transformPivotY + )); + + TR[0] += globalFrom.x; + TL[0] += globalFrom.x; + BL[0] += globalFrom.x; + BR[0] += globalFrom.x; + TR[1] += globalFrom.y; + TL[1] += globalFrom.y; + BL[1] += globalFrom.y; + BR[1] += globalFrom.y; + + // Move handles to appropriate places + this.handleCenter.x = globalFrom.x; + this.handleCenter.y = globalFrom.y; + [this.handleTL.x, this.handleTL.y] = TL; + [this.handleTR.x, this.handleTR.y] = TR; + [this.handleBL.x, this.handleBL.y] = BL; + [this.handleBR.x, this.handleBR.y] = BR; + this.handleT.x = (TL[0] + TR[0]) / 2; + this.handleT.y = (TL[1] + TR[1]) / 2; + this.handleL.x = (TL[0] + BL[0]) / 2; + this.handleL.y = (TL[1] + BL[1]) / 2; + this.handleR.x = (TR[0] + BR[0]) / 2; + this.handleR.y = (TR[1] + BR[1]) / 2; + this.handleB.x = (BL[0] + BR[0]) / 2; + this.handleB.y = (BL[1] + BR[1]) / 2; + // Rotation handle is placed a bit outside the frame + const shift = rotateRad(21 * Math.sign(this.applyScaleX), 0, this.applyRotation); + this.handleRotate.x = this.handleR.x + shift[0]; + this.handleRotate.y = this.handleR.y + shift[1]; + + // Hide middle handles if they're placed way too close to other elements + if (pdc(TL[0], TL[1], BL[0], BL[1]) < 32 || pdc(TL[0], TL[1], TR[0], TR[1]) <= 16) { + this.handleL.visible = this.handleR.visible = false; + } else { + this.handleL.visible = this.handleR.visible = true; + } + if (pdc(TL[0], TL[1], TR[0], TR[1]) < 32 || pdc(TL[0], TL[1], BL[0], BL[1]) <= 16) { + this.handleT.visible = this.handleB.visible = false; + } else { + this.handleT.visible = this.handleB.visible = true; + } + + this.frame.clear(); + // Outline the selected elements + this.outlineSelected(); + // Draw the frame + this.frame.lineStyle(4, getPixiSwatch('act')); + this.frame.moveTo(TL[0] - 0.5, TL[1] - 0.5); + this.frame.lineTo(TR[0] + 0.5, TR[1] - 0.5); + this.frame.lineTo(BR[0] + 0.5, BR[1] + 0.5); + this.frame.lineTo(BL[0] - 0.5, BL[1] + 0.5); + this.frame.lineTo(TL[0] - 0.5, TL[1] - 0.5); + this.frame.lineStyle(2, getPixiSwatch('background')); + this.frame.moveTo(TL[0] - 0.5, TL[1] - 0.5); + this.frame.lineTo(TR[0] + 0.5, TR[1] - 0.5); + this.frame.lineTo(BR[0] + 0.5, BR[1] + 0.5); + this.frame.lineTo(BL[0] - 0.5, BL[1] + 0.5); + this.frame.lineTo(TL[0] - 0.5, TL[1] - 0.5); + } + + blink(): void { + this.alpha = 0; + ease.add(this, { + alpha: 1 + }, { + duration: 150 + }); + } +} diff --git a/src/node_requires/roomEditor/entityClasses/Viewport.ts b/src/node_requires/roomEditor/entityClasses/Viewport.ts new file mode 100644 index 000000000..a07d4fd6b --- /dev/null +++ b/src/node_requires/roomEditor/entityClasses/Viewport.ts @@ -0,0 +1,58 @@ +import {getPixiSwatch} from '../../themes'; +import {RoomEditor} from '..'; + +interface ICtViewport { + width: number; + height: number; + x?: number; + y?: number; +} + +class Viewport extends PIXI.Graphics { + view: ICtViewport; + starting: boolean; + startingIcon: PIXI.Graphics; + editor: RoomEditor; + + constructor(view: ICtViewport, starting: boolean, editor: RoomEditor) { + super(); + this.editor = editor; + this.starting = starting; + this.view = view; + this.x = this.view.x ?? 0; + this.y = this.view.y ?? 0; + this.startingIcon = new PIXI.Graphics(); + this.startingIcon + .lineStyle(2, getPixiSwatch('orange'), 1, 0.5) + .moveTo(0, 0) + .lineTo(17, 10) + .lineTo(0, 20) + .lineTo(0, 0) + .closePath(); + this.startingIcon.y = 16; + this.startingIcon.visible = this.starting; + this.addChild(this.startingIcon); + this.redrawFrame(); + } + destroy(): void { + this.editor.viewports.delete(this); + super.destroy(); + } + + redrawFrame(): void { + this.x = this.view.x ?? 0; + this.y = this.view.y ?? 0; + this.startingIcon.scale.set(this.editor.camera.scale.x); + this.startingIcon.visible = this.starting && + (this.view.height / this.editor.camera.scale.x > 48); + this.clear(); + this.lineStyle(4 * this.editor.camera.scale.x, getPixiSwatch('act')) + .drawRoundedRect(0, 0, this.view.width, this.view.height, 0.1); + this.lineStyle(2 * this.editor.camera.scale.x, getPixiSwatch('background')) + .drawRoundedRect(0, 0, this.view.width, this.view.height, 0.1); + this.startingIcon.x = this.view.width - (16 + 17) * this.editor.camera.scale.x; + this.startingIcon.y = 16 * this.editor.camera.scale.y; + } +} + +export {Viewport}; diff --git a/src/node_requires/roomEditor/entityClasses/ViewportRestriction.ts b/src/node_requires/roomEditor/entityClasses/ViewportRestriction.ts new file mode 100644 index 000000000..a4bd8bce6 --- /dev/null +++ b/src/node_requires/roomEditor/entityClasses/ViewportRestriction.ts @@ -0,0 +1,57 @@ +import {getPixiSwatch} from '../../themes'; +import {RoomEditor} from '..'; + +export class ViewportRestriction extends PIXI.Graphics { + icon: PIXI.Graphics; + editor: RoomEditor; + constructor(editor: RoomEditor) { + super(); + this.editor = editor; + this.x = this.editor.ctRoom.restrictMinX; + this.y = this.editor.ctRoom.restrictMinY; + this.icon = new PIXI.Graphics(); + this.icon + .lineStyle(2, getPixiSwatch('orange'), 1, 0.5); + this.icon.drawRect(0, 10, 20, 14); + this.icon.arc(10, 6, 6, Math.PI, Math.PI * 2); + this.icon.moveTo(10, 14); + this.icon.lineTo(10, 20); + this.icon.moveTo(4, 6); + this.icon.lineTo(4, 10); + this.icon.moveTo(4 + 12, 6); + this.icon.lineTo(4 + 12, 10); + this.icon.y = 16; + this.addChild(this.icon); + this.redrawFrame(); + } + + redrawFrame(): void { + if (!this.editor.ctRoom.restrictCamera) { + this.visible = false; + return; + } + this.visible = true; + this.x = this.editor.ctRoom.restrictMinX; + this.y = this.editor.ctRoom.restrictMinY; + let width = this.editor.ctRoom.restrictMaxX - this.editor.ctRoom.restrictMinX, + height = this.editor.ctRoom.restrictMaxY - this.editor.ctRoom.restrictMinY; + if (width < 0) { + width = Math.abs(width); + this.x = this.editor.ctRoom.restrictMaxX; + } + if (height < 0) { + height = Math.abs(height); + this.y = this.editor.ctRoom.restrictMaxY; + } + this.icon.scale.set(this.editor.camera.scale.x); + this.icon.visible = (height / this.editor.camera.scale.x > 48); + this.clear(); + this.lineStyle(4 * this.editor.camera.scale.x, getPixiSwatch('act')) + .drawRoundedRect(0, 0, width, height, 0.1); + this.lineStyle(2 * this.editor.camera.scale.x, getPixiSwatch('background')) + .drawRoundedRect(0, 0, width, height, 0.1); + this.icon.x = width - (16 + 20) * this.editor.camera.scale.x; + this.icon.y = 16 * this.editor.camera.scale.y; + } +} + diff --git a/src/node_requires/roomEditor/history.ts b/src/node_requires/roomEditor/history.ts new file mode 100644 index 000000000..1efebcb1e --- /dev/null +++ b/src/node_requires/roomEditor/history.ts @@ -0,0 +1,290 @@ +import {Copy} from './entityClasses/Copy'; +import {Tile} from './entityClasses/Tile'; +import {TileLayer} from './entityClasses/TileLayer'; +import {Background} from './entityClasses/Background'; +import {RoomEditor} from '.'; + +type transformationSnapshot = { + position: { + x: number; + y: number; + } + rotation: number; + scale: { + x: number; + y: number; + } + tint: number; + alpha: number; +}; + +/** + * In order: The entity that was changed, transformation before the change, and after it. + */ +type transformation = { + type: 'transformation', + transformations: Map +}; + +type deletion = { + type: 'deletion', + deleted: Set<[Copy | Tile, TileLayer?]> +}; +type creation = { + type: 'creation', + created: Set<[Copy | Tile, TileLayer?]> +}; + +type tileLayerCreation = { + type: 'tileLayerCreation', + created: TileLayer +} +type tileLayerDeletion = { + type: 'tileLayerDeletion', + deleted: TileLayer +} + +type backgroundCreation = { + type: 'backgroundCreation', + created: Background +} +type backgroundDeletion = { + type: 'backgroundDeletion', + deleted: Background +} + +type propChange = { + type: 'propChange', + key: string, + target: unknown, + before: unknown, + after: unknown +} + +export type change = transformation | deletion | creation | + tileLayerCreation | tileLayerDeletion | + backgroundCreation | backgroundDeletion | + propChange; + +const snapshotTransform = (entity: PIXI.Sprite): transformationSnapshot => ({ + position: { + x: entity.position.x, + y: entity.position.y + }, + rotation: entity.rotation, + scale: { + x: entity.scale.x, + y: entity.scale.y + }, + tint: entity.tint, + alpha: entity.alpha +}); + +export class History { + stack: change[] = []; + /** + * Describes the last change made in the given period of time in history. + * Undo operation undos this change, while redo operation redos the change next to it. + */ + currentChange?: change; + editor: RoomEditor; + + constructor(editor: RoomEditor) { + this.editor = editor; + } + + undo(): boolean { + if (!this.currentChange) { + return false; + } + const change = this.currentChange; + // eslint-disable-next-line default-case + switch (change.type) { + case 'transformation': + this.editor.transformer.clear(); + for (const transform of change.transformations) { + const [entity, [before]] = transform; + entity.position.set(before.position.x, before.position.y); + entity.scale.set(before.scale.x, before.scale.y); + entity.alpha = before.alpha; + entity.rotation = before.rotation; + entity.tint = before.tint; + this.editor.currentSelection.add(entity); + } + this.editor.transformer.setup(true); + this.editor.riotEditor.refs.propertiesPanel?.updatePropList(); + break; + case 'deletion': + for (const deletion of change.deleted) { + const [entity, parent] = deletion; + entity.restore(parent); + } + break; + case 'creation': + this.editor.transformer.clear(); + for (const creation of change.created) { + const [entity] = creation; + entity.detach(); + } + break; + case 'tileLayerCreation': + change.created.detach(); + if (!this.editor.tileLayers.includes(this.editor.riotEditor.currentTileLayer)) { + [this.editor.riotEditor.currentTileLayer] = this.editor.tileLayers; + } + this.editor.riotEditor.refs.tileEditor?.update(); + break; + case 'tileLayerDeletion': + change.deleted.restore(); + this.editor.riotEditor.currentTileLayer = change.deleted; + this.editor.riotEditor.refs.tileEditor?.update(); + break; + case 'backgroundCreation': + change.created.detach(); + this.editor.riotEditor.refs.backgroundsEditor?.update(); + break; + case 'backgroundDeletion': + change.deleted.restore(); + this.editor.riotEditor.refs.backgroundsEditor?.update(); + break; + case 'propChange': + (change.target as Record)[change.key] = change.before; + this.updateUiFor(change); + break; + } + const prevChangeType = change.type; + this.currentChange = this.stack[this.stack.indexOf(change) - 1]; + if (prevChangeType === 'transformation' && !change) { + // If we reached history's end with transformation reversal, leave + // this last change as current one, as the transformer selects the same set + // of entities and initial transforms are totally correct. + [this.currentChange] = this.stack; + } + this.editor.riotEditor.update(); + return true; + } + redo(): boolean { + if (this.currentChange === this.stack[this.stack.length - 1]) { + return false; + } + const newChange = this.stack[this.stack.indexOf(this.currentChange) + 1]; + // eslint-disable-next-line default-case + switch (newChange.type) { + case 'transformation': + this.editor.transformer.clear(); + for (const change of newChange.transformations) { + const [entity, [, after]] = change; + entity.position.set(after.position.x, after.position.y); + entity.scale.set(after.scale.x, after.scale.y); + entity.alpha = after.alpha; + entity.rotation = after.rotation; + entity.tint = after.tint; + this.editor.currentSelection.add(entity); + } + this.editor.transformer.setup(true); + this.editor.riotEditor.refs.propertiesPanel?.updatePropList(); + break; + case 'deletion': + this.editor.transformer.clear(); + for (const deletion of newChange.deleted) { + const [entity] = deletion; + entity.detach(); + } + break; + case 'creation': + for (const creation of newChange.created) { + const [entity, parent] = creation; + entity.restore(parent); + } + break; + case 'tileLayerCreation': + newChange.created.restore(); + this.editor.riotEditor.currentTileLayer = newChange.created; + this.editor.riotEditor.refs.tileEditor?.update(); + break; + case 'tileLayerDeletion': + newChange.deleted.detach(); + if (!this.editor.tileLayers.includes(newChange.deleted)) { + [this.editor.riotEditor.currentTileLayer] = this.editor.tileLayers; + } + this.editor.riotEditor.refs.tileEditor?.update(); + break; + case 'backgroundCreation': + newChange.created.restore(); + this.editor.riotEditor.refs.backgroundsEditor?.update(); + break; + case 'backgroundDeletion': + newChange.deleted.detach(); + this.editor.riotEditor.refs.backgroundsEditor?.update(); + break; + case 'propChange': + (newChange.target as Record)[newChange.key] = newChange.after; + this.updateUiFor(newChange); + break; + } + this.currentChange = newChange; + this.editor.riotEditor.update(); + return true; + } + pushChange(change: change): void { + const id = this.stack.indexOf(this.currentChange); + this.stack = this.stack.slice(0, id + 1); + this.stack.push(change); + this.currentChange = change; + if (this.stack.length > 30) { + this.stack.shift(); + } + this.editor.riotEditor.update(); + } + initiateTransformChange(): void { + const transform: change = { + type: 'transformation', + transformations: new Map() + }; + for (const entity of this.editor.currentSelection) { + const initialTransform = snapshotTransform(entity); + transform.transformations.set(entity as Copy | Tile, [ + initialTransform, + { + ...initialTransform + } + ]); + } + this.pushChange(transform); + } + snapshotTransforms(): void { + if (this.currentChange.type !== 'transformation') { + throw new Error('Cannot snapshot transforms as the current change\'s type is not "transformation"'); + } + for (const [entity, value] of this.currentChange.transformations) { + value[1] = snapshotTransform(entity); + } + void this; + } + updateUiFor(change: propChange): void { + const {target, key} = change, + {editor} = this, + riot = editor.riotEditor; + if (target instanceof TileLayer) { + riot.refs.tileEditor?.update(); + } else if (target === editor.ctRoom) { + riot.refs.propertiesPanel?.update(); + if (key === 'backgroundColor') { + editor.renderer.backgroundColor = + PIXI.utils.string2hex(editor.ctRoom.backgroundColor); + } + } else if (target instanceof Background) { + if (key === 'bgTexture') { + target.changeTexture(target.bgTexture); + } + riot.refs.backgroundsEditor?.update(); + } + } + + get canUndo(): boolean { + return Boolean(this.currentChange); + } + get canRedo(): boolean { + return this.currentChange !== this.stack[this.stack.length - 1]; + } +} diff --git a/src/node_requires/roomEditor/index.ts b/src/node_requires/roomEditor/index.ts new file mode 100644 index 000000000..d5bcaaf38 --- /dev/null +++ b/src/node_requires/roomEditor/index.ts @@ -0,0 +1,561 @@ +import {History} from './history'; + +import {Copy} from './entityClasses/Copy'; +import {Tile} from './entityClasses/Tile'; +import {TileLayer} from './entityClasses/TileLayer'; +import {Background} from './entityClasses/Background'; +import {Viewport} from './entityClasses/Viewport'; + +import {SnapTarget} from './entityClasses/SnapTarget'; +import {MarqueeBox} from './entityClasses/MarqueeBox'; +import {Transformer} from './entityClasses/Transformer'; +import {ViewportRestriction} from './entityClasses/ViewportRestriction'; + +import {IRoomEditorRiotTag} from './IRoomEditorRiotTag'; +import {IRoomEditorInteraction, AllowedListener, allowedListeners, interactions} from './interactions'; +import {getPixiSwatch} from './../themes'; +import {defaultTextStyle, recolorFilters, eraseCursor} from './common'; +import {ease} from 'node_modules/pixi-ease'; + +const roomEditorDefaults = { + width: 10, + height: 10, + autoDensity: true, + transparent: false, + sharedLoader: true, + sharedTicker: false, + resolution: devicePixelRatio, + antialias: true, + preserveDrawingBuffer: true +}; + +export type tileClipboardData = ['tile', ITileTemplate, TileLayer]; +export type copyClipboardData = ['copy', IRoomCopy]; + +class RoomEditor extends PIXI.Application { + history = new History(this); + riotEditor: IRoomEditorRiotTag; + ctRoom: IRoom; + currentSelection: Set = new Set(); + clipboard: Set = new Set(); + /** A sprite that catches any click events */ + clicktrap = new PIXI.Sprite(PIXI.Texture.WHITE); + /** A small circle that shows currently snapped position and a ghost for copy/tile placement */ + snapTarget = new SnapTarget(this); + /** A secondary ghost container for more complex prefabs and constructions */ + compoundGhost = new PIXI.Container(); + /** + * An empty Container that will be used as a camera. + * The camera provides inverted transforms for proper view placement. + */ + camera = new PIXI.Container(); + /** An overlay showing current rectangular selection */ + marqueeBox = new MarqueeBox(this, 0, 0, 10, 10); + /** A container for all the room's entities */ + room = new PIXI.Container(); + /** A container for viewport boxes, grid, and other overlays */ + overlays = new PIXI.Container(); + /** A free transform widget that exists in **global** coordinates. */ + transformer = new Transformer(this); + primaryViewport: Viewport; + restrictViewport: ViewportRestriction; + grid = new PIXI.Graphics(); + /** + * A label that will display current mouse coords relative to a room, + * in a left-bottom corner. Useful for lining up things in a level. + */ + pointerCoords = new PIXI.Text('(0;0)', defaultTextStyle); + /** + * Whether the room editor currently processes a user interaction. + * While this is true, no new interactions can be started. + */ + interacting = false; + interactions: IRoomEditorInteraction[]; + currentInteraction: IRoomEditorInteraction; + affixedInteractionData: unknown; + + copies = new Set(); + tiles = new Set(); + backgrounds: Background[] = []; + viewports = new Set(); + tileLayers: TileLayer[] = []; + + /** + * Creates a pixi.js app — a room editor + * Its `stage` manipulates the camera, managing panning and zooming. + * All the CRUD operations are in the Room class. + * + * @param {Object} opts A partial set of PIXI.Application options that must + * include a mounting point (`view`) + * @param {RiotTag} editor a tag instance of a `room-editor` + */ + constructor(opts: unknown, editor: IRoomEditorRiotTag, pixelart: boolean) { + super(Object.assign({}, roomEditorDefaults, opts, { + resizeTo: editor.root, + roundPixels: pixelart + })); + this.ticker.maxFPS = 60; + + const {room} = editor.opts; + this.ctRoom = room; + this.riotEditor = editor; + + this.clicktrap.alpha = 0; + this.stage.addChild(this.clicktrap); + this.resizeClicktrap(); + this.room.sortableChildren = true; + + this.camera.x = room.width / 2; + this.camera.y = room.height / 2; + this.stage.addChild(this.camera); + + this.stage.addChild(this.room); + this.redrawGrid(); + this.overlays.addChild(this.grid); + this.stage.addChild(this.overlays); + this.compoundGhost.alpha = 0.5; + this.overlays.addChild(this.compoundGhost); + this.marqueeBox.visible = false; + this.overlays.addChild(this.marqueeBox); + this.overlays.addChild(this.snapTarget); + this.deserialize(editor.opts.room); + this.stage.addChild(this.transformer); + + this.pointerCoords.zIndex = Infinity; + this.pointerCoords.x = 8; + this.stage.addChild(this.pointerCoords); + + this.ticker.add(() => { + this.resizeClicktrap(); + this.realignCamera(); + this.snapTarget.update(); + this.repositionCoordLabel(); + this.tickBackgrounds(); + this.tickCopies(); + if (this.transformer.visible) { + this.transformer.updateFrame(); + } + if (['addCopies', 'addTiles'].includes(this.riotEditor.currentTool)) { + if (this.riotEditor.controlMode && ['default', 'inherit'].includes(this.view.style.cursor)) { + this.view.style.cursor = eraseCursor; + this.snapTarget.visible = false; + } + if (!this.riotEditor.controlMode && this.view.style.cursor.includes('Erase')) { + this.view.style.cursor = 'default'; + this.snapTarget.visible = true; + } + } + }); + + this.stage.interactive = true; + this.interactions = interactions; + for (const event of allowedListeners) { + this.stage.on(event, (e: PIXI.InteractionEvent) => { + this.listen(e, event); + }); + } + + // Riot's observable objects lose function's context, so pass an anonymous function instead + this.updateTexturesHandle = (textureId: string) => this.updateTextures(textureId); + this.updateCopiesHandle = (templateId: string) => this.updateCopies(templateId); + window.signals.on('pixiTextureChanged', this.updateTexturesHandle); + window.signals.on('templateChanged', this.updateCopiesHandle); + } + destroy(removeView: boolean, stageOptions: { + children?: boolean; + texture?: boolean; + baseTexture?: boolean; + }): void { + window.signals.off('pixiTextureChanged', this.updateTexturesHandle); + window.signals.off('templateChanged', this.updateCopiesHandle); + super.destroy(removeView, stageOptions); + } + + listen(event: PIXI.InteractionEvent, listener: AllowedListener): void { + var callback = () => { + this.interacting = false; + this.currentInteraction = this.affixedInteractionData = void 0; + }; + for (const interaction of this.interactions) { + if (!this.interacting && interaction.ifListener === listener) { + if (interaction.if.apply(this, [event, this.riotEditor])) { + this.interacting = true; + this.currentInteraction = interaction; + this.affixedInteractionData = {}; + break; + } + } + } + for (const interaction of this.interactions) { + if (this.interacting && this.currentInteraction === interaction) { + if (listener in this.currentInteraction.listeners) { + this.currentInteraction.listeners[listener].apply( + this, + [event, this.riotEditor, this.affixedInteractionData, callback] + ); + } + } + } + } + + deserialize(room: IRoom): void { + this.simulate = room.simulate ?? true; + this.renderer.backgroundColor = PIXI.utils.string2hex(room.backgroundColor); + // Add primary viewport + this.primaryViewport = new Viewport(room, true, this); + this.restrictViewport = new ViewportRestriction(this); + this.overlays.addChild(this.restrictViewport); + this.overlays.addChild(this.primaryViewport); + this.viewports.add(this.primaryViewport); + // Add the remaining entities + for (const bg of room.backgrounds) { + this.addBackground(bg); + } + for (const copy of room.copies) { + const pixiCopy = new Copy(copy, this); + this.room.addChild(pixiCopy); + } + for (const tileLayer of room.tiles) { + this.addTileLayer(tileLayer); + } + } + serialize(): void { + this.ctRoom.copies = [...this.copies].map(c => c.serialize()); + this.ctRoom.tiles = this.tileLayers.map(tl => tl.serialize()); + this.ctRoom.backgrounds = this.backgrounds.map(bg => bg.serialize()); + this.ctRoom.lastmod = Number(new Date()); + } + + /** + * It is separated into a method to be usable externally. + * room-tile-editor uses it to add new layers. + */ + addTileLayer(tileLayer: ITileLayerTemplate | TileLayer, writeToHistory?: boolean): TileLayer { + const pixiTileLayer = tileLayer instanceof TileLayer ? + tileLayer : + new TileLayer(tileLayer, this); + if (this.colorizeTileLayers) { + pixiTileLayer.filters = [recolorFilters[pixiTileLayer.id % 6]]; + } + this.room.addChild(pixiTileLayer); + this.tileLayers.push(pixiTileLayer); + this.tileLayers.sort((a, b) => b.zIndex - a.zIndex); + if (pixiTileLayer.children) { + for (const tile of pixiTileLayer.children) { + this.tiles.add(tile); + } + } + if (writeToHistory) { + this.history.pushChange({ + type: 'tileLayerCreation', + created: pixiTileLayer + }); + } + return pixiTileLayer; + } + + /** + * It is separated as well to be usable by UI written with Riot. + */ + addBackground(bgTemplate: IRoomBackground): Background { + const bg = new Background(bgTemplate, this); + this.backgrounds.push(bg); + this.room.addChild(bg); + return bg; + } + + resizeClicktrap(): void { + this.clicktrap.width = this.screen.width; + this.clicktrap.height = this.screen.height; + } + redrawGrid(): void { + const w = this.ctRoom.gridX, + h = this.ctRoom.gridY; + this.grid.clear(); + if (!this.riotEditor.gridOn) { + // Grid isn't needed + return; + } + // Don't draw too fine grid + if (w / this.camera.scale.x < 8 || h / this.camera.scale.y < 8) { + return; + } + this.grid.lineStyle(this.camera.scale.x, getPixiSwatch('act'), 0.3); + // Camera boundaries with extra tiles around the border + const cw = this.screen.width * this.camera.scale.x + w * 2, + ch = this.screen.height * this.camera.scale.y + h * 2, + cx = this.camera.x - this.screen.width / 2 * this.camera.scale.x - w, + cy = this.camera.y - this.screen.height / 2 * this.camera.scale.y - h; + const xstart = cx; + const ystart = cy; + this.grid.x = -(cx % w); + this.grid.y = -(cy % h); + if (this.ctRoom.diagonalGrid) { + const angle1 = Math.atan(h / w); + const angle2 = Math.PI - angle1; + const cos1 = Math.cos(angle1), + cos2 = Math.cos(angle2), + sin1 = Math.sin(angle1), + sin2 = Math.sin(angle2); + const max = Math.sqrt(cw * cw + ch * ch); + for (let x = xstart; x < cx + cw; x += w) { + this.grid.moveTo(x, cy); + this.grid.lineTo(x + cos1 * max, cy + sin1 * max); + this.grid.moveTo(x, cy); + this.grid.lineTo(x + cos2 * max, cy + sin2 * max); + } + for (let y = ystart + h; y < cy + ch; y += h) { + this.grid.moveTo(cx, y); + this.grid.lineTo(cx + cos1 * max, y + sin1 * max); + } + const cwCorrected = Math.ceil(cw / w) * w; + for (let y = ystart; y < cy + ch; y += h) { + this.grid.moveTo(cx + cwCorrected, y); + this.grid.lineTo(cx + cwCorrected + cos2 * max, y + sin2 * max); + } + } else { + for (let x = xstart; x < cx + cw; x += w) { + this.grid.moveTo(x, cy); + this.grid.lineTo(x, cy + ch); + } + for (let y = ystart; y < cy + ch; y += h) { + this.grid.moveTo(cx, y); + this.grid.lineTo(cx + cw, y); + } + } + } + redrawViewports(): void { + for (const viewport of this.viewports) { + viewport.redrawFrame(); + } + this.restrictViewport.redrawFrame(); + } + /** + * Updates room position based on the camera position. + * @returns {void} + */ + realignCamera(): void { + this.room.transform.setFromMatrix(this.camera.worldTransform + .clone() + .invert() + .translate( + this.view.width / devicePixelRatio / 2, + this.view.height / devicePixelRatio / 2 + )); + this.overlays.transform = this.room.transform; + this.redrawGrid(); + this.redrawViewports(); + } + tickBackgrounds(): void { + for (const background of this.backgrounds) { + background.tick(this.ticker.deltaTime); + } + } + tickCopies(): void { + if (!this.simulate) { + return; + } + for (const copy of this.copies) { + copy.update(this.ticker.deltaTime); + } + } + repositionCoordLabel(): void { + this.pointerCoords.y = this.screen.height - 30; + } + + updateTextures(textureId: string): void { + for (const child of this.room.children) { + if (child instanceof Copy) { + if (child.cachedTemplate.texture === textureId) { + child.refreshTexture(); + } + } else if (child instanceof Tile) { + if (child.tileTexture === textureId) { + child.refreshTexture(); + } + } else if (child instanceof Background) { + if (child.bgTexture === textureId) { + child.refreshTexture(); + } + } + } + } + updateCopies(templateId: string): void { + for (const child of this.room.children) { + if (child instanceof Copy) { + if (child.templateId === templateId) { + child.refreshTexture(); + } + } + } + } + updateTexturesHandle: (textureId: string) => void; + updateCopiesHandle: (templateId: string) => void; + + #simulate: boolean; + get simulate(): boolean { + return this.#simulate; + } + set simulate(value: boolean) { + this.#simulate = value; + if (this.#simulate) { + this.ticker.speed = 1; + } else { + this.ticker.speed = 0; + } + } + + #copiesVisible = true; + #tilesVisible = true; + #backgroundsVisible = true; + #xrayMode = false; + #colorizeTileLayers = false; + get copiesVisible(): boolean { + return this.#copiesVisible; + } + set copiesVisible(value: boolean) { + value = Boolean(value); + if (value === this.#copiesVisible) { + return; + } + this.#copiesVisible = value; + for (const copy of this.copies) { + copy.visible = this.#copiesVisible; + } + } + get tilesVisible(): boolean { + return this.#tilesVisible; + } + set tilesVisible(value: boolean) { + value = Boolean(value); + if (value === this.#tilesVisible) { + return; + } + this.#tilesVisible = value; + for (const layer of this.tileLayers) { + layer.visible = this.#tilesVisible; + } + } + get backgroundsVisible(): boolean { + return this.#backgroundsVisible; + } + set backgroundsVisible(value: boolean) { + value = Boolean(value); + if (value === this.#backgroundsVisible) { + return; + } + this.#backgroundsVisible = value; + for (const bg of this.backgrounds) { + bg.visible = this.#backgroundsVisible; + } + } + get xrayMode(): boolean { + return this.#xrayMode; + } + set xrayMode(value: boolean) { + this.#xrayMode = Boolean(value); + this.room.alpha = this.#xrayMode ? 0.5 : 1; + } + get colorizeTileLayers(): boolean { + return this.#colorizeTileLayers; + } + set colorizeTileLayers(value: boolean) { + this.#colorizeTileLayers = Boolean(value); + for (const layer of this.tileLayers) { + if (this.#colorizeTileLayers) { + layer.filters = [recolorFilters[layer.id % 6]]; + } else { + layer.filters = []; + } + layer.visible = this.#tilesVisible; + } + } + + #selectCopies = true; + #selectTiles = true; + get selectCopies(): boolean { + return this.#selectCopies; + } + set selectCopies(value: boolean) { + value = Boolean(value); + this.#selectCopies = value; + } + get selectTiles(): boolean { + return this.#selectTiles; + } + set selectTiles(value: boolean) { + value = Boolean(value); + this.#selectTiles = value; + } + + goHome(): void { + this.riotEditor.zoom = 1; + ease.add(this.camera, { + x: this.ctRoom.width / 2, + y: this.ctRoom.height / 2, + scale: 1 + }, { + duration: 500 + }) + .on('each', () => { + this.riotEditor.refs.zoomLabel.innerHTML = `${Math.round(this.getZoom())}%`; + }); + } + zoomTo(zoom: number): void { + const scale = 1 / zoom * 100; + ease.add(this.camera, { + scale + }, { + duration: 500 + }) + .on('each', () => { + this.riotEditor.refs.zoomLabel.innerHTML = `${Math.round(this.getZoom())}%`; + }); + } + getZoom(): number { + // Somehow, when updating a room-editor tag, it loses camera but not the editor itself + return this.camera ? (1 / this.camera.scale.x * 100) : 100; + } + + /** + * Returns a base64 string of a room's main viewport. + * It is expected to be run when the room editor is no longer needed, + * as it repositions the room. + */ + getSplashScreen(big: boolean): HTMLCanvasElement { + const w = big ? 340 : 64, + h = big ? 256 : 64; + const renderTexture = PIXI.RenderTexture.create({ + width: w, + height: h + }); + this.overlays.visible = false; + this.transformer.visible = false; + this.pointerCoords.visible = false; + this.clicktrap.width = w; + this.clicktrap.height = h; + this.clicktrap.alpha = 1; + this.clicktrap.tint = this.renderer.backgroundColor; + this.room.scale.set(Math.min(w / this.ctRoom.width, h / this.ctRoom.height)); + this.room.x = (w - this.ctRoom.width * this.room.scale.x) / 2; + this.room.y = (h - this.ctRoom.height * this.room.scale.y) / 2; + this.renderer.render(this.stage, renderTexture); + return this.renderer.extract.canvas(renderTexture); + } +} + + +const setup = (canvas: HTMLCanvasElement, editorTag: IRoomEditorRiotTag): RoomEditor => { + const pixelart = Boolean(currentProject.settings.rendering.pixelatedrender); + editorTag.pixiEditor = new RoomEditor({ + view: canvas + }, editorTag, pixelart); + return editorTag.pixiEditor; +}; + + +export { + setup, + IRoomEditorInteraction, + RoomEditor +}; diff --git a/src/node_requires/roomEditor/interactions/camera/home.ts b/src/node_requires/roomEditor/interactions/camera/home.ts new file mode 100644 index 000000000..9f5f81583 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/camera/home.ts @@ -0,0 +1,16 @@ +import {IRoomEditorInteraction} from '..'; + +const goHome: IRoomEditorInteraction = { + ifListener: 'home', + if() { + return true; + }, + listeners: { + home(e, riotTag, affixedData, callback) { + this.goHome(); + callback(); + } + } +}; + +export {goHome}; diff --git a/src/node_requires/roomEditor/interactions/camera/move.ts b/src/node_requires/roomEditor/interactions/camera/move.ts new file mode 100644 index 000000000..603a8b427 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/camera/move.ts @@ -0,0 +1,46 @@ +import {IRoomEditorInteraction} from '..'; + +interface IMoveCameraAffixedData { + cameraFromPos: { + x: number, + y: number + }, + fromOffsetPos: { + x: number, + y: number + } +} + +const moveCameraOnWheelPress: IRoomEditorInteraction = { + ifListener: 'pointerdown', + if(e) { + // Checks for a pressed mouse wheel + return e.data.button === 1; + }, + listeners: { + pointerdown(e, roomTag, affixedData) { + affixedData.cameraFromPos = { + x: this.camera.x, + y: this.camera.y + }; + affixedData.fromOffsetPos = { + x: e.data.global.x, + y: e.data.global.y + }; + }, + pointermove(e, roomTag, affixedData) { + const cfp = affixedData.cameraFromPos, + op = affixedData.fromOffsetPos; + this.camera.x = cfp.x + (op.x - e.data.global.x) * this.camera.scale.x; + this.camera.y = cfp.y + (op.y - e.data.global.y) * this.camera.scale.y; + this.camera.updateTransform(); + this.tickBackgrounds(); + }, + pointerup: (e, roomTag, affixedData, callback) => { + callback(); + } + } +}; +moveCameraOnWheelPress.listeners.pointerupoutside = moveCameraOnWheelPress.listeners.pointerup; + +export {moveCameraOnWheelPress}; diff --git a/src/node_requires/roomEditor/interactions/camera/zoom.ts b/src/node_requires/roomEditor/interactions/camera/zoom.ts new file mode 100644 index 000000000..d3bcb17f2 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/camera/zoom.ts @@ -0,0 +1,48 @@ +import {IRoomEditorInteraction} from '../..'; +import {ease, Easing} from 'node_modules/pixi-ease'; + +interface IZoomData { + ease: Easing +} + +const zoomInteraction: IRoomEditorInteraction = { + ifListener: 'wheel', + if() { + return true; + }, + listeners: { + wheel(e, roomTag, affixedData, finishCallback) { + const oldZoom = roomTag.zoom; + const dx = this.screen.width / 2 - e.data.global.x, + dy = this.screen.height / 2 - e.data.global.y; + let newZoom; + if ((e.data.originalEvent as WheelEvent).deltaY < 0) { + newZoom = oldZoom * 0.75; + } else { + newZoom = oldZoom * 1.25; + } + if (Math.abs(newZoom - 1) < 0.1) { + newZoom = 1; + } + roomTag.zoom = newZoom; + if (affixedData.ease) { + affixedData.ease.remove(); + } + affixedData.ease = ease.add(this.camera, { + scale: newZoom, + x: this.camera.x + dx * (newZoom - this.camera.scale.x), + y: this.camera.y + dy * (newZoom - this.camera.scale.y) + }, { + duration: 200 + }) + .on('each', () => { + this.camera.updateTransform(); + this.realignCamera(); + roomTag.refs.zoomLabel.innerHTML = `${Math.round(this.getZoom())}%`; + }) + .once('complete', finishCallback); + } + } +}; + +export {zoomInteraction}; diff --git a/src/node_requires/roomEditor/interactions/copies/deleteCopies.ts b/src/node_requires/roomEditor/interactions/copies/deleteCopies.ts new file mode 100644 index 000000000..b442bb650 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/copies/deleteCopies.ts @@ -0,0 +1,40 @@ +import {IRoomEditorInteraction} from '../..'; +import {Copy} from '../../entityClasses/Copy'; + +type affixedData = { + deleted: Set<[Copy]>; +} + +export const deleteCopies: IRoomEditorInteraction = { + ifListener: 'pointerdown', + if(e) { + if (this.riotEditor.currentTool !== 'addCopies') { + return false; + } + return e.data.button === 0 && e.data.originalEvent.ctrlKey; + }, + listeners: { + pointerdown(e, riotTag, affixedData) { + affixedData.deleted = new Set(); + if (e.target instanceof Copy) { + affixedData.deleted.add([e.target.detach()]); + } + }, + pointermove(e, riotTag, affixedData) { + if (e.target instanceof Copy) { + affixedData.deleted.add([e.target.detach()]); + } + }, + pointerup(e, roomTag, affixedData, callback) { + if (affixedData.deleted.size) { + this.history.pushChange({ + type: 'deletion', + deleted: affixedData.deleted + }); + } + callback(); + } + } +}; + +deleteCopies.listeners.pointerupoutside = deleteCopies.listeners.pointerup; diff --git a/src/node_requires/roomEditor/interactions/copies/placeCopy.ts b/src/node_requires/roomEditor/interactions/copies/placeCopy.ts new file mode 100644 index 000000000..16f83a4ce --- /dev/null +++ b/src/node_requires/roomEditor/interactions/copies/placeCopy.ts @@ -0,0 +1,148 @@ +import {IRoomEditorInteraction, RoomEditor} from '../..'; +import {Copy} from '../../entityClasses/Copy'; + +import {calcPlacement} from '../placementCalculator'; + +import {soundbox} from '../../../3rdparty/soundbox'; + +interface IAffixedData { + mode: 'free' | 'straight'; + startPos: PIXI.IPoint; + prevPos: PIXI.IPoint; + prevLength: number; + stepX: number; + stepY: number; + diagonalGrid: boolean; + gridX: number; + gridY: number; + noGrid: boolean; + created: Set<[Copy]>; +} + +const createCopy = ( + pos: PIXI.IPoint, + template: ITemplate, + editor: RoomEditor, + ghost?: boolean +) => new Copy({ + x: pos.x, + y: pos.y, + exts: {}, + customProperties: {}, + scale: { + x: 1, + y: 1 + }, + uid: template.uid, + opacity: 1, + rotation: 0, + tint: 0xffffff +}, editor, ghost); + +export const placeCopy: IRoomEditorInteraction = { + ifListener: 'pointerdown', + if(e, riotTag) { + if (this.riotEditor.currentTool !== 'addCopies') { + return false; + } + if (e.data.button !== 0) { + return false; + } + return riotTag.currentTemplate && riotTag.currentTemplate !== -1; + }, + listeners: { + pointerdown(e, roomTag, affixedData) { + this.compoundGhost.removeChildren(); + affixedData.created = new Set(); + // Two possible modes: placing in straight vertical/horizontal/diagonal lines + // and in a free form, like drawing with a brush. + // Straight method creates a ghost preview before actually creating all the copies, + // while the free form places copies as a user moves their cursor. + if (e.data.originalEvent.shiftKey) { + affixedData.mode = 'straight'; + affixedData.prevLength = 1; + } else { + affixedData.mode = 'free'; + } + affixedData.gridX = this.ctRoom.gridX; + affixedData.gridY = this.ctRoom.gridY; + affixedData.diagonalGrid = this.ctRoom.diagonalGrid; + affixedData.startPos = affixedData.prevPos = this.snapTarget.position.clone(); + affixedData.noGrid = !roomTag.gridOn || roomTag.freePlacementMode; + const newCopy = createCopy( + affixedData.startPos, + this.riotEditor.currentTemplate as ITemplate, + this + ); + affixedData.created.add([newCopy]); + this.room.addChild(newCopy); + affixedData.stepX = affixedData.stepY = 1; + soundbox.play('Wood_Start'); + }, + pointermove(e, roomTag, affixedData) { + affixedData.noGrid = !roomTag.gridOn || roomTag.freePlacementMode; + const newPos = this.snapTarget.position.clone(); + const ghosts = calcPlacement( + newPos, + affixedData, + ((position): Copy => { + soundbox.play('Wood_Start'); + const copy = createCopy( + position, + this.riotEditor.currentTemplate as ITemplate, + this + ); + this.room.addChild(copy); + affixedData.created.add([copy]); + return copy; + }) + ); + // Play feedback sound on length change + if (ghosts.length !== affixedData.prevLength) { + affixedData.prevLength = ghosts.length; + soundbox.play('Wood_Start'); + } + // Remove excess ghost instances + if (this.compoundGhost.children.length > ghosts.length) { + this.compoundGhost.removeChildren(ghosts.length); + } + // Add missing ghost instances + while (this.compoundGhost.children.length < ghosts.length) { + this.compoundGhost.addChild(createCopy( + affixedData.startPos, + this.riotEditor.currentTemplate as ITemplate, + this, + true + )); + } + for (let i = 0; i < ghosts.length; i++) { + const ghost = this.compoundGhost.children[i]; + ghost.x = ghosts[i].x; + ghost.y = ghosts[i].y; + } + }, + pointerup(e, roomTag, affixedData, callback) { + if (affixedData.mode === 'straight') { + // Replace all the preview copies with real ones + for (const ghost of this.compoundGhost.children) { + const copy = createCopy( + ghost.position, + this.riotEditor.currentTemplate as ITemplate, + this + ); + this.room.addChild(copy); + affixedData.created.add([copy]); + } + } + soundbox.play('Wood_End'); + this.compoundGhost.removeChildren(); + this.history.pushChange({ + type: 'creation', + created: affixedData.created + }); + callback(); + } + } +}; + +placeCopy.listeners.pointerupoutside = placeCopy.listeners.pointerup; diff --git a/src/node_requires/roomEditor/interactions/copyPaste.ts b/src/node_requires/roomEditor/interactions/copyPaste.ts new file mode 100644 index 000000000..fbdd3cf12 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/copyPaste.ts @@ -0,0 +1,126 @@ +import {IRoomEditorInteraction} from '..'; +import {Copy} from '../entityClasses/Copy'; +import {Tile} from '../entityClasses/Tile'; +import {TileLayer} from '../entityClasses/TileLayer'; + +import {snapToDiagonalGrid, snapToRectangularGrid} from '../common'; + +import {getTemplateFromId} from '../../resources/templates'; + +export const copy: IRoomEditorInteraction = { + ifListener: 'copy', + if() { + return this.riotEditor.currentTool === 'select' && this.currentSelection.size > 0; + }, + listeners: { + copy(e, riotEditor, affixedData, callback) { + this.clipboard.clear(); + for (const stuff of this.currentSelection) { + if (stuff instanceof Copy) { + this.clipboard.add([ + 'copy', + stuff.serialize() + ]); + } else if (stuff instanceof Tile) { + this.clipboard.add([ + 'tile', + stuff.serialize(), + stuff.parent + ]); + } + } + this.transformer.blink(); + callback(); + } + } +}; + +export const paste: IRoomEditorInteraction = { + ifListener: 'paste', + if() { + return this.clipboard.size > 0; + }, + listeners: { + paste(e, riotEditor, affixedData, callback) { + const createdSet = new Set<[Copy | Tile, TileLayer?]>(); + if (riotEditor.currentTool === 'select' && + this.currentSelection.size && + this.history.currentChange?.type === 'transformation' + ) { + this.history.snapshotTransforms(); + } + this.transformer.clear(); + const extraTileLayer = this.tileLayers.find(tl => tl.zIndex === 0) || new TileLayer({ + depth: 0, + tiles: [] + }, this); + for (const copied of this.clipboard) { + let created; + if (copied[0] === 'tile') { + const [, template, layer] = copied; + const target = this.tileLayers.includes(layer) ? layer : extraTileLayer; + created = new Tile(template, this, false); + target.addChild(created); + createdSet.add([created, target]); + } else if (copied[0] === 'copy') { + const [, template] = copied; + // Skip copies that no longer exist in the project + try { + getTemplateFromId(template.uid); + created = new Copy(template, this, false); + this.room.addChild(created); + createdSet.add([created]); + } catch (_) { + continue; + } + } else { + // Unsupported selectable entity + continue; + } + this.currentSelection.add(created); + } + if (extraTileLayer.children.length && !this.tileLayers.includes(extraTileLayer)) { + this.addTileLayer(extraTileLayer); + this.history.pushChange({ + type: 'tileLayerCreation', + created: extraTileLayer + }); + } else { + extraTileLayer.destroy(); + } + this.history.pushChange({ + type: 'creation', + created: createdSet + }); + if (riotEditor.currentTool !== 'select') { + riotEditor.setTool('select')(); + riotEditor.update(); + } + this.transformer.setup(true); + + // place the stuff under mouse cursor but do take the grid into account + const {mouse} = this.renderer.plugins.interaction; + const mousePos = mouse.getLocalPosition(this.room); + let dx = mousePos.x - this.transformer.transformPivotX, + dy = mousePos.y - this.transformer.transformPivotY; + if (this.riotEditor.gridOn) { + const snap = this.ctRoom.diagonalGrid ? snapToDiagonalGrid : snapToRectangularGrid; + const snapped = snap({ + x: dx, + y: dy + }, this.ctRoom.gridX, this.ctRoom.gridY); + dx = snapped.x; + dy = snapped.y; + } + this.transformer.transformPivotX += dx; + this.transformer.transformPivotY += dy; + this.transformer.applyTranslateX += dx; + this.transformer.applyTranslateY += dy; + this.transformer.applyTransforms(); + this.transformer.setup(); + riotEditor.refs.propertiesPanel.updatePropList(); + this.transformer.blink(); + callback(); + } + } +}; diff --git a/src/node_requires/roomEditor/interactions/history.ts b/src/node_requires/roomEditor/interactions/history.ts new file mode 100644 index 000000000..c5040c91a --- /dev/null +++ b/src/node_requires/roomEditor/interactions/history.ts @@ -0,0 +1,37 @@ +import {IRoomEditorInteraction} from '..'; + +export const undo: IRoomEditorInteraction = { + ifListener: 'undo', + if() { + // History object has its internal checks, + // and this is the only interaction that uses this listener, + // so always returning true is okay. + return true; + }, + listeners: { + undo(e, roomTag, affixedData, callback) { + if (this.history.undo()) { + e.data.originalEvent.preventDefault(); + } + callback(); + } + } +}; + +export const redo: IRoomEditorInteraction = { + ifListener: 'redo', + if() { + // History object has its internal checks, + // and this is the only interaction that uses this listener, + // so always returning true is okay. + return true; + }, + listeners: { + redo(e, roomTag, affixedData, callback) { + if (this.history.redo()) { + e.data.originalEvent.preventDefault(); + } + callback(); + } + } +}; diff --git a/src/node_requires/roomEditor/interactions/index.ts b/src/node_requires/roomEditor/interactions/index.ts new file mode 100644 index 000000000..9c4f228ba --- /dev/null +++ b/src/node_requires/roomEditor/interactions/index.ts @@ -0,0 +1,96 @@ +/* slint-disable no-use-before-define */ +import {RoomEditor} from '..'; +import {IRoomEditorRiotTag} from '../IRoomEditorRiotTag'; + +export enum EAllowedListeners { + pointertap, + pointerup, + pointerupoutside, + pointerdown, + pointermove, + pointerleave, + + // Custom events below + wheel, + + home, + + delete, + copy, + paste, + undo, + redo, + + nudgeright, + nudgeleft, + nudgeup, + nudgedown +} +export type AllowedListener = keyof typeof EAllowedListeners; +export const allowedListeners: AllowedListener[] = + Object.keys(EAllowedListeners) as AllowedListener[]; + +export type InteractionListener = ( + this: RoomEditor, + e: PIXI.InteractionEvent, + roomTag: IRoomEditorRiotTag, + affixedData: affixedInterface, + finishCallback: () => void +) => void; +export interface IRoomEditorInteraction { + ifListener: AllowedListener; + /** + * Checks if it is possible to run an interaction now. + * If this method returns true, all the further interactions will be skipped + * until the startingAction calls the provided finishCallback + */ + if: (this: RoomEditor, e: PIXI.InteractionEvent, roomTag: IRoomEditorRiotTag) => boolean; + listeners: Partial>>; +} + +import {updateMousePosition} from './mousePosLabel'; +import {moveCameraOnWheelPress} from './camera/move'; +import {goHome} from './camera/home'; +import {zoomInteraction} from './camera/zoom'; +import {placeCopy} from './copies/placeCopy'; +import {deleteCopies} from './copies/deleteCopies'; +import {placeTile} from './tiles/placeTile'; +import {deleteTiles} from './tiles/deleteTiles'; +import {select} from './transformer/select'; +import {nudgeLeft, nudgeRight, nudgeUp, nudgeDown} from './transformer/nudge'; +import {rotateSelection} from './transformer/rotate'; +import {moveSelection} from './transformer/move'; +import {scaleSelection} from './transformer/scale'; +import {deleteSelected} from './transformer/delete'; +import {copy, paste} from './copyPaste'; +import {undo, redo} from './history'; + +export const interactions = [ + updateMousePosition, // Ambient interaction — never blocks the queue + + nudgeLeft, + nudgeRight, + nudgeUp, + nudgeDown, + + copy, + paste, + undo, + redo, + + rotateSelection, + moveSelection, + scaleSelection, + deleteSelected, + select, + + deleteCopies, + placeCopy, + + deleteTiles, + placeTile, + + zoomInteraction, + moveCameraOnWheelPress, + goHome +]; diff --git a/src/node_requires/roomEditor/interactions/mousePosLabel.ts b/src/node_requires/roomEditor/interactions/mousePosLabel.ts new file mode 100644 index 000000000..52a0def47 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/mousePosLabel.ts @@ -0,0 +1,15 @@ +import {IRoomEditorInteraction} from '..'; + +const updateMousePosition: IRoomEditorInteraction = { + ifListener: 'pointermove', + if() { + const x = Math.round(this.snapTarget.x * 100) / 100, + y = Math.round(this.snapTarget.y * 100) / 100; + this.pointerCoords.text = `(${x}; ${y})`; + // This interaction never actually marks itself as valid + return false; + }, + listeners: {} +}; + +export {updateMousePosition}; diff --git a/src/node_requires/roomEditor/interactions/placementCalculator.ts b/src/node_requires/roomEditor/interactions/placementCalculator.ts new file mode 100644 index 000000000..0c3ff99ad --- /dev/null +++ b/src/node_requires/roomEditor/interactions/placementCalculator.ts @@ -0,0 +1,136 @@ +/* +This code was separated for DRY principle, as almost the same code +is used while placing tiles and copies. + +This code is intended to be used as part of pointermove event, +and returns a list of locations of ghost objects, which is not empty +only while using parallel placement. + +During the free placement, it may call placeImmediately as a callback +when a new object should be placed. +*/ + +import {fromRectangular, fromDiagonal, toRectangular, toDiagonal} from '../common'; + +type PlacementData = { + mode: 'free' | 'straight'; + startPos: PIXI.IPoint; + prevPos: PIXI.IPoint; + prevLength: number; + stepX: number; + stepY: number; + diagonalGrid: boolean; + gridX: number; + gridY: number; + noGrid: boolean; +}; + +type ghostPoints = { + x: number; + y: number; +}[]; +type ISimplePoint = { + x: number; + y: number; +}; + +// eslint-disable-next-line max-lines-per-function +export const calcPlacement = ( + newPos: PIXI.IPoint, + affixedData: PlacementData, + placeImmediately: (position: PIXI.IPoint) => void +): ghostPoints => { + const from = affixedData.diagonalGrid ? fromDiagonal : fromRectangular; + const to = affixedData.diagonalGrid ? toDiagonal : toRectangular; + // Correct placement position based on step size. + const newPosOnGrid = to(newPos, affixedData.gridX, affixedData.gridY), + startPosOnGrid = to(affixedData.startPos, affixedData.gridX, affixedData.gridY); + let newPosWSkips: ISimplePoint | PIXI.IPoint = from({ + x: newPosOnGrid.x - ((startPosOnGrid.x - newPosOnGrid.x) % affixedData.stepX), + y: newPosOnGrid.y - ((startPosOnGrid.y - newPosOnGrid.y) % affixedData.stepY) + }, affixedData.gridX, affixedData.gridY); + newPosWSkips = new PIXI.Point(newPosWSkips.x, newPosWSkips.y); + + // Free placement (drawing) + if (affixedData.mode === 'free') { + // When working without a grid, place copies in a strip, + // spacing of which depends on the grid size. + if (affixedData.noGrid) { + let dx = (newPos.x - affixedData.prevPos.x) / affixedData.gridX, + dy = (newPos.y - affixedData.prevPos.y) / affixedData.gridY; + const l = Math.sqrt(dx * dx + dy * dy); + if (l >= 1) { + dx /= l; + dy /= l; + const placeX = dx * affixedData.gridX + affixedData.prevPos.x, + placeY = dy * affixedData.gridY + affixedData.prevPos.y; + const newPlace = new PIXI.Point(placeX, placeY); + placeImmediately(newPlace); + affixedData.prevPos = newPlace; + } + return []; + } + // Skip spawning if position on-grid didn't change from the previous frame. + if (newPosWSkips.x === affixedData.prevPos.x && newPosWSkips.y === affixedData.prevPos.y) { + return []; + } + placeImmediately(newPosWSkips as PIXI.Point); + affixedData.prevPos = newPosWSkips as PIXI.Point; + return []; + } + + affixedData.prevPos = newPos; + + // Straight-line placement + const startGrid = to( + affixedData.startPos, + affixedData.gridX, + affixedData.gridY + ); + const endGrid = to( + newPos, + affixedData.gridX, + affixedData.gridY + ); + const dx = Math.abs(startGrid.x - endGrid.x), + dy = Math.abs(startGrid.y - endGrid.y); + const straightEndGrid: ISimplePoint = { + x: 0, + y: 0 + }; + const angle = Math.atan2(dy, dx); + if (Math.abs(angle) > Math.PI * 0.375 && Math.abs(angle) < Math.PI * 0.525) { + // Seems to be a vertical line + straightEndGrid.x = startGrid.x; + straightEndGrid.y = endGrid.y; + } else if (Math.abs(angle) < Math.PI * 0.125) { + // Seems to be a horizontal line + straightEndGrid.x = endGrid.x; + straightEndGrid.y = startGrid.y; + } else { + // It is more or so diagonal + const max = Math.max(dx, dy); + straightEndGrid.x = endGrid.x > startGrid.x ? + startGrid.x + max : + startGrid.x - max; + straightEndGrid.y = endGrid.y > startGrid.y ? + startGrid.y + max : + startGrid.y - max; + } + const incX = Math.sign(straightEndGrid.x - startGrid.x) * affixedData.stepX, + incY = Math.sign(straightEndGrid.y - startGrid.y) * affixedData.stepY; + const l = Math.max(dx / affixedData.stepX, dy / affixedData.stepY); + const ghosts = []; + // Calculate ghost positions + for (let i = 0, {x, y} = startGrid; + i < l; + i++, x += incX, y += incY + ) { + const localPos = from({ + x: x + incX, + y: y + incY + }, affixedData.gridX, affixedData.gridY); + ghosts.push(localPos); + } + return ghosts; +}; diff --git a/src/node_requires/roomEditor/interactions/tiles/ITilePatch.d.ts b/src/node_requires/roomEditor/interactions/tiles/ITilePatch.d.ts new file mode 100644 index 000000000..675800135 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/tiles/ITilePatch.d.ts @@ -0,0 +1,7 @@ +export interface ITilePatch { + startX: number; + startY: number; + spanX: number; + spanY: number; + texture: ITexture; +} diff --git a/src/node_requires/roomEditor/interactions/tiles/deleteTiles.ts b/src/node_requires/roomEditor/interactions/tiles/deleteTiles.ts new file mode 100644 index 000000000..f8e3a2ae5 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/tiles/deleteTiles.ts @@ -0,0 +1,43 @@ +import {IRoomEditorInteraction} from '../..'; +import {Tile} from '../../entityClasses/Tile'; +import {TileLayer} from '../../entityClasses/TileLayer'; + +type affixedData = { + deleted: Set<[Tile, TileLayer]>; +} + +export const deleteTiles: IRoomEditorInteraction = { + ifListener: 'pointerdown', + if(e) { + if (this.riotEditor.currentTool !== 'addTiles' || !this.riotEditor.currentTileLayer) { + return false; + } + return e.data.button === 0 && e.data.originalEvent.ctrlKey; + }, + listeners: { + pointerdown(e, riotTag, affixedData) { + affixedData.deleted = new Set(); + if (e.target instanceof Tile && e.target.parent === riotTag.currentTileLayer) { + const {parent} = e.target; + affixedData.deleted.add([e.target.detach(), parent]); + } + }, + pointermove(e, riotTag, affixedData) { + if (e.target instanceof Tile && e.target.parent === riotTag.currentTileLayer) { + const {parent} = e.target; + affixedData.deleted.add([e.target.detach(), parent]); + } + }, + pointerup(e, roomTag, affixedData, callback) { + if (affixedData.deleted.size) { + this.history.pushChange({ + type: 'deletion', + deleted: affixedData.deleted + }); + } + callback(); + } + } +}; + +deleteTiles.listeners.pointerupoutside = deleteTiles.listeners.pointerup; diff --git a/src/node_requires/roomEditor/interactions/tiles/placeTile.ts b/src/node_requires/roomEditor/interactions/tiles/placeTile.ts new file mode 100644 index 000000000..399863478 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/tiles/placeTile.ts @@ -0,0 +1,192 @@ +import {Tile} from '../../entityClasses/Tile'; +import {TileLayer} from '../../entityClasses/TileLayer'; +import {IRoomEditorInteraction, RoomEditor} from '../..'; +import {calcPlacement} from '../placementCalculator'; +import {ITilePatch} from './ITilePatch'; + +import {soundbox} from '../../../3rdparty/soundbox'; + +interface IAffixedData { + mode: 'free' | 'straight'; + startPos: PIXI.IPoint; + prevPos: PIXI.IPoint; + prevLength: number; + stepX: number; + stepY: number; + diagonalGrid: boolean; + gridX: number; + gridY: number; + noGrid: boolean; + created: Set<[Tile, TileLayer]>; +} + +interface ISimplePoint { + x: number; + y: number; +} + +const createTile = ( + pos: ISimplePoint, + texture: string, + frame: number, + editor: RoomEditor, + ghost?: boolean +) => new Tile({ + x: pos.x, + y: pos.y, + scale: { + x: 1, + y: 1 + }, + opacity: 1, + rotation: 0, + tint: 0xffffff, + frame, + texture +}, editor, ghost); + +export const createTilePatch = ( + tilePatch: ITilePatch, + startPos: ISimplePoint, + editor: RoomEditor, + ghost?: boolean +): Tile[] => { + const tiles: Tile[] = []; + const {texture} = tilePatch; + for (let x = 0; x < tilePatch.spanX; x++) { + for (let y = 0; y < tilePatch.spanY; y++) { + const frame = x + tilePatch.startX + + (y + tilePatch.startY) * texture.grid[0]; + tiles.push(createTile({ + x: startPos.x + x * texture.width, + y: startPos.y + y * texture.height + }, texture.uid, frame, editor, ghost)); + } + } + return tiles; +}; + +export const placeTile: IRoomEditorInteraction = { + ifListener: 'pointerdown', + if(e, riotTag) { + if (this.riotEditor.currentTool !== 'addTiles' || !this.riotEditor.currentTileLayer) { + return false; + } + if (e.data.button !== 0) { + return false; + } + return Boolean(riotTag.tilePatch?.texture); + }, + listeners: { + pointerdown(e, riotTag, affixedData) { + this.compoundGhost.removeChildren(); + affixedData.created = new Set(); + // Two possible modes: placing in straight vertical/horizontal/diagonal lines + // and in a free form, like drawing with a brush. + // Straight method creates a ghost preview before actually creating all the copies, + // while the free form places copies as a user moves their cursor. + if (e.data.originalEvent.shiftKey) { + affixedData.mode = 'straight'; + affixedData.prevLength = 1; + } else { + affixedData.mode = 'free'; + } + affixedData.gridX = this.ctRoom.gridX; + affixedData.gridY = this.ctRoom.gridY; + const {texture} = riotTag.tilePatch; + // Allow skipping grid cells if texture's and room's grids match + if (this.ctRoom.gridX === texture.width && this.ctRoom.gridY === texture.height) { + affixedData.stepX = riotTag.tilePatch.spanX; + affixedData.stepY = riotTag.tilePatch.spanY; + } else { + affixedData.stepX = affixedData.stepY = 1; + } + affixedData.diagonalGrid = this.ctRoom.diagonalGrid; + affixedData.noGrid = !riotTag.gridOn || riotTag.freePlacementMode; + affixedData.startPos = affixedData.prevPos = this.snapTarget.position.clone(); + const newTiles = createTilePatch( + riotTag.tilePatch, + affixedData.startPos, + this + ); + riotTag.currentTileLayer.addChild(...newTiles); + for (const tile of newTiles) { + affixedData.created.add([tile, tile.parent]); + } + soundbox.play('Wood_Start'); + }, + pointermove(e, riotTag, affixedData) { + affixedData.noGrid = !riotTag.gridOn || riotTag.freePlacementMode; + const newPos = this.snapTarget.position.clone(); + const ghosts = calcPlacement( + newPos, + affixedData, + (position => { + soundbox.play('Wood_Start'); + const newTiles = createTilePatch( + riotTag.tilePatch, + position, + this + ); + riotTag.currentTileLayer.addChild(...newTiles); + for (const tile of newTiles) { + affixedData.created.add([tile, tile.parent]); + } + }) + ); + // Play feedback sound on length change + if (ghosts.length !== affixedData.prevLength) { + affixedData.prevLength = ghosts.length; + soundbox.play('Wood_Start'); + } + // Remove excess ghost instances + if (this.compoundGhost.children.length > ghosts.length) { + this.compoundGhost.removeChildren(ghosts.length); + } + // Add missing ghost instances + // Tile patches are grouped into containers + while (this.compoundGhost.children.length < ghosts.length) { + const ghostTilePatch = new PIXI.Container(); + ghostTilePatch.addChild(...createTilePatch(riotTag.tilePatch, { + x: 0, + y: 0 + }, this, true)); + this.compoundGhost.addChild(ghostTilePatch); + } + // Reposition ghost containers + for (let i = 0; i < ghosts.length; i++) { + const ghost = this.compoundGhost.children[i]; + ghost.x = ghosts[i].x; + ghost.y = ghosts[i].y; + } + }, + pointerup(e, riotTag, affixedData, callback) { + if (affixedData.mode === 'straight') { + // Replace all the preview copies with real ones + for (const ghost of this.compoundGhost.children) { + const newTiles = createTilePatch( + riotTag.tilePatch, + ghost.position, + this + ); + riotTag.currentTileLayer.addChild(...newTiles); + for (const tile of newTiles) { + affixedData.created.add([tile, tile.parent]); + } + } + } + soundbox.play('Wood_End'); + this.compoundGhost.removeChildren(); + this.stage.interactive = true; // Causes to rediscover nested elements + if (affixedData.created.size) { + this.history.pushChange({ + type: 'creation', + created: affixedData.created + }); + } + callback(); + } + } +}; + +placeTile.listeners.pointerupoutside = placeTile.listeners.pointerup; diff --git a/src/node_requires/roomEditor/interactions/transformer/delete.ts b/src/node_requires/roomEditor/interactions/transformer/delete.ts new file mode 100644 index 000000000..da6ac95e0 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/transformer/delete.ts @@ -0,0 +1,32 @@ +import {IRoomEditorInteraction} from '..'; +import {Copy} from '../../entityClasses/Copy'; +import {Tile} from '../../entityClasses/Tile'; +import {TileLayer} from '../../entityClasses/TileLayer'; + +export const deleteSelected: IRoomEditorInteraction = { + ifListener: 'delete', + if() { + return this.riotEditor.currentTool === 'select' && this.currentSelection.size > 0; + }, + listeners: { + delete(e, riotEditor, affixedData, callback) { + const changes = new Set<[Copy | Tile, TileLayer?]>(); + for (const stuff of this.currentSelection) { + if (stuff instanceof Tile) { + const {parent} = stuff; + changes.add([stuff.detach(), parent]); + } else if (stuff instanceof Copy) { + changes.add([stuff.detach()]); + } + } + this.history.pushChange({ + type: 'deletion', + deleted: changes + }); + this.transformer.clear(); + riotEditor.refs.propertiesPanel.updatePropList(); + + callback(); + } + } +}; diff --git a/src/node_requires/roomEditor/interactions/transformer/move.ts b/src/node_requires/roomEditor/interactions/transformer/move.ts new file mode 100644 index 000000000..d31176eae --- /dev/null +++ b/src/node_requires/roomEditor/interactions/transformer/move.ts @@ -0,0 +1,57 @@ +import {IRoomEditorInteraction} from '../..'; +import {snapToRectangularGrid, snapToDiagonalGrid} from '../../common'; + +interface IAffixedData { + startingGlobalPos: PIXI.Point; + startingTranslateX: number; + startingTranslateY: number; + startingPivotX: number; + startingPivotY: number; +} + +export const moveSelection: IRoomEditorInteraction = { + ifListener: 'pointerdown', + if(e) { + if (this.riotEditor.currentTool !== 'select') { + return false; + } + if (this.currentSelection.size === 0) { + return false; + } + return e.target === this.transformer.handleCenter; + }, + listeners: { + pointerdown(e, roomTag, affixed) { + affixed.startingGlobalPos = e.data.global.clone(); + affixed.startingTranslateX = this.transformer.applyTranslateX; + affixed.startingTranslateY = this.transformer.applyTranslateY; + affixed.startingPivotX = this.transformer.transformPivotX; + affixed.startingPivotY = this.transformer.transformPivotY; + }, + pointermove(e, roomTag, affixed) { + let delta = { + x: (e.data.global.x - affixed.startingGlobalPos.x) * this.camera.scale.x, + y: (e.data.global.y - affixed.startingGlobalPos.y) * this.camera.scale.x + }; + // Ignore grid when alt key is pressed, or when the grid is disabled + if (!e.data.originalEvent.altKey && roomTag.gridOn) { + // Otherwise, snap delta to a grid + if (this.ctRoom.diagonalGrid) { + delta = snapToDiagonalGrid(delta, this.ctRoom.gridX, this.ctRoom.gridY); + } else { + delta = snapToRectangularGrid(delta, this.ctRoom.gridX, this.ctRoom.gridY); + } + } + this.transformer.applyTranslateX = affixed.startingTranslateX + delta.x; + this.transformer.applyTranslateY = affixed.startingTranslateY + delta.y; + this.transformer.transformPivotX = affixed.startingPivotX + delta.x; + this.transformer.transformPivotY = affixed.startingPivotY + delta.y; + this.transformer.applyTransforms(); + this.riotEditor.refs.propertiesPanel.updatePropList(); + }, + pointerup(e, roomTag, affixedData, callback) { + this.history.snapshotTransforms(); + callback(); + } + } +}; diff --git a/src/node_requires/roomEditor/interactions/transformer/nudge.ts b/src/node_requires/roomEditor/interactions/transformer/nudge.ts new file mode 100644 index 000000000..addc0bc2c --- /dev/null +++ b/src/node_requires/roomEditor/interactions/transformer/nudge.ts @@ -0,0 +1,66 @@ +import {IRoomEditorInteraction} from '..'; + +export const nudgeDown: IRoomEditorInteraction = { + ifListener: 'nudgedown', + if() { + return Boolean(this.riotEditor.currentTool === 'select' && this.currentSelection.size); + }, + listeners: { + nudgedown(e, roomTag, affixedData, callback) { + const delta = e.data.originalEvent.ctrlKey ? 1 : this.ctRoom.gridY; + this.transformer.applyTranslateY += delta; + this.transformer.transformPivotY += delta; + this.transformer.applyTransforms(); + callback(); + } + } +}; + +export const nudgeUp: IRoomEditorInteraction = { + ifListener: 'nudgeup', + if() { + return Boolean(this.riotEditor.currentTool === 'select' && this.currentSelection.size); + }, + listeners: { + nudgeup(e, roomTag, affixedData, callback) { + const delta = e.data.originalEvent.ctrlKey ? 1 : this.ctRoom.gridY; + this.transformer.applyTranslateY -= delta; + this.transformer.transformPivotY -= delta; + this.transformer.applyTransforms(); + callback(); + } + } +}; + +export const nudgeLeft: IRoomEditorInteraction = { + ifListener: 'nudgeleft', + if() { + return Boolean(this.riotEditor.currentTool === 'select' && this.currentSelection.size); + }, + listeners: { + nudgeleft(e, roomTag, affixedData, callback) { + const delta = e.data.originalEvent.ctrlKey ? 1 : this.ctRoom.gridX; + this.transformer.applyTranslateX -= delta; + this.transformer.transformPivotX -= delta; + this.transformer.applyTransforms(); + callback(); + } + } +}; + +export const nudgeRight: IRoomEditorInteraction = { + ifListener: 'nudgeright', + if() { + return Boolean(this.riotEditor.currentTool === 'select' && this.currentSelection.size); + }, + listeners: { + nudgeright(e, roomTag, affixedData, callback) { + const delta = e.data.originalEvent.ctrlKey ? 1 : this.ctRoom.gridX; + this.transformer.applyTranslateX += delta; + this.transformer.transformPivotX += delta; + this.transformer.applyTransforms(); + this.history.snapshotTransforms(); + callback(); + } + } +}; diff --git a/src/node_requires/roomEditor/interactions/transformer/rotate.ts b/src/node_requires/roomEditor/interactions/transformer/rotate.ts new file mode 100644 index 000000000..d77c3a3c3 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/transformer/rotate.ts @@ -0,0 +1,46 @@ +import {IRoomEditorInteraction} from '../..'; + +import {pdn, degToRad, radToDeg} from '../../../utils/trigo'; + +export const rotateSelection: IRoomEditorInteraction = { + ifListener: 'pointerdown', + if(e) { + if (this.riotEditor.currentTool !== 'select') { + return false; + } + if (this.currentSelection.size === 0) { + return false; + } + return e.target === this.transformer.handleRotate; + }, + listeners: { + pointermove(e) { + const globalPivot = this.room.toGlobal(new PIXI.Point( + this.transformer.transformPivotX, + this.transformer.transformPivotY + )); + let rad = pdn( + globalPivot.x, + globalPivot.y, + e.data.global.x, + e.data.global.y + ); + // When the group is mirrored horizontally, + // the handle appears on the left side, not on the right side. + if (this.transformer.applyScaleX < 0) { + rad += Math.PI; + } + if (e.data.originalEvent.shiftKey) { + // Snap at 15 degrees + rad = degToRad(Math.round(radToDeg(rad) / 15) * 15); + } + this.transformer.applyRotation = rad; + this.transformer.applyTransforms(); + this.riotEditor.refs.propertiesPanel.updatePropList(); + }, + pointerup(e, roomTag, affixedData, callback) { + this.history.snapshotTransforms(); + callback(); + } + } +}; diff --git a/src/node_requires/roomEditor/interactions/transformer/scale.ts b/src/node_requires/roomEditor/interactions/transformer/scale.ts new file mode 100644 index 000000000..75d46bc24 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/transformer/scale.ts @@ -0,0 +1,154 @@ +import {IRoomEditorInteraction} from '../..'; +import {Handle} from '../../entityClasses/Transformer'; + +import {rotateRad} from '../../../utils/trigo'; +import {snapToRectangularGrid, snapToDiagonalGrid} from '../../common'; + +interface IAffixedData { + axes: 'x' | 'y' | 'xy'; + startingSX: number; + startingSY: number; + startingTX: number; + startingTY: number; + startingPX: number; + startingPY: number; + startDragRoom: PIXI.IPoint; +} + +export const scaleSelection: IRoomEditorInteraction = { + ifListener: 'pointerdown', + if(e) { + if (this.riotEditor.currentTool !== 'select') { + return false; + } + if (this.currentSelection.size === 0) { + return false; + } + return this.transformer.scaleHandles.includes(e.target as Handle); + }, + listeners: { + pointerdown(e, roomTag, affixedData) { + // Fix scaling to zero + affixedData.startingSX = this.transformer.applyScaleX || 1; + affixedData.startingSY = this.transformer.applyScaleY || 1; + affixedData.startingTX = this.transformer.applyTranslateX; + affixedData.startingTY = this.transformer.applyTranslateY; + affixedData.startingPX = this.transformer.transformPivotX; + affixedData.startingPY = this.transformer.transformPivotY; + affixedData.startDragRoom = this.room.toLocal(e.target.position); + const t = this.transformer; + if ([t.handleBL, t.handleBR, t.handleTL, t.handleTR].includes(e.target as Handle)) { + affixedData.axes = 'xy'; + } else if ([t.handleR, t.handleL].includes(e.target as Handle)) { + affixedData.axes = 'x'; + } else { + affixedData.axes = 'y'; + } + }, + // eslint-disable-next-line max-lines-per-function + pointermove(e, riotTag, affixedData) { + const {transformer} = this; + const scaleSymmetrically = e.data.originalEvent.ctrlKey; + const proportionalScale = e.data.originalEvent.shiftKey && affixedData.axes === 'xy'; + const snapToGrid = !e.data.originalEvent.altKey && riotTag.gridOn; + const {axes} = affixedData; + const dragEndRoom = this.room.toLocal(e.data.global); + if (snapToGrid) { + if (this.ctRoom.diagonalGrid) { + ({x: dragEndRoom.x, y: dragEndRoom.y} = snapToDiagonalGrid( + dragEndRoom, + this.ctRoom.gridX, + this.ctRoom.gridY + )); + } else { + ({x: dragEndRoom.x, y: dragEndRoom.y} = snapToRectangularGrid( + dragEndRoom, + this.ctRoom.gridX, + this.ctRoom.gridY + )); + } + } + + const startUnrotated = rotateRad( + affixedData.startDragRoom.x - affixedData.startingPX, + affixedData.startDragRoom.y - affixedData.startingPY, + -transformer.applyRotation + ); + const endUnrotated = rotateRad( + dragEndRoom.x - affixedData.startingPX, + dragEndRoom.y - affixedData.startingPY, + -transformer.applyRotation + ); + // kx and ky describe how much a container expanded relative to its starting width + let kx = endUnrotated[0] / startUnrotated[0], + ky = endUnrotated[1] / startUnrotated[1]; + if (!Number.isFinite(kx)) { + kx = 1; + } + if (!Number.isFinite(ky)) { + ky = 1; + } + if (proportionalScale) { + const max = Math.max(Math.abs(kx), Math.abs(ky)); + kx = (Math.sign(kx) || 1) * max; + ky = (Math.sign(ky) || 1) * max; + if (Math.sign(kx * ky) === -1) { + // Constraint handles to its own diagonal + kx *= -1; + } + // Project an end point along a diagonal + endUnrotated[0] = kx * startUnrotated[0]; + endUnrotated[1] = ky * startUnrotated[1]; + } + if (!scaleSymmetrically) { + kx = kx * 0.5 + 0.5; + ky = ky * 0.5 + 0.5; + } + transformer.applyTranslateX = affixedData.startingTX; + transformer.applyTranslateY = affixedData.startingTY; + transformer.transformPivotX = affixedData.startingPX; + transformer.transformPivotY = affixedData.startingPY; + if (axes === 'x' || axes === 'xy') { + transformer.applyScaleX = affixedData.startingSX * kx || 1; + if (!scaleSymmetrically) { + // Shift the pivot and update the translate values of the transformer widget + // so entities slide in the specified direction, + // keeping the opposing side in its place + const shift = rotateRad( + endUnrotated[0] - startUnrotated[0], + 0, + transformer.applyRotation + ); + transformer.applyTranslateX += shift[0] / 2; + transformer.applyTranslateY += shift[1] / 2; + transformer.transformPivotX += shift[0] / 2; + transformer.transformPivotY += shift[1] / 2; + } + } + if (axes === 'y' || axes === 'xy') { + transformer.applyScaleY = affixedData.startingSY * ky || 1; + if (!scaleSymmetrically) { + // Shift the pivot and update the translate values of the transformer widget + // so entities slide in the specified direction, + // keeping the opposing side in its place + const shift = rotateRad( + 0, + endUnrotated[1] - startUnrotated[1], + transformer.applyRotation + ); + transformer.applyTranslateX += shift[0] * 0.5; + transformer.applyTranslateY += shift[1] * 0.5; + transformer.transformPivotX += shift[0] * 0.5; + transformer.transformPivotY += shift[1] * 0.5; + } + } + + transformer.applyTransforms(); + this.riotEditor.refs.propertiesPanel.updatePropList(); + }, + pointerup(e, roomTag, affixedData, callback) { + this.history.snapshotTransforms(); + callback(); + } + } +}; diff --git a/src/node_requires/roomEditor/interactions/transformer/select.ts b/src/node_requires/roomEditor/interactions/transformer/select.ts new file mode 100644 index 000000000..12964be48 --- /dev/null +++ b/src/node_requires/roomEditor/interactions/transformer/select.ts @@ -0,0 +1,162 @@ +import {IRoomEditorInteraction} from '../..'; +import {Copy} from '../../entityClasses/Copy'; +import {Tile} from '../../entityClasses/Tile'; + +interface IAffixedData { + startRoomPos: PIXI.IPoint; + startClientPos: PIXI.IPoint; + startSelected: PIXI.DisplayObject; + mode: 'pick' | 'add' | 'remove' | 'toggle'; +} + +const modifySet = ( + set: Set, + delta: PIXI.DisplayObject[], + mode: IAffixedData['mode'] +) => { + switch (mode) { + case 'add': + for (const elt of delta) { + set.add(elt); + } + break; + case 'remove': + for (const elt of delta) { + set.delete(elt); + } + break; + case 'toggle': + for (const elt of delta) { + if (set.has(elt)) { + set.delete(elt); + } else { + set.add(elt); + } + } + break; + default: + set.clear(); + for (const elt of delta) { + set.add(elt); + } + break; + } +}; + +const getCenter = function (obj: PIXI.DisplayObject, room: PIXI.Container): PIXI.IPoint { + const bounds = obj.getBounds(); + const centerGlobal = new PIXI.Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2); + return room.toLocal(centerGlobal); +}; + +/** + * An interaction that selects individual objects on clicks + * and multiple ones on click+drag, in a rectangular selection. + * Manages RoomEditor.marqueeBox position. + * + * Depending on what keys were pressed on selection start (ctrl, shift, alt), + * the operation shifts between three different modes (toggle, add, remove) + */ +const select: IRoomEditorInteraction = { + ifListener: 'pointerdown', + if(e) { + if (e.data.button !== 0) { + return false; + } + return this.riotEditor.currentTool === 'select'; + }, + listeners: { + pointerdown(e, riotTag, affixedData) { + if (e.data.originalEvent.shiftKey) { + affixedData.mode = 'add'; + } else if (e.data.originalEvent.ctrlKey) { + affixedData.mode = 'toggle'; + } else if (e.data.originalEvent.altKey) { + affixedData.mode = 'remove'; + } else { + affixedData.mode = 'pick'; + } + affixedData.startClientPos = e.data.global.clone(); + affixedData.startRoomPos = this.room.toLocal(e.data.global); + this.marqueeBox.redrawBox(affixedData.startRoomPos.x, affixedData.startRoomPos.y, 0, 0); + affixedData.startSelected = e.target; + }, + pointermove(e, riotTag, affixedData) { + const roomPos = this.room.toLocal(e.data.global); + this.marqueeBox.visible = true; + this.marqueeBox.redrawBox( + affixedData.startRoomPos.x, + affixedData.startRoomPos.y, + roomPos.x - affixedData.startRoomPos.x, + roomPos.y - affixedData.startRoomPos.y + ); + }, + pointerup(e, riotTag, affixedData, callback) { + // Apply any possible property changes to the previous selectio set + this.riotEditor.refs.propertiesPanel.applyChanges(); + + const selectMap: [boolean, Iterable][] = [ + [this.selectCopies, this.copies], + [this.selectTiles, this.tiles] + ]; + const roomPos = this.room.toLocal(e.data.global); + const dxClient = e.data.global.x - affixedData.startClientPos.x, + dyClient = e.data.global.y - affixedData.startClientPos.y; + const lClient = Math.sqrt(dxClient ** 2 + dyClient ** 2); + // Too small selections on a client scale count as clicks + if (lClient < 8) { + let s = affixedData.startSelected, + currentSelection; + // Pick a suitable entity under the cursor (try both from pointerdown and pointerup) + if ((s instanceof Copy && this.selectCopies) || + (s instanceof Tile && this.selectTiles) + ) { + currentSelection = s; + } else { + s = e.target; + if ((s instanceof Copy && this.selectCopies) || + (s instanceof Tile && this.selectTiles) + ) { + currentSelection = s; + } + } + if (currentSelection) { + modifySet(this.currentSelection, [s], affixedData.mode); + } else if (affixedData.mode === 'pick') { + // If no keyboard modifiers were active and a user clicked, clear the selection + this.currentSelection.clear(); + } + } else { + // Rectangular selection + // Loop through all the selectable elements in the room and put into the selection + // those which *visible* centers are inside the rectangle (ignore pivots). + const delta = []; + const rect = new PIXI.Rectangle( + Math.min(affixedData.startRoomPos.x, roomPos.x), + Math.min(affixedData.startRoomPos.y, roomPos.y), + Math.abs(roomPos.x - affixedData.startRoomPos.x), + Math.abs(roomPos.y - affixedData.startRoomPos.y) + ); + for (const selectType of selectMap) { + if (selectType[0]) { + for (const object of selectType[1]) { + const {x, y} = getCenter(object, this.room); + if (rect.contains(x, y)) { + delta.push(object); + } + } + } + } + modifySet(this.currentSelection, delta, affixedData.mode); + } + this.transformer.setup(); + this.marqueeBox.visible = false; + this.riotEditor.refs.propertiesPanel.updatePropList(); + callback(); + } + } +}; + +select.listeners.pointerupoutside = select.listeners.pointerup; + +export {select}; diff --git a/src/node_requires/themes/index.ts b/src/node_requires/themes/index.ts index 6900086a8..7c67350bc 100644 --- a/src/node_requires/themes/index.ts +++ b/src/node_requires/themes/index.ts @@ -1,4 +1,4 @@ -const path = require('path'); +import {join} from 'path'; const defaultTheme = 'Day'; const defaultMonacoTheme = defaultTheme; @@ -25,6 +25,21 @@ interface ITheme { css: string; } +// @see https://mmazzarolo.com/blog/2021-10-10-on-toggling-stylesheets/ +const waitForStylesheet = (): Promise => { + const stylesheet = [...document.styleSheets].find(s => s.ownerNode === document.getElementById('themeCSS')); + const oldHref = stylesheet?.href; + return new Promise((resolve) => { + const interval = setInterval(() => { + const stylesheet2 = [...document.styleSheets].find(s => s.ownerNode === document.getElementById('themeCSS')); + if (stylesheet2 && (!oldHref || (stylesheet2.href && oldHref !== stylesheet2.href))) { + clearInterval(interval); + resolve(); + } + }, 20); + }); +}; + var currentSwatches: Record; const registeredThemes: ITheme[] = []; @@ -37,7 +52,7 @@ const updateSwatches = (): void => { swatchTester.style.display = 'none'; document.body.appendChild(swatchTester); swatchTester.innerText = 'sausage'; - for (const swatch of ['act', 'acttext', 'accent1', 'borderPale', 'borderBright', 'text', 'backgroundDeeper', 'act-contrast', 'acttext-contrast', 'accent1-contrast']) { + for (const swatch of ['act', 'acttext', 'accent1', 'borderPale', 'borderBright', 'text', 'background', 'backgroundDeeper', 'act-contrast', 'acttext-contrast', 'accent1-contrast', 'red', 'green', 'orange']) { swatchTester.setAttribute('css-swatch', swatch); const style = window.getComputedStyle(swatchTester); currentSwatches[swatch] = style.getPropertyValue('color'); @@ -52,12 +67,12 @@ const mod = { } let monacoTheme; try { - monacoTheme = require(path.join('./data/node_requires/monaco-themes', `${name}.json`)); + monacoTheme = require(join('./data/node_requires/monaco-themes', `${name}.json`)); (window as Window).monaco.editor.defineTheme(name, monacoTheme); } catch (e) { // eslint-disable-next-line no-console console.warn('Could not load a monaco theme due to an error:', e, '\nFalling back to the default theme.'); - monacoTheme = require(path.join('./data/node_requires/monaco-themes', `${defaultMonacoTheme}.json`)); + monacoTheme = require(join('./data/node_requires/monaco-themes', `${defaultMonacoTheme}.json`)); (window as Window).monaco.editor.defineTheme(name, monacoTheme); } const css = `./data/theme${name}.css`; @@ -92,20 +107,19 @@ const mod = { } await fs.lstat(theme.css); const link = (document.getElementById('themeCSS') as HTMLLinkElement); - link.addEventListener('load', () => { - updateSwatches(); - }, { - once: true - }); // Avoid flickering on startup theme reloading if (link.href !== theme.css) { + const theWait = waitForStylesheet(); link.href = theme.css; + await theWait; + updateSwatches(); } (window as Window).monaco.editor.setTheme(theme.name); (window as Window).signals.trigger('UIThemeChanged', name); localStorage.UItheme = name; } catch (oO) { (window as Window).alertify.error(`Could not load theme ${name}. Rolling back to the default ${defaultTheme}.`); + console.error(oO); await mod.switchToTheme(defaultTheme); } }, @@ -126,6 +140,18 @@ const mod = { ...currentSwatches }; }, + getPixiSwatch(color: string): number { + if (!currentSwatches) { + updateSwatches(); + } + return PIXI.utils.rgb2hex(currentSwatches[color].split(', ').map(i => parseInt(i.replace(/[^0-9]/g, ''), 10) / 255)); + }, + getSwatch(color: string): string { + if (!currentSwatches) { + updateSwatches(); + } + return currentSwatches[color]; + }, updateSwatches }; diff --git a/src/node_requires/imageUtils.ts b/src/node_requires/utils/imageUtils.ts similarity index 100% rename from src/node_requires/imageUtils.ts rename to src/node_requires/utils/imageUtils.ts diff --git a/src/node_requires/utils/propUtils.ts b/src/node_requires/utils/propUtils.ts new file mode 100644 index 000000000..108357dc0 --- /dev/null +++ b/src/node_requires/utils/propUtils.ts @@ -0,0 +1,30 @@ +const getProp = function (context: unknown, path: string): unknown { + var way = path.split(/(? 1) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + context = (context as any)[way[0]]; + way.shift(); + } + return context; +}; + +const writeProp = function (context: unknown, path: string, value: unknown): void { + var way = path.split(/(? 2) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (!(way[0] in (context as any))) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (context as any)[way[0]] = {}; + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + context = (context as any)[way[0]]; + way.shift(); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (context as any)[way[0]] = value; +}; + +export { + getProp, + writeProp +}; diff --git a/src/node_requires/utils/trigo.ts b/src/node_requires/utils/trigo.ts new file mode 100644 index 000000000..9e460f5f4 --- /dev/null +++ b/src/node_requires/utils/trigo.ts @@ -0,0 +1,51 @@ +/** lengthdir_x */ +export var ldx = function ldx(l: number, d: number): number { + return l * Math.cos(d); +}; +/** lengthdir_y */ +export var ldy = function ldy(l: number, d: number): number { + return l * Math.sin(d); +}; +/** Point-point DirectioN */ +export var pdn = function pdn(x1: number, y1: number, x2: number, y2: number): number { + return Math.atan2(y2 - y1, x2 - x1); +}; +/** Point-point DistanCe */ +export var pdc = function pdc(x1: number, y1: number, x2: number, y2: number): number { + return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); +}; +export var degToRad = function degToRad(deg: number): number { + return deg * Math.PI / -180; +}; +export var radToDeg = function radToDeg(rad: number): number { + return rad / Math.PI * -180; +}; +/** + * Rotates a vector (x; y) by rad around (0; 0) + * @param {number} x The x component + * @param {number} y The y component + * @param {number} rad The radian value to rotate by + * @returns {Array} A pair of new `x` and `y` parameters. + */ +export var rotateRad = function rotateRad(x: number, y: number, rad: number): [number, number] { + const sin = Math.sin(rad), + cos = Math.cos(rad); + return [ + cos * x - sin * y, + cos * y + sin * x + ]; +}; +export var deltaDirRad = function deltaDirRad(dir1: number, dir2: number): number { + dir1 = ((dir1 % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2); + dir2 = ((dir2 % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2); + var t = dir1, + h = dir2, + ta = h - t; + if (ta > Math.PI) { + ta -= Math.PI * 2; + } + if (ta < -Math.PI) { + ta += Math.PI * 2; + } + return ta; +}; diff --git a/src/pug/index.pug b/src/pug/index.pug index b3b3e1314..01b528b00 100644 --- a/src/pug/index.pug +++ b/src/pug/index.pug @@ -30,6 +30,15 @@ html process.versions.ctjs = require('./package.json').version; // Use the legacy version to support low-spec and dated devices running ct.IDE script(src="node_modules/pixi.js-legacy/dist/pixi-legacy.min.js") + script. + // PIXI-mousewheel plugin from https://github.com/Mwni/pixi-mousewheel + /* example usage: + displayObject.interactiveMousewheel = true + displayObject.on('mousewheel', (delta, event) => { + myOtherDisplayObject.y += delta * 100 + }) + */ + "use strict";!function(){var e=function(){function e(e){var t=this;this.app=e,this.eventHandler=function(e){return t.onMouseWheel(e)},this.app.view.addEventListener("mousewheel",this.eventHandler,{passive:!1}),this.app.view.addEventListener("DOMMouseScroll",this.eventHandler,{passive:!1})}var t=e.prototype;return t.onMouseWheel=function(e){var t=this.findScrollTarget({x:e.offsetX,y:e.offsetY});t&&(e.preventDefault(),t.emit("mousewheel",this.deriveNormalizedWheelDelta(e),e))},t.findScrollTarget=function(e){var t=this.app.renderer.plugins.interaction.hitTest(e);if(t&&t.interactiveMousewheel)return t},t.deriveNormalizedWheelDelta=function(e){return e.detail?e.wheelDelta?e.wheelDelta/e.detail/40*(e.detail>0?1:-1):-e.detail/3:e.wheelDelta/120},t.destroy=function(){this.app.view.removeEventListener("mousewheel",this.eventHandler),this.app.view.removeEventListener("DOMMouseScroll",this.eventHandler)},e}();Object.defineProperty(PIXI.DisplayObject.prototype,"interactiveMousewheel",{get:function(){return this._interactiveMousewheel},set:function(e){this._interactiveMousewheel=e,e&&!this.interactive&&(this.interactive=!0)}}),PIXI.Application.registerPlugin({init:function(t){this._mousewheelPlugin=new e(this)},destroy:function(){this._mousewheelPlugin.destroy()}})}(); script(src="data/ct.release/DragonBones.min.js") script(src="node_modules/pixi-particles/dist/pixi-particles.min.js") script. diff --git a/src/riotTags/debugger/debugger-toolbar.tag b/src/riotTags/debugger/debugger-toolbar.tag index 0d32664d4..00502ef38 100644 --- a/src/riotTags/debugger/debugger-toolbar.tag +++ b/src/riotTags/debugger/debugger-toolbar.tag @@ -159,9 +159,8 @@ debugger-toolbar const buff = new Buffer(shotBase64, 'base64'); const stream = fs.createWriteStream(fullPath); stream.on('finish', () => { - if (localStorage.disableSounds !== 'on') { - window.soundbox.play('Success'); - } + const {soundbox} = require('./data/node_requires/3rdparty/soundbox'); + soundbox.play('Success'); // eslint-disable-next-line no-new new Notification('Done!', { body: `Saved to ${fullPath} 👌`, @@ -211,4 +210,4 @@ debugger-toolbar nw.Window.get().close(); }; - nw.Window.get().on('close', this.closeItself); \ No newline at end of file + nw.Window.get().on('close', this.closeItself); diff --git a/src/riotTags/main-menu/export-mobile-panel.tag b/src/riotTags/main-menu/export-mobile-panel.tag index a9ddeb3ce..c18836bee 100644 --- a/src/riotTags/main-menu/export-mobile-panel.tag +++ b/src/riotTags/main-menu/export-mobile-panel.tag @@ -211,7 +211,7 @@ export-mobile-panel.aDimmer const {getDOMImage} = require('./data/node_requires/resources/textures'); const iconsSplashesPromises = []; const {imageCover, imageContain, imagePlaceInRect, imageRound, outputCanvasToFile} = - require('./data/node_requires/imageUtils'); + require('./data/node_requires/utils/imageUtils'); const projIconImage = await getDOMImage(projSettings.branding.icon || -1, 'ct_ide.png'); for (const name in androidIcons) { const icon = imageContain( diff --git a/src/riotTags/main-menu/main-menu-latest-projects.tag b/src/riotTags/main-menu/main-menu-latest-projects.tag index cc1765bf5..a89d6f840 100644 --- a/src/riotTags/main-menu/main-menu-latest-projects.tag +++ b/src/riotTags/main-menu/main-menu-latest-projects.tag @@ -21,8 +21,9 @@ main-menu-latest-projects this.loadLatestProject = projPath => { alertify.confirm(window.languageJSON.common.reallyExitConfirm, e => { if (e) { + const {openProject} = require('./data/node_requires/resources/projects'); window.signals.trigger('resetAll'); - window.loadProject(projPath); + openProject(projPath); } }); }; diff --git a/src/riotTags/main-menu/main-menu-project.tag b/src/riotTags/main-menu/main-menu-project.tag index 5a8f86834..5ae1c39c7 100644 --- a/src/riotTags/main-menu/main-menu-project.tag +++ b/src/riotTags/main-menu/main-menu-project.tag @@ -86,7 +86,8 @@ main-menu-project return; } window.signals.trigger('resetAll'); - window.loadProject(projFile); + const {openProject} = require('./data/node_requires/resources/projects'); + openProject(projFile); }); }; diff --git a/src/riotTags/notepad-panel.tag b/src/riotTags/notepad-panel.tag index 56f4a5b92..bb783dfa0 100644 --- a/src/riotTags/notepad-panel.tag +++ b/src/riotTags/notepad-panel.tag @@ -59,7 +59,9 @@ notepad-panel#notepad.aPanel.dockright(class="{opened: opened}") setTimeout(() => { if (this.tab && this.refs[this.tab] && this.refs[this.tab].codeEditor) { this.refs[this.tab].codeEditor.layout(); - this.refs[this.tab].codeEditor.focus(); + if (this.opened) { + this.refs[this.tab].codeEditor.focus(); + } } }, 0); }); diff --git a/src/riotTags/project-selector.tag b/src/riotTags/project-selector.tag index 603423827..ae3d5861a 100644 --- a/src/riotTags/project-selector.tag +++ b/src/riotTags/project-selector.tag @@ -133,6 +133,7 @@ project-selector script. const fs = require('fs-extra'), path = require('path'); + const {openProject} = require('./data/node_requires/resources/projects'); this.ctjsVersion = process.versions.ctjs; this.requirePath = path; this.namespace = 'intro'; @@ -243,7 +244,7 @@ project-selector } }); }, 0); - window.loadProject(path.join(way, codename + '.ict')); + openProject(path.join(way, codename + '.ict')); }; /** @@ -251,7 +252,7 @@ project-selector */ this.loadProjectByPath = e => { const projectPath = e.item.project; - window.loadProject(projectPath); + openProject(projectPath); }; /** * Prompts user to clone a project into a different folder/under a different name. @@ -273,7 +274,7 @@ project-selector } await fs.copy(project, newIctLocation); await fs.copy(project.slice(0, -4), newIctLocation.slice(0, -4)); - window.loadProject(newIctLocation); + openProject(newIctLocation); })(); }; /** @@ -330,7 +331,7 @@ project-selector return; } if (path.extname(proj).toLowerCase() === '.ict') { - window.loadProject(proj); + openProject(proj); sessionStorage.projname = path.basename(proj); global.projdir = path.dirname(proj) + path.sep + path.basename(proj, '.ict'); } else { diff --git a/src/riotTags/project-settings/tabs/rendering-settings.tag b/src/riotTags/project-settings/tabs/rendering-settings.tag index f6fc61ec3..e03500a2f 100644 --- a/src/riotTags/project-settings/tabs/rendering-settings.tag +++ b/src/riotTags/project-settings/tabs/rendering-settings.tag @@ -7,7 +7,7 @@ rendering-settings input.short(type="number" min="1" value="{renderSettings.maxFPS || 60}" onchange="{wire('this.renderSettings.maxFPS')}") fieldset label.block.checkbox - input(type="checkbox" value="{renderSettings.pixelatedrender}" checked="{renderSettings.pixelatedrender}" onchange="{wire('this.renderSettings.pixelatedrender')}") + input(type="checkbox" value="{renderSettings.pixelatedrender}" checked="{renderSettings.pixelatedrender}" onchange="{wireAndUpdatePixelated('this.renderSettings.pixelatedrender')}") span {voc.pixelatedRender} label.block.checkbox input(type="checkbox" value="{renderSettings.highDensity}" checked="{renderSettings.highDensity}" onchange="{wire('this.renderSettings.highDensity')}") @@ -40,3 +40,9 @@ rendering-settings this.mixin(window.riotWired); this.currentProject = global.currentProject; this.renderSettings = this.currentProject.settings.rendering; + + this.wireAndUpdatePixelated = path => e => { + this.wire(path)(e); + const {setPixelart} = require('./data/node_requires/resources/textures'); + setPixelart(currentProject.settings.rendering.pixelatedrender); + } diff --git a/src/riotTags/rooms/copy-custom-properties-modal.tag b/src/riotTags/rooms/copy-custom-properties-modal.tag deleted file mode 100644 index 39c3023ef..000000000 --- a/src/riotTags/rooms/copy-custom-properties-modal.tag +++ /dev/null @@ -1,93 +0,0 @@ -// - Shows a table of a copy's extensions object that is modifiable - - @attribute closestcopy (object) - The copy to show its extensions object - - @attribute showme (function) - A function that changes whether this modal is shown - -copy-custom-properties-modal - .aPanel.flexfix(ref="widget" style='overflow: auto; max-height: 600px') - h2.flexfix-header {voc.customProperties} - .flexfix-body - table.wide.aPaddedTable - tr - th {voc.property} - th {voc.value} - th - tr(each="{val, prop in opts.closestcopy.exts}") - td - input.wide(name="copyCustomProp" type="text" value="{prop}" onchange="{onTableChange}") - td - input.wide(name="copyCustomValue" type="text" value="{JSON.stringify(val)}" onchange="{onTableChange}") - td - button.toright.square.inline(onclick="{deleteCustomProperty.bind(null, prop)}" title="{voc.delete}") - svg.feather - use(xlink:href="#trash") - .clear - p - .flexrow.flexfix-footer - .filler - button.nogrow(onclick="{addCustomProperty}") - svg.feather - use(xlink:href="#plus") - span {voc.addProperty} - button.nogrow(onclick="{finished}") - svg.feather - use(xlink:href="#check") - span {vocGlob.apply} - script. - this.namespace = 'copyCustomProperties'; - this.mixin(window.riotVoc); - if (!this.opts.closestcopy.exts) { - this.opts.closestcopy.exts = {}; - } - // an ID to use as newly created property names - this.currentId = 1; - - this.onTableChange = () => { - // read all properties from the table - var propElements = document.getElementsByName('copyCustomProp'); - var props = []; - for (const prop of propElements) { - props.push(prop.value); - } - - // read all values from the table - var valueElements = document.getElementsByName('copyCustomValue'); - var values = []; - - for (const value of valueElements) { - // attempt to parse the value - // only strings will be unparsable with the JSON.parse method - var trueValue; - try { - trueValue = JSON.parse(value.value); // JSON, number, boolean - } catch { - trueValue = value.value; // string - } - values.push(trueValue); - } - - var newExts = {}; - - props.forEach((prop, index) => { - newExts[prop] = values[index]; - }); - - this.opts.closestcopy.exts = newExts; - }; - - this.addCustomProperty = () => { - this.opts.closestcopy.exts['newProperty' + this.currentId] = ''; - this.currentId++; - }; - - this.deleteCustomProperty = (prop) => { - delete this.opts.closestcopy.exts[prop]; - }; - - this.finished = () => { - this.opts.showme(false); - }; diff --git a/src/riotTags/rooms/room-backgrounds-editor.tag b/src/riotTags/rooms/room-backgrounds-editor.tag index 366d30d38..614fbce31 100644 --- a/src/riotTags/rooms/room-backgrounds-editor.tag +++ b/src/riotTags/rooms/room-backgrounds-editor.tag @@ -1,74 +1,157 @@ -room-backgrounds-editor.room-editor-Backgrounds.tabbed.tall - ul - li.bg(each="{background, ind in opts.room.backgrounds}" oncontextmenu="{onContextMenu}") - img(src="{getTexturePreview(background.texture)}" onclick="{onChangeBgTexture}") - span - span(class="{active: detailedBackground === background}" onclick="{editBackground}") - svg.feather - use(xlink:href="#settings") - | {getTextureFromId(background.texture).name} ({background.depth}) - .clear - .anErrorNotice(if="{background.texture && background.texture !== -1 && !getTextureFromId(background.texture).tiled && !getTextureFromId(background.texture).ignoreTiledUse}") - | {voc.notBackgroundTextureWarning} +// + @attribute backgrounds (Background[]) + @attribute addbackground (riot function) + @attribute room (IRoom) + @attribute history (History) + +room-backgrounds-editor + collapsible-section( + each="{background, ind in opts.backgrounds}" + icon="settings" + ).aPanel + yield(to="header") + asset-input( + assettype="textures" + assetid="{background.bgTexture}" + compact="true" + onchanged="{parent.changeBgTexture(background)}" + ref="assetInput" + ) + error-notice( + if="{background.bgTexture && background.bgTexture !== -1 && !parent.getTextureFromId(background.bgTexture).tiled && !parent.getTextureFromId(background.bgTexture).ignoreTiledUse}" + target="{refs.assetInput}" + ) + | {parent.parent.voc.notBackgroundTextureWarning} | - span.a(onclick="{fixTexture(background)}") {voc.fixBackground} + span.a(onclick="{parent.parent.fixTexture}") {parent.parent.voc.fixBackground} | | - span.a(onclick="{dismissWarning(background)}") {voc.dismissWarning} - div(if="{detailedBackground === background}") - .clear - label - b {voc.depth} - input.wide(type="number" value="{background.depth || 0}" step="0" oninput="{onChangeBgDepth}") - - b {voc.shift} - .clear - label.fifty.npl.npt - input.wide(type="number" value="{background.extends.shiftX || 0}" step="8" oninput="{wire('this.detailedBackground.extends.shiftX')}") - label.fifty.npr.npt - input.wide(type="number" value="{background.extends.shiftY || 0}" step="8" oninput="{wire('this.detailedBackground.extends.shiftY')}") - - b {voc.scale} - .clear - label.fifty.npl.npt - input.wide(type="number" value="{background.extends.scaleX || 1}" step="0.01" oninput="{wire('this.detailedBackground.extends.scaleX')}") - label.fifty.npr.npt - input.wide(type="number" value="{background.extends.scaleY || 1}" step="0.01" oninput="{wire('this.detailedBackground.extends.scaleY')}") - - b {voc.movement} - .clear - label.fifty.npl.npt - input.wide(type="number" value="{background.extends.movementX || 0}" step="0.1" oninput="{wire('this.detailedBackground.extends.movementX')}") - label.fifty.npr.npt - input.wide(type="number" value="{background.extends.movementY || 0}" step="0.1" oninput="{wire('this.detailedBackground.extends.movementY')}") - - b {voc.parallax} - .clear - label.fifty.npl.npt - input.wide(type="number" value="{background.extends.parallaxX !== void 0 ? background.extends.parallaxX : 1}" step="0.01" oninput="{wire('this.detailedBackground.extends.parallaxX')}") - label.fifty.npr.npt - input.wide(type="number" value="{background.extends.parallaxY !== void 0 ? background.extends.parallaxY : 1}" step="0.01" oninput="{wire('this.detailedBackground.extends.parallaxY')}") - .clear - - b {voc.repeat} - select(onchange="{wire('this.detailedBackground.extends.repeat')}") - option(value="repeat" selected="{detailedBackground.extends.repeat === 'repeat'}") repeat - option(value="repeat-x" selected="{detailedBackground.extends.repeat === 'repeat-x'}") repeat-x - option(value="repeat-y" selected="{detailedBackground.extends.repeat === 'repeat-y'}") repeat-y - option(value="no-repeat" selected="{detailedBackground.extends.repeat === 'no-repeat'}") no-repeat - + span.a(onclick="{parent.parent.dismissWarning}") {parent.parent.voc.dismissWarning} + fieldset + label + b {parent.voc.depth} + input.wide( + type="number" step="1" + onfocus="{parent.rememberValue}" + value="{background.zIndex}" + oninput="{parent.tweak(background, 'zIndex')}" + onchange="{parent.recordChange(background, 'zIndex')}" + ) + fieldset + b {parent.voc.shift} + .aPoint2DInput.compact.wide + label.flexrow + span.nogrow X: + input.nmr( + type="number" step="8" placeholder="0" + onfocus="{parent.rememberValue}" + oninput="{parent.tweak(background, 'shiftX')}" + onchange="{parent.recordChange(background, 'shiftX')}" + value="{background.shiftX}" + ) + .aSpacer.noshrink.nogrow + label.flexrow + span.nogrow Y: + input.nmr( + type="number" step="8" placeholder="0" + onfocus="{parent.rememberValue}" + oninput="{parent.tweak(background, 'shiftY')}" + onchange="{parent.recordChange(background, 'shiftY')}" + value="{background.shiftY}" + ) + b {parent.voc.scale} + .aPoint2DInput.compact.wide + label.flexrow + span.nogrow X: + input.nmr( + type="number" step="0.1" placeholder="1" + onfocus="{parent.rememberValue}" + oninput="{parent.tweak(background.tileScale, 'x')}" + onchange="{parent.recordChange(background.tileScale, 'x')}" + value="{background.tileScale.x}" + ) + .aSpacer.noshrink.nogrow + label.flexrow + span.nogrow Y: + input.nmr( + type="number" step="0.1" placeholder="1" + onfocus="{parent.rememberValue}" + oninput="{parent.tweak(background.tileScale, 'y')}" + onchange="{parent.recordChange(background.tileScale, 'y')}" + value="{background.tileScale.y}" + ) + fieldset + b {parent.voc.movement} + .aPoint2DInput.compact.wide + label.flexrow + span.nogrow X: + input.nmr( + type="number" step="1" placeholder="0" + onfocus="{parent.rememberValue}" + oninput="{parent.tweak(background, 'movementX')}" + onchange="{parent.recordChange(background, 'movementX')}" + value="{background.movementX}" + ) + .aSpacer.noshrink.nogrow + label.flexrow + span.nogrow Y: + input.nmr( + type="number" step="1" placeholder="0" + onfocus="{parent.rememberValue}" + oninput="{parent.tweak(background, 'movementY')}" + onchange="{parent.recordChange(background, 'movementY')}" + value="{background.movementY}" + ) + b {parent.voc.parallax} + .aPoint2DInput.compact.wide + label.flexrow + span.nogrow X: + input.nmr( + type="number" step="0.1" placeholder="1" + onfocus="{parent.rememberValue}" + oninput="{parent.tweak(background, 'parallaxX')}" + onchange="{parent.recordChange(background, 'parallaxX')}" + value="{background.parallaxX}" + ) + .aSpacer.noshrink.nogrow + label.flexrow + span.nogrow Y: + input.nmr( + type="number" step="0.1" placeholder="1" + onfocus="{parent.rememberValue}" + oninput="{parent.tweak(background, 'parallaxY')}" + onchange="{parent.recordChange(background, 'parallaxY')}" + value="{background.parallaxY}" + ) + fieldset + b {parent.voc.repeat} + | + select( + onfocus="{parent.rememberValue}" + onchange="{parent.recordAndTweak(background, 'repeat')}" + ) + option(value="repeat" selected="{background.repeat === 'repeat'}") repeat + option(value="repeat-x" selected="{background.repeat === 'repeat-x'}") repeat-x + option(value="repeat-y" selected="{background.repeat === 'repeat-y'}") repeat-y + option(value="no-repeat" selected="{background.repeat === 'no-repeat'}") no-repeat + .aSpacer + button.wide(onclick="{parent.removeBg}") + svg.feather + use(xlink:href="#trash") + span {parent.vocGlob.delete} + .aSpacer(if="{opts.backgrounds.length}") button.inline.wide(onclick="{addBg}") svg.feather use(xlink:href="#plus") span {voc.add} + // Used for selecting a texture for newly created backgrounds asset-selector( ref="texturePicker" - if="{pickingBackground}" + if="{newBg}" assettype="textures" oncancelled="{onTextureCancel}" onselected="{onTextureSelected}" ) - context-menu(menu="{roomBgMenu}" ref="roomBgMenu") script. const glob = require('./data/node_requires/glob'); this.glob = glob; @@ -80,85 +163,119 @@ room-backgrounds-editor.room-editor-Backgrounds.tabbed.tall this.pickingBackground = false; this.namespace = 'roomBackgrounds'; this.mixin(window.riotVoc); - this.mixin(window.riotWired); - this.on('update', () => { - if (this.parent.tab === 'roombackgrounds') { - this.parent.refreshRoomCanvas(); + + this.tweak = (obj, field) => e => { + const input = e.target; + if (input.type === 'radio' || input.type === 'checkbox') { + obj[field] = input.checked; + } else if (input.type === 'number') { + obj[field] = Number(input.value); + } else { + obj[field] = input.value; } - }); + }; + + // These two are only for newly created backgrounds, for which an asset selection modal + // is automatically created this.onTextureSelected = textureId => { - this.editingBackground.texture = textureId; - this.pickingBackground = false; - this.creatingBackground = false; + this.newBg.changeTexture(textureId); + this.opts.history.pushChange({ + type: 'backgroundCreation', + created: this.newBg + }); + this.newBg = void 0; this.update(); }; this.onTextureCancel = () => { this.pickingBackground = false; - if (this.creatingBackground) { - const bgs = this.opts.room.backgrounds; - bgs.splice(bgs.indexOf(this.editingBackground), 1); - this.parent.resortRoom(); - this.creatingBackground = false; + if (this.newBg) { + this.newBg.destroy(); } + this.newBg = false; this.update(); }; + this.addBg = () => { - var newBg = { + const bgTemplate = { depth: 0, texture: -1, - extends: {} + parallaxX: 1, + parallaxY: 1, + shiftX: 0, + shiftY: 0, + scaleX: 1, + scaleY: 1, + movementX: 0, + movementY: 0, + repeat: 'repeat' }; - this.opts.room.backgrounds.push(newBg); - this.editingBackground = newBg; + const bg = this.opts.addbackground(bgTemplate); + this.newBg = bg; this.pickingBackground = true; - this.creatingBackground = true; - this.opts.room.backgrounds.sort((a, b) => a.depth - b.depth); - this.parent.resortRoom(); - this.update(); }; - this.onContextMenu = e => { - this.editedBg = Number(e.item.ind); - this.refs.roomBgMenu.popup(e.clientX, e.clientY); - e.preventDefault(); + + this.changeBgTexture = background => textureId => { + const prevId = background.bgTexture; + background.changeTexture(textureId); + this.opts.history.pushChange({ + type: 'propChange', + key: 'bgTexture', + target: background, + before: prevId, + after: textureId + }); + this.update(); }; - this.roomBgMenu = { - opened: false, - items: [{ - label: window.languageJSON.common.delete, - click: () => { - this.opts.room.backgrounds.splice(this.editedBg, 1); - this.parent.resortRoom(); - this.update(); - } - }] + + this.removeBg = e => { + const {background} = e.item; + background.detach(); + this.opts.history.pushChange({ + type: 'backgroundDeletion', + deleted: background + }); }; - this.onChangeBgTexture = e => { - this.pickingBackground = true; - this.editingBackground = e.item.background; + + this.fixTexture = e => { + const {background} = e.item; + const tex = getTextureFromId(background.bgTexture); + tex.tiled = true; + e.stopPropagation(); this.update(); }; - this.onChangeBgDepth = e => { - e.item.background.depth = Number(e.target.value); - this.opts.room.backgrounds.sort((a, b) => a.depth - b.depth); - this.parent.resortRoom(); + this.dismissWarning = e => { + const {background} = e.item; + const tex = getTextureFromId(background.bgTexture); + tex.ignoreTiledUse = true; + e.stopPropagation(); + this.update(); }; - this.editBackground = e => { - if (this.detailedBackground === e.item.background) { - this.detailedBackground = void 0; + var prevValue; + this.rememberValue = e => { + if (e.target.type === 'number') { + prevValue = Number(e.target.value); } else { - this.detailedBackground = e.item.background; - if (!('extends' in this.detailedBackground)) { - this.detailedBackground.extends = {}; - } + prevValue = e.target.value; } }; - - this.fixTexture = background => () => { - const tex = getTextureFromId(background.texture); - tex.tiled = true; + this.recordChange = (entity, key) => e => { + if (!this.opts.history) { + return; + } + let value = e.target.value; + if (e.target.type === 'number') { + value = Number(value); + } + this.opts.history.pushChange({ + type: 'propChange', + key, + target: entity, + before: prevValue, + after: value + }); }; - this.dismissWarning = background => () => { - const tex = getTextureFromId(background.texture); - tex.ignoreTiledUse = true; + this.recordAndTweak = (entity, key) => e => { + this.tweak(entity, key)(e); + this.recordChange(entity, key)(e); }; diff --git a/src/riotTags/rooms/room-copy-properties.tag b/src/riotTags/rooms/room-copy-properties.tag deleted file mode 100644 index cdf4520b6..000000000 --- a/src/riotTags/rooms/room-copy-properties.tag +++ /dev/null @@ -1,65 +0,0 @@ -room-copy-properties.aPanel - b {voc.position}: - .aPoint2DInput.compact.wide - label - span X: - | - input.compact( - step="8" type="number" - oninput="{wire('this.opts.copy.x')}" - value="{opts.copy.x}" - ) - .aSpacer - label - span.nogrow Y: - | - input.compact( - step="8" type="number" - oninput="{wire('this.opts.copy.y')}" - value="{opts.copy.y}" - ) - b {voc.scale}: - .aPoint2DInput.compact.wide - label - span X: - | - input.compact( - step="0.1" type="number" - oninput="{wire('this.opts.copy.tx')}" - value="{opts.copy.tx === void 0 ? 1 : opts.copy.tx}" - ) - .aSpacer - label - span.nogrow Y: - | - input.compact( - step="0.1" type="number" - oninput="{wire('this.opts.copy.ty')}" - value="{opts.copy.ty === void 0 ? 1 : opts.copy.ty}" - ) - b {voc.rotation}: - dd - .flexrow - .aSliderWrap - input.compact( - type="range" min="0" max="360" step="1" - value="{opts.copy.tr || 0}" - oninput="{wire('this.opts.copy.tr')}" - ) - .aSpacer - input.compact( - min="0" max="360" step="1" type="number" - value="{opts.copy.tr || 0}" - oninput="{wire('this.opts.copy.tr')}" - ) - extensions-editor(entity="{opts.copy.exts}" type="copy" compact="yes" wide="yup") - script. - this.namespace = 'roomView.copyProperties'; - this.mixin(window.riotVoc); - this.mixin(window.riotWired); - - this.on('update', () => { - if (this.opts.copy && !this.opts.copy.exts) { - this.opts.copy.exts = {}; - } - }); diff --git a/src/riotTags/rooms/room-editor.tag b/src/riotTags/rooms/room-editor.tag index a08798161..cd78cb6eb 100644 --- a/src/riotTags/rooms/room-editor.tag +++ b/src/riotTags/rooms/room-editor.tag @@ -1,805 +1,472 @@ -room-editor.aPanel.aView - .toolbar.tall(style="width: {sidebarWidth}px") - copy-custom-properties-modal(if="{showCopyPropertiesModal}" closestcopy="{closestCopy}" showme="{toggleCopyProperties}") - .settings.nogrow.noshrink - b {voc.name} - br - input.wide(type="text" value="{room.name}" onchange="{wire('this.room.name')}") - .anErrorNotice(if="{nameTaken}" ref="errorNotice") {vocGlob.nameTaken} - button.wide(onclick="{openRoomEvents}") - svg.feather(if="{room.events && room.events.length}") - use(xlink:href="#check") - span {voc.events} - .palette - .tabwrap.flexfix - ul.tabs.aNav.noshrink.nogrow.flexfix-header - li(onclick="{changeTab('roomcopies')}" title="{voc.copies}" class="{active: tab === 'roomcopies'}") - svg.feather - use(xlink:href="#template") - span(if="{sidebarWidth > 500}") {voc.copies} - li(onclick="{changeTab('roombackgrounds')}" title="{voc.backgrounds}" class="{active: tab === 'roombackgrounds'}") - svg.feather - use(xlink:href="#image") - span(if="{sidebarWidth > 500}") {voc.backgrounds} - li(onclick="{changeTab('roomtiles')}" title="{voc.tiles}" class="{active: tab === 'roomtiles'}") - svg.feather - use(xlink:href="#texture") - span(if="{sidebarWidth > 500}") {voc.tiles} - li(onclick="{changeTab('properties')}" title="{voc.properties}" class="{active: tab === 'properties'}") - svg.feather - use(xlink:href="#settings") - span(if="{sidebarWidth > 500}") {voc.properties} - .relative.flexfix-body - room-template-picker(show="{tab === 'roomcopies'}" current="{currentTemplate}") - room-backgrounds-editor(show="{tab === 'roombackgrounds'}" room="{room}") - room-tile-editor(show="{tab === 'roomtiles'}" room="{room}") - .pad.aPanel(show="{tab === 'properties'}") - fieldset - .fifty.npt.npb.npl - b {voc.width} - br - input.wide(type="number" value="{room.width}" onchange="{wireAndRedraw('this.room.width')}") - .fifty.npt.npb.npr - b {voc.height} - br - input.wide(type="number" value="{room.height}" onchange="{wireAndRedraw('this.room.height')}") - .clear - fieldset - label.checkbox - input(type="checkbox" checked="{room.restrictCamera}" onchange="{wireAndRedraw('this.room.restrictCamera')}") - span {voc.restrictCamera} - .aPoint2DInput.compact.wide(if="{room.restrictCamera}") - label - span {voc.minimumX}: - | - input.compact( - step="{room.gridX}" type="number" - oninput="{wireAndRedraw('this.room.restrictMinX')}" - value="{room.restrictMinX === void 0 ? 0 : room.restrictMinX}" - ) - .aSpacer - label - span.nogrow {voc.minimumY}: - | - input.compact( - step="{room.gridY}" type="number" - oninput="{wireAndRedraw('this.room.restrictMinY')}" - value="{room.restrictMinY === void 0 ? 0 : room.restrictMinY}" - ) - .aPoint2DInput.compact.wide(if="{room.restrictCamera}") - label - span {voc.maximumX}: - | - input.compact( - step="{room.gridX}" type="number" - oninput="{wireAndRedraw('this.room.restrictMaxX')}" - value="{room.restrictMaxX === void 0 ? room.width : room.restrictMaxX}" - ) - .aSpacer - label - span.nogrow {voc.maximumY}: - | - input.compact( - step="{room.gridY}" type="number" - oninput="{wireAndRedraw('this.room.restrictMaxY')}" - value="{room.restrictMaxY === void 0 ? room.height : room.restrictMaxY}" - ) - - fieldset - b {voc.backgroundColor} - br - color-input.wide(onchange="{updateRoomBackground}" color="{room.backgroundColor || '#000000'}") - - fieldset - extensions-editor(entity="{room.extends}" type="room" wide="aye" compact="sure") +// + @attribute room + The room to edit + @attribute onclose (riot function) - fieldset - label.block.checkbox - input(type="checkbox" checked="{room.extends.isUi}" onchange="{wire('this.room.extends.isUi')}") - b {voc.isUi} - - .done.nogrow - button.wide#roomviewdone(onclick="{roomSave}") +room-editor.aPanel.aView + canvas(ref="canvas" onwheel="{triggerWheelEvent}") + // Toolbar + .room-editor-aToolsetHolder + .room-editor-aToolbar.aButtonGroup.vertical + button.forcebackground( + onclick="{setTool('select')}" + class="{active: currentTool === 'select'}" + title="{voc.tools.select} (Q)" + data-hotkey="q" + data-hotkey-require-scope="rooms" + ) svg.feather - use(xlink:href="#check") - span {voc.done} - .aResizer.vertical(ref="gutter" onmousedown="{gutterMouseDown}") - .editor(ref="canvaswrap") - canvas( - ref="canvas" - onclick="{onCanvasClick}" - onmousedown="{onCanvasPress}" - onmousemove="{onCanvasMove}" - onmouseup="{onCanvasMouseUp}" - onmouseout="{refreshRoomCanvas}" - onmousewheel="{onCanvasWheel}" - oncontextmenu="{onCanvasContextMenu}" - ) - .shift.flexrow - button.inline.square.forcebackground(title="{voc.shift}" onclick="{roomShift}") + use(xlink:href="#cursor") + button.forcebackground( + onclick="{setTool('addCopies')}" + class="{active: currentTool === 'addCopies'}" + title="{voc.tools.addCopies} (W)" + data-hotkey="w" + data-hotkey-require-scope="rooms" + ) svg.feather - use(xlink:href="#move") - .aButtonGroup - button.inline.square.forcebackground( - title="{voc.sortHorizontally}" - onclick="{sortHorizontally}" - if="{tab === 'roomcopies' || tab === 'roomtiles'}" - ) - svg.feather - use(xlink:href="#sort-horizontal") - button.inline.square.forcebackground( - title="{voc.sortVertically}" - onclick="{sortVertically}" - if="{tab === 'roomcopies' || tab === 'roomtiles'}" + use(xlink:href="#template") + button.forcebackground( + onclick="{setTool('addTiles')}" + class="{active: currentTool === 'addTiles'}" + title="{voc.tools.addTiles} (E)" + data-hotkey="e" + data-hotkey-require-scope="rooms" + ) + svg.feather + use(xlink:href="#grid") + button.forcebackground( + onclick="{setTool('manageBackgrounds')}" + class="{active: currentTool === 'manageBackgrounds'}" + title="{voc.tools.manageBackgrounds} (R)" + data-hotkey="r" + data-hotkey-require-scope="rooms" + ) + svg.feather + use(xlink:href="#image") + button.forcebackground( + onclick="{setTool('roomProperties')}" + class="{active: currentTool === 'roomProperties'}" + title="{voc.tools.roomProperties} (T)" + data-hotkey="t" + data-hotkey-require-scope="rooms" + ) + svg.feather + use(xlink:href="#settings") + + // Contextual panels for tools + .room-editor-aContextPanel( + if="{currentTool === 'select' && pixiEditor}" + ) + h3.nogrow.nm.inlineblock {vocGlob.select}: + .aSpacer.inlineblock + .aButtonGroup.nm + button.inline.square( + each="{lockable in lockableTypes}" + class="{active: parent.pixiEditor && parent.pixiEditor[lockable.key]}" + onclick="{toggleSelectables}" + title="{voc[lockable.hintVocKey]}" ) svg.feather - use(xlink:href="#sort-vertical") - span.aContrastingPlaque(if="{window.innerWidth - sidebarWidth > 940}") {voc.hotkeysNotice} - .zoom.flexrow - b.aContrastingPlaque - span(if="{window.innerWidth - sidebarWidth > 980}") {vocGlob.zoom}: - | - | - span {Math.round(zoomFactor * 100)}% - .aSpacer - zoom-slider(onchanged="{setZoom}" ref="zoomslider" value="{zoomFactor}") - .grid - button#roomgrid.forcebackground(onclick="{roomToggleGrid}" class="{active: room.gridX > 0}") - span {voc[room.gridX > 0? 'gridOff' : 'grid']} - .center - button#roomcenter.forcebackground(onclick="{roomToCenter}") {voc.toCenter} - b.aMouseCoord.aContrastingPlaque(show="{window.innerWidth - sidebarWidth > 470}" ref="mousecoords") ({mouseX}:{mouseY}) - room-copy-properties( - if="{this.selectedCopies && this.selectedCopies.length === 1}" - copy="{this.selectedCopies[0]}" - onchange="{refreshRoomCanvas}" oninput="{refreshRoomCanvas}" + use(xlink:href="#{lockable.icon}") + room-entities-properties(ref="propertiesPanel" pixieditor="{pixiEditor}" ontransformchange="{updateSelectFrame}") + room-properties.room-editor-aContextPanel( + if="{currentTool === 'roomProperties'}" + room="{opts.room}" + history="{pixiEditor?.history}" + updatebg="{changeBgColor}" + ref="propertiesPanel" + ) + room-template-picker.room-editor-aContextPanel( + if="{currentTool === 'addCopies'}" + onselect="{changeSelectedTemplate}" + selected="{currentTemplate}" + ) + room-tile-editor.room-editor-aContextPanel( + if="{currentTool === 'addTiles'}" + layer="{currentTileLayer}" + layers="{pixiEditor.tileLayers}" + onchangetile="{changeTilePatch}" + onchangelayer="{changeTileLayer}" + pixieditor="{pixiEditor}" + removelayer="{pixiEditor?.removeLayer?.bind(pixiEditor)}" + addlayer="{pixiEditor?.addTileLayer?.bind(pixiEditor)}" + ref="tileEditor" ) - room-events-editor(if="{editingCode}" room="{room}") - context-menu(menu="{roomCanvasCopiesMenu}" ref="roomCanvasCopiesMenu") - context-menu(menu="{roomCanvasMenu}" ref="roomCanvasMenu") - context-menu(menu="{roomCanvasTileMenu}" ref="roomCanvasTileMenu") - context-menu(menu="{roomCanvasTilesMenu}" ref="roomCanvasTilesMenu") + room-backgrounds-editor.room-editor-aContextPanel( + if="{currentTool === 'manageBackgrounds'}" + backgrounds="{pixiEditor?.backgrounds}" + addbackground="{pixiEditor?.addBackground?.bind(pixiEditor)}" + room="{opts.room}" + history="{pixiEditor?.history}" + ref="backgroundsEditor" + ) + + // Global controls placed at the top-center + .room-editor-aTopPanel + button.slim(onclick="{pixiEditor?.history.undo.bind(pixiEditor.history)}" title="{vocGlob.undo}" class="{dim: !pixiEditor?.history.canUndo}") + svg.feather + use(xlink:href="#undo") + button.slim(onclick="{pixiEditor?.history.redo.bind(pixiEditor.history)}" title="{vocGlob.redo}" class="{dim: !pixiEditor?.history.canRedo}") + svg.feather + use(xlink:href="#redo") + label.checkbox(title="Shift+S") + input( + type="checkbox" + onchange="{changeSimulated}" + checked="{pixiEditor?.simulate}" + data-hotkey="S" + data-hotkey-require-scope="rooms" + ) + span {voc.simulate} + button(onclick="{openZoomMenu}") + span(ref="zoomLabel") {Math.round(pixiEditor?.getZoom() || 100)}% + button(onclick="{openGridMenu}") + span {voc.grid} + button.slim(onclick="{openVisibilityMenu}") + svg.feather + use(xlink:href="#eye") + button(onclick="{openEventsList}") + span {voc.events} + button(onclick="{saveRoom}") + svg.feather + use(xlink:href="#check") + span {vocGlob.save} + + room-events-editor(if="{editingEvents}" room="{opts.room}" onsave="{closeRoomEvents}") + context-menu(menu="{gridMenu}" ref="gridMenu") + context-menu(menu="{zoomMenu}" ref="zoomMenu") + context-menu(menu="{visibilityMenu}" ref="visibilityMenu" if="{pixiEditor}") script. - const minSizeW = 250; - const getMaxSizeW = () => window.innerWidth - 300; - this.sidebarWidth = Math.max( - minSizeW, - Math.min(getMaxSizeW(), localStorage.roomSidebarWidth || 300) - ); + this.namespace = 'roomView'; + this.mixin(window.riotVoc); - this.gutterMouseDown = () => { - this.draggingGutter = true; - }; - const gutterMove = e => { - if (!this.draggingGutter) { + this.freePlacementMode = false; + const modifiersDownListener = e => { + if (e.repeat || + !window.hotkeys.inScope('rooms') || + window.hotkeys.isFormField(e.target) + ) { return; } - this.sidebarWidth = Math.max(minSizeW, Math.min(getMaxSizeW(), e.clientX)); - localStorage.roomSidebarWidth = this.sidebarWidth; - this.update(); - var {canvas} = this.refs, - sizes = this.refs.canvaswrap.getBoundingClientRect(); - if (canvas.width !== sizes.width || canvas.height !== sizes.height) { - canvas.width = sizes.width; - canvas.height = sizes.height; + if (e.key === 'Alt') { + this.freePlacementMode = true; + e.preventDefault(); + } else if (e.key === 'Control') { + this.controlMode = true; + e.preventDefault(); } - this.refreshRoomCanvas(); }; - const gutterUp = () => { - if (this.draggingGutter) { - this.draggingGutter = false; - // updateCanvasSize(); - // document.body.removeChild(catcher); + const modifiersUpListener = e => { + if (e.repeat || + !window.hotkeys.inScope('rooms') || + window.hotkeys.isFormField(e.target) + ) { + return; + } + if (e.key === 'Alt') { + this.freePlacementMode = false; + e.preventDefault(); + } else if (e.key === 'Control') { + this.controlMode = false; + e.preventDefault(); } }; - document.addEventListener('mousemove', gutterMove); - document.addEventListener('mouseup', gutterUp); - this.on('unmount', () => { - document.removeEventListener('mousemove', gutterMove); - document.removeEventListener('mouseup', gutterUp); - }); - - this.editingCode = false; - this.forbidDrawing = false; - const fs = require('fs-extra'); - const glob = require('./data/node_requires/glob'); - this.namespace = 'roomView'; - this.mixin(window.riotVoc); - this.mixin(window.riotWired); - this.mixin(window.roomCopyTools); - this.mixin(window.roomTileTools); - this.wireAndRedraw = way => e => { - this.wire(way)(e); - this.refreshRoomCanvas(); - }; - - this.room = this.opts.room; - if (!this.room.extends) { - this.room.extends = {}; - } - - this.mouseX = this.mouseY = 0; - this.roomx = this.room.width / 2; - this.roomy = this.room.height / 2; - this.zoomFactor = 1; - this.room.gridX = this.room.gridX || this.room.grid || 64; - this.room.gridY = this.room.gridY || this.room.grid || 64; - this.dragging = false; - this.tab = 'roomcopies'; - - this.toggleCopyProperties = value => { - this.showCopyPropertiesModal = value; - this.update(); - this.refreshRoomCanvas(); - }; - - this.updateRoomBackground = (e, color) => { - this.room.backgroundColor = color; - this.refreshRoomCanvas(); + const blurListener = () => { + // Specifically designed to catch Alt+Tab + this.freePlacementMode = false; }; - - var updateCanvasSize = () => { - // Firstly, check that we don't need to reflow the layout due to window shrinking - const oldSidebarWidth = this.sidebarWidth; - this.sidebarWidth = Math.max(minSizeW, Math.min(getMaxSizeW(), this.sidebarWidth)); - if (oldSidebarWidth !== this.sidebarWidth) { - this.update(); - } - var {canvas} = this.refs, - sizes = this.refs.canvaswrap.getBoundingClientRect(); - if (canvas.width !== sizes.width || canvas.height !== sizes.height) { - canvas.width = sizes.width; - canvas.height = sizes.height; + const tabListener = e => { + if (!window.hotkeys.inScope('rooms') || window.hotkeys.isFormField(e.target)) { + return; } - setTimeout(this.refreshRoomCanvas, 10); + this.gridOn = !this.gridOn; }; - this.on('update', () => { - if (global.currentProject.rooms.find(room => - this.room.name === room.name && this.room !== room)) { - this.nameTaken = true; - } else { - this.nameTaken = false; - } - }); this.on('mount', () => { - this.room = this.opts.room; - this.refs.canvas.x = this.refs.canvas.getContext('2d'); - this.gridCanvas = document.createElement('canvas'); - this.gridCanvas.x = this.gridCanvas.getContext('2d'); - this.redrawGrid(); - window.addEventListener('resize', updateCanvasSize); - updateCanvasSize(); + window.hotkeys.push('roomEditor'); + window.hotkeys.on('Control+g', tabListener); + document.addEventListener('keydown', modifiersDownListener); + document.addEventListener('keyup', modifiersUpListener); + window.addEventListener('blur', blurListener); }); this.on('unmount', () => { - window.removeEventListener('resize', updateCanvasSize); + window.hotkeys.exit('roomEditor'); + window.hotkeys.off('Control+g', tabListener); + document.removeEventListener('keydown', modifiersDownListener); + document.removeEventListener('keyup', modifiersUpListener); + window.addEventListener('blur', blurListener); }); - this.openRoomEvents = () => { - this.editingCode = true; + this.lockableTypes = [{ + icon: 'template', + hintVocKey: 'copies', + key: 'selectCopies' + }, { + icon: 'grid', + hintVocKey: 'tiles', + key: 'selectTiles' + }]; + this.toggleSelectables = e => { + this.pixiEditor[e.item.lockable.key] = !this.pixiEditor[e.item.lockable.key]; }; - - // Навигация по комнате, настройки вида - this.roomToggleZoom = zoomFactor => () => { - this.zoomFactor = zoomFactor; - this.redrawGrid(); - this.refreshRoomCanvas(); - }; - this.roomToCenter = () => { - this.roomx = this.room.width / 2; - this.roomy = this.room.height / 2; - this.refreshRoomCanvas(); - }; - this.redrawGrid = () => { - this.gridCanvas.width = this.room.gridX; - this.gridCanvas.height = this.room.gridY; - this.gridCanvas.x.clearRect(0, 0, this.room.gridX, this.room.gridY); - this.gridCanvas.x.globalAlpha = 0.3; - this.gridCanvas.x.strokeStyle = localStorage.UItheme === 'Night' ? '#44dbb5' : '#446adb'; - this.gridCanvas.x.lineWidth = 1 / this.zoomFactor; - this.gridCanvas.x.strokeRect( - 0.5 / this.zoomFactor, 0.5 / this.zoomFactor, - this.room.gridX, this.room.gridY - ); - }; - this.roomToggleGrid = () => { - if (this.room.gridX === 0) { - window.alertify - .confirm(this.voc.gridSize + '
x ') - .then(e => { - if (e.buttonClicked === 'ok') { - this.room.gridX = Number(document.getElementById('theGridSizeX').value); - this.room.gridY = Number(document.getElementById('theGridSizeY').value); - } - this.redrawGrid(); - this.refreshRoomCanvas(); - this.update(); - }); - } else { - this.refreshRoomCanvas(); - this.room.gridX = 0; - this.room.gridY = 0; - } + this.updateSelectFrame = () => { + this.pixiEditor.transformer.setup(); }; - // Работа с копиями - this.tab = 'roomcopies'; - this.changeTab = tab => () => { - this.tab = tab; - this.selectedCopies = this.selectedTiles = false; - if (tab === 'roombackgrounds' || tab === 'properties') { - this.roomUnpickTemplate(); - } - if (tab !== 'roomcopies') { - this.toggleCopyProperties(false); - } - }; - this.roomUnpickTemplate = () => { - this.currentTemplate = -1; + const setup = require('./data/node_requires/roomEditor').setup; + this.on('mount', () => { + setup(this.refs.canvas, this); + // adds this.pixiEditor + [this.currentTileLayer] = this.pixiEditor.tileLayers; + this.update(); + }); + this.on('unmount', () => { + this.pixiEditor.destroy(false, { + children: true + }); + }); + this.triggerWheelEvent = e => { + e.preventUpdate = true; + // pixi v5 doesn't have a wheel event! we will have to fabricate one. + this.pixiEditor.stage._events.wheel.fn({ + type: 'wheel', + target: this.pixiEditor.stage, + currentTarget: this.pixiEditor.stage, + data: { + global: { + x: e.offsetX, + y: e.offsetY + }, + originalEvent: e + } + }); }; - - /** Преобразовать x на канвасе в x на комнате */ - this.xToRoom = x => (x - Math.floor(this.refs.canvas.width / 2)) / this.zoomFactor + this.roomx; - /** Преобразовать y на канвасе в y на комнате */ - this.yToRoom = y => (y - Math.floor(this.refs.canvas.height / 2)) / this.zoomFactor + this.roomy; - /** Преобразовать x в комнате в x на канвасе */ - this.xToCanvas = x => (x - this.roomx) * this.zoomFactor + Math.floor(this.refs.canvas.width / 2); - /** Преобразовать y в комнате в y на канвасе */ - this.yToCanvas = y => (y - this.roomy) * this.zoomFactor + Math.floor(this.refs.canvas.height / 2); - - this.onCanvasClick = e => { - if (this.tab === 'roomcopies') { - this.onCanvasClickCopies(e); - } else if (this.tab === 'roomtiles') { - this.onCanvasClickTiles(e); + // Keyboard events + const phabricateEvent = (name, e) => { + if (!(name in this.pixiEditor.stage._events)) { + console.error(`An event ${name} was triggered on the room editor, but it is not allowed.`); + return; } + this.pixiEditor.stage._events[name].fn({ + type: name, + target: this.pixiEditor.stage, + currentTarget: this.pixiEditor.stage, + data: { + originalEvent: e + } + }); }; - /** При нажатии на канвас, если не выбрана копия, то начинаем перемещение */ - this.onCanvasPress = e => { - this.mouseDown = true; - this.startx = e.offsetX; - this.starty = e.offsetY; - - if (this.tab === 'roomcopies' && this.onCanvasPressCopies(e)) { + const triggerKeyboardEvent = e => { + if (['input', 'textarea', 'select'].includes(e.target.nodeName.toLowerCase())) { return; } - if ((this.currentTemplate === -1 && !e.shiftKey && this.tab !== 'roomtiles' && e.button === 0 && !e.ctrlKey) || - e.button === 1) { - this.dragging = true; - } - }; - /** и безусловно прекращаем перемещение при отпускании мыши */ - this.onCanvasMouseUp = e => { - this.mouseDown = false; - this.lastCopyX = null; - this.lastCopyY = null; - this.lastTileX = null; - this.lastTileY = null; - if (this.dragging) { - this.dragging = false; - this.roomx = Math.round(this.roomx); - this.roomy = Math.round(this.roomy); - this.refreshRoomCanvas(); - } else if (this.tab === 'roomtiles') { - this.onCanvasMouseUpTiles(e); - } else if (this.tab === 'roomcopies') { - this.onCanvasMouseUpCopies(e); + if (e.key === 'Delete') { + return phabricateEvent('delete', e); + } else if (e.code === 'KeyC' && e.ctrlKey) { + return phabricateEvent('copy', e); + } else if (e.code === 'KeyV' && e.ctrlKey) { + return phabricateEvent('paste', e); + } else if (e.code === 'KeyZ' && e.ctrlKey && e.shiftKey) { + return phabricateEvent('redo', e); + } else if (e.code === 'KeyZ' && e.ctrlKey) { + return phabricateEvent('undo', e); + } else if (e.code === 'KeyH') { + return phabricateEvent('home', e); + } else if (e.key === 'ArrowRight') { + return phabricateEvent('nudgeright', e); + } else if (e.key === 'ArrowLeft') { + return phabricateEvent('nudgeleft', e); + } else if (e.key === 'ArrowUp') { + return phabricateEvent('nudgeup', e); + } else if (e.key === 'ArrowDown') { + return phabricateEvent('nudgedown', e); } - setTimeout(() => { - this.movingStuff = false; - }, 0); - }; - this.drawDeleteCircle = e => { - // Рисовка кружка для удаления копий - var maxdist = Math.max(this.room.gridX, this.room.gridY) || 32; - this.refreshRoomCanvas(e); - var cx = this.refs.canvas.x; - cx.fillStyle = '#F00'; - cx.strokeStyle = '#000'; - cx.globalAlpha = 0.5; - cx.beginPath(); - cx.arc(this.xToRoom(e.offsetX), this.yToRoom(e.offsetY), maxdist, 0, 2 * Math.PI); - cx.fill(); - cx.stroke(); }; + this.on('mount', () => { + window.addEventListener('keydown', triggerKeyboardEvent); + }); + this.on('unmount', () => { + window.removeEventListener('keydown', triggerKeyboardEvent); + }); - /** - * Updating mouse coordinates display at the bottom-left corner - */ - this.updateMouseCoords = function updateMouseCoords(e) { - var dx = Math.floor(this.xToRoom(e.offsetX)), - dy = Math.floor(this.yToRoom(e.offsetY)); - if (this.room.gridX === 0 || e.altKey) { - this.mouseX = dx; - this.mouseY = dy; - } else { - this.mouseX = Math.round(dx / this.room.gridX) * this.room.gridX; - this.mouseY = Math.round(dy / this.room.gridY) * this.room.gridY; - } - this.refs.mousecoords.innerHTML = `(${this.mouseX}:${this.mouseY})`; + this.currentTool = 'select'; + const mandatoryVisibilityMap = { + addCopies: 'copiesVisible', + addTiles: 'tilesVisible', + manageBackgrounds: 'backgroundsVisible' }; - - /** Start moving or show a placement preview **/ - this.onCanvasMove = e => { - e.preventUpdate = true; - if (this.dragging && !this.movingStuff) { - // Drag the viewport - this.roomx -= e.movementX / this.zoomFactor; - this.roomy -= e.movementY / this.zoomFactor; - this.refreshRoomCanvas(e); - } else if ( // Make more tiles or copies if Shift key is down - e.shiftKey && this.mouseDown && - ( - (this.tab === 'roomcopies' && this.currentTemplate !== -1) || - this.tab === 'roomtiles' - ) - ) { - this.onCanvasClick(e); - } else if (this.tab === 'roomcopies') { - this.onCanvasMoveCopies(e); - } else if (this.tab === 'roomtiles') { - this.onCanvasMoveTiles(e); + this.setTool = tool => () => { + this.currentTool = tool; + if (tool in mandatoryVisibilityMap) { + this.pixiEditor[mandatoryVisibilityMap[tool]] = true; } - this.updateMouseCoords(e); - }; - - /** Change zoom on mouse wheel */ - this.onCanvasWheel = e => { - if (e.wheelDelta > 0) { - this.refs.zoomslider.zoomIn(); - } else { - this.refs.zoomslider.zoomOut(); + if (tool !== 'select') { + this.pixiEditor.transformer.clear(); } - }; - this.setZoom = zoom => { - this.zoomFactor = zoom; - this.update(); - this.redrawGrid(); - this.refreshRoomCanvas(); - }; - - this.onCanvasContextMenu = e => { - this.dragging = false; - this.mouseDown = false; - if (this.tab === 'roomcopies') { - if (this.selectedCopies && this.selectedCopies.length) { - this.onCanvasContextMenuMultipleCopies(e); - } else { - this.onCanvasContextMenuCopies(e); - } - } else if (this.tab === 'roomtiles') { - if (this.selectedTiles && this.selectedTiles.length) { - this.onCanvasContextMenuMultipleTiles(e); - } else { - this.onCanvasContextMenuTiles(e); - } + if (tool === 'addTiles' && !this.pixiEditor.tileLayers.includes(this.currentTileLayer)) { + this.currentTileLayer = this.pixiEditor.tileLayers[0]; } - e.preventDefault(); - return true; }; - // Prompts a modal window then and shifts all the copies in a room at once. - this.roomShift = () => { - window.alertify.confirm(` - ${window.languageJSON.roomView.shiftLabel} - - - `) - .then(e => { - if (e.buttonClicked === 'ok') { - var dx = Number(document.getElementById('roomshiftx').value) || 0, - dy = Number(document.getElementById('roomshifty').value) || 0; - for (const copy of this.room.copies) { - copy.x += dx; - copy.y += dy; - } - for (const tileLayer of this.room.tiles) { - for (const tile of tileLayer.tiles) { - tile.x += dx; - tile.y += dy; + this.currentTemplate = -1; + this.changeSelectedTemplate = template => { + this.currentTemplate = template; + }; + + this.tilePatch = void 0; + this.changeTilePatch = tilePatch => { + this.tilePatch = tilePatch; + }; + this.changeTileLayer = layer => { + this.currentTileLayer = layer; + }; + + this.zoom = 1; + + this.changeBgColor = (e, color) => { + this.opts.room.backgroundColor = color; + this.pixiEditor.renderer.backgroundColor = PIXI.utils.string2hex(color); + }; + + this.changeSimulated = () => { + this.pixiEditor.simulate = !this.pixiEditor.simulate; + }; + + this.gridOn = true; + this.gridMenu = { + opened: false, + items: [{ + label: this.voc.gridOff, + click: () => { + this.gridOn = !this.gridOn; + }, + type: 'checkbox', + checked: () => !this.gridOn, + hotkeyLabel: 'Ctrl+G' + }, { + label: this.voc.toggleDiagonalGrid, + click: () => { + this.opts.room.diagonalGrid = !this.opts.room.diagonalGrid; + }, + type: 'checkbox', + checked: () => this.opts.room.diagonalGrid + }, { + label: this.voc.changeGridSize, + click: () => { + window.alertify + .confirm(this.voc.gridSize + `
x `) + .then(e => { + if (e.buttonClicked === 'ok') { + this.opts.room.gridX = Number(document.getElementById('theGridSizeX').value); + this.opts.room.gridY = Number(document.getElementById('theGridSizeY').value); } - } - this.refreshRoomCanvas(); + this.update(); + }); } - }); + }] + }; + this.openGridMenu = e => { + this.refs.gridMenu.popup(e.clientX, e.clientY); }; - this.roomSave = () => { - if (this.nameTaken) { - // animate the error notice - require('./data/node_requires/jellify')(this.refs.errorNotice); - if (localStorage.disableSounds !== 'on') { - window.soundbox.play('Failure'); + this.zoomMenu = { + opened: false, + items: [...[12.5, 25, 50, 100, 200, 400, 800].map(zoom => ({ + label: `${zoom}%`, + click: () => { + this.zoom = 1 / zoom * 100; + this.pixiEditor.zoomTo(zoom); } - return false; - } - this.room.lastmod = Number(new Date()); - this.roomGenSplash() - .then(() => { - glob.modified = true; - this.parent.editing = false; - this.parent.update(); + })), { + type: 'separator' + }, { + label: this.voc.resetView, + click: () => { + this.pixiEditor.goHome(); + }, + hotkeyLabel: 'H' + }] + }; + this.openZoomMenu = e => { + this.refs.zoomMenu.popup(e.clientX, e.clientY); + }; + + const entityToIconMap = { + copies: 'template', + tiles: 'grid', + backgrounds: 'image' + }; + const entityVisibilityItems = []; + for (const entityType in entityToIconMap) { + const icon = entityToIconMap[entityType]; + entityVisibilityItems.push({ + label: this.voc[entityType], + click: () => { + this.pixiEditor[entityType + 'Visible'] = !this.pixiEditor[entityType + 'Visible']; + }, + type: 'checkbox', + checked: () => this.pixiEditor[entityType + 'Visible'] }) - .catch(err => { - console.error(err); - glob.modified = true; - this.parent.editing = false; - this.parent.update(); - }); - return true; }; - - this.sortHorizontally = () => { - if (this.tab === 'roomcopies') { - this.room.copies.sort((a, b) => a.x - b.x); - } else { - // tiles - this.currentTileLayer.tiles.sort((a, b) => a.x - b.x); - } - this.resortRoom(); - this.refreshRoomCanvas(); + this.visibilityMenu = { + opened: false, + items: [ + ...entityVisibilityItems, + { + type: 'separator' + }, { + label: this.voc.xrayMode, + click: () => { + this.pixiEditor.xrayMode = !this.pixiEditor.xrayMode; + }, + type: 'checkbox', + checked: () => this.pixiEditor.xrayMode + }, { + label: this.voc.colorizeTileLayers, + click: () => { + this.pixiEditor.colorizeTileLayers = !this.pixiEditor.colorizeTileLayers; + }, + type: 'checkbox', + checked: () => this.pixiEditor.colorizeTileLayers + } + ] }; - this.sortVertically = () => { - if (this.tab === 'roomcopies') { - this.room.copies.sort((a, b) => a.y - b.y); - } else { - // tiles - this.currentTileLayer.tiles.sort((a, b) => a.y - b.y); - } - this.resortRoom(); - this.refreshRoomCanvas(); + this.openVisibilityMenu = e => { + this.refs.visibilityMenu.popup(e.clientX, e.clientY); }; - this.resortRoom = () => { - // Make an array of all the backgrounds, tile layers and copies, and then sort it. - this.stack = this.room.copies.concat(this.room.backgrounds).concat(this.room.tiles); - const projTemplates = global.currentProject.templates; - this.stack.sort((a, b) => { - const depthA = a.depth !== void 0 ? a.depth : projTemplates[glob.templatemap[a.uid]].depth, - depthB = b.depth !== void 0 ? b.depth : projTemplates[glob.templatemap[b.uid]].depth; - return depthA - depthB; - }); + this.editingEvents = false; + this.openEventsList = () => { + this.editingEvents = true; }; - this.resortRoom(); - var templatesChanged = () => { - this.currentTemplate = -1; - this.resortRoom(); + this.closeRoomEvents = () => { + this.editingEvents = false; + this.update(); }; - window.signals.on('templatesChanged', templatesChanged); - this.on('unmount', () => { - window.signals.off('templatesChanged', templatesChanged); - }); - /** Canvas redrawing, with all the backgrounds, tiles and copies */ - // eslint-disable-next-line max-lines-per-function, complexity - this.refreshRoomCanvas = () => { - if (this.forbidDrawing) { - return; - } - const {canvas} = this.refs, - sizes = this.refs.canvaswrap.getBoundingClientRect(); - // Make sure the canvas size is of correct width - if (Number(canvas.width) !== sizes.width || Number(canvas.height) !== sizes.height) { - canvas.width = sizes.width; - canvas.height = sizes.height; - } - - // Reset drawing transforms - canvas.x.setTransform(1, 0, 0, 1, 0, 0); - canvas.x.globalAlpha = 1; - // Clear the canvas - canvas.x.clearRect(0, 0, canvas.width, canvas.height); - // Fill it with a background color - canvas.x.fillStyle = this.room.backgroundColor || '#000000'; - canvas.x.fillRect(0, 0, canvas.width, canvas.height); - - // Apply camera movement + zoom - canvas.x.translate(Math.floor(canvas.width / 2), Math.floor(canvas.height / 2)); - canvas.x.scale(this.zoomFactor, this.zoomFactor); - canvas.x.translate(-this.roomx, -this.roomy); - - // Disable pixel interpolation, if needed - canvas.x.imageSmoothingEnabled = !global.currentProject.settings.rendering.pixelatedrender; - - for (let i = 0, li = this.stack.length; i < li; i++) { - if (this.stack[i].tiles) { // a tile layer - const layer = this.stack[i]; - if (!layer.hidden) { - for (const tile of layer.tiles) { - const img = glob.texturemap[tile.texture], - tex = img.g; - const x = tex.offx + (tex.width + tex.marginx) * tile.grid[0] - tex.marginx, - y = tex.offy + (tex.height + tex.marginy) * tile.grid[1] - tex.marginy, - w = (tex.width + tex.marginx) * tile.grid[2] - tex.marginx, - h = (tex.height + tex.marginy) * tile.grid[3] - tex.marginy; - canvas.x.drawImage( - img, - x, y, w, h, - tile.x, tile.y, w, h - ); - } - } - } else if (this.stack[i].texture) { // a background layer - if (this.stack[i].texture !== -1) { - if (!('extends' in this.stack[i])) { - this.stack[i].extends = {}; - } - const scx = this.stack[i].extends.scaleX || 1, - scy = this.stack[i].extends.scaleY || 1, - shx = this.stack[i].extends.shiftX || 0, - shy = this.stack[i].extends.shiftY || 0; - canvas.x.save(); - canvas.x.fillStyle = canvas.x.createPattern(glob.texturemap[this.stack[i].texture], this.stack[i].extends.repeat || 'repeat'); - canvas.x.translate(shx, shy); - canvas.x.scale(scx, scy); - canvas.x.fillRect( - (this.xToRoom(0) - shx) / scx, (this.yToRoom(0) - shy) / scy, - canvas.width / scx / this.zoomFactor, - canvas.height / scy / this.zoomFactor - ); - canvas.x.restore(); - } - } else { // A copy - const copy = this.stack[i], - template = global.currentProject.templates[glob.templatemap[copy.uid]]; - let texture, gra, w, h, ox, oy, - grax, gray; // texture's drawing center - if (template.texture !== -1) { - texture = glob.texturemap[template.texture]; - gra = glob.texturemap[template.texture].g; - w = gra.width; - h = gra.height; - ox = gra.offx; - oy = gra.offy; - [grax, gray] = gra.axis; - } else { - texture = glob.texturemap[-1]; - w = h = 32; - grax = gray = 16; - ox = oy = 0; - } - if ((copy.tx || copy.tx === 0) || - (copy.ty || copy.ty === 0) || - (copy.tr && copy.tr !== 0)) { - canvas.x.save(); - canvas.x.translate(copy.x, copy.y); - canvas.x.rotate((copy.tr || 0) * Math.PI / -180); - canvas.x.scale(copy.tx ?? 1, copy.ty ?? 1); - canvas.x.drawImage( - texture, - ox, oy, w, h, - -grax, -gray, w, h - ); - canvas.x.restore(); - } else { - const tex = glob.texturemap[template.texture].g; - canvas.x.drawImage( - texture, - tex.offx, tex.offy, w, h, - copy.x - grax, copy.y - gray, w, h - ); - } - } - } - - // Grid drawing - if (this.room.gridX > 1) { - canvas.x.globalCompositeOperation = 'exclusion'; - canvas.x.fillStyle = canvas.x.createPattern(this.gridCanvas, 'repeat'); - canvas.x.fillRect( - this.xToRoom(0), this.yToRoom(0), - canvas.width / this.zoomFactor, canvas.height / this.zoomFactor - ); - canvas.x.globalCompositeOperation = 'source-over'; - } - // Outline selected tiles - if (this.tab === 'roomtiles' && this.selectedTiles && this.selectedTiles.length) { - for (const tile of this.selectedTiles) { - const {g} = glob.texturemap[tile.texture]; - this.drawSelection( - tile.x, - tile.y, - tile.x + g.width * tile.grid[2], - tile.y + g.height * tile.grid[3] - ); - } - } - // Outline selected copies - if (this.tab === 'roomcopies' && this.selectedCopies && this.selectedCopies.length) { - for (const copy of this.selectedCopies) { - this.drawSelection(copy); - } - } - - // Outline the starting viewport frame - this.drawSelection(-1.5, -1.5, this.room.width + 1.5, this.room.height + 1.5); - - // Outline room's limits - if (this.room.restrictCamera) { - this.drawSelection( - (this.room.restrictMinX || 0) - 1.5, - (this.room.restrictMinY || 0) - 1.5, - (this.room.restrictMaxX === void 0 ? this.room.width : this.room.restrictMaxX) + 1.5, - (this.room.restrictMaxY === void 0 ? this.room.height : this.room.restrictMaxY) + 1.5 - ); - } + this.saveRoom = async () => { + const {writeRoomPreview} = require('./data/node_requires/resources/rooms'); + this.pixiEditor.serialize(); + await Promise.all([ + writeRoomPreview(this.opts.room, this.pixiEditor.getSplashScreen(true), true), + writeRoomPreview(this.opts.room, this.pixiEditor.getSplashScreen(false), false) + ]); + this.opts.onclose(); }; - this.drawSelection = (x1, y1, x2, y2) => { - const cx = this.refs.canvas.x; - cx.lineJoin = 'round'; - cx.lineCap = 'round'; - if (typeof x1 !== 'number') { - const copy = x1, - template = global.currentProject.templates[glob.templatemap[copy.uid]], - texture = glob.texturemap[template.texture].g; - var left, top, height, width; - if (copy.tr) { - cx.strokeStyle = localStorage.UItheme === 'Night' ? '#44dbb5' : '#446adb'; - cx.lineWidth = 3; - cx.beginPath(); - cx.moveTo(copy.x - 32, copy.y); - cx.lineTo(copy.x + 32, copy.y); - cx.moveTo(copy.x, copy.y - 32); - cx.lineTo(copy.x, copy.y + 32); - cx.stroke(); - cx.strokeStyle = localStorage.UItheme === 'Night' ? '#1C2B42' : '#fff'; - cx.lineWidth = 1; - cx.moveTo(copy.x - 32, copy.y); - cx.lineTo(copy.x + 32, copy.y); - cx.moveTo(copy.x, copy.y - 32); - cx.lineTo(copy.x, copy.y + 32); - cx.stroke(); - return; - } - if (template.texture !== -1) { - left = copy.x - texture.axis[0] * (copy.tx ?? 1) - 1.5; - top = copy.y - texture.axis[1] * (copy.ty ?? 1) - 1.5; - width = texture.width * (copy.tx ?? 1) + 3; - height = texture.height * (copy.ty ?? 1) + 3; - } else { - left = copy.x - 16 - 1.5; - top = copy.y - 16 - 1.5; - height = 32 + 3; - width = 32 + 3; - } - x1 = left; - y1 = top; - x2 = left + width; - y2 = top + height; - } - cx.strokeStyle = localStorage.UItheme === 'Night' ? '#44dbb5' : '#446adb'; - cx.lineWidth = 3; - cx.strokeRect(x1, y1, x2 - x1, y2 - y1); - cx.strokeStyle = localStorage.UItheme === 'Night' ? '#1C2B42' : '#fff'; - cx.lineWidth = 1; - cx.strokeRect(x1, y1, x2 - x1, y2 - y1); + const resizeEditor = () => { + setTimeout(() => { + this.pixiEditor.resize(); + }, 10); }; - - /** - * Генерирует миниатюру комнаты - */ - this.roomGenSplash = function roomGenSplash() { - const {imageCover, toBuffer} = require('./data/node_requires/imageUtils'); - return new Promise((accept, decline) => { - const c = imageCover(this.refs.canvas, 340, 256); - const buf = toBuffer(c); - const roomSplashName = global.projdir + '/img/r' + this.room.uid + '.png'; - fs.writeFile(roomSplashName, buf, err => { - if (err) { - decline(err); - } else { - accept(roomSplashName); - } - }); - const projSplashName = global.projdir + '/img/splash.png'; - fs.writeFile(projSplashName, buf, err => { - if (err) { - decline(err); - } - }); - }); + const serialize = () => { + this.pixiEditor.serialize(); }; + this.on('mount', () => { + window.signals.on('exportProject', serialize); + window.signals.on('roomsFocus', resizeEditor); + }); + this.on('unmount', () => { + window.signals.off('exportProject', serialize); + window.signals.off('roomsFocus', resizeEditor); + }); diff --git a/src/riotTags/rooms/room-entities-properties.tag b/src/riotTags/rooms/room-entities-properties.tag new file mode 100644 index 000000000..1d3870f59 --- /dev/null +++ b/src/riotTags/rooms/room-entities-properties.tag @@ -0,0 +1,482 @@ +// + @attribute pixieditor (RoomEditor) + The reference to the current pixi editor + + @attribute ontransformchange (riot function) + This function is called when this widget makes transformation + changes to selected objects. Used to update the selection box. + + @method applyChanges + Call this on selection change to apply changes to the current selection + @method updatePropList + Call this on selection change to re-scan the selection for values + +room-entities-properties + div(if="{opts.pixieditor?.currentSelection.size}") + // Basic properties + virtual(each="{prop in basicProps}") + b {voc.copyProperties[prop.vocKey]}: + // Point2D + .aPoint2DInput.compact.wide(if="{prop.type === 'xy'}") + label.flexrow + span.nogrow X: + input.nmr( + type="number" + oninput="{wireAndApply('this.changes.basic.' + prop.key + '.x')}" + onchange="{memorizeChanges}" + value="{changes.basic[prop.key].x}" + placeholder="{String(changes.basic[prop.key].x)}" + step="{prop.step}" + ) + .aSpacer.noshrink.nogrow + label.flexrow + span.nogrow Y: + input.nmr( + type="number" + oninput="{wireAndApply('this.changes.basic.' + prop.key + '.y')}" + onchange="{memorizeChanges}" + value="{changes.basic[prop.key].y}" + placeholder="{String(changes.basic[prop.key].y)}" + step="{prop.step}" + ) + .flexrow(if="{prop.type === 'slider'}") + .aSliderWrap + input.compact( + type="range" min="{prop.from}" max="{prop.to}" step="{prop.step}" + value="{(changes.basic[prop.key] === parent.multipleType) ? 0 : (changes.basic[prop.key] || 0)}" + oninput="{wireAndApply('this.changes.basic.' + prop.key)}" + onchange="{memorizeChanges}" + list="{prop.datalist}" + ) + .DataTicks(if="{prop.datalist}") + .aDataTick(each="{value in [-180, -90, 0, 90, 180]}" style="left: {(value + 180) / 3.6}%") + .aSpacer + input.compact( + min="{prop.from}" max="{prop.to}" step="{prop.step}" type="number" + value="{String(changes.basic[prop.key])}" + oninput="{wireAndApply('this.changes.basic.' + prop.key)}" + onchange="{memorizeChanges}" + placeholder="{String(changes.basic[prop.key])}" + ) + color-input( + if="{prop.type === 'color'}" + color="{PIXI.utils.hex2string(changes.basic[prop.key])}" + onchange="{writeColor(prop.key)}" + onapply="{writeColorAndMemorize(prop.key)}" + hidealpha="true" + ) + + // Copies' extensions that come from mods + extensions-editor(show="{hasCopies}" entity="{changes.exts}" ref="exts" type="copy" compact="yes" wide="yup") + + // Custom properties for copies + div(if="{hasCopies}") + h3 {voc.customProperties} + table.wide.aPaddedTable.cellsmiddle + tr + th {voc.copyCustomProperties.property} + th {voc.copyCustomProperties.value} + th + tr(each="{val, prop in changes.customProps}") + td + input.wide( + type="text" + value="{prop}" + onchange="{renameProp}" + ) + p.anErrorNotice(if="{reservedProps.includes(prop)}") {voc.copyCustomProperties.nameOccupied} + td + input.wide( + type="text" + value="{val === multipleType ? '' : JSON.stringify(val)}" + placeholder="{val === multipleType ? String(multipleType) : ''}" + onchange="{changeValue}" + ) + td + button.toright.square.inline.nm(onclick="{deleteCustomProperty(prop)}" title="{vocGlob.delete}") + svg.feather + use(xlink:href="#trash") + .clear + button.nogrow(onclick="{addCustomProperty}") + svg.feather + use(xlink:href="#plus") + span {voc.copyCustomProperties.addProperty} + datalist#theDatalistDegrees + option(value="-180") + option(value="-90") + option(value="0") + option(value="90") + option(value="180") + script. + this.namespace = 'roomView'; + this.mixin(window.riotVoc); + this.mixin(window.riotWired); + + const {Copy} = require('./data/node_requires/roomEditor/entityClasses/Copy'); + + this.changes = { + exts: {}, + basic: {}, + customProps: {} + }; + + this.basicProps = [{ + // An i18n key to look for in roomView.copyProperties, for a label + vocKey: 'position', + // A key to write to + key: 'position', + // The type of this field. `xy` stands for 2D point input + type: 'xy', + step: 8 + }, { + vocKey: 'scale', + key: 'scale', + type: 'xy', + step: 0.1 + }, { + vocKey: 'rotation', + key: 'angle', + type: 'slider', + from: -180, + to: 180, + step: 1, + datalist: 'theDatalistDegrees' + }, { + vocKey: 'opacity', + key: 'alpha', + type: 'slider', + from: 0, + to: 1, + step: 0.01 + }, { + vocKey: 'tint', + key: 'tint', + type: 'color' + }]; + + // Utilities for writing basic properties + const typeWrap = (prop, entity) => { + if (prop.type == 'xy') { + return { + x: entity[prop.key].x, + y: entity[prop.key].y + }; + } + return entity[prop.key]; + }; + this.writeColor = key => (e, value) => { + this.changes.basic[key] = PIXI.utils.string2hex(value); + this.applyChanges(); + }; + this.wireAndApply = path => e => { + this.wire(path)(e); + this.applyChanges(); + this.opts.ontransformchange(); + e.stopPropagation(); + }; + + const Magic = function Magic() { + void 'sparkles'; + }; + Magic.prototype.toString = () => this.voc.copyProperties.multipleValues; + Magic.prototype.toNumber = () => 0; + this.multipleType = new Magic(); + + this.firstRun = true; + /** + * Rescans the list of selected items and forms a list of matching and different properties. + * Different changes are reflected as this.multipleType. + * + * Before the rescan, it always writes applied changes to the previous selection. + */ + this.updatePropList = () => { + this.firstRun = false; + this.changes = { + exts: {}, + basic: {}, + customProps: {} + }; + + this.hasCopies = false; + const {basic} = this.changes; + const selection = this.opts.pixieditor.currentSelection; + // Quicker run for built-in properties + for (const property of this.basicProps) { + for (const entity of selection) { + if (!(property.key in basic)) { + basic[property.key] = typeWrap(property, entity); + } else if (property.type === 'xy') { + if (basic[property.key].x !== this.multipleType) { + if (basic[property.key].x !== entity[property.key].x) { + basic[property.key].x = this.multipleType; + } + } + if (basic[property.key].y !== this.multipleType) { + if (basic[property.key].y !== entity[property.key].y) { + basic[property.key].y = this.multipleType; + } + } + if (basic[property.key].x === this.multipleType && + basic[property.key].y === this.multipleType + ) { + break; + } + } else if (basic[property.key] !== entity[property.key]) { + basic[property.key] = this.multipleType; + break; + } + } + } + let copyCount = 0; + const propCount = {}; + // Separate run for custom properties and extensions + for (const entity of selection) { + // Skip stuff that doesn't support custom properties + if (!(entity instanceof Copy)) { + continue; + } + this.hasCopies = true; + copyCount++; + for (const property in entity.copyCustomProps) { + if (!(property in this.changes.customProps)) { + this.changes.customProps[property] = entity.copyCustomProps[property]; + propCount[property] = 1; + } else if (this.changes.customProps[property] !== entity.copyCustomProps[property]) { + this.changes.customProps[property] = this.multipleType; + propCount[property] ++; + } else { + propCount[property] ++; + } + } + } + // check if some copies did not have particular custom properties and mark such as (Multiple) + for (const property in propCount) { + if (propCount[property] !== copyCount) { + this.changes.customProps[property] = this.multipleType; + console.log(`Marked property '${property}' as multiple, got ${propCount[property]} properties for ${copyCount} copies`); + } + } + this.update(); + }; + + // an ID to use as newly created property names + this.currentId = 1; + this.renameProp = e => { + const {prop, val} = e.item; + const newName = e.target.value.trim(); + delete this.changes.customProps[prop]; + this.changes.customProps[newName] = val; + }; + this.changeValue = e => { + const {prop} = e.item; + // attempt to parse the value + // only strings will be unparsable with the JSON.parse method + let trueValue; + try { + trueValue = JSON.parse(e.target.value); // JSON, number, boolean + } catch { + trueValue = e.target.value; // string + } + this.changes.customProps[prop] = trueValue; + }; + this.addCustomProperty = () => { + this.changes.customProps['newProperty' + this.currentId] = ''; + this.currentId++; + }; + this.deleteCustomProperty = (prop) => e => { + delete this.changes.customProps[prop]; + this.applyChanges(); + }; + + this.reservedProps = [ + '_accessibleActive', + '_accessibleDiv', + '_bounds', + '_boundsID', + '_boundsRect', + '_cachedTint', + '_destroyed', + '_enabledFilters', + '_height', + '_lastSortedIndex', + '_localBounds', + '_localBoundsRect', + '_mask', + '_tempDisplayObjectParent', + '_tintedCanvas', + '_width', + '_zIndex', + 'accessible', + 'accessibleChildren', + 'accessibleHint', + 'accessiblePointerEvents', + 'accessibleTitle', + 'accessibleType', + 'alpha', + 'anchor', + 'angle', + 'animationSpeed', + 'autoUpdate', + 'blendMode', + 'buttonMode', + 'cacheAsBitmap', + 'children', + 'currentFrame', + 'cursor', + 'filterArea', + 'filters', + 'height', + 'hitArea', + 'interactive', + 'interactiveChildren', + 'isMask', + 'isSprite', + 'localTransform', + 'loop', + 'mask', + 'onComplete', + 'onFrameChange', + 'onLoop', + 'parent', + 'pivot', + 'playing', + 'pluginName', + 'position', + 'renderable', + 'rotation', + 'roundPixels', + 'scale', + 'skew', + 'sortableChildren', + 'sortDirty', + 'texture', + 'textures', + 'tint', + 'totalFrames', + 'transform', + 'updateAnchor', + 'visible', + 'width', + 'worldAlpha', + 'worldTransform', + 'worldVisible', + 'x', + 'y', + 'zIndex', + 'fromFrames', + 'fromImages', + '_calculateBounds', + '_onTextureUpdate', + '_recursivePostUpdateTransform', + '_render', + 'addChild', + 'addChildAt', + 'calculateBounds', + 'calculateTrimmedVertices', + 'calculateVertices', + 'containerUpdateTransform', + 'containsPoint', + 'destroy', + 'disableTempParent', + 'displayObjectUpdateTransform', + 'enableTempParent', + 'getBounds', + 'getChildAt', + 'getChildByName', + 'getChildIndex', + 'getGlobalPosition', + 'getLocalBounds', + 'gotoAndPlay', + 'gotoAndStop', + 'onChildrenChange', + 'play', + 'removeChild', + 'removeChildAt', + 'removeChildren', + 'render', + 'renderAdvanced', + 'renderAdvancedWebGL', + 'renderCanvas', + 'renderWebGL', + 'setChildIndex', + 'setParent', + 'setTransform', + 'sortChildren', + 'stop', + 'swapChildren', + 'toGlobal', + 'toLocal', + 'update', + 'updateTransform' + ]; + + this.applyChanges = () => { + if (this.firstRun) { + return; + } + const selection = this.opts.pixieditor.currentSelection || []; + for (const entity of selection) { + // basic properties are applied to everything + for (const property in this.changes.basic) { + const value = this.changes.basic[property]; + if (value === this.multipleType) { + continue; + } + const type = this.basicProps.find(prop => prop.key === property).type; + switch (type) { + case 'xy': + if (value.x !== this.multipleType) { + entity[property].x = value.x; + } + if (value.y !== this.multipleType) { + entity[property].y = value.y; + } + break; + case 'color': + case 'slider': + entity[property] = value; + break; + default: + console.error(`Ignoring unknown property type: ${type}`); + break; + } + } + // Extensions and custom properties are supported for copies only + if (!(entity instanceof Copy)) { + continue; + } + // Write custom properties + for (const property in this.changes.customProps) { + const value = this.changes.customProps[property]; + if (value === this.multipleType) { + continue; + } + entity.copyCustomProps[property] = value; + } + // Custom properties that are missing from the changeset are removed + for (const property in entity.copyCustomProps) { + if (!(property in this.changes.customProps)) { + delete entity.copyCustomProps[property]; + } + } + // Write modded extensions + if (!this.refs.exts) { + // Nothing to write + continue; + } + for (const extension in this.refs.exts.extensions) { + const value = this.changes.exts[extension.key]; + if (value === this.multipleType) { + continue; + } + entity.copyExts[extension.key] = value; + } + } + }; + this.memorizeChanges = () => { + this.opts.pixieditor.history.snapshotTransforms(); + }; + this.writeColorAndMemorize = key => (e, value) => { + this.writeColor(key)(e, value); + this.opts.pixieditor.history.snapshotTransforms(); + } diff --git a/src/riotTags/rooms/room-events-editor.tag b/src/riotTags/rooms/room-events-editor.tag index 97c21783c..1fd2d54e9 100644 --- a/src/riotTags/rooms/room-events-editor.tag +++ b/src/riotTags/rooms/room-events-editor.tag @@ -1,3 +1,6 @@ +// + @attribute room (IRoom) + @attribute onsave (riot function) room-events-editor.aView.flexrow.pad .tall.flexfix.aPanel.pad.room-events-editor-Properties.nogrow .flexfix-body @@ -53,6 +56,5 @@ room-events-editor.aView.flexrow.pad }; this.roomSaveEvents = () => { - this.parent.editingCode = false; - this.parent.update(); + this.opts.onsave(); }; diff --git a/src/riotTags/rooms/room-properties.tag b/src/riotTags/rooms/room-properties.tag new file mode 100644 index 000000000..e1d22a274 --- /dev/null +++ b/src/riotTags/rooms/room-properties.tag @@ -0,0 +1,161 @@ +// + @attribute room + @attribute updatebg (riot function) + @attribute history (History) +room-properties + fieldset + label + b {voc.name} + br + input.wide( + type="text" + onfocus="{rememberValue}" + oninput="{wire('this.opts.room.name')}" + onchange="{recordChange(opts.room, 'name')}" + value="{opts.room.name}" + ) + fieldset + .aPoint2DInput.compact.wide + label + b {voc.width} + br + input.wide( + type="number" min="1" step="8" + onfocus="{rememberValue}" + oninput="{wire('this.opts.room.width')}" + onchange="{recordChange(opts.room, 'width')}" + value="{opts.room.width}" + ) + .aSpacer + label + b {voc.height} + br + input.wide( + type="number" min="1" step="8" + onfocus="{rememberValue}" + oninput="{wire('this.opts.room.height')}" + onchange="{recordChange(opts.room, 'height')}" + value="{opts.room.height}" + ) + fieldset + label.checkbox + input( + type="checkbox" + checked="{opts.room.restrictCamera}" + onchange="{handleToggle(opts.room, 'restrictCamera')}" + ) + span {voc.restrictCamera} + fieldset + .aPoint2DInput.compact.wide(if="{opts.room.restrictCamera}") + label + b {voc.minimumX}: + | + input.compact( + step="{opts.room.gridX}" type="number" + onfocus="{rememberValue}" + oninput="{wire('this.opts.room.restrictMinX')}" + onchange="{recordChange(opts.room, 'restrictMinX')}" + value="{opts.room.restrictMinX === void 0 ? 0 : opts.room.restrictMinX}" + ) + .aSpacer + label + b.nogrow {voc.minimumY}: + | + input.compact( + step="{opts.room.gridY}" type="number" + onfocus="{rememberValue}" + oninput="{wire('this.opts.room.restrictMinY')}" + onchange="{recordChange(opts.room, 'restrictMinY')}" + value="{opts.room.restrictMinY === void 0 ? 0 : opts.room.restrictMinY}" + ) + .aPoint2DInput.compact.wide(if="{opts.room.restrictCamera}") + label + b {voc.maximumX}: + | + input.compact( + step="{opts.room.gridX}" type="number" + onfocus="{rememberValue}" + oninput="{wire('this.opts.room.restrictMaxX')}" + onchange="{recordChange(opts.room, 'restrictMaxX')}" + value="{opts.room.restrictMaxX === void 0 ? opts.room.width : opts.room.restrictMaxX}" + ) + .aSpacer + label + b.nogrow {voc.maximumY}: + | + input.compact( + step="{opts.room.gridY}" type="number" + onfocus="{rememberValue}" + oninput="{wire('this.opts.room.restrictMaxY')}" + onchange="{recordChange(opts.room, 'restrictMaxY')}" + value="{opts.room.restrictMaxY === void 0 ? opts.room.height : opts.room.restrictMaxY}" + ) + + fieldset + b {voc.backgroundColor} + br + color-input.wide(onchange="{changeBgColor}" color="{opts.room.backgroundColor || '#000000'}") + + fieldset + label.block.checkbox + input( + type="checkbox" checked="{opts.room.isUi}" + onchange="{handleToggle(opts.room, 'isUi')}" + ) + b {voc.isUi} + + fieldset + extensions-editor(entity="{opts.room.extends}" type="room" wide="true" compact="true") + + script. + this.namespace = 'roomView'; + this.mixin(window.riotVoc); + this.mixin(window.riotWired); + + var prevValue; + this.rememberValue = e => { + if (e.target.type === 'number') { + prevValue = Number(e.target.value); + } else { + prevValue = e.target.value; + } + }; + this.recordChange = (entity, key) => e => { + if (!this.opts.history) { + return; + } + let value = e.target.value; + if (e.target.type === 'number') { + value = Number(value); + } + this.opts.history.pushChange({ + type: 'propChange', + key, + target: entity, + before: prevValue, + after: value + }); + }; + + this.changeBgColor = (e, color) => { + const prevChange = this.opts.room.backgroundColor; + this.opts.updatebg(e, color); + this.opts.history.pushChange({ + type: 'propChange', + key: 'backgroundColor', + target: this.opts.room, + before: prevChange, + after: this.opts.room.backgroundColor + }); + }; + this.handleToggle = (entity, key) => e => { + const prevValue = entity[key]; + entity[key] = !entity[key]; + this.opts.history.pushChange({ + type: 'propChange', + key, + target: entity, + before: prevValue, + after: entity[key] + }); + }; diff --git a/src/riotTags/rooms/room-template-picker.tag b/src/riotTags/rooms/room-template-picker.tag new file mode 100644 index 000000000..2be51b586 --- /dev/null +++ b/src/riotTags/rooms/room-template-picker.tag @@ -0,0 +1,23 @@ +// + @attribute onselect (riot function) + This function is called when a template is selected. + The only argument passed to this function is the selected template. + @attribute selected (ITemplate | -1) + Currently selected template, piped back from the room editor +room-template-picker + asset-viewer( + collection="{currentProject.templates}" + namespace="templates" + assettype="templates" + forcelayout="list" + click="{selectTemplate}" + thumbnails="{thumbnails}" + compact="true" + shownone="true" + selected="{opts.selected}" + ) + script. + this.thumbnails = require('./data/node_requires/resources/templates').getTemplatePreview; + this.selectTemplate = template => () => { + this.opts.onselect(template); + }; diff --git a/src/riotTags/rooms/room-tile-editor.tag b/src/riotTags/rooms/room-tile-editor.tag index e6bd5224f..8e4a1e43b 100644 --- a/src/riotTags/rooms/room-tile-editor.tag +++ b/src/riotTags/rooms/room-tile-editor.tag @@ -1,34 +1,56 @@ -room-tile-editor.room-editor-Tiles.tabbed.tall.flexfix +// + @attribute layer (TileLayer) + A pixi.js container with all its tiles. + @attribute layers (Iterable) + All exising tile layers in the current room. + @attribute pixieditor (RoomEditor) + When other attributes are not enough + + @attribute onchangetile (riot function) + Called with ITileSelection instance as its only argument + @attribute onchangelayer (riot function) + Called with TileLayer as its only argument. + + @attribute addlayer (riot function) + Called when a user wants to add a layer. + The only argument is an ITileLayerTemplate instance. + +room-tile-editor.room-editor-Tiles.flexfix(class="{opts.class}") + .flexfix-header + button.inline.wide(onclick="{openTextureSelector}") + svg.feather + use(xlink:href="#search") + span {voc.findTileset} .flexfix-body - canvas( + canvas.room-tile-editor-aCanvas( ref="tiledImage" - onmousedown="{startTileSelection}" - onmouseup="{stopTileSelection}" - onmousemove="{moveTileSelection}" + onpointerdown="{startTileSelection}" + onpointerup="{stopTileSelection}" + onpointermove="{moveTileSelection}" ) .flexfix-footer - button.inline.wide(onclick="{switchTiledImage}") + ul.aMenu.room-tile-editor-aLayerList + li.checkbox(each="{layer in opts.layers}" onclick="{changeTileLayer}" class="{active: layer === parent.opts.layer}") + input(type="checkbox" name="tileLayers" checked="{layer.alpha === 1}" onchange="{toggleTileLayer}") + b {layer.zIndex} + span.a(title="{parent.voc.moveTileLayer}") + svg.feather(onclick="{moveTileLayer}") + use(xlink:href="#shuffle") + span.a(title="{parent.vocGlob.delete}") + svg.feather(onclick="{deleteTileLayer}") + use(xlink:href="#trash") + button.inline.wide(onclick="{addTileLayer}") svg.feather - use(xlink:href="#search") - span {voc.findTileset} - .flexrow - select.wide(onchange="{changeTileLayer}" value="{parent.currentTileLayerId}") - option(each="{layer, ind in opts.room.tiles}" selected="{parent.currentTileLayerId === ind}" value="{ind}") {layer.hidden? '❌' : '✅'} {layer.depth} - - span.act(title="{vocGlob.delete}" onclick="{deleteTileLayer}") - svg.feather - use(xlink:href="#trash") - span.act(title="{parent.currentTileLayer.hidden? voc.show: voc.hide}" onclick="{toggleTileLayer}") - svg.feather - use(xlink:href="#{parent.currentTileLayer.hidden? 'eye' : 'eye-off'}") - span.act(title="{voc.moveTileLayer}" onclick="{moveTileLayer}") - svg.feather - use(xlink:href="#shuffle") - span.act(title="{vocGlob.add}" onclick="{addTileLayer}") - svg.feather - use(xlink:href="#plus") + use(xlink:href="#plus") + span {voc.addTileLayer || vocGlob.add} .block - extensions-editor(type="tileLayer" entity="{parent.currentTileLayer.extends}" compact="yep" wide="sure") + extensions-editor( + if="{opts.layer}" + type="tileLayer" + entity="{opts.layer.extends}" + compact="true" + wide="true" + ) asset-selector( ref="tilesetPicker" if="{pickingTileset}" @@ -37,43 +59,35 @@ room-tile-editor.room-editor-Tiles.tabbed.tall.flexfix onselected="{onTilesetSelected}" ) script. - this.parent.tileX = 0; - this.parent.tileY = 0; - this.parent.tileSpanX = 1; - this.parent.tileSpanY = 1; - if (!('tiles' in this.opts.room) || !this.opts.room.tiles.length) { - this.opts.room.tiles = [{ - depth: -10, - tiles: [], - extends: {} - }]; - this.parent.resortRoom(); - } - [this.parent.currentTileLayer] = this.opts.room.tiles; - this.parent.currentTileLayerId = 0; + this.tileX = 0; + this.tileY = 0; + this.tileSpanX = 1; + this.tileSpanY = 1; this.namespace = 'roomTiles'; this.mixin(window.riotVoc); this.mixin(window.riotWired); - this.deleteTileLayer = () => { + this.on('update', () => { + if (!this.opts.layer && this.opts.layers.length) { + this.opts.onchangelayer(this.opts.layers[0]); + this.update(); + } else if (this.opts.layer && !this.opts.layers.length) { + this.opts.onchangelayer(void 0); + this.update(); + } + }); + + this.deleteTileLayer = e => { + const {layer} = e.item; window.alertify .okBtn(window.languageJSON.common.delete) .cancelBtn(window.languageJSON.common.cancel) .confirm(window.languageJSON.common.confirmDelete.replace('{0}', window.languageJSON.common.tileLayer)) .then(e => { if (e.buttonClicked === 'ok') { - var tiles = this.opts.room; - var index = tiles.tiles.indexOf(this.parent.currentTileLayer); - tiles.tiles.splice(index, 1); - if (tiles.tiles.length) { - [this.parent.currentTileLayer] = tiles.tiles; - this.parent.currentTileLayerId = 0; - } else { - this.parent.currentTileLayer = false; - } - this.parent.resortRoom(); - this.parent.refreshRoomCanvas(); + layer.detach(true); + this.opts.onchangelayer(this.opts.layers[0]); this.update(); window.alertify .okBtn(window.languageJSON.common.ok) @@ -81,15 +95,25 @@ room-tile-editor.room-editor-Tiles.tabbed.tall.flexfix } }); }; - this.moveTileLayer = () => { + this.moveTileLayer = e => { + const {layer} = e.item; window.alertify - .defaultValue(this.parent.currentTileLayer.depth) + .defaultValue(layer.zIndex) + .okBtn(window.languageJSON.common.ok) + .cancelBtn(window.languageJSON.common.cancel) .prompt(window.languageJSON.roomView.newDepth) .then(e => { if (e.inputValue && Number(e.inputValue)) { - this.parent.currentTileLayer.depth = Number(e.inputValue); - this.parent.resortRoom(); - this.parent.refreshRoomCanvas(); + const before = layer.zIndex; + layer.zIndex = Number(e.inputValue); + this.opts.layers.sort((a, b) => b.zIndex - a.zIndex); + this.opts.pixieditor.history.pushChange({ + type: 'propChange', + key: 'zIndex', + target: layer, + before, + after: layer.zIndex + }); this.update(); } }); @@ -100,71 +124,68 @@ room-tile-editor.room-editor-Tiles.tabbed.tall.flexfix .prompt(window.languageJSON.roomView.newDepth) .then(e => { if (e.inputValue && Number(e.inputValue)) { - var layer = { + const layer = { depth: Number(e.inputValue), tiles: [], extends: {} }; - this.opts.room.tiles.push(layer); - this.parent.currentTileLayer = layer; - this.parent.currentTileLayerId = this.opts.room.tiles.length - 1; - this.parent.resortRoom(); + const pixiTileLayer = this.opts.addlayer(layer, true); + this.opts.onchangelayer(pixiTileLayer); this.update(); } }); }; this.toggleTileLayer = () => { - this.parent.currentTileLayer.hidden = !this.parent.currentTileLayer.hidden; - this.parent.refreshRoomCanvas(); + this.opts.layer.visible = !this.opts.layer.visible; }; this.changeTileLayer = e => { - this.parent.currentTileLayer = this.opts.room.tiles[Number(e.target.value)]; - if (!this.parent.currentTileLayer.extends) { - this.parent.currentTileLayer.extends = {}; - } - this.parent.currentTileLayerId = Number(e.target.value); + this.opts.onchangelayer(e.item.layer); }; - this.switchTiledImage = () => { + this.openTextureSelector = () => { this.pickingTileset = true; }; this.onTilesetCancel = () => { this.pickingTileset = false; this.update(); }; - this.onTilesetSelected = textureId => { - const textures = require('./data/node_requires/resources/textures'); - this.parent.currentTileset = textures.getById(textureId); + this.onTilesetSelected = async textureId => { + const {getById, getDOMImage} = require('./data/node_requires/resources/textures'); + this.currentTexture = getById(textureId); this.pickingTileset = false; + this.update(); + this.currentTextureImg = await getDOMImage(this.currentTexture); this.redrawTileset(); + this.tileX = this.tileY = 0; + this.tileSpanX = this.tileSpanY = 1; + this.sendTileSelection(); this.update(); }; this.redrawTileset = () => { - const glob = require('./data/node_requires/glob'); var c = this.refs.tiledImage, cx = c.getContext('2d'), - g = this.parent.currentTileset, - i = glob.texturemap[g.uid]; - c.width = i.width; - c.height = i.height; + tex = this.currentTexture, + img = this.currentTextureImg; + c.width = img.width; + c.height = img.height; if (global.currentProject.settings.rendering.pixelatedrender) { c.style.imageRendering = 'pixelated'; } else { c.style.imageRendering = 'unset'; } cx.globalAlpha = 1; - cx.drawImage(i, 0, 0); + cx.drawImage(img, 0, 0); cx.strokeStyle = '#0ff'; cx.lineWidth = 1; cx.globalAlpha = 0.5; cx.globalCompositeOperation = 'exclusion'; - for (let i = 0, l = Math.min(g.grid[0] * g.grid[1], g.untill || Infinity); i < l; i++) { - const xx = i % g.grid[0], - yy = Math.floor(i / g.grid[0]), - x = g.offx + xx * (g.marginx + g.width), - y = g.offy + yy * (g.marginy + g.height), - w = g.width, - h = g.height; + for (let i = 0, l = Math.min(tex.grid[0] * tex.grid[1], tex.untill || Infinity); i < l; i++) { + const xx = i % tex.grid[0], + yy = Math.floor(i / tex.grid[0]), + x = tex.offx + xx * (tex.marginx + tex.width), + y = tex.offy + yy * (tex.marginy + tex.height), + w = tex.width, + h = tex.height; cx.strokeRect(x, y, w, h); } cx.globalCompositeOperation = 'source-over'; @@ -172,33 +193,33 @@ room-tile-editor.room-editor-Tiles.tabbed.tall.flexfix cx.lineJoin = 'round'; cx.strokeStyle = localStorage.UItheme === 'Night' ? '#44dbb5' : '#446adb'; cx.lineWidth = 3; - const selX = g.offx + this.parent.tileX * (g.width + g.marginx), - selY = g.offy + this.parent.tileY * (g.height + g.marginy), - selW = g.width * this.parent.tileSpanX + g.marginx * (this.parent.tileSpanX - 1), - selH = g.height * this.parent.tileSpanY + g.marginy * (this.parent.tileSpanY - 1); + const selX = tex.offx + this.tileX * (tex.width + tex.marginx), + selY = tex.offy + this.tileY * (tex.height + tex.marginy), + selW = tex.width * this.tileSpanX + tex.marginx * (this.tileSpanX - 1), + selH = tex.height * this.tileSpanY + tex.marginy * (this.tileSpanY - 1); cx.strokeRect(-0.5 + selX, -0.5 + selY, selW + 1, selH + 1); cx.strokeStyle = localStorage.UItheme === 'Night' ? '#1C2B42' : '#fff'; cx.lineWidth = 1; cx.strokeRect(-0.5 + selX, -0.5 + selY, selW + 1, selH + 1); }; this.startTileSelection = e => { - if (!this.parent.currentTileset) { + if (!this.currentTexture) { return; } // Adjust the pointer coordinates to account for potential scaling const bbox = e.target.getBoundingClientRect(); const px = e.layerX / bbox.width * e.target.width, py = e.layerY / bbox.height * e.target.height; - var g = this.parent.currentTileset; - this.parent.tileSpanX = 1; - this.parent.tileSpanY = 1; + const tex = this.currentTexture; + this.tileSpanX = 1; + this.tileSpanY = 1; this.selectingTile = true; - this.tileStartX = Math.round((px - g.offx - g.width * 0.5) / (g.width + g.marginx)); - this.tileStartX = Math.max(0, Math.min(g.grid[0], this.tileStartX)); - this.tileStartY = Math.round((py - g.offy - g.height * 0.5) / (g.height + g.marginy)); - this.tileStartY = Math.max(0, Math.min(g.grid[1], this.tileStartY)); - this.parent.tileX = this.tileStartX; - this.parent.tileY = this.tileStartY; + this.tileStartX = Math.round((px - tex.offx - tex.width * 0.5) / (tex.width + tex.marginx)); + this.tileStartX = Math.max(0, Math.min(tex.grid[0], this.tileStartX)); + this.tileStartY = Math.round((py - tex.offy - tex.height * 0.5) / (tex.height + tex.marginy)); + this.tileStartY = Math.max(0, Math.min(tex.grid[1], this.tileStartY)); + this.tileX = this.tileStartX; + this.tileY = this.tileStartY; this.redrawTileset(); }; this.moveTileSelection = e => { @@ -209,21 +230,32 @@ room-tile-editor.room-editor-Tiles.tabbed.tall.flexfix const bbox = e.target.getBoundingClientRect(); const px = e.layerX / bbox.width * e.target.width, py = e.layerY / bbox.height * e.target.height; - var g = this.parent.currentTileset; - this.tileEndX = Math.round((px - g.offx - g.width * 0.5) / (g.width + g.marginx)); - this.tileEndX = Math.max(0, Math.min(g.grid[0], this.tileEndX)); - this.tileEndY = Math.round((py - g.offy - g.height * 0.5) / (g.height + g.marginy)); - this.tileEndY = Math.max(0, Math.min(g.grid[1], this.tileEndY)); - this.parent.tileSpanX = 1 + Math.abs(this.tileStartX - this.tileEndX); - this.parent.tileSpanY = 1 + Math.abs(this.tileStartY - this.tileEndY); - this.parent.tileX = Math.min(this.tileStartX, this.tileEndX); - this.parent.tileY = Math.min(this.tileStartY, this.tileEndY); + const tex = this.currentTexture; + this.tileEndX = Math.round((px - tex.offx - tex.width * 0.5) / (tex.width + tex.marginx)); + this.tileEndX = Math.max(0, Math.min(tex.grid[0], this.tileEndX)); + this.tileEndY = Math.round((py - tex.offy - tex.height * 0.5) / (tex.height + tex.marginy)); + this.tileEndY = Math.max(0, Math.min(tex.grid[1], this.tileEndY)); + this.tileSpanX = 1 + Math.abs(this.tileStartX - this.tileEndX); + this.tileSpanY = 1 + Math.abs(this.tileStartY - this.tileEndY); + this.tileX = Math.min(this.tileStartX, this.tileEndX); + this.tileY = Math.min(this.tileStartY, this.tileEndY); this.redrawTileset(); }; + this.stopTileSelection = e => { if (!this.selectingTile) { return; } this.moveTileSelection(e); + this.sendTileSelection(); this.selectingTile = false; }; + this.sendTileSelection = () => { + this.opts.onchangetile({ + startX: this.tileX, + startY: this.tileY, + spanX: this.tileSpanX, + spanY: this.tileSpanY, + texture: this.currentTexture + }); + }; diff --git a/src/riotTags/rooms/room-type-picker.tag b/src/riotTags/rooms/room-type-picker.tag deleted file mode 100644 index c20849b85..000000000 --- a/src/riotTags/rooms/room-type-picker.tag +++ /dev/null @@ -1,89 +0,0 @@ -room-template-picker.room-editor-TemplateSwatches.tabbed.tall - .aSearchWrap - input.inline(type="text" onkeyup="{fuseSearch}" ref="fusesearch") - svg.feather - use(xlink:href="#search") - .room-editor-aTemplateSwatch( - if="{!searchResults}" - onclick="{parent.roomUnpickTemplate}" - class="{active: opts.current === -1}" - ) - span {voc.selectAndMove} - svg.feather - use(xlink:href="#move") - .room-editor-aTemplateSwatch( - each="{template in (searchResults? searchResults : templates)}" - title="{template.name}" - onclick="{selectTemplate(template)}" - class="{active: parent.opts.current === template}" - ) - span {template.name} - img( - src="{template.texture === -1? 'data/img/notexture.png' : (glob.texturemap[template.texture].src.split('?')[0] + '_prev.png?' + getTextureRevision(template))}" - draggable="false" - ) - .room-editor-aTemplateSwatch.filler - .room-editor-aTemplateSwatch.filler - .room-editor-aTemplateSwatch.filler - .room-editor-aTemplateSwatch.filler - .room-editor-aTemplateSwatch.filler - .room-editor-aTemplateSwatch.filler - .room-editor-aTemplateSwatch.filler - - script. - const glob = require('./data/node_requires/glob'); - this.glob = glob; - this.namespace = 'roomView'; - this.mixin(window.riotVoc); - this.mixin(window.riotWired); - - this.getTextureRevision = template => glob.texturemap[template.texture].g.lastmod; - - const fuseOptions = { - shouldSort: true, - tokenize: true, - threshold: 0.5, - location: 0, - distance: 100, - maxPatternLength: 32, - minMatchCharLength: 1, - keys: ['name'] - }; - const Fuse = require('fuse.js'); - this.fuseSearch = e => { - if (!this.mounted) { - this.searchResults = null; - return; - } - var val = (e ? e.target.value : this.refs.fusesearch.value).trim(); - if (val) { - var fuse = new Fuse(this.templates, fuseOptions); - this.searchResults = fuse.search(val); - } else { - this.searchResults = null; - } - }; - this.selectTemplate = template => () => { - this.parent.currentTemplate = template; - this.parent.selectedCopies = false; - }; - - this.updateTemplateList = () => { - this.templates = [...global.currentProject.templates]; - this.templates.sort((a, b) => a.name.localeCompare(b.name)); - this.fuseSearch(); - }; - this.updateTemplateList(); - var templatesChanged = () => { - this.updateTemplateList(); - this.update(); - }; - - window.signals.on('templatesChanged', templatesChanged); - this.on('unmount', () => { - window.signals.off('templatesChanged', templatesChanged); - }); - - this.on('mount', () => { - this.mounted = true; - }); diff --git a/src/riotTags/rooms/rooms-panel.tag b/src/riotTags/rooms/rooms-panel.tag index 8fdbc8a03..914d7b7f9 100644 --- a/src/riotTags/rooms/rooms-panel.tag +++ b/src/riotTags/rooms/rooms-panel.tag @@ -15,7 +15,7 @@ rooms-panel.aPanel.aView svg.feather use(xlink:href="#plus") span {parent.voc.create} - room-editor(if="{editing}" room="{editingRoom}") + room-editor(if="{editing}" room="{editingRoom}" onclose="{closeRoomEditor}") context-menu(menu="{roomMenu}" ref="roomMenu") script. const generateGUID = require('./data/node_requires/generateGUID'); @@ -44,6 +44,11 @@ rooms-panel.aPanel.aView this.editingRoom = room; this.editing = true; }; + this.closeRoomEditor = () => { + this.editingRoom = void 0; + this.editing = false; + this.update(); + }; this.roomMenu = { items: [{ diff --git a/src/riotTags/shared/asset-input.tag b/src/riotTags/shared/asset-input.tag index 9ed4fc1f4..499383d00 100644 --- a/src/riotTags/shared/asset-input.tag +++ b/src/riotTags/shared/asset-input.tag @@ -78,11 +78,12 @@ asset-input } this.openAsset = e => { - e.stopPropagation(); window.orders.trigger('openAsset', `${this.opts.assettype}/${this.currentAsset.uid}`); + e.stopPropagation(); }; - this.openSelector = () => { + this.openSelector = e => { this.showingSelector = true; + e.stopPropagation(); }; this.closeSelector = () => { this.showingSelector = false; diff --git a/src/riotTags/shared/asset-selector.tag b/src/riotTags/shared/asset-selector.tag index c4e40c558..cd65f5ca6 100644 --- a/src/riotTags/shared/asset-selector.tag +++ b/src/riotTags/shared/asset-selector.tag @@ -58,8 +58,9 @@ asset-selector.aDimmer.pointer.pad.fadein(onclick="{closeOnDimmer}" ref="dimmer" this.opts.oncancelled(); } } + e.stopPropagation(); }; - this.onAssetPicked = asset => () => { + this.onAssetPicked = asset => e => { if (this.opts.onselected) { if (asset === -1) { this.opts.onselected(-1); @@ -67,4 +68,5 @@ asset-selector.aDimmer.pointer.pad.fadein(onclick="{closeOnDimmer}" ref="dimmer" this.opts.onselected(asset.uid); } } + e.stopPropagation(); }; diff --git a/src/riotTags/shared/asset-viewer.tag b/src/riotTags/shared/asset-viewer.tag index c4e27f517..d8f3d4ae2 100644 --- a/src/riotTags/shared/asset-viewer.tag +++ b/src/riotTags/shared/asset-viewer.tag @@ -7,38 +7,45 @@ @attribute class (string) This tag has its own CSS classes, but allows arbitrary ones added as an attribute. - @attribute namespace (string) + @attribute [namespace] (string) A unique namespace used to store settings. Fallbacks to 'default'. - @attribute defaultlayout (string) + @attribute [defaultlayout] (string) The default listing layout used if the user has not selected one yet. Can be "cards", "list", "largeCards". + @attribute [forcelayout] (string) + Similar to [defaultlayout] + @attribute [compact] (atomic) + If set, the viewer hides several elements to fit in a more tight layout. @attribute assettype (string) The type of assets shown. The attribute is needed for groups to function. @attribute collection (riot function) A collection of items to iterate over while generating markup, sorting and firing events. - @attribute names (riot function) + @attribute [shownone] (atomic) + If set, shows a "none" asset that returns -1 in opts.click event. + @attribute [selected] (IAsset | -1) + Currently selected asset. If set, it will be highlighted in UI. + + @attribute [names] (riot function) A mapping funtion that takes a collection object and returns its human-readable name. Fallbacks to `item.name` if not defined. - @attribute thumbnails (riot function) + @attribute [thumbnails] (riot function) A mapping funtion that takes a collection object and returns a url for its thumbnail. The function is passed with the collection object, `true` or `false` depending on whether the large-card view is active, and `false`, which match the arguments used to get a URL for the thumbnail of the proper size in many get{X}Preview methods. - @attribute useicons (atomic) + @attribute [useicons] (atomic) Tells the asset viewer to use SVG icons instead of img tag. The `thumbnails` function should then return the name of the SVG icon. - @attribute shownone (atomic) - If set, shows a "none" asset that returns -1 in opts.click event. - - @attribute icons (riot function) + @attribute [icons] (riot function) A mapping funtion that takes a collection object and returns an array of icon names. The icons are shown near the asset's name and are used to convey some metadata. + @attribute click (riot function) A two-fold callback (item => e => {…}) fired when a user clicks on an item, passing the associated collection object as its only argument in the first function, and a MouseEvent in a second function - @attribute contextmenu (riot function) + @attribute [contextmenu] (riot function) A two-fold callback (item => e => {…}) that is given a collection object as its only argument in the first function, and a MouseEvent in a second function, when a user tries to call a context menu on an item. @@ -51,11 +58,11 @@ category is selected. Otherwise, groups are meant to be distinguished by their `uid` property. -asset-viewer.flexfix(class="{opts.namespace} {opts.class}") +asset-viewer.flexfix(class="{opts.namespace} {opts.class} {compact: opts.compact}") .flexfix-header - .toright - b {vocGlob.sort} - .aButtonGroup + .toright(class="{flexrow: opts.compact}") + b(if="{!opts.compact}") {vocGlob.sort} + .aButtonGroup.nml button.inline.square( onclick="{switchSort('date')}" class="{selected: sort === 'date' && !searchResults}" @@ -68,17 +75,17 @@ asset-viewer.flexfix(class="{opts.namespace} {opts.class}") ) svg.feather use(xlink:href="#sort-alphabetically") - .aSearchWrap + .aSearchWrap(style="{opts.compact ? 'width: auto;' : ''}") input.inline(type="text" onkeyup="{fuseSearch}") svg.feather use(xlink:href="#search") - button.inline.square(onclick="{switchLayout}") + button.inline.square(if="{!opts.forcelayout}" onclick="{switchLayout}") svg.feather use(xlink:href="#{layoutToIconMap[currentLayout]}") - button.inline.square.nogrow(onclick="{addNewGroup}") + button.inline.square.nogrow.nmr(onclick="{addNewGroup}") svg.feather use(xlink:href="#folder-plus") - span {voc.addNewGroup} + span(if="{!opts.compact}") {voc.addNewGroup} .toleft .clear @@ -86,6 +93,7 @@ asset-viewer.flexfix(class="{opts.namespace} {opts.class}") .aSpacer ul.Cards.nmt( if="{opts.assettype}" + class="{list: opts.compact}" ) li.aCard( onclick="{openGroup({isUngroupedGroup: true})}" @@ -116,14 +124,15 @@ asset-viewer.flexfix(class="{opts.namespace} {opts.class}") use(xlink:href="data/img/weirdFoldersIllustration.svg#illustration") br span {vocGlob.nothingToShowFiller} - ul.Cards(class="{layoutToClassListMap[currentLayout]}") - li.aCard(if="{opts.shownone}" onclick="{opts.click && opts.click(-1)}") + ul.Cards(class="{layoutToClassListMap[opts.forcelayout || currentLayout]}") + li.aCard(if="{opts.shownone}" onclick="{opts.click && opts.click(-1)}" class="{active: opts.selected === -1}") .aCard-aThumbnail img(src="data/img/notexture.png") .aCard-Properties span {vocGlob.none} li.aCard( each="{asset in (searchResults? searchResults : getGrouped(collection))}" + class="{active: opts.selected === asset}" oncontextmenu="{parent.opts.contextmenu && parent.opts.contextmenu(asset)}" onlong-press="{parent.opts.contextmenu && parent.opts.contextmenu(asset)}" onclick="{parent.opts.click && parent.opts.click(asset)}" @@ -143,7 +152,7 @@ asset-viewer.flexfix(class="{opts.namespace} {opts.class}") .asset-viewer-Icons(if="{parent.opts.icons}") svg.feather(each="{icon in parent.opts.icons(asset)}" class="feather-{icon}") use(xlink:href="#{icon}") - span.date(if="{asset.lastmod}") {niceTime(asset.lastmod)} + span.date(if="{asset.lastmod && !parent.opts.compact}") {niceTime(asset.lastmod)} group-editor( if="{showingGroupEditor}" onapply="{closeGroupEditor}" diff --git a/src/riotTags/shared/collapsible-section.tag b/src/riotTags/shared/collapsible-section.tag index c66631211..52a0460a7 100644 --- a/src/riotTags/shared/collapsible-section.tag +++ b/src/riotTags/shared/collapsible-section.tag @@ -11,33 +11,35 @@ @attribute [heading] (string) The heading to display - @attribute hlevel (integer) + @attribute [hlevel] (integer) A heading level from 1 to 7. Can be empty; if it is, a regular h3 is shown. - @attribute defaultstate ("opened"|"closed") + @attribute [icon] (string) + An icon that will be displayed instead of the default chevron. + @attribute [defaultstate] ("opened"|"closed") Sets the default state of the section. If it is not set, the section will appear closed. - @attribute storestatekey (string) + @attribute [storestatekey] (string) If set, remembers the state of this section in localStorage under the specified key. - @attribute preservedom (atomic) + @attribute [preservedom] (atomic) Whether or not to hide the content instead of removing it from DOM. It is recommended to turn this on for larger layouts. - @attribute ontoggle (riot function) + @attribute [ontoggle] (riot function) A callback that triggers when a user folds/unfolds the section. Passes the new state and this tag as two arguments. collapsible-section(class="{opts.class} {opened ? 'opened' : 'closed'}") - .flexrow(onclick="{toggle}") - span(if="{opts.heading}") - h1(if="{opts.hlevel == 1}") {opts.heading} - h2(if="{opts.hlevel == 2}") {opts.heading} - h3(if="{opts.hlevel == 3 || !opts.hlevel}") {opts.heading} - h4(if="{opts.hlevel == 4}") {opts.heading} - h5(if="{opts.hlevel == 5}") {opts.heading} - h6(if="{opts.hlevel == 6}") {opts.heading} - h7(if="{opts.hlevel == 7}") {opts.heading} - yield(from="header") + .collapsible-section-aHeader(onclick="{toggle}") + span + h1(if="{opts.heading && opts.hlevel == 1}") {opts.heading} + h2(if="{opts.heading && opts.hlevel == 2}") {opts.heading} + h3(if="{opts.heading && (opts.hlevel == 3 || !opts.hlevel)}") {opts.heading} + h4(if="{opts.heading && opts.hlevel == 4}") {opts.heading} + h5(if="{opts.heading && opts.hlevel == 5}") {opts.heading} + h6(if="{opts.heading && opts.hlevel == 6}") {opts.heading} + h7(if="{opts.heading && opts.hlevel == 7}") {opts.heading} + yield(from="header") svg.feather.a(class="{rotated: this.opened}") - use(xlink:href="#chevron-up") + use(xlink:href="#{opts.icon ? opts.icon : 'chevron-up'}") .collapsible-section-aWrapper(if="{opened || opts.preservedom}" hide="{!opened && opts.preservedom}") script. diff --git a/src/riotTags/shared/context-menu.tag b/src/riotTags/shared/context-menu.tag index ddda3478d..7c3941462 100644 --- a/src/riotTags/shared/context-menu.tag +++ b/src/riotTags/shared/context-menu.tag @@ -31,7 +31,7 @@ context-menu(class="{opened: opts.menu.opened}" ref="root" style="{opts.menu.col use(xlink:href="#{item.icon instanceof Function? item.icon() : item.icon}") input(type="checkbox" checked="{item.checked instanceof Function? item.checked() : item.checked}" if="{item.type === 'checkbox'}") span(if="{!item.type !== 'separator'}") {item.label} - span.hotkey(if="{!item.type !== 'separator' && item.hotkey}") ({item.hotkeyLabel || item.hotkey}) + span.hotkey(if="{!item.type !== 'separator' && (item.hotkey || item.hotkeyLabel)}") ({item.hotkeyLabel || item.hotkey}) svg.feather.context-menu-aChevron(if="{item.submenu && item.type !== 'separator'}") use(xlink:href="#chevron-right") context-menu(if="{item.submenu && item.type !== 'separator'}" menu="{item.submenu}") diff --git a/src/riotTags/shared/error-notice.tag b/src/riotTags/shared/error-notice.tag new file mode 100644 index 000000000..8e8799fd7 --- /dev/null +++ b/src/riotTags/shared/error-notice.tag @@ -0,0 +1,21 @@ +// + @slot + @attribute target +error-notice.anErrorNotice + + script. + const reposition = () => { + let {target} = this.opts; + if (target.root) { + target = target.root; + } + const box = target.getBoundingClientRect(); + this.root.style.top = (box.top + box.height) + 'px'; + this.root.style.left = (box.left + box.width / 2) + 'px'; + }; + this.on('update', reposition); + this.on('mount', reposition); + const interval = setInterval(reposition, 150); + this.on('unmount', () => { + clearInterval(interval); + }); diff --git a/src/riotTags/shared/zoom-slider.tag b/src/riotTags/shared/zoom-slider.tag index f5d25e28b..577dd898d 100644 --- a/src/riotTags/shared/zoom-slider.tag +++ b/src/riotTags/shared/zoom-slider.tag @@ -5,6 +5,8 @@ Calls the funtion when a user changes the zoom value. Passes the new zoom value as the one argument. + @method setZoom + Call this with a new zoom value in percents to manually update this zoom slider. @method zoomIn Call this property to advance the zoom value. This will call opts.onchage callback. @method zoomOut @@ -65,6 +67,11 @@ zoom-slider this.opts.onchanged(this.rawToZoom(e.target.value)); } }; + this.setZoom = newZoom => { + const rawValue = this.zoomToRaw(newZoom); + this.refs.zoomslider.value = rawValue; + this.update(); + }; this.zoomIn = () => { const rawValue = Math.min(Number(this.refs.zoomslider.value) + 10, 100); diff --git a/src/riotTags/sounds/sound-editor.tag b/src/riotTags/sounds/sound-editor.tag index f72fca24e..51d38f37b 100644 --- a/src/riotTags/sounds/sound-editor.tag +++ b/src/riotTags/sounds/sound-editor.tag @@ -53,9 +53,8 @@ sound-editor.aDimmer if (this.nameTaken) { // animate the error notice require('./data/node_requires/jellify')(this.refs.errorNotice); - if (localStorage.disableSounds !== 'on') { - soundbox.play('Failure'); - } + const {soundbox} = require('./data/node_requires/3rdparty/soundbox'); + soundbox.play('Failure'); return false; } diff --git a/src/riotTags/style-editor.tag b/src/riotTags/style-editor.tag index f213fd470..728ab8409 100644 --- a/src/riotTags/style-editor.tag +++ b/src/riotTags/style-editor.tag @@ -284,9 +284,8 @@ style-editor.aPanel.aView if (this.nameTaken) { // animate the error notice require('./data/node_requires/jellify')(this.refs.errorNotice); - if (localStorage.disableSounds !== 'on') { - soundbox.play('Failure'); - } + const {soundbox} = require('./data/node_requires/3rdparty/soundbox'); + soundbox.play('Failure'); return false; } this.styleobj.lastmod = Number(new Date()); diff --git a/src/riotTags/template-editor.tag b/src/riotTags/template-editor.tag index 7c5111e5d..a62718302 100644 --- a/src/riotTags/template-editor.tag +++ b/src/riotTags/template-editor.tag @@ -27,6 +27,10 @@ mixin templateProperties option(value="multiply" selected="{parent.template.blendMode === 'multiply'}") {parent.voc.blendModes.multiply} option(value="screen" selected="{parent.template.blendMode === 'screen'}") {parent.voc.blendModes.screen} fieldset + label.flexrow + b.nogrow.alignmiddle {parent.voc.animationFPS} + .aSpacer.nogrow + input.alignmiddle(type="number" max="60" min="1" step="1" value="{parent.template.animationFPS ?? 60}" onchange="{parent.wire('this.template.animationFPS')}") label.block.checkbox input(type="checkbox" checked="{parent.template.playAnimationOnStart}" onchange="{parent.wire('this.template.playAnimationOnStart')}") span {parent.voc.playAnimationOnStart} @@ -160,9 +164,8 @@ template-editor.aPanel.aView.flexrow this.update(); // animate the error notice require('./data/node_requires/jellify')(this.refs.errorNotice); - if (localStorage.disableSounds !== 'on') { - soundbox.play('Failure'); - } + const {soundbox} = require('./data/node_requires/3rdparty/soundbox'); + soundbox.play('Failure'); return false; } glob.modified = true; @@ -171,6 +174,7 @@ template-editor.aPanel.aView.flexrow this.parent.fillTemplateMap(); this.parent.update(); window.signals.trigger('templatesChanged'); + window.signals.trigger('templateChanged', this.template.uid); return true; }; this.changeCodeTab = scriptableEvent => { diff --git a/src/riotTags/textures/texture-editor.tag b/src/riotTags/textures/texture-editor.tag index 7ef4e1cdf..f835c92f1 100644 --- a/src/riotTags/textures/texture-editor.tag +++ b/src/riotTags/textures/texture-editor.tag @@ -856,15 +856,18 @@ texture-editor.aPanel.aView if (this.nameTaken) { // animate the error notice require('./data/node_requires/jellify')(this.refs.errorNotice); - if (localStorage.disableSounds !== 'on') { - soundbox.play('Failure'); - } + const {soundbox} = require('./data/node_requires/3rdparty/soundbox'); + soundbox.play('Failure'); return false; } this.parent.fillTextureMap(); glob.modified = true; this.texture.lastmod = Number(new Date()); - const {textureGenPreview} = require('./data/node_requires/resources/textures'); + const {textureGenPreview, updatePixiTexture} = require('./data/node_requires/resources/textures'); + updatePixiTexture(this.texture) + .then(() => { + window.signals.trigger('pixiTextureChanged', this.texture.uid); + }); textureGenPreview(this.texture, global.projdir + '/img/' + this.texture.origname + '_prev@2.png', 128); textureGenPreview(this.texture, global.projdir + '/img/' + this.texture.origname + '_prev.png', 64) .then(() => { diff --git a/src/riotTags/textures/texture-generator.tag b/src/riotTags/textures/texture-generator.tag index 3a8a2f19d..d9d3bc2c8 100644 --- a/src/riotTags/textures/texture-generator.tag +++ b/src/riotTags/textures/texture-generator.tag @@ -195,9 +195,8 @@ texture-generator.aView if (this.nameTaken) { this.update(); require('./data/node_requires/jellify')(this.refs.errorNotice); - if (localStorage.disableSounds !== 'on') { - soundbox.play('Failure'); - } + const {soundbox} = require('./data/node_requires/3rdparty/soundbox'); + soundbox.play('Failure'); return false; } diff --git a/src/styl/buildingBlocks.styl b/src/styl/buildingBlocks.styl index 4a50fe26d..000d37210 100644 --- a/src/styl/buildingBlocks.styl +++ b/src/styl/buildingBlocks.styl @@ -1,6 +1,9 @@ .aSpacer width 1rem height @width + &.small + width 0.5rem + height @width .aDimmer position fixed @@ -277,6 +280,8 @@ .aCard background background padding 0.8em + &.compact + padding 0.4em 0.8em margin 0 box-sizing border-box border 1px solid borderPale @@ -332,6 +337,16 @@ pointer-events none &:hover img background rgba(act, 0.35) + .aCard.compact & + width 1.5rem + svg + width 1.5rem + height 1.5rem + stroke-width 2 + img + width 2rem + height 2rem + margin -0.25rem 0 -0.25rem -0.25rem .aCard-Actions position absolute top 0.5rem @@ -380,6 +395,9 @@ sounds-panel, rooms-panel th border-bottom 1px solid borderBright text-align left + &.cellsmiddle + td, th + vertical-align middle .aNiceTable margin 1rem 0 border 1px solid borderBright diff --git a/src/styl/common.styl b/src/styl/common.styl index e6b4bcc39..0200d7a60 100644 --- a/src/styl/common.styl +++ b/src/styl/common.styl @@ -188,3 +188,11 @@ icon(icon = 'slash', color = act) color text [css-swatch="backgroundDeeper"] color backgroundDeeper +[css-swatch="background"] + color background +[css-swatch="red"] + color red +[css-swatch="green"] + color green +[css-swatch="orange"] + color orange diff --git a/src/styl/inputs.styl b/src/styl/inputs.styl index 3973dfe81..eea69c34f 100644 --- a/src/styl/inputs.styl +++ b/src/styl/inputs.styl @@ -222,6 +222,25 @@ input[type="reset"], margin 0 button, .button flex 1 1 auto + &.vertical + flex-flow column nowrap + button, .button + margin 0 + border-radius 0 + border-bottom-width 0 + border-right-width 1px + if themeThickBorders + border-right-width 2px + @extend button.square + &:first-child + border-top-left-radius br + border-top-right-radius br + &:last-child + border-bottom-left-radius br + border-bottom-right-radius br + border-bottom-width 1px + if themeThickBorders + border-bottom-width 2px button, input[type="button"], input[type="submit"], @@ -336,6 +355,8 @@ fieldset &::after content '' icon(check, background) + // a hack to fix pixelization of icons in certain context menus + transform scale(1) width 0.85rem height 1rem position absolute diff --git a/src/styl/tags/rooms/room-backgrounds-editor.styl b/src/styl/tags/rooms/room-backgrounds-editor.styl new file mode 100644 index 000000000..f5d4ea756 --- /dev/null +++ b/src/styl/tags/rooms/room-backgrounds-editor.styl @@ -0,0 +1,3 @@ +room-backgrounds-editor + collapsible-section asset-input > .aButtonGroup + margin-right 0 diff --git a/src/styl/tags/rooms/room-copy-properties.styl b/src/styl/tags/rooms/room-copy-properties.styl deleted file mode 100644 index 1d7f834ca..000000000 --- a/src/styl/tags/rooms/room-copy-properties.styl +++ /dev/null @@ -1,9 +0,0 @@ -room-copy-properties - display block - padding 1rem - room-editor &.aPanel - {shadamb} - position absolute - right 1rem - top 4rem - width 20rem \ No newline at end of file diff --git a/src/styl/tags/rooms/room-editor.styl b/src/styl/tags/rooms/room-editor.styl index c86cd3814..e61b31318 100644 --- a/src/styl/tags/rooms/room-editor.styl +++ b/src/styl/tags/rooms/room-editor.styl @@ -1,173 +1,101 @@ room-editor - display flex - flex-direction row - .room-editor-TemplateSwatches .aSearchWrap - display block - flex 1 1 100% - margin 0 0 3px - input - box-sizing border-box - width 100% - font-size 90% - border-radius 0 - .toolbar - display flex - flex-direction column - padding 0.5em - width 17em - box-sizing border-box - flex 0 0 auto - flex-grow 0 - .settings .fifty - padding 0.5rem - .palette - flex 1 1 auto - .settings button - margin 0.5em 0 - .aNav - border-bottom-right-radius 0 - border-bottom-left-radius 0 - .palette - position relative - .tabwrap - position absolute - left 0 - right 0 - top 0 - bottom 0 - .editor - display flex - position relative - flex 1 1 auto - .shift - position absolute - top 0.5rem - left 0.5rem - .zoom - position absolute - top 0.5rem - right 0.5rem - zoom-slider - width 20rem - .grid - position absolute - bottom 0.5rem - right 0.5rem - .center - position absolute - bottom 0.5rem - left 0.5rem - canvas - width 100% - height 100% - -.room-editor-TemplateSwatches, .room-editor-Backgrounds, .room-editor-Tiles - overflow-y scroll - position absolute - width 100% -.room-editor-TemplateSwatches - padding 0 0 0 1px !important - display flex - flex-flow row wrap - align-content start - align-items flex-start -.room-editor-aTemplateSwatch - list-style none - border 1px solid borderPale - flex 1 0 5rem - display inline-block - box-sizing border-box - text-align center - margin -1px 0 0 -1px - cursor pointer - padding 1.75rem 0.4em 0 - font-size 80% - line-height 1.7 - {trans} - position relative - z-index 1 - svg - width 2.5rem - height @width - color act - line-height 3rem - margin 1.35rem auto 0 - display block - padding-bottom 0.5rem - span - display block - text-overflow ellipsis - overflow hidden - width auto + background backgroundDeeper + & > canvas position absolute - left 0.5rem - top 0.25rem - right 0.5rem - &:hover - border-color act - z-index 10 - {transshort} - &.active - border-color accent1 - z-index 10 - img - height 64px - width 64px - &.filler - height 0 - visibility hidden - -.room-editor-Backgrounds - &.tabbed - padding 0.5rem - ul + left 0 + top 0 + width 100% + height 100% + .&-aToolsetHolder + pointer-events none + & > * + pointer-events initial + position absolute + left 0 + right 0 + top 0 + bottom 0 + overflow hidden + padding 1rem + display grid + grid-template-columns auto auto 1fr + grid-gap 0 1rem + align-items start + .&-aToolbar + border-radius br margin 0 - padding 0 - .bg - list-style none - padding 0.3em 0.8em + {shad} + button + border-color borderBright + .&-aContextPanel + @extends .aPanel + display block + width 18rem + padding 1rem border-radius br - border 1px solid borderBright - margin-bottom 0.2em - img - float left - width 64px - height 64px - border-radius br - cursor pointer - margin-right 1rem - & > span - display block - vertical-align middle - margin-top 1em - span - cursor pointer - {trans} - float right - margin-left 0.5rem - .active - color act - label + label - margin-top 0 - .fifty - padding 0.5rem 0.25rem - -.room-editor-Tiles - canvas - cursor pointer - min-width 100% - .act - color text - cursor pointer + overflow auto + z-index 2 + {shadamb} + resize both + min-width 15rem + max-width 50vw // why would you need it any longer + min-height 4rem + max-height calc(100% - 2rem) + .&-aTopPanel + border-radius br + border borderBright + {shad} + display flex + flex-flow row nowrap + background background + width max-content + justify-self center + grid-column 3 + & > * + padding 0.25rem 1rem + box-shadow none + border-top 0 + border-bottom 0 + border-left 0 + border-right 1px solid borderBright + margin 0 + border-radius 0 + &:first-child + border-radius br 0 0 br + &:last-child + border 0 + border-radius 0 br br 0 + & > .slim + padding 0.25rem 0.5rem + & > .checkbox + padding-left 2.5rem + [type="checkbox"] + top 50% + margin-left 1rem + transform translate(0, -50%) + & > zoom-slider + width 10rem + .&-aSelectionToggle display inline-block - padding 0.35rem 0 - line-height 1 - margin-left 0.5rem - {trans} - &:hover - color act - {transshort} - .flexfix-footer button - margin-bottom 0.25rem - select - padding 0.25rem + position relative + padding 0 1rem 0.5rem 0 + cursor pointer + &.active + svg + color act + &:last-child + color accent1 + svg + {trans} + &:last-child + width 1rem + height @width + padding 0.25rem + display block + //background background + border-radius 100% + overflow visible + position absolute + bottom 0 + right 0 + //{shad} diff --git a/src/styl/tags/rooms/room-tile-editor.styl b/src/styl/tags/rooms/room-tile-editor.styl new file mode 100644 index 000000000..ee05996a1 --- /dev/null +++ b/src/styl/tags/rooms/room-tile-editor.styl @@ -0,0 +1,26 @@ +room-tile-editor + .&-aCanvas + min-width 100% + margin 1rem 0 + display block + .&-aLayerList + max-height 10rem + li.checkbox + border-radius br + display flex + padding-left 2rem + padding-right 0.5rem + &:hover + padding-left 2rem + padding-right 0.5rem + [type="checkbox"] + left 0.5rem + * + flex 0 0 auto + b + flex 1 1 auto + .a + margin-left 0.5rem + &.active + background rgba(act, 0.25) + color text diff --git a/src/styl/tags/shared/asset-input.styl b/src/styl/tags/shared/asset-input.styl index 770badcd8..938fe3516 100644 --- a/src/styl/tags/shared/asset-input.styl +++ b/src/styl/tags/shared/asset-input.styl @@ -1,4 +1,20 @@ asset-input + line-height 0 + & > * + line-height 1.5 + & > .aButtonGroup + max-width 100% + :first-child + display flex + flex-flow row nowrap + align-items center + overflow hidden + & img, & svg + flex 0 0 auto + & span + flex 1 1 auto + overflow hidden + text-overflow ellipsis &.wide & > .aButtonGroup @extends .aButtonGroup.wide diff --git a/src/styl/tags/shared/asset-viewer.styl b/src/styl/tags/shared/asset-viewer.styl index adc408f30..cfcd1506f 100644 --- a/src/styl/tags/shared/asset-viewer.styl +++ b/src/styl/tags/shared/asset-viewer.styl @@ -22,3 +22,9 @@ asset-viewer height @width & + svg margin-left 0.5rem + &.compact + .aSearchWrap + flex 1 1 auto + input + width 100% + box-sizing border-box diff --git a/src/styl/tags/shared/collapsible-section.styl b/src/styl/tags/shared/collapsible-section.styl index ca1de5bd3..0adf8c73f 100644 --- a/src/styl/tags/shared/collapsible-section.styl +++ b/src/styl/tags/shared/collapsible-section.styl @@ -3,33 +3,36 @@ collapsible-section display block &:first-child margin-top 0 - & > .flexrow + .&-aHeader padding 0.5rem 0 - align-items center - cursor pointer + align-items center border-bottom 1px solid borderBright - h1, h2, h3, h4, h5, h6 - padding 0 - margin 0 - flex 1 1 auto + display grid + grid-template-columns 1fr auto + grid-gap 0.5rem + & > :first-child + display contents + & > h1, & > h2, & > h3, & > h4, & > h5, & > h6 + padding 0 + margin 0 + overflow hidden + text-overflow ellipsis + white-space nowrap + asset-input overflow hidden - text-overflow ellipsis - white-space nowrap - svg + & > svg {trans} - margin-left 0.5rem flex 0 0 auto - align-self flex-end + cursor pointer &.rotated transform rotate(180deg) .&-aWrapper padding 1rem 0 0.5rem &.aPanel - & > .flexrow - h1, h2, h3, h4, h5, h6 + .collapsible-section-aHeader + padding 0.5rem 1rem + & > h1, & > h2, & > h3, & > h4, & > h5, & > h6 margin 0 1rem - svg - margin-right 0.5rem &.closed > .flexrow border-bottom 0 .collapsible-section-aWrapper diff --git a/src/styl/tags/shared/error-notice.styl b/src/styl/tags/shared/error-notice.styl new file mode 100644 index 000000000..cc1689dd2 --- /dev/null +++ b/src/styl/tags/shared/error-notice.styl @@ -0,0 +1,6 @@ +error-notice.anErrorNotice + position fixed + width 15rem + z-index 10 + transform translate(-50%, 0) + {trans} diff --git a/src/styl/themeSpringStream.styl b/src/styl/themeSpringStream.styl index cbcfa372b..6e07d11ab 100644 --- a/src/styl/themeSpringStream.styl +++ b/src/styl/themeSpringStream.styl @@ -109,6 +109,8 @@ input[type="reset"], color background &.selected background acttext +.aButtonGroup.vertical button, .aButtonGroup.vertical .button + border 0 #theIntroBg background introBg diff --git a/tsconfig.json b/tsconfig.json index 2d4568437..14a6200fb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,16 @@ "module": "umd", "noImplicitAny": true, "moduleResolution": "node", - "baseUrl": "./" + "baseUrl": "./", + "typeRoots": [ + "./node_modules/@types/", + "./app/node_modules/@types/" + ], + "paths": { + "node_modules/*": [ + "./app/node_modules/*", + "./node_modules/*" + ], + } } }

sWh3OUz)CTn(fR^e#pp2T-) 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 HH)Q_@W;*TE literal 0 HcmV?d00001 diff --git a/app/data/ct.libs/place/index.js b/app/data/ct.libs/place/index.js index 0c8830fed..d627888cf 100644 --- a/app/data/ct.libs/place/index.js +++ b/app/data/ct.libs/place/index.js @@ -286,6 +286,9 @@ drawDebugGraphic(absolute) { const shape = this._shape || getSSCDShape(this); const g = this.$cDebugCollision; + const inverse = this.transform.localTransform.clone().invert(); + this.$cDebugCollision.transform.setFromMatrix(inverse); + this.$cDebugCollision.position.set(0, 0); let color = 0x00ffff; if (this instanceof Copy) { color = 0x0066ff; diff --git a/app/data/ct.libs/place/injections/beforedraw.js b/app/data/ct.libs/place/injections/beforedraw.js index 4a73bb439..b50d023df 100644 --- a/app/data/ct.libs/place/injections/beforedraw.js +++ b/app/data/ct.libs/place/injections/beforedraw.js @@ -1,7 +1,9 @@ if ([/*%debugMode%*/][0] && this instanceof ct.templates.Copy) { - this.$cDebugText.scale.x = this.$cDebugCollision.scale.x = 1 / this.scale.x; - this.$cDebugText.scale.y = this.$cDebugCollision.scale.y = 1 / this.scale.y; - this.$cDebugText.angle = this.$cDebugCollision.angle = -this.angle; + const inverse = this.transform.localTransform.clone().invert(); + this.$cDebugCollision.transform.setFromMatrix(inverse); + this.$cDebugCollision.position.set(0, 0); + this.$cDebugText.transform.setFromMatrix(inverse); + this.$cDebugText.position.set(0, 0); const newtext = `Partitions: ${this.$chashes.join(', ')} CGroup: ${this.cgroup || 'unset'} diff --git a/app/data/ct.release/rooms.js b/app/data/ct.release/rooms.js index 4190dec59..ae8ccbb98 100644 --- a/app/data/ct.release/rooms.js +++ b/app/data/ct.release/rooms.js @@ -22,26 +22,28 @@ class Room extends PIXI.Container { ct.room = ct.rooms.current = this; } if (template) { - if (template.extends) { - ct.u.ext(this, template.extends); - } this.onCreate = template.onCreate; this.onStep = template.onStep; this.onDraw = template.onDraw; this.onLeave = template.onLeave; this.template = template; this.name = template.name; + this.isUi = template.isUi; + if (template.extends) { + ct.u.ext(this, template.extends); + } if (this === ct.room) { ct.pixiApp.renderer.backgroundColor = ct.u.hexToPixi(this.template.backgroundColor); } /*%beforeroomoncreate%*/ for (let i = 0, li = template.bgs.length; i < li; i++) { - // Need to put extensions here, so we don't use ct.backgrounds.add + // Need to put additional properties like parallax here, + // so we don't use ct.backgrounds.add const bg = new ct.templates.Background( template.bgs[i].texture, null, template.bgs[i].depth, - template.bgs[i].extends + template.bgs[i] ); this.addChild(bg); } @@ -52,17 +54,22 @@ class Room extends PIXI.Container { this.addChild(tl); } for (let i = 0, li = template.objects.length; i < li; i++) { - const exts = template.objects[i].exts || {}; + const copy = template.objects[i]; + const exts = copy.exts || {}; + const customProperties = copy.customProperties || {}; ct.templates.copyIntoRoom( - template.objects[i].template, - template.objects[i].x, - template.objects[i].y, + copy.template, + copy.x, + copy.y, this, { - tx: template.objects[i].tx, - ty: template.objects[i].ty, - tr: template.objects[i].tr, - ...exts + ...exts, + ...customProperties, + scaleX: copy.scale.x, + scaleY: copy.scale.y, + rotation: copy.rotation, + alpha: copy.opacity, + tint: copy.tint } ); } diff --git a/app/data/ct.release/templates.js b/app/data/ct.release/templates.js index 6961e1c8d..24019b8c4 100644 --- a/app/data/ct.release/templates.js +++ b/app/data/ct.release/templates.js @@ -65,6 +65,7 @@ const Copy = (function Copy() { this.parent = container; this.blendMode = t.blendMode || PIXI.BLEND_MODES.NORMAL; this.loop = t.loopAnimation; + this.animationSpeed = t.animationFPS / 60; if (t.playAnimationOnStart) { this.play(); } @@ -89,14 +90,11 @@ const Copy = (function Copy() { this.timer1 = this.timer2 = this.timer3 = this.timer4 = this.timer5 = this.timer6 = 0; if (exts) { ct.u.ext(this, exts); - if (exts.tx) { - this.scale.x = exts.tx; + if (exts.scaleX) { + this.scale.x = exts.scaleX; } - if (exts.ty) { - this.scale.y = exts.ty; - } - if (exts.tr) { - this.angle = exts.tr; + if (exts.scaleY) { + this.scale.y = exts.scaleY; } } this.uid = ++uid; diff --git a/app/data/ct.release/tilemaps.js b/app/data/ct.release/tilemaps.js index 9928663e0..9ffb427c7 100644 --- a/app/data/ct.release/tilemaps.js +++ b/app/data/ct.release/tilemaps.js @@ -19,15 +19,21 @@ class Tilemap extends PIXI.Container { Object.assign(this, template.extends); } for (let i = 0, l = template.tiles.length; i < l; i++) { - const textures = ct.res.getTexture(template.tiles[i].texture); - const sprite = new PIXI.Sprite(textures[template.tiles[i].frame]); - sprite.anchor.x = sprite.anchor.y = 0; + const tile = template.tiles[i]; + const textures = ct.res.getTexture(tile.texture); + const sprite = new PIXI.Sprite(textures[tile.frame]); + sprite.anchor.x = textures[0].defaultAnchor.x; + sprite.anchor.y = textures[0].defaultAnchor.y; sprite.shape = textures.shape; + sprite.scale.set(tile.scale.x, tile.scale.y); + sprite.rotation = tile.rotation; + sprite.alpha = tile.opacity; + sprite.tint = tile.tint; + sprite.x = tile.x; + sprite.y = tile.y; this.addChild(sprite); this.pixiTiles.push(sprite); this.tiles[i].sprite = sprite; - sprite.x = template.tiles[i].x; - sprite.y = template.tiles[i].y; } } else { this.tiles = []; diff --git a/app/data/cursorErase.svg b/app/data/cursorErase.svg new file mode 100644 index 000000000..c96e113da --- /dev/null +++ b/app/data/cursorErase.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/app/data/cursorRotate.svg b/app/data/cursorRotate.svg new file mode 100644 index 000000000..d2f8adb9d --- /dev/null +++ b/app/data/cursorRotate.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/data/i18n/Brazilian Portuguese.json b/app/data/i18n/Brazilian Portuguese.json index b22be4a88..e56fc4e58 100644 --- a/app/data/i18n/Brazilian Portuguese.json +++ b/app/data/i18n/Brazilian Portuguese.json @@ -67,7 +67,8 @@ "template": "", "room": "", "sound": "", - "tandem": "" + "tandem": "", + "type": "" }, "newName": "Novo nome:", "saveProject": "Salvar projeto", @@ -125,7 +126,9 @@ "", "" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "current": "Novo", @@ -587,7 +590,10 @@ "SpringStream": "Spring Stream", "LucasDracula": "Lucas Dracula", "Horizon": "", - "HCBlack": "" + "HCBlack": "", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "codeFontDefault": "Padrão (Iosevka Light)", "codeFontOldSchool": "Old school", @@ -602,7 +608,10 @@ "translateToYourLanguage": "Traduza o ct.js!", "disableSounds": "Desabilitar sons de UI", "changeDataFolder": "", - "forceProductionForDebug": "" + "forceProductionForDebug": "", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "save": "Salvar projeto", @@ -638,14 +647,36 @@ "sounds": "Sons", "ui": "UI", "fx": "FX", - "templates": "Tipos" - }, - "copyCustomProperties": { - "customProperties": "", - "addProperty": "", - "property": "", - "value": "", - "delete": "" + "templates": "Tipos", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "", @@ -716,7 +747,13 @@ "copyProperties": { "position": "", "rotation": "", - "scale": "" + "scale": "", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "", + "property": "", + "value": "" }, "customProperties": "", "restrictCamera": "", @@ -736,7 +773,19 @@ "deleteTiles": "Remover tiles", "moveTilesToLayer": "Mover para camada", "shiftTiles": "Trocar tiles", - "changeCopyRotation": "Rotacionar" + "changeCopyRotation": "Rotacionar", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Ativo", @@ -869,7 +918,9 @@ "add": "", "multiply": "", "screen": "" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "assetInput": { "changeAsset": "", @@ -889,5 +940,71 @@ "visitAuthorsItch": "", "visitAuthorsTwitter": "", "tipAuthor": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } } \ No newline at end of file diff --git a/app/data/i18n/Chinese Simplified.json b/app/data/i18n/Chinese Simplified.json index e9f0b1729..f501867a3 100644 --- a/app/data/i18n/Chinese Simplified.json +++ b/app/data/i18n/Chinese Simplified.json @@ -67,7 +67,8 @@ "template": "模板", "room": "房间", "sound": "声音", - "tandem": "粒子发射器" + "tandem": "粒子发射器", + "type": "" }, "newName": "新名称", "saveProject": "保存项目", @@ -125,7 +126,9 @@ "骨骼精灵图形", "骨骼精灵图形" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "current": "新建", @@ -542,7 +545,10 @@ "SpringStream": "Spring Stream", "LucasDracula": "Lucas Dracula", "Horizon": "Horizon", - "HCBlack": "High-contrast Black" + "HCBlack": "High-contrast Black", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "newFont": "新字体:", "language": "语言", @@ -552,7 +558,10 @@ "codeDense": "密集布局", "disableSounds": "关闭 UI 音效", "changeDataFolder": "设置数据文件夹位置", - "forceProductionForDebug": "强制生产任务用于调试导出" + "forceProductionForDebug": "强制生产任务用于调试导出", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "heading": "项目", @@ -588,7 +597,36 @@ "restart": "重新启动", "launch": "编译并运行", "launchHotkeys": "(F5; Alt+F5 在默认浏览器中运行)", - "templates": "类型" + "templates": "类型", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "docsPanel": { "documentation": "文档", @@ -640,13 +678,6 @@ "folderNotWritable": "您没有权限写入这个文件夹. 选择其他试试", "complete": "文件夹已设置, 一切正常✅" }, - "copyCustomProperties": { - "customProperties": "自定义属性", - "addProperty": "添加属性", - "property": "属性", - "value": "值", - "delete": "删除" - }, "assetViewer": { "addNewGroup": "新分组", "ungrouped": "显示未分组", @@ -716,7 +747,13 @@ "copyProperties": { "position": "位置", "rotation": "旋转", - "scale": "缩放" + "scale": "缩放", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "添加属性", + "property": "属性", + "value": "值" }, "customProperties": "自定义属性", "restrictCamera": "保持相机在一个矩形中", @@ -736,7 +773,19 @@ "deleteTiles": "删除图块", "moveTilesToLayer": "移至图层", "shiftTiles": "移动瓷砖", - "changeCopyRotation": "旋转" + "changeCopyRotation": "旋转", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "激活", @@ -869,7 +918,9 @@ "add": "掺入 (溶解)", "multiply": "倍增 (变暗)", "screen": "遮蔽 (变亮)" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "assetInput": { "changeAsset": "切换资产", @@ -889,5 +940,71 @@ "visitAuthorsItch": "访问作者的 itch.io 页面", "visitAuthorsTwitter": "访问作者的 Twitter 页面", "tipAuthor": "奖励作者的辛勤工作 :D" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } -} +} \ No newline at end of file diff --git a/app/data/i18n/Comments.json b/app/data/i18n/Comments.json index b3308135e..a610995ab 100644 --- a/app/data/i18n/Comments.json +++ b/app/data/i18n/Comments.json @@ -67,7 +67,8 @@ "template": "", "room": "", "sound": "", - "tandem": "" + "tandem": "", + "type": "" }, "newName": "", "saveProject": "", @@ -125,7 +126,9 @@ "", "" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "current": "", @@ -587,7 +590,10 @@ "SpringStream": "", "LucasDracula": "", "Horizon": "", - "HCBlack": "" + "HCBlack": "", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "codeFontDefault": "", "codeFontOldSchool": "", @@ -602,7 +608,10 @@ "forceProductionForDebug": "", "heading": "", "language": "", - "translateToYourLanguage": "" + "translateToYourLanguage": "", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "save": "", @@ -638,14 +647,36 @@ "fx": "", "restart": "", "project": "", - "templates": "" - }, - "copyCustomProperties": { - "customProperties": "", - "addProperty": "", - "property": "", - "value": "", - "delete": "" + "templates": "", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "", @@ -716,7 +747,13 @@ "copyProperties": { "position": "", "rotation": "", - "scale": "" + "scale": "", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "", + "property": "", + "value": "" }, "customProperties": "", "restrictCamera": "", @@ -736,7 +773,19 @@ "deleteTiles": "", "moveTilesToLayer": "", "shiftTiles": "", - "changeCopyRotation": "" + "changeCopyRotation": "", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "", @@ -869,7 +918,9 @@ "add": "", "multiply": "", "screen": "" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "assetInput": { "changeAsset": "", @@ -889,5 +940,71 @@ "visitAuthorsItch": "", "visitAuthorsTwitter": "", "tipAuthor": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } } \ No newline at end of file diff --git a/app/data/i18n/Debug.json b/app/data/i18n/Debug.json index 1ad1f5a2f..5f0ea7c12 100644 --- a/app/data/i18n/Debug.json +++ b/app/data/i18n/Debug.json @@ -64,7 +64,11 @@ "text": "common.fieldTypes.text", "textfield": "common.fieldTypes.textfield", "texture": "common.fieldTypes.texture", - "type": "common.fieldTypes.type" + "type": "common.fieldTypes.type", + "template": "", + "room": "", + "sound": "", + "tandem": "" }, "newName": "common.newName", "saveProject": "common.saveProject", @@ -77,7 +81,54 @@ "addToNotes": "common.addToNotes", "noRooms": "common.noRooms", "tileLayer": "common.tileLayer", - "ctSite": "common.ctSite" + "ctSite": "common.ctSite", + "docsShort": "", + "docsLong": "", + "openAssetGallery": "", + "assetTypes": { + "textures": [ + "", + "", + "" + ], + "templates": [ + "", + "", + "" + ], + "emitterTandems": [ + "", + "", + "" + ], + "rooms": [ + "", + "", + "" + ], + "fonts": [ + "", + "", + "" + ], + "styles": [ + "", + "", + "" + ], + "sounds": [ + "", + "", + "" + ], + "skeletons": [ + "", + "", + "" + ] + }, + "next": "", + "previous": "" }, "colorPicker": { "current": "colorPicker.current", @@ -97,7 +148,15 @@ "log": "exportPanel.log", "windowsCrossBuildWarning": "exportPanel.windowsCrossBuildWarning", "cannotBuildForMacOnWin": "exportPanel.cannotBuildForMacOnWin", - "firstRunNotice": "exportPanel.firstRunNotice" + "firstRunNotice": "exportPanel.firstRunNotice", + "projectTitleRequired": "", + "appIdRequired": "", + "noAndroidSdkFound": "", + "envVarNotice": "", + "downloadAndroidStudio": "", + "requiresInternetNotice": "", + "noJdkFound": "", + "downloadJDK": "" }, "intro": { "loading": "intro.loading", @@ -132,7 +191,9 @@ "github": "intro.github", "itch": "intro.itch", "vkontakte": "intro.vkontakte", - "patreon": "intro.patreon" + "patreon": "intro.patreon", + "templates": "", + "templatesInfo": "" }, "modules": { "author": "modules.author", @@ -174,7 +235,8 @@ "skeletons": "texture.skeletons", "createTemplate": "texture.createTemplate", "importFromClipboard": "texture.importFromClipboard", - "generatePlaceholder": "texture.generatePlaceholder" + "generatePlaceholder": "texture.generatePlaceholder", + "textures": "" }, "sounds": { "create": "sounds.create", @@ -365,7 +427,9 @@ "site": "settings.authoring.site", "title": "settings.authoring.title", "version": "settings.authoring.version", - "versionPostfix": "settings.authoring.versionPostfix" + "versionPostfix": "settings.authoring.versionPostfix", + "appId": "", + "appIdExplanation": "" }, "branding": { "heading": "settings.branding.heading", @@ -374,7 +438,11 @@ "icon": "settings.branding.icon", "iconNotice": "settings.branding.iconNotice", "invertPreloaderScheme": "settings.branding.invertPreloaderScheme", - "hideLoadingLogo": "settings.branding.hideLoadingLogo" + "hideLoadingLogo": "settings.branding.hideLoadingLogo", + "splashScreen": "", + "splashScreenNotice": "", + "forceSmoothIcons": "", + "forceSmoothSplashScreen": "" }, "modules": { "heading": "settings.modules.heading" @@ -392,7 +460,15 @@ "windowed": "settings.rendering.launchModes.windowed" }, "hideCursor": "settings.rendering.hideCursor", - "pixelatedRender": "settings.rendering.pixelatedRender" + "pixelatedRender": "settings.rendering.pixelatedRender", + "usePixiLegacy": "", + "mobileBuilds": "", + "screenOrientation": "", + "screenOrientations": { + "unspecified": "", + "landscape": "", + "portrait": "" + } }, "scripts": { "heading": "settings.scripts.heading", @@ -434,13 +510,19 @@ "deleteContentType": "settings.content.deleteContentType", "confirmDeletionMessage": "settings.content.confirmDeletionMessage", "gotoEntries": "settings.content.gotoEntries", - "entries": "settings.content.entries" + "entries": "settings.content.entries", + "array": "" }, "contentTypes": "settings.contentTypes" }, "extensionsEditor": { "noEntries": "extensionsEditor.noEntries", - "addRow": "extensionsEditor.addRow" + "addRow": "extensionsEditor.addRow", + "actions": "", + "values": "", + "moveDown": "", + "moveUp": "", + "deleteRow": "" }, "textureGenerator": { "name": "textureGenerator.name", @@ -494,7 +576,8 @@ "exportDesktop": "mainMenu.deploy.exportDesktop", "successZipExport": "mainMenu.deploy.successZipExport", "zipExport": "mainMenu.deploy.zipExport", - "heading": "mainMenu.deploy.heading" + "heading": "mainMenu.deploy.heading", + "exportAndroid": "" }, "latestProjects": { "recentProjects": "mainMenu.latestProjects.recentProjects" @@ -507,7 +590,10 @@ "SpringStream": "mainMenu.settings.themes.SpringStream", "LucasDracula": "mainMenu.settings.themes.LucasDracula", "Horizon": "mainMenu.settings.themes.Horizon", - "HCBlack": "mainMenu.settings.themes.HCBlack" + "HCBlack": "mainMenu.settings.themes.HCBlack", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "codeFontDefault": "mainMenu.settings.codeFontDefault", "codeFontOldSchool": "mainMenu.settings.codeFontOldSchool", @@ -523,7 +609,9 @@ "forceProductionForDebug": "mainMenu.settings.forceProductionForDebug", "heading": "mainMenu.settings.heading", "language": "mainMenu.settings.language", - "translateToYourLanguage": "mainMenu.settings.translateToYourLanguage" + "translateToYourLanguage": "mainMenu.settings.translateToYourLanguage", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "save": "mainMenu.project.save", @@ -542,7 +630,8 @@ "heading": "mainMenu.meta.heading", "twitter": "mainMenu.meta.twitter", "vkontakte": "mainMenu.meta.vkontakte", - "ctjsForum": "mainMenu.meta.ctjsForum" + "ctjsForum": "mainMenu.meta.ctjsForum", + "openStylebook": "" } }, "appView": { @@ -558,14 +647,36 @@ "fx": "appView.fx", "restart": "appView.restart", "project": "appView.project", - "templates": "appView.templates" - }, - "copyCustomProperties": { - "customProperties": "copyCustomProperties.customProperties", - "addProperty": "copyCustomProperties.addProperty", - "property": "copyCustomProperties.property", - "value": "copyCustomProperties.value", - "delete": "copyCustomProperties.delete" + "templates": "appView.templates", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "assetViewer.addNewGroup", @@ -636,7 +747,13 @@ "copyProperties": { "position": "roomView.copyProperties.position", "rotation": "roomView.copyProperties.rotation", - "scale": "roomView.copyProperties.scale" + "scale": "roomView.copyProperties.scale", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "copyCustomProperties.addProperty", + "property": "copyCustomProperties.property", + "value": "copyCustomProperties.value" }, "customProperties": "roomView.customProperties", "restrictCamera": "roomView.restrictCamera", @@ -656,7 +773,19 @@ "deleteTiles": "roomView.deleteTiles", "moveTilesToLayer": "roomView.moveTilesToLayer", "shiftTiles": "roomView.shiftTiles", - "changeCopyRotation": "roomView.changeCopyRotation" + "changeCopyRotation": "roomView.changeCopyRotation", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "styleView.active", @@ -779,6 +908,103 @@ "learnAboutTypes": "templateView.learnAboutTypes", "name": "templateView.name", "step": "templateView.step", - "visible": "templateView.visible" + "visible": "templateView.visible", + "appearance": "", + "opacity": "", + "blendMode": "", + "playAnimationOnStart": "", + "blendModes": { + "normal": "", + "add": "", + "multiply": "", + "screen": "" + }, + "animationFPS": "", + "loopAnimation": "" + }, + "assetInput": { + "changeAsset": "", + "jumpToAsset": "", + "selectAssetHeader": "" + }, + "builtinAssetGallery": { + "galleryTip": "", + "assetGalleryHeader": "", + "importIntoProject": "", + "importAll": "", + "byAuthorPrefix": "", + "cannotImportExplanation": "", + "nameOccupied": "", + "cannotImportNameOccupied": "", + "visitSource": "", + "visitAuthorsItch": "", + "visitAuthorsTwitter": "", + "tipAuthor": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } -} +} \ No newline at end of file diff --git a/app/data/i18n/Dutch.json b/app/data/i18n/Dutch.json index 38bc739b2..27f6095c6 100644 --- a/app/data/i18n/Dutch.json +++ b/app/data/i18n/Dutch.json @@ -67,7 +67,8 @@ "template": "Sjabloon", "room": "Kamer", "sound": "Geluid", - "tandem": "Deeltjesverspreider" + "tandem": "Deeltjesverspreider", + "type": "" }, "newName": "Nieuwe naam:", "saveProject": "Project opslaan", @@ -80,7 +81,7 @@ "addToNotes": "Notitie toevoegen", "noRooms": "Je hebt ten minste één kamer nodig om de app te compileren.", "tileLayer": "tegellaag", - "ctSite": "ct.js thuispagina", + "ctSite": "ct.js thuispagina", "docsShort": "Docs", "docsLong": "Documentatie", "openAssetGallery": "Galerij", @@ -125,7 +126,9 @@ "skeletten", "skeletten" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "current": "New", @@ -589,7 +592,10 @@ "SpringStream": "Lente Stroom", "LucasDracula": "Lucas Dracula", "Horizon": "Horizon", - "HCBlack": "Hoog-contrast Zwart" + "HCBlack": "Hoog-contrast Zwart", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "codeFontDefault": "Standaard (Iosevka Licht)", "codeFontOldSchool": "Ouderwets", @@ -602,7 +608,10 @@ "heading": "Instellingen", "disableSounds": "Schakel UI geluiden uit", "changeDataFolder": "Stel maplocatie voor data in", - "forceProductionForDebug": "Forceer productietaken voor debug exports" + "forceProductionForDebug": "Forceer productietaken voor debug exports", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "save": "Sla project op", @@ -638,14 +647,36 @@ "fx": "FX", "restart": "Herstart", "project": "Project", - "templates": "Sjablonen" - }, - "copyCustomProperties": { - "customProperties": "Aangepaste eigenschappen", - "addProperty": "Voeg eigenschap toe", - "property": "Eigenschap", - "value": "Waarde", - "delete": "Verwijder" + "templates": "Sjablonen", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "Nieuwe groep", @@ -716,7 +747,13 @@ "copyProperties": { "position": "Positie", "rotation": "Rotatie", - "scale": "Schaal" + "scale": "Schaal", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "Voeg eigenschap toe", + "property": "Eigenschap", + "value": "Waarde" }, "customProperties": "Aangepaste eigenschappen", "restrictCamera": "Houd camera in een rechthoek", @@ -736,7 +773,19 @@ "deleteTiles": "Verwijder tegels", "moveTilesToLayer": "Beweeg naar laag", "shiftTiles": "Verschuif tegels", - "changeCopyRotation": "Draai" + "changeCopyRotation": "Draai", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Activeer", @@ -869,7 +918,9 @@ "add": "Voeg toe (brand)", "multiply": "Vermenigvuldig (donkerder maken)", "screen": "Scherm (lichter maken)" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "assetInput": { "changeAsset": "Druk om het onderdeel te veranderen", @@ -889,5 +940,71 @@ "visitAuthorsItch": "De auteurs itch.io pagina bezoeken", "visitAuthorsTwitter": "De Twitterpagina van de auteur bezoeken", "tipAuthor": "De auteur een fooi geven voor hun harde werk :D" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } -} +} \ No newline at end of file diff --git a/app/data/i18n/English.json b/app/data/i18n/English.json index e662c6a48..b3c43288e 100644 --- a/app/data/i18n/English.json +++ b/app/data/i18n/English.json @@ -50,6 +50,8 @@ "zoom": "Zoom", "zoomIn": "Zoom in", "zoomOut": "Zoom out", + "undo": "Undo", + "redo": "Redo", "fieldTypes": { "checkbox": "Checkbox", "code": "Codebox", @@ -71,7 +73,8 @@ "template": "Template", "room": "Room", "sound": "Sound", - "tandem": "Particle emitter" + "tandem": "Particle emitter", + "type": "" }, "newName": "New name:", "saveProject": "Save project", @@ -160,13 +163,6 @@ "old": "Old", "projectPalette": "Project's Palette" }, - "copyCustomProperties": { - "customProperties": "Custom Properties", - "addProperty": "Add Property", - "property": "Property", - "value": "Value", - "delete": "Delete" - }, "curveEditor": { "curveLineHint": "Click the curve to add a point", "dragPointHint": "Drag to move the point, right-click to delete it", @@ -655,7 +651,8 @@ "altTemplateLayout": "Alternative layout for template editor", "disableSounds": "Disable UI sounds", "changeDataFolder": "Set data folder location", - "forceProductionForDebug": "Force production tasks for debug exports" + "forceProductionForDebug": "Force production tasks for debug exports", + "settings": "" }, "project": { "heading": "Project", @@ -725,11 +722,11 @@ "roomBackgrounds": { "add": "Add a Background", "depth": "Depth:", - "movement": "Movement speed (X, Y):", - "parallax": "Parallax (X, Y):", + "movement": "Movement speed:", + "parallax": "Parallax:", "repeat": "Repeat:", - "scale": "Scaling (X, Y):", - "shift": "Shift (X, Y):", + "scale": "Scaling:", + "shift": "Shift:", "notBackgroundTextureWarning": "This texture is not marked as a background. It will have gaps when exported.", "fixBackground": "Fix it.", "dismissWarning": "Dismiss." @@ -745,7 +742,14 @@ "width": "View width:", "height": "View height:", "isUi": "Is a UI layer?", - "events": "Room events", + "simulate": "Simulate", + "grid": "Grid", + "toggleDiagonalGrid": "Diagonal grid", + "changeGridSize": "Change cell size", + "events": "Events", + "gridOff": "Disable grid", + "xrayMode": "X-ray mode", + "colorizeTileLayers": "Colorize tile layers", "copies": "Copies", "backgrounds": "Backgrounds", "backgroundColor": "Background color:", @@ -754,7 +758,6 @@ "add": "Add", "none": "Nothing", "done": "Done", - "grid": "Set grid", "hotkeysNotice": "Ctrl = Delete, Alt = No grid, Shift = Multiple", "hotkeysNoticeMovement": "Ctrl = Delete, Shift = Select", "shift": "Shift everything", @@ -769,17 +772,26 @@ "selectAndMove": "Select and Move", "customProperties": "Custom Properties", "findTileset": "Find a tileset", + "resetView": "Reset view", "copyProperties": { "position": "Position", "rotation": "Rotation", - "scale": "Scale" + "scale": "Scale", + "opacity": "Opacity", + "tint": "Tint", + "multipleValues": "(Multiple)" + }, + "copyCustomProperties": { + "addProperty": "Add Property", + "property": "Property", + "value": "Value", + "nameOccupied": "This property is used by ct.js! You should come up with a different name." }, "restrictCamera": "Keep camera in a rectangle", "minimumX": "Min X", "minimumY": "Min Y", "maximumX": "Max X", "maximumY": "Max Y", - "gridOff": "Disable grid", "gridSize": "Grid size:", "toCenter": "To center", "shiftLabel": "Shift by:", @@ -791,7 +803,14 @@ "deleteTiles": "Delete tiles", "moveTilesToLayer": "Move to layer", "shiftTiles": "Shift tiles", - "changeCopyRotation": "Rotate" + "changeCopyRotation": "Rotate", + "tools": { + "select": "Select tool", + "addCopies": "Add copies", + "addTiles": "Add tiles", + "manageBackgrounds": "Manage backgrounds", + "roomProperties": "Room properties" + } }, "styleView": { "active": "Active", @@ -984,6 +1003,7 @@ "depth": "Depth:", "opacity": "Opacity:", "blendMode": "Blend mode:", + "animationFPS": "Animation FPS:", "playAnimationOnStart": "Play animation on start", "loopAnimation": "Loop animation", "blendModes": { diff --git a/app/data/i18n/French.json b/app/data/i18n/French.json index 095ed0bb4..108ea31b9 100644 --- a/app/data/i18n/French.json +++ b/app/data/i18n/French.json @@ -93,7 +93,8 @@ "template": "", "room": "", "sound": "", - "tandem": "" + "tandem": "", + "type": "" }, "newName": "Nouveau nom:", "saveProject": "Sauvegarder le projet", @@ -151,7 +152,9 @@ "", "" ] - } + }, + "next": "", + "previous": "" }, "exportPanel": { "hide": "Cacher", @@ -589,7 +592,10 @@ "SpringStream": "", "LucasDracula": "", "Horizon": "", - "HCBlack": "" + "HCBlack": "", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "codeFontDefault": "Font par défault (Iosevka Light)", "codeFontOldSchool": "Old school", @@ -602,7 +608,10 @@ "heading": "Paramètres", "disableSounds": "", "changeDataFolder": "", - "forceProductionForDebug": "" + "forceProductionForDebug": "", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "save": "Sauvegarder le projet", @@ -638,14 +647,36 @@ "fx": "FX", "restart": "", "project": "", - "templates": "Types" - }, - "copyCustomProperties": { - "customProperties": "", - "addProperty": "", - "property": "", - "value": "", - "delete": "" + "templates": "Types", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "", @@ -716,7 +747,13 @@ "copyProperties": { "position": "", "rotation": "", - "scale": "" + "scale": "", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "", + "property": "", + "value": "" }, "customProperties": "", "restrictCamera": "", @@ -736,7 +773,19 @@ "deleteTiles": "Supprimer les Tiles", "moveTilesToLayer": "Déplacer le calque", "shiftTiles": "Déplacer les Tiles", - "changeCopyRotation": "" + "changeCopyRotation": "", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Activer", @@ -869,7 +918,9 @@ "add": "", "multiply": "", "screen": "" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "assetInput": { "changeAsset": "", @@ -889,5 +940,71 @@ "visitAuthorsItch": "", "visitAuthorsTwitter": "", "tipAuthor": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } } \ No newline at end of file diff --git a/app/data/i18n/German.json b/app/data/i18n/German.json index 67b9c85b0..d43d8e4fb 100644 --- a/app/data/i18n/German.json +++ b/app/data/i18n/German.json @@ -67,7 +67,8 @@ "template": "", "room": "", "sound": "", - "tandem": "" + "tandem": "", + "type": "" }, "newName": "Neuer Name:", "saveProject": "Project speichern", @@ -125,7 +126,9 @@ "", "" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "current": "Neu", @@ -589,7 +592,10 @@ "SpringStream": "", "LucasDracula": "", "Horizon": "", - "HCBlack": "" + "HCBlack": "", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "codeFontDefault": "Standard (Iosevka Light)", "codeFontOldSchool": "Old School", @@ -602,7 +608,10 @@ "heading": "Einstellungen", "disableSounds": "", "changeDataFolder": "", - "forceProductionForDebug": "" + "forceProductionForDebug": "", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "save": "Projekt speichern", @@ -638,14 +647,36 @@ "fx": "FX", "restart": "", "project": "", - "templates": "Types" - }, - "copyCustomProperties": { - "customProperties": "", - "addProperty": "", - "property": "", - "value": "", - "delete": "" + "templates": "Types", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "", @@ -716,7 +747,13 @@ "copyProperties": { "position": "", "rotation": "", - "scale": "" + "scale": "", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "", + "property": "", + "value": "" }, "customProperties": "", "restrictCamera": "", @@ -736,7 +773,19 @@ "deleteTiles": "Tiles löschen ", "moveTilesToLayer": "Auf Ebene verschieben", "shiftTiles": "Tiles verschieben", - "changeCopyRotation": "" + "changeCopyRotation": "", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Aktiv", @@ -869,7 +918,9 @@ "add": "", "multiply": "", "screen": "" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "assetInput": { "changeAsset": "", @@ -889,5 +940,71 @@ "visitAuthorsItch": "", "visitAuthorsTwitter": "", "tipAuthor": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } } \ No newline at end of file diff --git a/app/data/i18n/Japanese.json b/app/data/i18n/Japanese.json index f86390759..6e73f73f0 100644 --- a/app/data/i18n/Japanese.json +++ b/app/data/i18n/Japanese.json @@ -69,7 +69,8 @@ "template": "", "room": "", "sound": "", - "tandem": "" + "tandem": "", + "type": "" }, "newName": "新しい名前:", "saveProject": "プロジェクトを保存", @@ -125,7 +126,9 @@ "", "" ] - } + }, + "next": "", + "previous": "" }, "assetInput": { "changeAsset": "アセットを変更する", @@ -144,13 +147,6 @@ "old": "古い", "projectPalette": "プロジェクトのパレット" }, - "copyCustomProperties": { - "customProperties": "カスタムプロパティ", - "addProperty": "プロパティを追加", - "property": "プロパティ", - "value": "数字", - "delete": "削除" - }, "curveEditor": { "curveLineHint": "カーブをクリックしてポイントを追加", "dragPointHint": "ドラッグでポイントを移動、右クリックで削除", @@ -620,7 +616,10 @@ "SpringStream": "春の小川", "LucasDracula": "ルーカス・ドラキュラ", "Horizon": "地平線", - "HCBlack": "高コントラストの黒" + "HCBlack": "高コントラストの黒", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "language": "言語", "translateToYourLanguage": "ct.jsを翻訳する!", @@ -634,7 +633,10 @@ "codeDense": "高密度なレイアウト", "disableSounds": "UIサウンドを無効化", "changeDataFolder": "データフォルダの場所を設定", - "forceProductionForDebug": "デバッグエクスポートのためのプロダクションタスクの強制" + "forceProductionForDebug": "デバッグエクスポートのためのプロダクションタスクの強制", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "heading": "プロジェクト", @@ -670,7 +672,36 @@ "sounds": "音", "ui": "UI", "fx": "FX", - "templates": "テンプレート" + "templates": "テンプレート", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "roomBackgrounds": { "add": "背景を追加", @@ -722,7 +753,13 @@ "copyProperties": { "position": "位置", "rotation": "回転", - "scale": "大きさ" + "scale": "大きさ", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "プロパティを追加", + "property": "プロパティ", + "value": "数字" }, "restrictCamera": "カメラを四角に収める", "minimumX": "最小 X", @@ -741,7 +778,19 @@ "deleteTiles": "複数のタイルを削除", "moveTilesToLayer": "レイヤーに移動", "shiftTiles": "タイルに移動", - "changeCopyRotation": "回転" + "changeCopyRotation": "回転", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "有効", @@ -874,7 +923,9 @@ "add": "", "multiply": "", "screen": "" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "builtinAssetGallery": { "galleryTip": "", @@ -889,5 +940,71 @@ "visitAuthorsItch": "", "visitAuthorsTwitter": "", "tipAuthor": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } } \ No newline at end of file diff --git a/app/data/i18n/Polish.json b/app/data/i18n/Polish.json index f79bb9f29..537c723fe 100644 --- a/app/data/i18n/Polish.json +++ b/app/data/i18n/Polish.json @@ -67,7 +67,8 @@ "template": "", "room": "", "sound": "", - "tandem": "" + "tandem": "", + "type": "" }, "newName": "Nowa nazwa:", "saveProject": "Zapisz projekt", @@ -125,7 +126,9 @@ "", "" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "current": "Nowy", @@ -589,7 +592,10 @@ "SpringStream": "", "LucasDracula": "", "Horizon": "", - "HCBlack": "" + "HCBlack": "", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "codeFontDefault": "Domyślny (Iosevka Light)", "codeFontOldSchool": "Old school", @@ -602,7 +608,10 @@ "heading": "Ustawienia", "disableSounds": "", "changeDataFolder": "", - "forceProductionForDebug": "" + "forceProductionForDebug": "", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "save": "Zapisz projekt", @@ -638,14 +647,36 @@ "fx": "", "restart": "", "project": "", - "templates": "Typy" - }, - "copyCustomProperties": { - "customProperties": "", - "addProperty": "", - "property": "", - "value": "", - "delete": "" + "templates": "Typy", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "", @@ -716,7 +747,13 @@ "copyProperties": { "position": "", "rotation": "", - "scale": "" + "scale": "", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "", + "property": "", + "value": "" }, "customProperties": "", "restrictCamera": "", @@ -736,7 +773,19 @@ "deleteTiles": "Usuń kafelki", "moveTilesToLayer": "Przenieś do warstwy", "shiftTiles": "Przesuń kafelki", - "changeCopyRotation": "" + "changeCopyRotation": "", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Aktywny", @@ -869,7 +918,9 @@ "add": "", "multiply": "", "screen": "" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "assetInput": { "changeAsset": "", @@ -889,5 +940,71 @@ "visitAuthorsItch": "", "visitAuthorsTwitter": "", "tipAuthor": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } } \ No newline at end of file diff --git a/app/data/i18n/Romanian.json b/app/data/i18n/Romanian.json index 8807389aa..09d1e5995 100644 --- a/app/data/i18n/Romanian.json +++ b/app/data/i18n/Romanian.json @@ -67,7 +67,8 @@ "template": "", "room": "", "sound": "", - "tandem": "" + "tandem": "", + "type": "" }, "newName": "Nume nou:", "saveProject": "Salvează proiectul", @@ -125,7 +126,9 @@ "", "" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "current": "Nou", @@ -589,7 +592,10 @@ "SpringStream": "", "LucasDracula": "", "Horizon": "", - "HCBlack": "" + "HCBlack": "", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "codeFontDefault": "", "codeFontOldSchool": "", @@ -602,7 +608,10 @@ "heading": "Setări", "disableSounds": "", "changeDataFolder": "", - "forceProductionForDebug": "" + "forceProductionForDebug": "", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "save": "Salvează proiectul", @@ -638,14 +647,36 @@ "fx": "", "restart": "", "project": "", - "templates": "Tipuri" - }, - "copyCustomProperties": { - "customProperties": "", - "addProperty": "", - "property": "", - "value": "", - "delete": "" + "templates": "Tipuri", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "", @@ -716,7 +747,13 @@ "copyProperties": { "position": "", "rotation": "", - "scale": "" + "scale": "", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "", + "property": "", + "value": "" }, "customProperties": "", "restrictCamera": "", @@ -736,7 +773,19 @@ "deleteTiles": "Șterge tile-urile", "moveTilesToLayer": "Mută în layer", "shiftTiles": "Deplasează tile-urile", - "changeCopyRotation": "" + "changeCopyRotation": "", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Activ", @@ -869,7 +918,9 @@ "add": "", "multiply": "", "screen": "" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "assetInput": { "changeAsset": "", @@ -889,5 +940,71 @@ "visitAuthorsItch": "", "visitAuthorsTwitter": "", "tipAuthor": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } } \ No newline at end of file diff --git a/app/data/i18n/Russian.json b/app/data/i18n/Russian.json index 9afbd2a4f..b854d70c8 100644 --- a/app/data/i18n/Russian.json +++ b/app/data/i18n/Russian.json @@ -67,7 +67,8 @@ "template": "Шаблон", "room": "Комната", "sound": "Звук", - "tandem": "Система частиц" + "tandem": "Система частиц", + "type": "" }, "newName": "Новое имя:", "saveProject": "Сохранить проект", @@ -125,7 +126,9 @@ "скелетных спрайта", "скелетных спрайтов" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "old": "Старый", @@ -607,7 +610,8 @@ "disableSounds": "Отключить звуки интерфейса", "changeDataFolder": "Изменить папку данных ct.js", "forceProductionForDebug": " Включить релизные функции для дебаг-экспортов", - "altTemplateLayout": "Альт. вёрстка редактора шаблонов" + "altTemplateLayout": "Альт. вёрстка редактора шаблонов", + "settings": "" }, "project": { "save": "Сохранить проект", @@ -643,14 +647,36 @@ "ui": "Интерфейс", "fx": "Эффекты", "restart": "Перезапустить", - "templates": "Шаблоны" - }, - "copyCustomProperties": { - "customProperties": "Пользовательские поля", - "addProperty": "Добавить поле", - "property": "Имя поля", - "value": "Значение", - "delete": "Удалить" + "templates": "Шаблоны", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "Новая группа", @@ -721,7 +747,13 @@ "copyProperties": { "position": "Позиция", "rotation": "Поворот", - "scale": "Размер" + "scale": "Размер", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "Добавить поле", + "property": "Имя поля", + "value": "Значение" }, "customProperties": "Пользовательские поля", "restrictCamera": "Ограничить камеру в прямоугольнике", @@ -741,7 +773,19 @@ "deleteTiles": "Удалить плитки", "moveTilesToLayer": "Переместить в другой слой", "shiftTiles": "Сместить плитки", - "changeCopyRotation": "Повернуть" + "changeCopyRotation": "Повернуть", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Активно?", @@ -875,7 +919,8 @@ "multiply": "Умножить (затемнение)", "screen": "Экран (осветление)" }, - "loopAnimation": "Цикличная анимация" + "loopAnimation": "Цикличная анимация", + "animationFPS": "" }, "assetInput": { "changeAsset": "Нажмите, чтобы заменить ассет", @@ -909,7 +954,8 @@ "actions": "Действия", "pointer": "События указателя", "misc": "Разное", - "animation": "Анимация" + "animation": "Анимация", + "timers": "" }, "coreEvents": { "OnCreate": "Создание", @@ -931,7 +977,8 @@ "OnActionDown": "Действие нажато", "OnFrameChange": "Смена кадра", "OnAnimationLoop": "Перезапуск анимации", - "OnAnimationComplete": "Конец анимации" + "OnAnimationComplete": "Конец анимации", + "Timer": "" }, "coreParameterizedNames": { "OnActionPress": "При нажатии %%action%%", @@ -942,7 +989,8 @@ "action": "Действие" }, "coreEventsLocals": { - "OnActionDown_value": "Текущее значение действия" + "OnActionDown_value": "Текущее значение действия", + "OnActionPress_value": "" }, "coreEventsDescriptions": { "OnCreate": "Срабатывает при создании копии.", @@ -955,7 +1003,8 @@ "OnActionRelease": "Срабатывает, когда действие перестаёт быть активно — когда отпускают клавиши, джойстики и т.п.", "OnActionDown": "Срабатывает каждый кадр, пока методы ввода этого действия активны.", "OnAnimationLoop": "Срабатывает каждый раз, когда цикличная анимация подходит к концу.", - "OnAnimationComplete": "Срабатывает один раз, когда нецикличная анимация заканчивается." + "OnAnimationComplete": "Срабатывает один раз, когда нецикличная анимация заканчивается.", + "Timer": "" } } -} +} \ No newline at end of file diff --git a/app/data/i18n/Spanish.json b/app/data/i18n/Spanish.json index eff068789..e264772d7 100644 --- a/app/data/i18n/Spanish.json +++ b/app/data/i18n/Spanish.json @@ -67,7 +67,8 @@ "template": "", "room": "", "sound": "", - "tandem": "" + "tandem": "", + "type": "" }, "newName": "Nombre Nuevo:", "saveProject": "Guardar proyecto", @@ -125,7 +126,9 @@ "", "" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "current": "Nuevo", @@ -590,7 +593,10 @@ "SpringStream": "Corriente de Primavera", "LucasDracula": "Lucas Dracula", "Horizon": "", - "HCBlack": "" + "HCBlack": "", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "codeFontDefault": "Predeterminado (Iosevka Light)", "codeFontOldSchool": "Vieja Escuela", @@ -602,7 +608,10 @@ "codeDense": "Diseño Denso", "disableSounds": "", "changeDataFolder": "", - "forceProductionForDebug": "" + "forceProductionForDebug": "", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "save": "Guardar proyecto", @@ -638,14 +647,36 @@ "restart": "Reiniciar", "project": "Proyecto", "fx": "Effectos", - "templates": "Tipos" - }, - "copyCustomProperties": { - "customProperties": "", - "addProperty": "", - "property": "", - "value": "", - "delete": "" + "templates": "Tipos", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "", @@ -716,7 +747,13 @@ "copyProperties": { "position": "", "rotation": "", - "scale": "" + "scale": "", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "", + "property": "", + "value": "" }, "customProperties": "", "restrictCamera": "", @@ -736,7 +773,19 @@ "deleteTiles": "Eliminar tiles", "moveTilesToLayer": "Mover a capa", "shiftTiles": "Cambiar tiles", - "changeCopyRotation": "Rotar" + "changeCopyRotation": "Rotar", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Activar", @@ -869,7 +918,9 @@ "add": "", "multiply": "", "screen": "" - } + }, + "animationFPS": "", + "loopAnimation": "" }, "assetInput": { "changeAsset": "", @@ -889,5 +940,71 @@ "visitAuthorsItch": "", "visitAuthorsTwitter": "", "tipAuthor": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + } } } \ No newline at end of file diff --git a/app/data/i18n/Turkish.json b/app/data/i18n/Turkish.json index ac128cd89..275b8e8b2 100644 --- a/app/data/i18n/Turkish.json +++ b/app/data/i18n/Turkish.json @@ -76,7 +76,8 @@ "template": "Şablon", "room": "Oda", "sound": "Ses", - "tandem": "Partikül dağıtıcısı" + "tandem": "Partikül dağıtıcısı", + "type": "" }, "assetTypes": { "textures": [ @@ -125,7 +126,9 @@ "edit": "Değiştir", "nothingToShowFiller": "Burada gösterilecek hiçbir şey yok!", "required": "Gerekli", - "settings": "Ayarlar" + "settings": "Ayarlar", + "next": "", + "previous": "" }, "assetInput": { "changeAsset": "Görseli değiştirmek için tıkla", @@ -158,13 +161,6 @@ "old": "Eski", "projectPalette": "Proje'nin paleti" }, - "copyCustomProperties": { - "customProperties": "Özel Özellikler", - "addProperty": "Özellik Ekle", - "property": "Özellik", - "value": "Değer", - "delete": "Sil" - }, "curveEditor": { "curveLineHint": "Nokta eklemek için kavise tıkla", "dragPointHint": "Noktayı hareket ettirmek için sürükle, silmek için sağ tıkla.", @@ -621,7 +617,10 @@ "SpringStream": "İlkbahar Yayını", "LucasDracula": "Lucas Drakula", "Horizon": "Ufuk", - "HCBlack": "Yüksek-kontrast siyah" + "HCBlack": "Yüksek-kontrast siyah", + "RosePine": "", + "RosePineMoon": "", + "RosePineDawn": "" }, "language": "Dil", "translateToYourLanguage": "ct.js'i çevir!", @@ -635,7 +634,10 @@ "codeDense": "Düzeni yoğunlaştır", "disableSounds": "Arayüz seslerini kapat", "changeDataFolder": "Veri klasörü yolunu ayarla", - "forceProductionForDebug": "Hata ayıklamaları dışarı aktarmak için üretim işlemlerini zorla" + "forceProductionForDebug": "Hata ayıklamaları dışarı aktarmak için üretim işlemlerini zorla", + "settings": "", + "prideMode": "", + "altTemplateLayout": "" }, "project": { "heading": "Proje", @@ -671,7 +673,36 @@ "sounds": "Sesler", "ui": "Arayüz", "fx": "Efektler", - "templates": "Şablonlar" + "templates": "Şablonlar", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "roomBackgrounds": { "add": "Arkaplan ekle", @@ -736,13 +767,31 @@ "copyProperties": { "position": "Pozisyon", "rotation": "Rotasyon", - "scale": "Boyut" + "scale": "Boyut", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "Özellik Ekle", + "property": "Özellik", + "value": "Değer" }, "restrictCamera": "Kamerayı dörtgende tut", "minimumX": "Minimum X", "minimumY": "Minimum Y", "maximumX": "Maksimum X", - "maximumY": "Maksimum Y" + "maximumY": "Maksimum Y", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Aktif", @@ -888,6 +937,74 @@ "add": "Ekle (yanık)", "multiply": "Çoğalt (karanlık)", "screen": "Ekran (aydınlık)" + }, + "animationFPS": "", + "loopAnimation": "" + }, + "scriptables": { + "addEvent": "", + "removeEvent": "", + "removeEventConfirm": "", + "changeArguments": "", + "eventAlreadyExists": "", + "localEventVars": "", + "createEventHint": "", + "coreEventsCategories": { + "lifecycle": "", + "actions": "", + "pointer": "", + "misc": "", + "animation": "", + "timers": "" + }, + "coreEvents": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnPointerClick": "", + "OnPointerSecondaryClick": "", + "OnPointerEnter": "", + "OnPointerLeave": "", + "OnPointerDown": "", + "OnPointerUp": "", + "OnPointerUpOutside": "", + "OnPointerWheel": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnFrameChange": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" + }, + "coreParameterizedNames": { + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "" + }, + "coreEventsArguments": { + "action": "" + }, + "coreEventsLocals": { + "OnActionDown_value": "", + "OnActionPress_value": "" + }, + "coreEventsDescriptions": { + "OnCreate": "", + "OnRoomStart": "", + "OnStep": "", + "OnDraw": "", + "OnDestroy": "", + "OnRoomEnd": "", + "OnActionPress": "", + "OnActionRelease": "", + "OnActionDown": "", + "OnAnimationLoop": "", + "OnAnimationComplete": "", + "Timer": "" } } -} +} \ No newline at end of file diff --git a/app/data/i18n/Ukranian.json b/app/data/i18n/Ukranian.json index d842a68b8..923a7e622 100644 --- a/app/data/i18n/Ukranian.json +++ b/app/data/i18n/Ukranian.json @@ -67,7 +67,8 @@ "template": "Шаблон", "room": "Кімната", "sound": "Звук", - "tandem": "Система частинок" + "tandem": "Система частинок", + "type": "" }, "newName": "Нове ім'я:", "saveProject": "Зберегти проект", @@ -125,7 +126,9 @@ "скелетного спрайту", "скелетних спрайтів" ] - } + }, + "next": "", + "previous": "" }, "colorPicker": { "old": "Старий", @@ -607,7 +610,8 @@ "disableSounds": "Вимкнути звуки інтерфейсу", "changeDataFolder": "Змінити папку даних ct.js", "forceProductionForDebug": " Включити релізні функції для дебаг-експортів", - "altTemplateLayout": "Альт. верстка редактора шаблонів" + "altTemplateLayout": "Альт. верстка редактора шаблонів", + "settings": "" }, "project": { "save": "Зберегти проект", @@ -643,14 +647,36 @@ "ui": "Інтерфейс", "fx": "Ефекти", "restart": "Перезапустити", - "templates": "Шаблони" - }, - "copyCustomProperties": { - "customProperties": "Користувацькі поля", - "addProperty": "Додати поле", - "property": "Ім'я поля", - "value": "Значення", - "delete": "Видалити" + "templates": "Шаблони", + "tour": { + "header": "", + "aboutTour": "", + "helpPanel": "", + "helpPanelTabs": "", + "projectResources": "", + "tabTextures": "", + "tabTexturesImport": "", + "tabTexturesGallery": "", + "tabTexturesClipboard": "", + "tabTexturesPlaceholders": "", + "tabTemplates": "", + "tabRooms": "", + "tabSounds": "", + "tabSoundsImport": "", + "tabSoundsGallery": "", + "tabSoundsRecord": "", + "tabInterlude": "", + "tabUI": "", + "tabFX": "", + "tabProject": "", + "tabProjectModules": "", + "tabProjectModuleDocs": "", + "tabMainMenu": "", + "tabMainMenuSettings": "", + "tabMainMenuMeta": "", + "helpPanelReminder": "", + "buttonStartTutorial": "" + } }, "assetViewer": { "addNewGroup": "Нова група", @@ -721,7 +747,13 @@ "copyProperties": { "position": "Позиція", "rotation": "Поворот", - "scale": "Розмір" + "scale": "Розмір", + "multipleValues": "" + }, + "copyCustomProperties": { + "addProperty": "Додати поле", + "property": "Ім'я поля", + "value": "Значення" }, "customProperties": "Користувацькі поля", "restrictCamera": "Обмежити камеру в прямокутнику", @@ -741,7 +773,19 @@ "deleteTiles": "Видалити плитки", "moveTilesToLayer": "Перемістити до іншого шару", "shiftTiles": "Змістити плитки", - "changeCopyRotation": "Повернути" + "changeCopyRotation": "Повернути", + "simulate": "", + "toggleDiagonalGrid": "", + "changeGridSize": "", + "xrayMode": "", + "colorizeTileLayers": "", + "tools": { + "select": "", + "addCopies": "", + "addTiles": "", + "manageBackgrounds": "", + "roomProperties": "" + } }, "styleView": { "active": "Активно?", @@ -875,7 +919,8 @@ "multiply": "Помножити (затемнення)", "screen": "Екран (освітлення)" }, - "loopAnimation": "Циклічна анімація" + "loopAnimation": "Циклічна анімація", + "animationFPS": "" }, "assetInput": { "changeAsset": "Натисніть, щоб замінити ассет", @@ -883,7 +928,7 @@ "selectAssetHeader": "Вибрати асет" }, "builtinAssetGallery": { - "galleryTip": "Це вбудована галерея різних безкоштовних текстур і звуків. Вони всі під ліцензією CCO, WTFPL, або на спец. правах для движка ct.js, і ти можеш використовувати їх як завгодно, в комерційних проектах і не тільки." , + "galleryTip": "Це вбудована галерея різних безкоштовних текстур і звуків. Вони всі під ліцензією CCO, WTFPL, або на спец. правах для движка ct.js, і ти можеш використовувати їх як завгодно, в комерційних проектах і не тільки.", "assetGalleryHeader": "Асети", "importIntoProject": "Вставити в проект", "importAll": "Імпортувати все", @@ -909,7 +954,8 @@ "actions": "Дії", "pointer": "Події покажчика", "misc": "Різне", - "animation": "Анімація" + "animation": "Анімація", + "timers": "" }, "coreEvents": { "OnCreate": "Створення", @@ -931,7 +977,8 @@ "OnActionDown": "Дія натиснута", "OnFrameChange": "Зміна кадру", "OnAnimationLoop": "Перепуск анімації", - "OnAnimationComplete": "Кінець анімації" + "OnAnimationComplete": "Кінець анімації", + "Timer": "" }, "coreParameterizedNames": { "OnActionPress": "При натисканні %%action%%", @@ -942,7 +989,8 @@ "action": "Дія" }, "coreEventsLocals": { - "OnActionDown_value": "Поточне значення дії" + "OnActionDown_value": "Поточне значення дії", + "OnActionPress_value": "" }, "coreEventsDescriptions": { "OnCreate": "Спрацьовує під час створення копії.", @@ -955,7 +1003,8 @@ "OnActionRelease": "Спрацьовує, коли дія перестає бути активною - коли відпускають клавіші, джойстики і т.п.", "OnActionDown": "Спрацьовує кожен кадр, доки методи введення цієї дії активні.", "OnAnimationLoop": "Спрацьовує щоразу, коли циклічна анімація добігає кінця.", - "OnAnimationComplete": "Спрацьовує один раз, коли нециклічна анімація закінчується." + "OnAnimationComplete": "Спрацьовує один раз, коли нециклічна анімація закінчується.", + "Timer": "" } } -} +} \ No newline at end of file diff --git a/app/package-lock.json b/app/package-lock.json index 1d68db617..c7973a8be 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1,12 +1,12 @@ { "name": "ctjs", - "version": "2.0.2", + "version": "2.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ctjs", - "version": "2.0.2", + "version": "2.1.0", "license": "MIT", "dependencies": { "@capacitor/cli": "^3.4.0", @@ -34,6 +34,7 @@ "nanoid": "^3.1.31", "npm": "^8.11.0", "opentype.js": "^1.3.3", + "pixi-ease": "^3.0.7", "pixi-particles": "4.3.1", "pixi.js": "5.3.11", "pixi.js-legacy": "5.3.11", @@ -8071,6 +8072,11 @@ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" }, + "node_modules/penner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/penner/-/penner-0.1.3.tgz", + "integrity": "sha512-UzkaC2L6d9J1VzJAFH0TQwuKE/rerpTZkgW6aPLVeu/LdjWn6rnuY9lXcVN1AE9tZVfHrsJ2gZOBsRjpQECNHA==" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -8090,6 +8096,23 @@ "node": ">=4" } }, + "node_modules/pixi-ease": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/pixi-ease/-/pixi-ease-3.0.7.tgz", + "integrity": "sha512-ew1IzAi2layygHrk8+tk6XTuue3WM6Po5LsA46v+9BtQNMa2sX0PMLzQ4nq1UpTbLg4Dwqep9RTzDRsFhCYJJw==", + "dependencies": { + "eventemitter3": "^4.0.0", + "penner": "^0.1.3" + }, + "peerDependencies": { + "pixi.js": ">=4.6.0" + } + }, + "node_modules/pixi-ease/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/pixi-particles": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/pixi-particles/-/pixi-particles-4.3.1.tgz", @@ -8802,6 +8825,21 @@ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "optional": true }, + "node_modules/rollup": { + "version": "2.76.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.76.0.tgz", + "integrity": "sha512-9jwRIEY1jOzKLj3nsY/yot41r19ITdQrhs+q3ggNWhr9TQgduHqANvPpS32RNpzGklJu3G1AJfvlZLi/6wFgWA==", + "peer": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/rsvp": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", @@ -9634,6 +9672,19 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -16226,6 +16277,11 @@ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" }, + "penner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/penner/-/penner-0.1.3.tgz", + "integrity": "sha512-UzkaC2L6d9J1VzJAFH0TQwuKE/rerpTZkgW6aPLVeu/LdjWn6rnuY9lXcVN1AE9tZVfHrsJ2gZOBsRjpQECNHA==" + }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -16236,6 +16292,22 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, + "pixi-ease": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/pixi-ease/-/pixi-ease-3.0.7.tgz", + "integrity": "sha512-ew1IzAi2layygHrk8+tk6XTuue3WM6Po5LsA46v+9BtQNMa2sX0PMLzQ4nq1UpTbLg4Dwqep9RTzDRsFhCYJJw==", + "requires": { + "eventemitter3": "^4.0.0", + "penner": "^0.1.3" + }, + "dependencies": { + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + } + } + }, "pixi-particles": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/pixi-particles/-/pixi-particles-4.3.1.tgz", @@ -16776,6 +16848,15 @@ } } }, + "rollup": { + "version": "2.76.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.76.0.tgz", + "integrity": "sha512-9jwRIEY1jOzKLj3nsY/yot41r19ITdQrhs+q3ggNWhr9TQgduHqANvPpS32RNpzGklJu3G1AJfvlZLi/6wFgWA==", + "peer": true, + "requires": { + "fsevents": "~2.3.2" + } + }, "rsvp": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", @@ -17411,6 +17492,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "peer": true + }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", diff --git a/app/package.json b/app/package.json index 4c8ff0c01..4f0f4db12 100644 --- a/app/package.json +++ b/app/package.json @@ -2,7 +2,7 @@ "main": "index.html", "name": "ctjs", "description": "ct.js — a free 2D game engine", - "version": "2.0.2", + "version": "2.2.0", "homepage": "https://ctjs.rocks/", "author": { "name": "Cosmo Myzrail Gorynych", @@ -78,6 +78,7 @@ "nanoid": "^3.1.31", "npm": "^8.11.0", "opentype.js": "^1.3.3", + "pixi-ease": "^3.0.7", "pixi-particles": "4.3.1", "pixi.js": "5.3.11", "pixi.js-legacy": "5.3.11", diff --git a/gulpfile.js b/gulpfile.js index 5f8b05fc7..ac881aa2f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -253,7 +253,6 @@ const watchRequires = () => { .on('change', fileChangeNotifier) .on('error', err => { notifier.notify(makeErrorObj('Failure of node_requires', err)); - console.error('[node_requires error]', err); }); }; const watchIcons = () => { diff --git a/package-lock.json b/package-lock.json index 87dfd7d30..69791099d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ctjsbuildenvironment", - "version": "2.0.2", + "version": "2.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ctjsbuildenvironment", - "version": "2.0.2", + "version": "2.1.0", "license": "MIT", "dependencies": { "@ct.js/gulp-typescript": "^6.0.0", diff --git a/package.json b/package.json index f94bda427..f8c49215d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ctjsbuildenvironment", - "version": "2.0.2", + "version": "2.2.0", "description": "", "directories": { "doc": "docs" diff --git a/src/examples/DungeonCrawler_tutorial.ict b/src/examples/DungeonCrawler_tutorial.ict index a405ee2cb..156dd055a 100644 --- a/src/examples/DungeonCrawler_tutorial.ict +++ b/src/examples/DungeonCrawler_tutorial.ict @@ -1,4 +1,4 @@ -ctjsVersion: 2.0.2 +ctjsVersion: 2.2.0 notes: /* empty */ libs: fittoscreen: @@ -453,7 +453,7 @@ textures: height: 16 offx: 0 offy: 0 - origname: 'i14d3f53f-a868-4820-84cd-63234ab6e6b9.png}' + origname: i14d3f53f-a868-4820-84cd-63234ab6e6b9.png shape: rect left: 0 right: 16 @@ -478,7 +478,7 @@ textures: height: 32 offx: 0 offy: 0 - origname: 'ia42e0dff-69c9-46c3-8996-745aaa769698.png}' + origname: ia42e0dff-69c9-46c3-8996-745aaa769698.png shape: rect left: 16 right: 16 @@ -729,7 +729,7 @@ templates: extends: cgroup: '' uid: c40336ea-2846-45d5-97ba-d51852d3f6c5 - lastmod: 1656663050756 + lastmod: 1659098686679 events: - lib: core arguments: {} @@ -738,7 +738,6 @@ templates: ct.camera.shiftY = -16; this.maxSpeed = 2; - this.animationSpeed = 5 / ct.speed; this.invincibleTimer = 0; eventKey: OnCreate - lib: core @@ -818,6 +817,7 @@ templates: type: template loopAnimation: true playAnimationOnStart: true + animationFPS: 5 - name: Crate depth: 0 texture: 31948760-8965-4768-ab1d-2b87d0b7fc3a @@ -1271,917 +1271,1193 @@ rooms: 'y': 64 uid: 7fea051e-83e5-4e54-848b-ab3ca861e5cb exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 152 'y': 192 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 160 'y': 208 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 168 'y': 192 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 280 'y': 192 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 280 'y': 64 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 96 'y': 88 uid: c40336ea-2846-45d5-97ba-d51852d3f6c5 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 96 'y': 160 uid: c701a029-af09-4fcf-9712-0fcdaa3581be exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 tiles: - depth: -6000 tiles: - x: 48 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 96 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 176 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 192 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 208 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 272 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 272 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 272 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 272 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 272 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 240 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 224 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 208 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 192 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 176 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 96 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 208 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 208 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 208 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 192 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 192 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 192 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 192 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 192 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 192 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 208 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 240 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 272 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 208 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 240 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 256 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 272 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 64 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 80 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 96 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 112 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 128 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 192 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 112 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 144 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 176 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 208 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 64 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 80 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 96 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 112 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 128 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 144 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 160 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 176 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 192 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 208 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 224 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 240 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 256 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 272 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 288 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 288 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 48 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 224 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 12 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 1 - - 1 - - 1 - x: 224 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 128 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 9 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 1 - - 1 - - 1 - x: 192 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 9 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 1 - - 1 - - 1 - x: 160 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 9 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 1 - - 1 - - 1 - x: 272 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 10 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 1 - - 1 - - 1 extends: cgroup: Solid hidden: false @@ -2189,764 +2465,954 @@ rooms: tiles: - x: 64 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 224 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 256 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 272 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 272 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 256 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 240 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 208 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 208 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 224 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 256 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 272 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 272 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 272 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 240 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 224 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 224 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 224 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 240 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 256 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 256 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 256 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 192 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 288 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 48 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 32 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 26 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 3 - - 1 - - 1 - x: 112 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 240 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 96 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 240 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 224 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 256 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 224 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 240 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 256 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 6 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 0 - - 1 - - 1 - x: 144 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 6 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 0 - - 1 - - 1 - x: 160 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 6 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 0 - - 1 - - 1 - x: 160 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 6 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 0 - - 1 - - 1 - x: 192 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 96 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 240 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 208 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 208 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 208 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 224 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 192 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 176 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 176 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 224 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 240 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 256 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 240 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 15 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 7 - - 1 - - 1 - - 1 - x: 240 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 15 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 7 - - 1 - - 1 - - 1 - x: 64 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 80 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 96 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 112 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 128 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 144 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 160 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 176 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 192 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 208 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 224 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 240 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 256 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 272 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 288 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - - x: 80 - 'y': 144 + - x: 96 + 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: ae954867-1039-43f6-bf6d-d8684cb58612 - grid: - - 0 - - 0 - - 1 - - 1 - x: 224 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 256 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 extends: cgroup: Decor hidden: false @@ -2977,6 +3443,8 @@ rooms: }); eventKey: OnRoomStart type: room + simulate: true + isUi: ! '' - name: Level_02 onstep: '' ondraw: '' @@ -2989,1752 +3457,2424 @@ rooms: 'y': 144 uid: c701a029-af09-4fcf-9712-0fcdaa3581be exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 106 'y': 238 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 359 'y': 239 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 136 'y': 61 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 111 'y': 79 uid: c40336ea-2846-45d5-97ba-d51852d3f6c5 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 124 'y': 233 uid: 9fc1fec8-50bb-49e6-8fb4-c10ad589bf0b exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 112 'y': 220 uid: 9fc1fec8-50bb-49e6-8fb4-c10ad589bf0b exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 255 'y': 232 uid: 5e40076f-8a61-4dfd-a517-a6c943ab9991 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 568 'y': 16 uid: 7fea051e-83e5-4e54-848b-ab3ca861e5cb exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 458 'y': 41 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 451 'y': 47 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 459 'y': 51 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 279 'y': 41 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 387 'y': 58 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 323 'y': 90 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 373 'y': 99 uid: 5e40076f-8a61-4dfd-a517-a6c943ab9991 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 447 'y': 68 uid: 5e40076f-8a61-4dfd-a517-a6c943ab9991 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 317 'y': 55 uid: 5e40076f-8a61-4dfd-a517-a6c943ab9991 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 432 'y': 80 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 352 'y': 112 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 368 'y': 48 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 568 'y': 80 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 334 'y': 230 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 224 'y': 184 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 240 'y': 184 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 256 'y': 184 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 272 'y': 184 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 224 'y': 248 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 240 'y': 248 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 256 'y': 248 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 272 'y': 248 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 280 'y': 56 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 280 'y': 72 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 408 'y': 104 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 424 'y': 104 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 440 'y': 104 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 160 'y': 224 uid: 469b9eef-6117-43a5-87d3-7151da7eba06 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 352 'y': 96 uid: 469b9eef-6117-43a5-87d3-7151da7eba06 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 352 'y': 208 uid: b336d91c-2876-4686-b8b4-901045a86ac7 + exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 tiles: - depth: -6000 tiles: - x: 64 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 96 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 176 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 304 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 320 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 96 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 176 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 192 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 304 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 320 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 368 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 352 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 336 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 368 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 368 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 368 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 368 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 368 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 368 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 320 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 320 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 320 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 368 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 320 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 13 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 1 - - 1 - - 1 - x: 304 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 272 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 256 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 272 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 288 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 304 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 320 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 336 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 352 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 368 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 448 - 'y': -0.0 + 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 384 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 400 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 416 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 432 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 448 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 464 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 464 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 464 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 464 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 480 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 496 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 512 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 528 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 544 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 480 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 496 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 512 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 528 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 544 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 560 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 576 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 576 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 576 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 576 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 576 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 576 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 544 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 544 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 544 'y': -16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 544 'y': -32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 544 'y': -32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 576 'y': -32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 560 'y': -32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 576 'y': -16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 480 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 10 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 1 - - 1 - - 1 - x: 528 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 10 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 1 - - 1 - - 1 - x: 544 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 12 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 1 - - 1 - - 1 - x: 432 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 416 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 400 - 'y': -0.0 + 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 384 - 'y': -0.0 + 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 416 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 13 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 1 - - 1 - - 1 - x: 128 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 144 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 160 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 208 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 64 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 144 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 80 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 96 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 112 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 128 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 144 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 160 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 64 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 48 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 288 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 304 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 368 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 352 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 336 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 320 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 288 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 192 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 176 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 160 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 144 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 128 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 112 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 96 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 80 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 464 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 448 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 432 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 384 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 272 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 288 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 320 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 336 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 352 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 368 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 384 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 400 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 432 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 448 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 496 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 512 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 464 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 560 'y': -16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 576 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 560 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 544 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 528 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 512 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 496 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 480 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 256 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 272 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 304 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 176 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 14 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 1 - - 1 - - 1 - x: 304 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 14 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 1 - - 1 - - 1 - x: 208 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 14 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 1 - - 1 - - 1 - x: 192 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 3 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 0 - - 1 - - 1 - x: 64 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 144 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 144 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 64 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 208 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 288 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 208 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 288 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 192 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 11 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 1 - - 1 - - 1 - x: 464 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 464 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 320 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 2 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 0 - - 1 - - 1 - x: 368 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 2 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 0 - - 1 - - 1 - x: 304 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 13 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 1 - - 1 - - 1 - x: 288 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 13 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 1 - - 1 - - 1 - x: 400 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 13 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 1 - - 1 - - 1 - x: 416 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 14 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 1 - - 1 - - 1 extends: cgroup: Solid hidden: false @@ -4742,1596 +5882,1994 @@ rooms: tiles: - x: 96 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 160 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 176 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 320 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 336 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 352 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 176 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 320 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 336 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 352 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 192 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 192 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 304 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 112 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 96 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 80 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 336 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 352 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 336 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 352 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 336 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 352 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 176 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 26 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 3 - - 1 - - 1 - x: 224 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 26 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 3 - - 1 - - 1 - x: 16 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 26 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 3 - - 1 - - 1 - x: 48 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 26 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 3 - - 1 - - 1 - x: 240 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 26 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 3 - - 1 - - 1 - x: 400 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 26 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 3 - - 1 - - 1 - x: 512 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 26 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 3 - - 1 - - 1 - x: 496 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 26 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 3 - - 1 - - 1 - x: 272 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 288 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 304 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 336 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 352 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 368 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 384 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 400 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 416 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 432 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 448 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 304 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 352 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 368 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 416 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 448 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 304 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 400 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 416 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 464 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 480 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 496 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 512 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 528 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 544 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 560 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 560 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 448 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 432 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 416 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 400 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 384 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 368 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 352 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 320 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 304 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 272 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 288 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 304 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 320 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 336 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 352 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 368 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 384 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 336 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 448 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 432 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 384 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 400 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 336 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 320 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 384 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 432 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 320 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 336 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 320 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 368 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 336 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 352 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 272 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 272 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 224 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 304 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 208 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 5 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 0 - - 1 - - 1 - x: 208 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 5 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 0 - - 1 - - 1 - x: 288 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 5 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 0 - - 1 - - 1 - x: 288 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 5 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 0 - - 1 - - 1 - x: 336 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 352 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 352 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 336 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 560 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 560 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 240 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 30 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 3 - - 1 - - 1 - x: 256 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 224 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 256 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 240 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 96 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 112 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 128 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 144 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 160 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 176 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 192 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 208 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 64 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 48 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 160 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 144 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 304 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 288 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 272 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 256 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 288 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 304 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 320 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 336 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 352 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 368 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 384 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 400 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 416 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 432 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 448 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 464 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 480 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 496 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 512 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 528 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 544 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 560 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 576 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 160 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 7 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 7 - - 0 - - 1 - - 1 - x: 560 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 15 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 7 - - 1 - - 1 - - 1 - x: 352 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 7 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 7 - - 0 - - 1 - - 1 - x: 224 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 240 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 256 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 272 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 272 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 20 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 2 - - 1 - - 1 - x: 288 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 20 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 2 - - 1 - - 1 - x: 272 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 28 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 3 - - 1 - - 1 - x: 288 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 28 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 3 - - 1 - - 1 - x: 272 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 28 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 3 - - 1 - - 1 - x: 288 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 29 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 5 - - 3 - - 1 - - 1 - x: 448 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 20 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 2 - - 1 - - 1 - x: 432 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 20 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 2 - - 1 - - 1 - x: 416 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 20 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 2 - - 1 - - 1 - x: 400 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 20 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 2 - - 1 - - 1 - x: 416 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 20 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 2 - - 1 - - 1 - - x: 336 - 'y': 128 + - x: 352 + 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: ae954867-1039-43f6-bf6d-d8684cb58612 - grid: - - 0 - - 0 - - 1 - - 1 extends: cgroup: Decor hidden: false @@ -6353,6 +7891,8 @@ rooms: }); eventKey: OnRoomStart type: room + simulate: true + isUi: ! '' - name: MainMenu oncreate: '' onstep: '' @@ -6364,41 +7904,62 @@ rooms: copies: - x: 120 'y': 116 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + rotation: 0 uid: 38f86691-8fcc-44e4-a201-8479ca64935f exts: {} + customProperties: {} - x: 32 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + rotation: 0 uid: ff0f561c-a96c-4205-a083-01d2a60ebb67 exts: {} + customProperties: {} tiles: - depth: -10 tiles: - - x: 16 - 'y': 16 + - x: 121 + 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: dc7b9662-c746-403c-9f3e-67425fd480a3 - grid: - - 0 - - 0 - - 1 - - 1 - - x: 62 - 'y': 151 + - x: 120 + 'y': 153 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 9a1f5e9c-16a8-4900-8991-fab3f42fa1fd - grid: - - 0 - - 0 - - 1 - - 1 extends: {} + hidden: false uid: eed8a427-1c70-425d-b633-7b6ea00c7b7c thumbnail: 7b6ea00c7b7c extends: {} gridX: 16 gridY: 16 backgroundColor: '#000337' - lastmod: 1656663135237 + lastmod: 1661000148459 events: [] type: room + simulate: true + isUi: ! '' - name: Level_03 onstep: '' ondraw: '' @@ -6410,2340 +7971,3338 @@ rooms: 'y': 64 uid: c40336ea-2846-45d5-97ba-d51852d3f6c5 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 112 'y': 64 uid: 469b9eef-6117-43a5-87d3-7151da7eba06 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 112 'y': 128 uid: c701a029-af09-4fcf-9712-0fcdaa3581be exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 104 'y': 192 uid: 36c82b3e-f5c1-4fff-b24a-417fa9509c96 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 120 'y': 192 uid: 36c82b3e-f5c1-4fff-b24a-417fa9509c96 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 112 'y': 224 uid: 469b9eef-6117-43a5-87d3-7151da7eba06 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 248 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 264 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 104 'y': 272 uid: 36c82b3e-f5c1-4fff-b24a-417fa9509c96 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 120 'y': 272 uid: 36c82b3e-f5c1-4fff-b24a-417fa9509c96 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 280 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 296 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 312 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 104 'y': 320 uid: 36c82b3e-f5c1-4fff-b24a-417fa9509c96 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 120 'y': 320 uid: 36c82b3e-f5c1-4fff-b24a-417fa9509c96 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 152 'y': 328 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 168 'y': 328 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 184 'y': 328 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 200 'y': 328 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 216 'y': 328 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 112 'y': 336 uid: 469b9eef-6117-43a5-87d3-7151da7eba06 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 136 'y': 344 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 232 'y': 344 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 136 'y': 360 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 232 'y': 360 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 181 'y': 362 uid: 3b6057ca-f175-4449-ac24-1c5630e0af7c exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 205 'y': 376 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 152 'y': 376 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 136 'y': 376 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 232 'y': 376 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 216 'y': 392 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 168 'y': 392 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 184 'y': 392 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 200 'y': 392 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 392 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 136 'y': 392 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 112 'y': 393 uid: 9fc1fec8-50bb-49e6-8fb4-c10ad589bf0b exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 408 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 104 'y': 416 uid: 36c82b3e-f5c1-4fff-b24a-417fa9509c96 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 120 'y': 416 uid: 36c82b3e-f5c1-4fff-b24a-417fa9509c96 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 424 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 88 'y': 440 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 440 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 456 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 120 'y': 464 uid: 36c82b3e-f5c1-4fff-b24a-417fa9509c96 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 472 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 136 'y': 472 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 488 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 120 'y': 488 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 72 'y': 504 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 136 'y': 504 uid: 0bc3c56b-3bf9-4912-9e3f-c27654c1b910 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 112 'y': 528 uid: 469b9eef-6117-43a5-87d3-7151da7eba06 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 115 'y': 574 uid: 9fc1fec8-50bb-49e6-8fb4-c10ad589bf0b exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 104 'y': 588 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 118 'y': 592 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 110 'y': 597 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 105 'y': 601 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 118 'y': 604 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 104 'y': 614 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 120 'y': 614 uid: 4e473462-8009-438e-9f53-1032e3a335cf exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 112 'y': 624 uid: c701a029-af09-4fcf-9712-0fcdaa3581be exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 113 'y': 636 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 58 'y': 643 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 122 'y': 648 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 90 'y': 659 uid: 5e40076f-8a61-4dfd-a517-a6c943ab9991 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 112 'y': 672 uid: 7fea051e-83e5-4e54-848b-ab3ca861e5cb exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 74 'y': 680 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 154 'y': 682 uid: 173dfb94-5133-4bbc-9e7d-6ed8c9fef330 exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 - x: 96 'y': 416 uid: b336d91c-2876-4686-b8b4-901045a86ac7 + exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 tiles: - depth: -6000 tiles: - x: 48 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 96 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 0 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 288 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 320 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 320 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 352 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 368 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 400 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 416 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 448 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 512 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 528 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 544 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 560 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 576 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 528 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 544 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 560 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 576 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 512 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 176 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 176 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 176 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 176 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 160 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 144 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 128 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 32 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 32 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 32 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 32 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 32 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 64 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 96 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 112 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 48 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 176 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 0 - - 1 - - 1 - x: 80 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 14 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 1 - - 1 - - 1 - x: 128 'y': 464 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 14 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 1 - - 1 - - 1 - x: 80 'y': 384 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 14 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 1 - - 1 - - 1 - x: 128 'y': 336 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 144 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 160 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 48 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 64 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 80 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 10 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 1 - - 1 - - 1 - x: 128 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 10 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 1 - - 1 - - 1 - x: 96 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 112 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 64 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 144 'y': 16 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 48 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 3 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 0 - - 1 - - 1 - x: 144 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 12 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 1 - - 1 - - 1 - x: 64 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 12 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 4 - - 1 - - 1 - - 1 - x: 48 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 64 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 144 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 160 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 19 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 2 - - 1 - - 1 - x: 48 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 64 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 80 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 112 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 128 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 144 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 160 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 96 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 14 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 1 - - 1 - - 1 - x: 80 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 11 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 1 - - 1 - - 1 - x: 128 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 160 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 48 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 - x: 80 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 2 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 0 - - 1 - - 1 - x: 128 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 2 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 0 - - 1 - - 1 - x: 128 'y': 432 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 3 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 0 - - 1 - - 1 - x: 80 'y': 336 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 3 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 3 - - 0 - - 1 - - 1 - x: 128 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 128 'y': 304 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 80 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 32 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 32 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 176 'y': 688 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 176 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 1 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 0 - - 1 - - 1 - x: 32 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 14 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 1 - - 1 - - 1 - x: 176 'y': 704 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 8 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 1 - - 1 - - 1 extends: cgroup: Solid - depth: -7000 tiles: - x: 208 'y': 352 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 192 'y': 368 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 192 'y': 352 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 208 'y': 368 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 176 'y': 368 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 160 'y': 352 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 176 'y': 352 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 96 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 112 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 112 'y': 432 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 96 'y': 480 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 112 'y': 560 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 96 'y': 544 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 24 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 3 - - 1 - - 1 - x: 96 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 112 'y': 592 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 96 'y': 576 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 112 'y': 576 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 96 'y': 560 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 112 'y': 544 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 112 'y': 528 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 496 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 464 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 448 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 464 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 416 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 400 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 416 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 96 'y': 400 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 96 'y': 512 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 96 'y': 528 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 512 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 160 'y': 368 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 176 'y': 384 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 192 'y': 384 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 208 'y': 384 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 112 'y': 480 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 96 'y': 432 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 18 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 2 - - 2 - - 1 - - 1 - x: 96 'y': 288 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 304 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 320 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 336 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 352 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 368 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 384 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 272 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 288 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 336 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 352 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 368 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 384 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 192 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 240 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 256 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 208 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 112 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 96 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 32 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 112 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 112 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 96 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 16 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 0 - - 2 - - 1 - - 1 - x: 112 'y': 224 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 96 'y': 176 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 144 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 80 'y': 80 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 80 'y': 48 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 64 'y': 64 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 112 'y': 304 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 112 'y': 320 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 25 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 3 - - 1 - - 1 - x: 96 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 608 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 160 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 160 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 160 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 160 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 48 'y': 672 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 48 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 48 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 48 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 144 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 128 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 112 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 80 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 48 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 656 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 64 'y': 640 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 17 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 1 - - 2 - - 1 - - 1 - x: 96 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 112 'y': 144 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 96 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - x: 112 'y': 160 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 22 + rotation: 0 texture: 4f8a6124-427b-410b-a467-ac42afec3644 - grid: - - 6 - - 2 - - 1 - - 1 - - x: 96 - 'y': 112 + - x: 112 + 'y': 128 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: ae954867-1039-43f6-bf6d-d8684cb58612 - grid: - - 0 - - 0 - - 1 - - 1 - - x: 96 - 'y': 608 + - x: 112 + 'y': 624 + opacity: 1 + tint: 16777215 + scale: + x: 1 + 'y': 1 + frame: 0 + rotation: 0 texture: ae954867-1039-43f6-bf6d-d8684cb58612 - grid: - - 0 - - 0 - - 1 - - 1 extends: cgroup: Decor uid: ae6bb30c-9ad9-4390-b632-127493eb58cf @@ -8774,6 +11333,8 @@ rooms: } eventKey: OnRoomEnd type: room + simulate: true + isUi: ! '' - name: UI_InGame onstep: '' onleave: '' @@ -8784,14 +11345,21 @@ rooms: - x: 96 'y': 88 uid: ff0f561c-a96c-4205-a083-01d2a60ebb67 + exts: {} + customProperties: {} + opacity: 1 + tint: 16777215 + rotation: 0 + scale: + x: 1 + 'y': 1 tiles: - depth: -10 tiles: [] extends: {} uid: ee8b4583-614a-44d6-aacc-6569f49f6b80 thumbnail: 6569f49f6b80 - extends: - isUi: true + extends: {} gridX: 8 gridY: 8 backgroundColor: '#000337' @@ -8819,6 +11387,8 @@ rooms: code: this.hearts.width = 16 * ct.room.lives; eventKey: OnDraw type: room + simulate: true + isUi: true actions: - name: MoveX methods: diff --git a/src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png} b/src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png similarity index 100% rename from src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png} rename to src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png diff --git a/src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png}_prev.png b/src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png_prev.png similarity index 100% rename from src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png}_prev.png rename to src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png_prev.png diff --git a/src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png}_prev@2.png b/src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png_prev@2.png similarity index 100% rename from src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png}_prev@2.png rename to src/examples/DungeonCrawler_tutorial/img/i14d3f53f-a868-4820-84cd-63234ab6e6b9.png_prev@2.png diff --git a/src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png} b/src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png similarity index 100% rename from src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png} rename to src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png diff --git a/src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png}_prev.png b/src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png_prev.png similarity index 100% rename from src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png}_prev.png rename to src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png_prev.png diff --git a/src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png}_prev@2.png b/src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png_prev@2.png similarity index 100% rename from src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png}_prev@2.png rename to src/examples/DungeonCrawler_tutorial/img/ia42e0dff-69c9-46c3-8996-745aaa769698.png_prev@2.png diff --git a/src/examples/DungeonCrawler_tutorial/img/r127493eb58cf.png b/src/examples/DungeonCrawler_tutorial/img/r127493eb58cf.png deleted file mode 100644 index 8749b9745445071a3acaec97784fbf263f6f337d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9594 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 BLht|p diff --git a/src/examples/DungeonCrawler_tutorial/img/r1cd7a8ef-febb-4174-ad90-42846504b06f.png b/src/examples/DungeonCrawler_tutorial/img/r1cd7a8ef-febb-4174-ad90-42846504b06f.png new file mode 100644 index 0000000000000000000000000000000000000000..f6cd9432ab66796002236c7a0bdb17bcdadaaea3 GIT binary patch literal 1664 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 bcQfT*WjTGrzUCfB00000NkvXXu0mjfv*x8w literal 0 HcmV?d00001 diff --git a/src/examples/DungeonCrawler_tutorial/img/r326893eb-b9c2-4616-aaee-bb4641e0423e@r.png b/src/examples/DungeonCrawler_tutorial/img/r326893eb-b9c2-4616-aaee-bb4641e0423e@r.png new file mode 100644 index 0000000000000000000000000000000000000000..0c795276fa7a259936175c1f6b8aa9cba30c7dfe GIT binary patch literal 7081 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 BLht|p diff --git a/src/examples/DungeonCrawler_tutorial/img/r3786dc4c7d4c.png b/src/examples/DungeonCrawler_tutorial/img/r3786dc4c7d4c.png deleted file mode 100644 index 8749b9745445071a3acaec97784fbf263f6f337d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9594 zcmdUVcT|&Ew>K&^3PB+v9YLiDC>W$;sEPuigGf=D^bS%ZVL%0G(uo9iXtV10YXGXM0w}7oH`NF z2~F@tL{19cnGXpCzpxSAkwa)cFr;0wB5@$y83qd!jV z#tTNV_V+jrC3Jnr^NF|%6PJSIUf%uC91u2M(O4fw>e?Ij=w0|@IdTP)Th#CLQeWk15?`x!Ij#^ zG0w+{Qjmtr#UEZ)pWo5F-nA-pNl2m&GNt!fot^~dZ!J4nQs1yCQ5_vJ!JP?(@Q}bi zZIf@xJIA9T>WY5oY4*f{<-RXINF+DzN>gfC3l@X!wIvT1elk|@Ot{!lqH!I8$iQ5o zXU#(ve|JoxKk@CS;H7aGC;BuQ`zWDn*1SPSajPB@ zO_y=+rTl^*6R&1uuVpatZA?0a110QCT}Y6MmoTxrWJ&z-PPB1($jFyr#zr?{^{@%) zD*BghoxH646vlJGcl``WLa@yr>%nqfyv4nSt0NJ3VdC425)S>MQ>rIr`b#AKA0Jzo;&<`KomHgtI5@5w*4+9dUA3c!mvk*#XGXvin%#PP1=Xei+ zwV(c%FxC_x5G2_{)NHoP?+s>1VlH8db_ZMh9_^0Zxs5t!<*cUE3bm&s{enEKG!Ker zTUZd`!tFkHlnih0PQRXqtoJTCdjrCA;S9#gv^1lztmR(UOIVI?`~BP!ZrtwJ8=1>O zjEz)ye;7|(7#H&M15+W!TCpmqw*IbFaQk|@F1ATig7M@>h!!i8_OE2u#iDnfpCsvc zD+52lGoH$s%jZ)nZ|-THhcuxwh2*d#QGy>k8UxTuh*G!umOv4QR#nG0gmQ>)6Ve8O z{wkM<&Vf=j`n3mnoCCGB7IvH}pq~Cuq{<*Uj}b@yvo;nG-b>U9PrGDE);=_yx=?NK zmXHZ!X+Kvvg?Tj{K3l+Lo9_~e<-z8!l%a4Ul9avd@WZ{7@Sny3t&qNty1ktYe=TQg zobk4;rpsXQ#fmv>hYgeJb)PpfW&sJN-o$&UmG?k0q}@U|M|9Y1<9|wV;b=8!Ow{xz zk^iZ6J?xbe(S7|2RJ1*0sxrHg$TwspFeV$}bFa}5(o@u;LH>qJgfu|suol}ve-Bu7 zR`-JkgvG2MS;#W!V%3>!Ch1jWrdL6-Bxk_CWMc6CvW{%UkCJ}_>9wCmC_NI86aPO- z?|;1Z|9e1H=gB}oIX?Uf=yE9Zj6mA!1@6gLjjRkBjyx`5T#lYb!7=w#;5l z&OGFr;!A7Xu8jikf*@dtA4Oyo;Y0w);Rq^>1&)}1zd+dA)di3Wi1vlx!8wMcRsVnI zo%-6x{2CyjeF+g+IOh2|+qK!eR;E2B^ujakONN9!-(ql@cZa zITn`6$Dn{@Y5`1l5n%Zd7XgC_IRC!^gMUv1`N@hG(2tk;uUB=vb54q$5v5(zk>2M+ z9X^ns_>iUSH^B^un81axUlpy}jMDSg9QuBc`0Se>>UGa1YSo5hu@ppVG=;Xl3lSNr ztr{qu^-&dHgy{`cw9`p{RKN<4ytR&p6)|oe{jLM<=d##ds-jb2tSynMr9${@Eo_+` zT|9MgmCB9-Er*cjnkxGdHOf>htl?Xmt_m%u_3|znN2RMS)NzWfXG57@_0-k+`uFy( zFCU%%9y(#OTXA#3C3xOs{9DKpEoJ5_qO5&m-4Yn{W8so`N~8NAKb|>L!WGo5*RBQz zYc>WHMugJTpPQ%2QaY`jF3<;Wk!C30Ua###^|#m(JAZCUUn8AyarWk~u;6&aW1lF} zoZNCzyj=ez!2ZtzB0Zk(9uZC=3DWnDd@A4ha50did%f`)n`53{;qY#yaLrPRs+iOa zdvr0sSO2VQ+*^tKCu%%WQntyBD^XX#-Au^6A>R9#-HnFf+r46^!}r$xyE5ja-tD1I z+cnoSrUSo9(~qQYRt4;x$o6cWEv^d$+k#_?|Fy)``mpI-i5ey4B7?|)E@FR_t7>- zQ(ItQe@64uhN*p{BX>rGEAjg4y_Bd^%_t)#KW2|XHoX#4f5vF!SAJ;CijKuT}@V_vDx^mOVath?H3X6e1sl_6FTRd!Rr* zP*e7aL6Jj)64pxql#PjPFDWP%B6IBq*@9!uGuJYuo>49S7&HwCqA?2yD(()w1L0|j zK__@qZhQ(hzZ)y?uIeLQuZ3L-gLaQ<&BBJOm>3%WZGUbzY&g44XsXMwe2T$ph!_;M zzf>;0*daHLO`n$Qaj1sxS&9Oz7&2z7ecxq$$71A_(9&Vc!B%Fo!d^9Le%HYcPd{>l zUJ(IrzWVqD8d8*jY05FZtT)06X}k9n|1WGpkAptoTTp- z8VEP)FDt4Dl7UpfQkS`LE%Mxo$dtsjlD4dQ3reSHzf-22-_8`!G`-Y5ozoMxg`Li1 z1gcZ%Zy&1XMp2`SGY1boy9#2AP&;2LY0Q2ko}LO*?TY4P@qWO+H=sH-ycLs85?wcC zpJ+v^dB7##EKLG44F~f(0o4&hdw#k)J8b>}{S)Bmb{HdK&8-onQ&{0d`99lj zi+S~1Bh?5EU*~po3>OG_K9QffEO0Lw8xLiW5kr|J-yzC79?>ZpzP2g>rHaj`!L>pN zCosvtLsIJC1_Zk{E?|P%#;+*=1YaJQA0-*2_2C5O^OmFs*;1Z;vY=a3*M|YAv49g1 zHdYpt?K`L?AFcW=Z4cFDcZQqNN%Iss4`f49`h=U56TFeg`Uh{%mV}lC-oK4}J-h7z zhdDJPpr67fL~o(b?=x-;$QyCc=y?~OlGi*dglIOFcDp>zZ#W&6F17+`*=Ic@a`4ojC9YYoNiLvu7@|~amlM; zO?-!=09|!N-FiFWJ+XKOQ^bLt_+Ib&xorE^x7RoJYY)qMMs`exTny!hryC%p=}x6_ zWNi>wy8Xn}p9?_*40p6kgcM-Sjks1rH|Y9b|4?MhlVSESj;!8R5vWssBXclJdD@BJ z+e0d8X;+?C@ZfNh{(_k{&YCgy@*~)MUPrM=XV0WR%qodI#yCY6W@Q`8q;5bqsZ#UW z$_X!U_{n}E58Ii&$Mee0EdYPRrr3P&&02m=Ef%IvBY*YlTh7&%&V^_qUd?Mx!kuX5 ze3=DF{4KqqUbY%9N{2dCse@bY%6)qxbBRKS?vGRgs%8a_nCK%O(&e@89E~MdHYP~A z@8)@ty|i-?D!?{1KR(V+-rns>b#=)QO-nzx7MU@)aNdir{P<~SAFmE``tI`XVYkBt zZ-vp4u%n~Jgt`5VO2^w3h79L5IhqaC2h^(wNA$8Lq}cdbE^=>)voj&7%TBTJ{zkrm zH@+U;+gYwacIk=9QOS$KDb4ztn~TvCG-vEhLH@3A4_>%wxeBz6bECp%C3$3VMAs9S z<~?P(kCj~V2+E}2+>)Z+-v~%pY4Ro4P~mXd2imFZ5A9SUHU40#Yi?r9e!DqE7a8Vt zxg0{J*?48V9s-w=|HX2E3(&&ouRnNu!>z1c+ai65S@KeNYkXf=2`Pzec6N za>S-YrgS)lJeV=>&pbZ{VLZw+=-O!r{yAqVs%_N8b+IPD2dqiDWTSx4;z+}kH5+-; zCcK*MVM9UX=8L?FWtgd;IhP!}n=Xe605i?NK&Sl&1spOH7x8M&sPbNst2@f>u+_*z z_HiqMW&Bk$0jAkzpT;}VuoB&IZ8u+AWFiC05Cd@!)ceI7{J$`-f03tGq&eW4HPjks zX&7{!p3ZPewN_36K_YbSEZJwxdUIj#j7CMTidIzwUtEy~WBTQ;aaKeorzaCw;Rc|= zW=JV>K2{w$VNv=QcFor$wG(#I##K^0=IE*jgi!6~nLh?T<9G6cS=|o64}UvSm{43* zXb_Bdxi=kx8yIS=Xf@*D6f3|wQEHXeM##+r7V;!7_J-wfq{{9s4L5Ovdw*sO1y(Zf zHov&G9`+AgdH7Jv=9sQ+XGMFa^6ydp*kp`82>G%aNROfDu87_BBWiZhS4cak1RWFfg` zX`}8ei#8TgihDj|)T0S&-8G$U<=aEK3FR#;TJNfc0Eu+P@j49&R9K|d*I>EN-BtiX zsRb%2>o={7oz6ziEunf2Qa;gK`Ls}Mt`z^=B^S@nm?-qYV|=~G`P;w~mYkW-$F^=s zwnO^rmx?zsaO~5Pvx&Fd0`42tA+)8+73|_Y6CQ{itS}|seBc@Mz_m@oY4T&eC@MvY zpX2?0_$>zDSxC}A|LK-<9+HEncV=3GZ_Q{g^1J8O(j?|oU`wCIp+>8CbQ^_q`EPS8XzQbJ4Xl`T!2?fc1&%O%X9Qb&IA-Kj2h5)8fK9V2`^Km3U*{=W%v|W7p0W^Fb}zL z=0CE8w)ZN+*04$?hg2tcO)?w*1Y&i&(U!eXf)V6}@}GI};L~aRYQ(Vf1*XjoK}gQH znZun`AQiHn{V5gFFk&Q#V!Veeke!K zF@{KgX~`)qU&E;|aW|Wn%Dq5Ay<|V$6Q6?#O6t}FSx~b{t8;%r0`Q^AK!)U#!i12p zW;}kd{Yr|E*SCyEUihS&EtqFZc%m$QEng&+Y~St2fAinl`#Ne^tQWYR?^6C6C7$x- z=EB4gsB;T8>KhNE0K-yqdIp~Ci1rR(C=F~)NnXv$N^mqKw1joBR_x7XP2>{JkL5%2 z-$3B)dUd=`Da+D6-xHfQUj*J};|4uMHUy#NXA;nwr5td4+6+0qQK^m(ff)xtLQdR| zG)i)MDq@}bI@W$AztC!g-Ai*JVPc`>g@0wB)l+F@Z%Ja%k9+V%i1u+P%nBppGhQGx zHC#R#ySpc(vHcGyfnuhu(*eeTa{eonfdr{@UVd1#Y#;1&fih=6C#Js+c!qFeklJ#8 zP3;^q>UWwWva zz4=C+?ysIasT*0f`9|nlE_-u6JU_4BKEd7Oc-*x*mquWT)jmGe-9+fuuIS4>_{l|a zR;MGk5!KGvTA$t466*r@a%Mygs?$gGETg)({8wRq8bu`8YgC~3>JPyPQPp=Js`{~~ zG9HcIAE;V2*{abp2$O6Y9+45?*OFZ4 zDb^f&+!cpd`Ch*T>MsLRh1Sfgr`5(D9ySe4rt%7GatJ;8=^(n-TRizHS0J|E-L~U} zZewnZ4s8*9ZTdPH<|l((mI*#7E|R-kJL}Oq-E-fazc286EnL>uDTu_Ms>iZWX(h}U<;vU+K)+G^0S-O?v$?2(*RS<=Pwd9M=}7VZ^8 z`I+#$KV9p0itMJDcYJVp3OCClEC76-ko^@|& zP_-?Et~6$!wiJmklIdW*L&(tjFHeE-QA5%|a&9t1Rdys121QfOqQ?EhG=y{eR6NjB zaVHY^^f)15bW9)*$;T6L*|^4h71K(q4uJk%ShS31Fz$1su*;p^6K?T0T%1&jG0+0+`P4Y?9HvqK?ehJM zhuneSL|>sH=vJ%1Yr*V?T<1q`&EB_v&O6*YI%hIf@4uv6GxU&Nh7P=b6)LM3bc)J&$K0&p~%&MvLTm6hqc+Gau%wxZd(>s)lN*LjRtaCEGZL#66|RV_I#Zc?aWM z`cXFIHh#U^ddpD#Xp(n)KL)kH$yzbwU+5+E7UL+cmbsXsQjahAp>mzx~Em(wWDtj(U6^`*K*Jt}K*Y>`F^u^<6_C)TUsJ3mD zJ8xn0?GO9Vtnm4`r~6F`Js0`Rr}$n%Y(eB5t!7!6Rc)~Ph@(fBB1r?|;7ip+C7Cev z{Sw8B%ar$*YF>ts;CthykrJMxsDc}eV$Fp{|QYb5i1-pA+S*uJF zI$bn=clVw-)V7`&Eiil9D`b7hTDUE|Ho8E0X0+2{T{%8jlf&MSr+bh`U3=Qs>!60& z!BAs3!~UkF-a9>>uo0sKqx<9b?u#0i&0e=oGRj)ZwTgerDy*Hcw~yP?nH4pU^WH#2 zGPyQOk4-$3J?B8~&oY zTS{eTjZ?UA)&KXdlO7g7Q1tA?Nfna#1BzT^!}s-f>{|s-XD0;d3brr$-Jk}hT;T*k z^ASd@S~jfp!RiCBoKww}-7IcLI327fQ5N%-(og@4N|u(tjXtiOSYXJp5P2u#lU;x~ z|GoI^=BL0*%dRwF!En?@^t^} zHRxS}8A6@_eXhz^biG=2`&i9+eO`SX->V&661*ew*#k4l6GeK+qla8+)`k^VXO?8G zvX)b$1ZRP_JE^h%Tg1JOCe3W(t@RChRw!Aj<%WDCY|0~^+z%>9RGyu(Ve0iGNm zrO4{8)*-TXKWx*s#U;JvU);xQ3nnERA zMp9TYgJ8QM5fKTT@GQWvS(xNhZXhX28NO}JJ@V|Ijtbwh7;y%z;ahl}mewWi@H(Z~EmG zr3`{ENwxkwttO$n21Jw%cm|-HSJ)diq<9YDD#CYv7(d>+_0d#Y0h>9`@(VrAhM^Bg}wX3m1xsiH>dK-<#*i zEvVsN^2w@q5LI1um*Q0!X*d}9g@l6JRWq{v>L!8WC5gYw5ip{;jBLMjL)7^09b{VO z{>aiMGYfE#VQb;EGZPd!{h;aRL+V7?$Mok+m1kUnsqw6;s;2)*{PoosaxiTF?aH6S z^+G@TszCf{JdR~CVRn;GKYi{wNBVAaG5f@a*<9aUB{0FI?JYzwJxXXF%1^ucP>z|b zDv;rUP=4|g?4JKqyV1HBG=tEJE*4*pHF;I8>__McSGIu80BnfNbBLA@p=|R2pg|WT z9lWOlrF?I{XZOR!uA412HK44|4Ci_u@UfgUh`7Z_m`$X=QTyTnW)nJZeIE1n8pl0} zX1(`4+#Klj0qg`AdVD=D{lJQ#i7)6 zknH!Rh?@d1OIz1|jn_+&=TVl%g^$t1ug(JSSe5NU{&ACvZ;sV*qsOe_!GV31%@x(S zOXXb&+-B_E`8n@wY({<_9(FprqMj?K1Ga2S0X=l0oU zo?Z)952fjvee_k`YUF0&uMquclo1l)(t_U_Gm zkELk^ws%`X)67W&8U3DC+TJ37FaGtypc$VgPRsg|Mo!lV? zV)UOLkP9bHFgCIG+9Z}r9DSyRvkxVO3KKWWDg*zCB38+e(zSf{2CLmq=v}BR{R+JM zzqj7gFbd@VkG>CW?`Nie@z&G`*Ta%WANC?_bpORnL$q zDhrp24=aXkXAN+vn1A~599qq#44?mWhK`O-g)V1U46|$TfoH0S?#Qdi704K){|mno BLht|p diff --git a/src/examples/DungeonCrawler_tutorial/img/r42846504b06f.png b/src/examples/DungeonCrawler_tutorial/img/r42846504b06f.png deleted file mode 100644 index 39a24d49b9da21f0b29e2aa4f71797236492b795..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18511 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 diff --git a/src/examples/DungeonCrawler_tutorial/img/r7b6ea00c7b7c.png b/src/examples/DungeonCrawler_tutorial/img/r7b6ea00c7b7c.png deleted file mode 100644 index 97d86c767a59b3adf51fdb5d360e269fba92bbbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10275 zcma)i2{hF0`}Z(0me4{f49dP!lr6(lG7~07WQnXbj5S&?Lxrcsnl1Z0wlP_=6OyIu z$ygeRvSnXqfj}T0 zqf6(_Kp+-0@B`vt2fkT|i~@cU0~wvyN8i1^m>&4U`GWtuKwNpfhY?XNA*b~w$9WDU z?BP_jBtM^Qt^pf|scd$AF^ogt#}za&-a!L#@NbtmHO^w$w=D|FvIhb#$mg>8JS1>D zW#Ar0w79Y#}LqNtzCMi+#fW z?{7H8Qdq*c)YWo0Lb$TR`6G|~MOoF%%4iAC5do&+%3_x}aZKm4FTx#ea}ILecf=|u z07TsTi_|Q;;(^L(KbUR=j}h<&kN}Jg#e(*%6`wj^(zH?29&LO@2%3D7 z&!Iy(e$_S;xnXGrJny%7@YA)|b1hSLw;<33MS zG!QB*>f3ga1uL)@S09}SE$VdfTEvXo8%@U(5s^y2UKQQ`L(+63OyzB%Ao%lCPf^YELmJ4Z8RHgZuhQPvqQ|4 z;tJiJ%x%sYdd!xJ-+}-K$y}lV!S{*LdrpbuFZ1t}B;G6JMfIOc8+qFv^H+6H9tU8Z+D?h`jx z!cRx2|6i6_&$bIAyKLn%FWj?c0X&?rH`x3doPAjVci;1RKbCb7LA}ZorD4bkmb(tT zI^N@zLYQiUzq{)i(+7u!E_k`Pu)&H%9A!X!-5C&*x~W^>tPSauaRMYvD-aA;4~J0i zPkd2?2(eP5g!)QsDrz#2h26&n6Z@`22y4^?h&7)U7~sj`uYE^iD!_YT4D4$`CnxF8(W3!LR5h-nFRUTDYBFoQ6Iwm4BFPJzb8$_o=XD;rVQeFOgS znyp`jM%EweJ+=3lu&AdCcCj!WoeK!A7aPz2*b?}tRO5ETcnQ zl^4P&_JOvOQ!;2{CB3Zk7!3AiSGLID^^bIBkl;}w-%nXxPkiL?Bc-?kKERGi=0;D! z7fnw~k!dKsz}+h6H_-Z>$6q%if~YN#4{fYtUPhCn8hVGuO9Gd+TB#Q{y{Oey)Jy() z%a2aY*9F|&F;Bw1)$wj8M0Rbl?bO8t)4exKr*no!w=k59qJB>J`v^*SQdc06FSoam z0X=1PA6wCGh;4NJH6}3LZDoXk+ z;Q}{HwYpb_fA1xp+Niv(<-4Ax6|aAA;{s`W_6*c6Xe>uBvuXSO&&oSc)rB)f%GK%k zpfcaT`9u&q{h`aUjNKN?V6i#Y(eQ6{3-HgLp47N9Y-GCsUE1!KVDub#>(;lYY13G| zLx=tS%1Fk0RgV%W zgkVJ>CRwNR+0deeLc>Xjdz5HTeP+fw?B#t;@(K||eP5{=f+;dKBlI3e6`A(hZpK|Z zwxA|7l&KKqra)^c{zwW|poNKl*Gd6nZtC%KRn|$6UZMn#5j8R#sbj@jy?6cYwNEUU z`HE+7pI{~u+d_3SA_y~Bgd*O+U*gLJp+BkgsH@(rGR;D{1gq=Rj?yQ1H*Po0!^Rqa z2F|RtL=!7)U-8W^h1Ti6OJ6k=A`-x|n5Xrb3qx1#TaOPxNr4lH^^F8llQJ~$xY!YD zEo>iz=z;YbHx;d%AdzOJti-`Z85y+GWt(VYARb5} zIIJu==6*oJo0FE;V}kOM!15t=S+MkthdVZ+HSav|YK%!%Y9bj-x4Y+oIg+%EA`Z62 zk0r`5>M#!7ajJY?43ux1dVwhWNHAQ1=H}7Cmlci|7W=e&I}>gvk=35KwFIS#q>`eA z{IPt4;|~K0Zt+!d5M2d#_;!(sqJ=0THwl%$gOrsa|JeU|T9#GvTDmA1Z7XJ4Cg?pfySQ%g#^5nN%`yr6ovQ=DNG4b-AO z!bRS}OS0xOD@BwYxGFHdC9-SNMfSTS+FPeNXDA3WQZ#Va<4L@1@MmWk+#&~YR9VYq zK{{14aeIK3)ZisjO4r*jCS;5g4$&na8-=IO#EHTpmrqreO;z7XVyxZn54DCA5?ahW zQ=2nYVuU5f&lTS6C^1$sp4(cY&>m>cmx3QW-?b^J^Zd2hvwPq2$8qBm1!#n~_9YJC?cY}K@_cEyz5WT`!|0`AzNI6+rK8*WnS z@$%b3eocDCbXs}O$yDXb#ZX(D0!GlxD^r002BWa0d*j_VDI)^?aY6xfEtcG7tYVih z{Hc1_oZg7GZQB-{k4Cw7h*p25!7A)#^!G2T zd2N37yH!g=T%Ie-K3>(0eut!Ny<1W&YO>FeH&p*S&<{JaaLJ?9y6@AMfLI0DwFF4o zjYe9mamP|D#rOG{e7d4@G*v&d&cDE>cxm1E+fbr7{&Rrk3!5Z&LA#Udn>C}=E@nAm6z z(pwzUSs>6`o(K63%m(n|XK;0hVTX=gU){HwmdL~f*~z$7klZSP*GXn$XaIc$#Gj%u8pK#e-Q?fsqPM^Lu5DW)ys`R|NM+U~1ZI|k^ z4LXZ?pGonM!OKeHY<-F^qU%=so}#@pPF=x_pP5OigH;-x^%!$3iJcLn4oT;r=HHwa z`1Ra+bxW4RN5&#jrNit@?kS*JeWSvxzFmDg`d9`Z7`#drOTH{8ilH(X^QSa+Crk$A zBj7A8iv;?*Uno^tD)yJ!kqWacN?;BhZWfJxFo(JaQeU*-yaXbD1p9HKJF@&rZXG6; zi5|cC@G2{sJ4y__0cG#MlVWLnlV2{xy4ckWM=ZB4RSlhz$u+EWx@?A<386O0S-*6B za?RzyZl#6XfS%yCSs0=#(8$f_FkAH$1oiUGE5;+BESPRjei?T80L47tF)uR6#U4W3OtT>%lD3LhF-Mo;_u2S0w7=Nu~;dd$tp9c~7NVL6GOZV?lt zowlU&1YZ_6zFZUg>Mjo}QIo}YpME^#1!^5hF_Mtw=XJtz<$6p!1jRzWvA{z7rMO!G zYh^KGEjJpCArq2LHdjd0o>IS>>W~s=6cKl5RN{5P`H!k@cVwGyk4X#@GzN`SM1FD( zPOjNoJADbfd@6xD6naR;uOp`biu*Q&Ix(*G`0sg%yd{dBi`j+oNYoBc`Ry*^I8+4=nhHlL~)+Tq|gm#QGuU00l zXxRhO8->IVIb4TJ!dR)-OW42*QVOjGoJ%&KSO@nr0IrwUv)HOj}LT z4ZDMgJaP5a=b3Ldd*)1k3nh)O46w?vj2m|eZq3~iA+i$J#X`(+dy$&#^E*=6iQ@j$ z-fxDuwVAh>{$yFZaeh~ZQLsXONX|Lq`78_K+CqM6q#irEE}EaD@jat5c$Fk4sdQ!$_P7ftBcTb~xCh6OzIvr~5i+n&B4NApJ%3v^Zc%6aZnT1N=^o z4@}&e6p#T?)i3aQbLmK<=1va=vx*%#aSpv#C8vv_Y8Pm0(Cmcf;;+cBM7ek4*Ba;l zI=42|L!O6!cdmQMmEc~FbsDH<_YUoHsX@r1x9%eBh)Rc0wG5uN01UD1%c*c(v;wW| zubD5L7nYq7EQ5_t=blLGNjK&PewEln&7+A%aq}7>h)p7R&`o*V?6tc8*7Io_bEi!7 z4DH${_%z)zb^CK75HM(^q404(m_NSbu$q=EkX&v-Qx9nqzS@8(tQZj@G;mfAObpbP z5=4zjEB)Y#*Tj1ueloYAVqujU$4v-qn?UG+) zEe@R*N{w5kn&Uu~4ZYv^OLAIjJ03RWQNA3S3_y#meRLKGLn&0?REO4WfAGu(n>T| zk+D^ZznlB(&a}KBTQG8%hyJohJSkJCvTVsIHE!pX&e7y%2b3&+?4C_`SZ2fd&zZ$M zq{D;SS7&3c$oaLNVV9cXCUtr3+6?N6k4D@1r)sVW1wN6)qz7)|7AZFpB#?)i7)uTB z`PRho#hTOM#9gy>zu>tc#ld6Rc>f}wElqNM)$3L%+E*LHraYOC_>NZz*O6R?rTsLS_CO)=;i}nq9f1{S`1K>rgL+yoL;L1T>b=2qYJ>FW;$yxCW#24 zH7u4hvM0PftSW{Z5;why0_i`S1OU_Iy9M35OWknfUKOebW zbg9#HKk-nqnTsGBu^5ql1Z6H(5qyx9q?bI(N;M5y9c6PiDC2)XY8aBM*Me1ID-JWl zd75;pR%1bfmCsp8d=~cUtV9bjgu@Z@#HA^r8L#Eh+IJPuEM&~1 zR(?5_LAf)WXg40Br|pN`JA<+S1=rxUeVEQuBXE&>5U#<; z{Gdvmnh*n?Nid9Oiw(FW-<>$gHgL_HxOA&{6ty*iUO;tTcPAXTZp<^G?Z64iq_3_k zMoR>W*0j!aH4^8ZI%*nbAQHVlZFTmc+L^}hCWpu1(+*nhu*gt_^%3;_GHv=0YeEJ* zQa7>`qvFh5uEt(bAqRh!VV}Gfm1UhP|_q&ZG6v##PBcE*&ZNmP34WNsWP$KsxDj{ra; z0JE-3=^qI6kjqtDoHPeuUuK$B%rjNsCZRo6qU|)a#F(Yu$wJ^O1I}G3Qo>^3|XzRumH*AL}7!-1RmfEn$sgo^8N>+j_#JJ2?tiD<3C!YuC}(%Gxl__` zg|FOo5!ESWV-BrM8;mQNwPqA*1=^*n;d*5`ACSm&S6LS?MSqJET8va7GP1 z;AbK}sPfY4Axwl#NwVI1w|Fdd8oRQFsSnUO8?d!=ZXG@CWy@+?H&O&A8pk(!_3gO$ z9;E-;G!b zcDMT(t_aQV#)woyahHEF)`InSu{-)W@2>pLc1KYF?qn1Qr8b(@u2T06?5;OId`Djy z($0`!Y%m1rZA}FC@5>u?n`wbE?k(5FYV8$D9bK@xW4>it5gz8+@55Vhor0=DWgFX5 z_BtY4i0w_QV6!T?%V~ew8ly{!AN=j&QK#*#=f<0dUnv)qyGvhv7b5~dpkVW9qHdhl z77qSkPAfL2{%WvH?!DrtBqdEvr1}+r4HEGk`EH<1z(HIr&vH-Q8tq%t;fO_$Q!YR}Je%aDT(+;RsY9a)hK9XU(2 z#(&td=eCI)+`B=JWjNe|fvw5K<5G!sRFXDF_ziJPR}yq{7zwhXA$UUpuZHQ?MNPHTbybH?^j` zN{G5|H=1utgN9gZrTWD?i~V8aLcv*y3=qm@AC($Bp4T~|%)(O~3YiFC7McRff8me@>0C!FBwecL8| zke$4EZb3(<=?@3}FcQfmI7hBr%bQ7V%g4giwtP(bDIow#;c2sqs!7@Sg+Z>t0Q$+1 z4=4ixlaQap90rj-TuE!1y>TQ0_`fiN$mrW0M_g6UWTI65Y@c@ek5~ua|Gq)iZ9_KtX@yy8M0807(4I~-u6|LIf z;>5n?eTN%gqG)=xQiB+DBY$%7*V`r?r|uFxfZ;dbf%Q~VW4u|pD#H!fP_%=EVRg=q zAQTN(YRSwhI@XU=ruHLTp_YV?A?J1!Ar{>j{l68JSq{!Z0Oxubtzh&`Zcv)CTE%O% z>eSH}x$||i_CZu&VGBgg;!PNdDgFH9CA)7nIoC|HhRH#pBXED)T$ivMoy2VeNtUcm z_LUqdc96vkepgO`_OnO}gubyKA4vxM|6>(F6AZZyx(} zZM{B2xV|0N$7U>a?|kM~rcF}vl(?)J^Sq+Po0Jp z*6+KPs&(ewrAXuQe2t0EydHU^t*&GiTl6;ZRZeC^KO63AO0qBh(Gy{R8mH~p%aKq$ zOmE!oo>wB$cf0eSpS$>AE;cZR&wq+rQNCuiL1UHBc!PHAXKwazBu|LB=>6BLXLgU% z8IT?7EiEL8)9y!iw5N*budl{o>&m)x+m+>lh+W(4`rx@uyoB5xs_50`ksRCSY8Qm0 zZQs4cU*9q_sh#m(E~4*#UVa?(*VAYE=g1p>JCKk#%*^wo%v+-MIYSqQ=3U!VTg?ll%Fz zZ@dz8+guE3c@9J>vwK?L8ItbGRTP)G_jPJMlV%j2K`{?DN z=hi}$RkUGmc&dZeP@WcN-oq}&aZZx71?1J}dH_FXBOvyvRXlMAM8GLI&on=i>CWmn zhm@C73PHHmHX`AVH{@g{|R{&#X#-EQOtpOxNM@zC)3hlfF&Su@A>6d!fdOoSB}Al9v4 zq=Cpf5BXq4p4vC1=)#TNH^49fs_o_v+>j+{U;iEr9fevIXN`4Ny(~T{2I~Sxr%gkDeY1y!WG@yykf|= ztUq2WO7GoC4OAR-ng?(4YkZ%yci(kgqy=oRstQ#Fy=SzqzZ29$W$9L1jbYR00-K7a zAoQBXiJ*z$2`p3JF)wXLjdouWLlM@*+mNUE0o;7SO& zpzGE8D9`G%FB%w%@DWo zOnuMC_GrW46D9J~%BU5b zLhH%^R7ilUbm1o*AvV6{(f`C2Yk@9Sn+!PuCcT6%su$3w*hv=E=eFT6|B^^q@=>cD zjZdp6qU3p?>mng_J7OH^8W~?^Bu7p@!6U0zkIu+3n5I4#BFai0H%s2|vJS&Iy_F-A z5#mRLC^Z=5K_4(1Oyu4rW*LhjcE{=Ed^gyNUiw0KDP#WRgGEe%E;-)7f6*_H*oYWh zAheSmi*?CbNPy8gdzBdhskh~UH}dp42zuPk~*nKEZ~*@3TeVOV(b;bEaaH8f~X)GZ4nzA_tpS@Ez0 zsmhX7#etScR!Z-Yj7r##DB{81t8gMCFRAFRvK_i?Iq4W@^e%9@=2w9Lr-C<+4xp+R zLzc#TOEu@>@_Tk{l+(s8cEfrC<>lo;)cv>lNgRAPbz!iEWeQJa&&_H*pp(QSbBfs* z!H-$|VE{<>0lJ{9M7a|4fiTo?{lb z0A0`j{GXCnvfQ#Wyeg>p*wH<_psr&k>BRppB47fH^L(6nNYeoET0cR6%@ee{2|08* znxj8~@j)V>_h6Eyhj-&b(U(nZWVtbCRur>K0tB@>`lr3;{G|=c(umG`s(p;yMQ$L= z4Qo;u-Ie)~v#6h~=YL6YpT97y7kWNWG69AJRpE z7AxEqxe0jK=!4L`t?X^*KS_5qd51y-^JDH@Jx59IEc5N$>w*G~@lSV&^}&B|)n0c= zt^^Z_{r^}=@Xp)bbg`-{kiGLE|G4!0na_Xh`JV+ymJ0&aQ=1O;fS#@h?V3;$c2U}9>v$N0}VVAETIr)S_SY2(~cxiVjNcUp9@U@w%Gf% z`L)OAf&I_+nvBjL^b!94AQEugB2{Mc{yjQ-{<}p7@It+z$}*s#>tvPRpVpE8aL*SoWMV})I&+_1JY)-;7q)0_XoR11}1q?Gi3 zmfcgX(_NO+af1oof{QCdAzNi=UM6~b8<#26fC>=c>w$mRL#oFinaseJ$d diff --git a/src/examples/DungeonCrawler_tutorial/img/rae6bb30c-9ad9-4390-b632-127493eb58cf.png b/src/examples/DungeonCrawler_tutorial/img/rae6bb30c-9ad9-4390-b632-127493eb58cf.png new file mode 100644 index 0000000000000000000000000000000000000000..0a55fb81c7e2dec9809db552c7bec18f4a06f489 GIT binary patch literal 1896 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 literal 0 HcmV?d00001 diff --git a/src/examples/DungeonCrawler_tutorial/img/rbb4641e0423e.png b/src/examples/DungeonCrawler_tutorial/img/rbb4641e0423e.png deleted file mode 100644 index 29bb94e953381caef0c2be6905d894430944b8e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11936 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 E0AKE3BLDyZ literal 0 HcmV?d00001 diff --git a/src/examples/DungeonCrawler_tutorial/img/ree8b4583-614a-44d6-aacc-6569f49f6b80@r.png b/src/examples/DungeonCrawler_tutorial/img/ree8b4583-614a-44d6-aacc-6569f49f6b80@r.png new file mode 100644 index 0000000000000000000000000000000000000000..0a886df3cd068acf01b844f12c74009ad8628356 GIT binary patch literal 2481 zcmeAS@N?(olHy`uVBq!ia0y~yUBG;`S~k?}O)ZJB*wP6ogfuJaIVpe+kdw z^1bK(R?MuZE&crL`c!!)77l@mEeEzPu)B4E0m%6yC=k-^(7@0*pQjE=mHQqDl8<5p&%sT`af zSsa%nfLb|L$tpNBICwY&I8QhR)anrM7O0-ZiK$7d$)pX)Y|3H>nj;`2a7AE=AyBJ8 zi1nxwMnhpVEe!D-!G5n%+Ct3^K9n_rD(diF4|eZEKVFzIXTF-{Y`OZ$;UI^}qs* zjVY4xe!%8=!k7IP+Wr^*|0SMbU#FkVT5p?;4GZiHKNQQ>|9cziGyk>ruk!7zEL(No z*)XxBv9gqY%Z%+|Xx!GYVB68T?hOalG%Pr0x3*hQ;ewdJm2Epda|p~36}WP9d8r{2 z%Ppp+TVmyMj7*!Enyh|r(Q|8Xh;|6L{pg&sLqeECK>GY^M>zyCxH+<-?^LpIoZ;el z_2%*}2}Y(|M#tQ4>wbpDNJhuGwNc{A4hwV@R^%2w7gR9NR#>sw|8)`z$Cgn?jfT`{ fni{a&SI2C!r9fcfj1%g>HW-7atDnm{r-UW|(Oxso literal 0 HcmV?d00001 diff --git a/src/examples/DungeonCrawler_tutorial/img/reed8a427-1c70-425d-b633-7b6ea00c7b7c.png b/src/examples/DungeonCrawler_tutorial/img/reed8a427-1c70-425d-b633-7b6ea00c7b7c.png new file mode 100644 index 0000000000000000000000000000000000000000..492948a8136d0de1d0b082cabb518673a242059e GIT binary patch literal 904 zcmV;319$w1P)Px&LP%$2;R?tYcFYb zay$wE7Q~CtfXP0+cng5CHfclpivfUuQ-J6Lpo{@>_v-*){rVHSd|;}GDHQ+>P7H|3 z3;+O{^77<^L7{p_EDi071%Hp+OiJ z0KFp)z;D%%J0|OeRuznU@ctbwo|@{airgWc|GFTCR6y@?HU`9`DN{X+oARRYvuoD zYXGMl-96otQOPQx_21e_eswO}H9b#iwq%0Ve`{XV6i5Of_TD^-eSR9$r@@V@`)Tgk zTe@)WAdTJoK>W-X?z!*c=WRtB_i?**FXwj3Z8$PUY=xZN4O0DCMy1pOp`d+M6 z`j9c`b!gjt48WogXcYi>aUXBZ(Y_;li}e7=ssQNm7SL!*0YIj1G5`|kK^P!|w^#z! zNZVx$kW5Pj0KNfK5&&2{gV1@in4AKV0TKXi=ZkGw^oE}p0NMrvfHqDE1PEI)joEiH z0HavxV==i3_@^=dH0Gbi{L@&j%0IJyBA2P4orT@6v-$|Cz{HLpJ&sntZYgy%Bj4nSQhP-Rz!d8{9X{4nH)AwLXdI}Gv14E}Epez`cxHhvEM zcSp{VMb)yIv*>0mf{h0t=g!n+D=P!)T69i74uHQ0_$XT4~vgJk4i=Y=l eFM^FOg1-Qp<(#gNpV##O0000e<-BRml@le2LQr5U24N1`0ND`RFd zJYonrJSjvW1{tSHPUDor5Sj6fcfEgo|9xw{|9s#2*1hhv_PwvYuD!3lfBU+A*L5d> z=yQ@12ni7p5lQRwmJT8!+pxk{1hz}qGjlIR_#v__#NiwuQrxaEB_i^hw6&!LHo|Q- z_tOi1D|mz1AB;^EaphvshnJSV)?JaQvlIm`!D2oE@vUMD>aacA51og_t6cv({&=_2 zzOQnkva;tpW2*1_ddsY3gpBD&1F0>Sxtz?IJE2+*?ggVu zBdMW&r2*2eRee#v^{mXBEIb&}kRF~zlEz4E=?<;>K5BVHe|wo%^vyAv7t91dvh0BA>*bM?_0SaMWO55Wnl zTV5YHmbBb3X4^9(UkcpAbgIeaOOPt%3jn*2-ZJ3c3D*<(`f$Q4w<*D%wJ97#J#5%S zfJ127Fp}-?&if%5%e(l^y3{6f=v3@1onRCmdy7c0n$;)mgEB4N0 zs_8(KJqgsh)GDQdsMPlh92G1%89WyJ`u&ySz z!tAZjnv46mG+&$7_fkXI{kvy-U$xm& zY$)6+b=EG35U}8e5zv>SaW8Cjc7!s)z7j*{91ag|K}Z8^tdAB4uut?hI^tR*xuOci_fUkLMWrM~pz7AW?35d-B(Sq5CjK&{dq7W?yI&YNH#w^kdDG`jaWr_u~>F(AM49OmNJS}oO>8c ztoY3E{8;VDxusHNs5rwnmJ}`&#v@%6!P0)+#UsC*u@fT6Xf4CWH10;^+xzo|F}r&~ zJ;y}OSRpW^d^_VJrLXJm*q{Ri5%6~esl+5=wVy)RT%?7jY=o@}HewO^DB;dKl_n&E z;WaHP&x@>1KEu+gOd3hgx3ezw<+xrYBc0Mie)c}aKn~FUr88;i1<4OQ-btyjm!L-> zjjC8O0v5{GtiSuS{M{r*kiqK?blty=sz9ZF%7{>dsEcKo+O(3rnF##^Iq+H z&!huf9U~ZOfBBD(EAXjWwfq^N_yp*AjfB@!c|&edYYTdu{gD|;!H4c=nlH&WE&dH_ zZVK?|bL-CGVydg6XJ!f~OxOs*Pwhl8ZFl1-iTtt5mtU4wvzee4V7GZUUTWG`WA^D)lTA0{rBRoeHtBC3t?9TzU zN^GVQ8cTW{0K4exG|7K*5CE_3*+FrL`$(v#&_jbeZpzL=)F6_iL>05pT;nm|&yv>KUgwzuNEPqfalevj5O>xSUyk z+C+E*_UpaH&Z(;kG4k3y^6w1atns5@uypR%->@g zz3li^bA^=*qWXh5!V7lM^{Q``MMjQ?zgMdcuI6%srf0hJallk99^|E&)1n+-$S}sd zVx=!TQ`D?GdaLDupm!g}hzhr(D5tw?d}_$?2_>BM*FJq1U3 zyez@$#)910SMD~|+~*V&=%QU=)$*K8gS2hH%6kibKY;&KXZFht2% zt8LHMN5B8xwi-=6wfS{~nNI^~()mxyPk$IU!4iJ^puPE~WfvOb_9IP= zHTS?7;UvU5h;hZ}F?9DaUs{Na{;ym^t69zGZO zZV6G?nSZDkG;L79N++)zgpsly_uWedXCr-$-Vk%DC3=D_$|*wf7`R8Y8b@muNhEF& z!aon)0JX}m?iSL;Cx8f)ru5%9sE~xsZ?1o`u8xab>@OP`;w8rA^If7p9Lu|I39spG zKe22kXzi{k;VJDB$1C=7Q_0-8IjeC35KH?A(S@B3A=UrT1Wd~K|KM#WcizhCF-maScz z#F;=`tp^1|i6|u$x!N*aI0uz~&cxLGFo&5%79fLi2ATuW9ffh)oq>86_~dDH92HsO zDA4NTJxhIUppp6p<*U(xXHERWJUZ3;^QQdAcu+& zfmIQsx}47i^tl{QTN%^>l{%P}cxKjFGPTnixvij%NajAit5%0f>TS<;cR_w$K3k;w zqwb_NO?O1?G22qkDia+P^7w+Q6FpA7GL){J4-`(cjP_YRZc3FF+!xE*PF=YnKC$Nn zGf96ud%{qa{argxE`sTh{v6BL(;d;Z03*d|)rF1rzBl}_9-N@{OCR_2NPO1535A+o^|+bvOZGjt9cs=_uZ31FvM#K3f1V0b zl|U`yRGYfeok9k6#Zj(ZHko_MPe?XLkN>csZeW0(7OV>#jY|-6L=-ZKa`tuJ``e&S zU7aV>vGR9p&+?P57QIAS?yg>t4i@%(ILib*Q)RiATw9x!b3xWaUrSY-WAllz4tKsa zMm45%WRYvXj(Av}z@!VK(P9fdrqt@ikMib=pY62dua?-RdHNxh+M#}aA<&c36j}33 zj)9}PWG&hfKO(;NcTX?h4wb}toMzn`j+$FGWFA}!@lAEP1+sbwGL8Gmh@GE}!y=1S zu#JhkG!5`NRh4y#$>6l|x5-*{+~`Q~-U^}LW4*p|3*7x%7TTh*1XZHp=hd3;l!P&O z<>XPYK%6Mf?Wn=`IA&#tO(4S7Y(1H>iy26)@Ay6+d{?k_TVoK{O~C_$941c@rJ1-~ ztXKPALE=x34(AXb|GMFu8y4L%=otft@={d*Q!fbqWQFhKXY#R@4DPi_yDQ7J+U~$& z@Mj`zc|*~y^O4Ue)7`Mrux>)i2%dsmNUpEEE@PqE4r#DI8_h1eW8i2l z#{oYI(ynIQCTWX=*Uy(5vHB%YJ2UJz*Cu_}YA#^ByUsiv^AjO6^6>->gdIg4cgdl^ zic-BP!m*?<_>Q@B6wX>j_G#taKD;pQ^8fP0Fg7TyX+K!`tjg;HSmP7Sg+e7Dn-0oy zBPGsDCst)Ua5}zESX&DTHoi3}BiUZ#BpLrW|NPU=Js;RvjFTtfjM<(1*Z9ts929nz zoNq@rw^@&2i7Gh!3 zgW(-hp&T)~huuJLaJ&S`e^;Q%R`#!YxRVK(9zJ_XVk<|7ZzD6_SgLMi-zT<_k$O*e z{(tZPbRUe*-w7Z2HD=M?X5DA;Wo4l5@01k(qD&a6bDJ~}vpiHNHmf*feB>svq>eQ( zv^jpLrlIN>OoeTM*#SuzAKwwW8gOLU;e&_9hiixi?X0!m;w2IkFSlUUqJFIp} zRPf%}u$mXEgH_JThMyjZ%5Wcz%0*E?F-3W@@nplEPA#%=gUazS zOsuRt9#B3d{+B;^m|cbarD#v#q|O$#VBkm~mqH?msj^9uzX6J&uVuJTc9aEH%5dK_ z_~c1J?V_Kj1Ie5_Gu7V?vq|^*?gO=>adEZg3%M?4jz@^THB`ugMno`UW2|WW&nvg@ zg3%!9cGYvRBxY23T*;j;NL)?vO$vIcl=CjhLTkaqP%fh|v z{3uUTi*3~1h5vSr?mJp2$5y})1CqRav)uxwgYXxRkM*S?o+$!~o(kH_+aYvG34!AM zS8f4wWkZQh0Zo6`KHzyC%Fs4*WCkTGXNsgi2rX9~At^qjBf||ov255)AZO`_DZDr@ zjT-Aa`oJ6E#`sd+%qotKVnT#p7x7Lkr5Be|Kva5@?=7(Tw>!0Ynm8!oLB;tC8mUG^ zS}(K^@z6Hf71m>HJaDz%81naY4m(9ADEpELK25T9!n&G{edSeK3EaR`#=UGKID?A6 zlIeabs@x@B1aOTHZZwiXZgFYUprP1lQAjC5go;iDWs!j5@_5k}wv4@P#aUiwkSg65 zn!6=+h|#k~j~1n~8sum93s3*cIXJ`d?wamX zhG^Qf%}!xg#38nYnDCO1t0z~S!17XRlUM>sTtx27+W2^drVkLwC>j350J=_qL2*Nc$ciuRCE<6HhXl) zSY#WLy~EroPYyy_XbtUwwC%2&PMo2Qroe?JU)ut_p1Bb4BDaoz5?aRnyulr<8B*Rf zBFs4{~rQ0JCvSKgrO4*6~l~||C1==sAnmeX2&FqnDSIL~9$ulpB zUZ9-U4F0t*!Ox+TYLGQ{(DrV*{aU@tl}902@~Vox9K+}J4+O6AiCy#5Z)56CT=%JU z&l>fWf>%?wAWz2L^`qO!99_5!VPHqW(WmP4u_9US+6SvBTG;EICl4T?Fooc@^hzg6 zmisUpYm^^LD0~o!8bmgBrCInIspii0KJRy-O?^gxgxP2=j#7(1;h~JCi`j9C0XIKV z&e9YUH}1n3Ve6Sr*R{Ie=V4;oNEb}gqtI)%-9JL<)QZr{{9ID2yUi?KZDhgm^Mx(5 zXtLZ5bu+-!=Qen1xCjl&3Jc_RD9~k7L(x4e!5(M!b(0uAxil5n7V1)?j;kqN#uIG! z7SLZzXvg_QDHeX`sNJVe(_C*gQ}w>Sr|Mf#93d>&$NsM^*nin{a=KbD U=XgO|_@6|?+6rx14E!1YUtJY=&j0`b literal 0 HcmV?d00001 diff --git a/src/examples/DungeonCrawler_tutorial/img/splash.png b/src/examples/DungeonCrawler_tutorial/img/splash.png index ce0daeb293bbd83af4131b894c641a74a2e1ce38..6615020cd9ad96bcf1da40757a9f36bbd4bddff2 100644 GIT binary patch literal 6485 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 U=XgO|_@6|?+6rx14E!1YUtJY=&j0`b literal 10200 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