diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml index d8ae89e9f..b1dd83794 100644 --- a/.github/workflows/auto-pr.yml +++ b/.github/workflows/auto-pr.yml @@ -1,7 +1,7 @@ name: Extension issue to Pull Request conversion on: issues: - types: [labeled, edited] + types: [labeled, edited] # We do not listen to the opened event because the issue will be labelled "New Extension" duplicating this action run. jobs: generate-pr: @@ -22,20 +22,24 @@ jobs: - name: Extract and verify extension uses: actions/github-script@v6 + id: prepare-extension + env: + BODY: ${{ github.event.issue.body }} with: script: | const { extractExtension } = require('./scripts/extract-extension.js'); const { verifyExtension } = require('./scripts/check-single-extension.js') - - const { error, extensionName } = await extractExtension("/tmp/ext.zip"); + const reviewed = !process.env.BODY.includes("Community (Unreviewed)"); + core.setOutput("reviewed", reviewed); + const { error, extensionName } = await extractExtension("/tmp/ext.zip", { reviewed }); if(error === "zip-error") github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `๐Ÿ‘‹ Thanks for your submission! Sadly, we were unable to properly extract your extension from its zip file. Try to create the zip with another software, and to update your original submission post with the new file. If that still doesn't work, ask a member of the extension team for help ๐Ÿ˜‰` + body: `๐Ÿ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! Sadly, we were unable to properly extract your extension from its zip file. Try to create the zip with another software, and to update your original submission post with the new file. If that still doesn't work, ask a member of the extension team for help ๐Ÿ˜‰` }) if(error === "too-many-files") @@ -43,7 +47,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `๐Ÿ‘‹ Thanks for your submission! We are kind of confused; Your zip file contained more than one JSON file, and only one extension can be submitted at a time. Please update your original submission post with a new zip file containing only one extension file ๐Ÿ™` + body: `๐Ÿ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are kind of confused; Your zip file contained more than one JSON file, and only one extension can be submitted at a time. Please update your original submission post with a new zip file containing only one extension file ๐Ÿ™` }) if(error === "no-json-found") @@ -51,7 +55,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `๐Ÿ‘‹ Thanks for your submission! We are kind of confused; Your zip file doesn't seem to contain an extension. Please update your original submission post with a new zip file containing an extension ๐Ÿ™\nIf your zip does already contain an extension, make sure your file ends with ".json", and that it is at the root of your zip file (not in a sub folder!), as otherwise it will be unrecognized and ignored by the system. If you've checked and nothing seems wrong with your zip, you can ask a member of the extension team for help ๐Ÿ˜‰` + body: `๐Ÿ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are kind of confused; Your zip file doesn't seem to contain an extension. Please update your original submission post with a new zip file containing an extension ๐Ÿ™\nIf your zip does already contain an extension, make sure your file ends with ".json", and that it is at the root of your zip file (not in a sub folder!), as otherwise it will be unrecognized and ignored by the system. If you've checked and nothing seems wrong with your zip, you can ask a member of the extension team for help ๐Ÿ˜‰` }) if(error === "invalid-file-name") @@ -59,7 +63,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `๐Ÿ‘‹ Thanks for your submission! We are sorry, but the filename of the extension has unrecognized characters. Since filenames with weird character can cause all kinds of problems and security flaws, our system won't allow file names with other characters than normal latin upper- and lowercase characters or numbers. Additionally, the first character must be an uppercase character. Please update your original submission post with a new zip file containing your extension with another file name following those guidelines ๐Ÿ™` + body: `๐Ÿ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are sorry, but the filename of the extension has unrecognized characters. Since filenames with weird character can cause all kinds of problems and security flaws, our system won't allow file names with other characters than normal latin upper- and lowercase characters or numbers. Additionally, the first character must be an uppercase character. Please update your original submission post with a new zip file containing your extension with another file name following those guidelines ๐Ÿ™` }) if(error) { @@ -74,7 +78,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `๐Ÿ‘‹ Thanks for your submission! We are sorry, but the filename of the extension has unrecognized characters. Since filenames with weird character can cause all kinds of problems and security flaws, our system won't allow file names with other characters than normal latin upper- and lowercase characters or numbers. Additionally, the first character must be an uppercase character. Please update your original submission post with a new zip file containing your extension with another file name following those guidelines ๐Ÿ™` + body: `๐Ÿ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are sorry, but the filename of the extension has unrecognized characters. Since filenames with weird character can cause all kinds of problems and security flaws, our system won't allow file names with other characters than normal latin upper- and lowercase characters or numbers. Additionally, the first character must be an uppercase character. Please update your original submission post with a new zip file containing your extension with another file name following those guidelines ๐Ÿ™` }) if(code === "not-found") @@ -82,7 +86,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `๐Ÿ‘‹ Thanks for your submission! We are sorry, but it seems your extension file miraculously disappeared just after being extracted ๐Ÿค”. This should never happen, please ask @GDevelopApp/extensions-team for assistance.` + body: `๐Ÿ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are sorry, but it seems your extension file miraculously disappeared just after being extracted ๐Ÿค”. This should never happen, please ask @GDevelopApp/extensions-team for assistance.` }) if(code === "duplicated" ) @@ -90,7 +94,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `๐Ÿ‘‹ Thanks for your submission! We are sorry, but it seems we already have a reviewed extension with that name. Extensions cannot be in both the community and reviewed extensions list at once. If you are trying to update that extension, please ask a member of the extension team for help. If the name clash is a coincidence, please update your original submission post with a new zip file containing your extension with a file name that is not already taken ๐Ÿ™` + body: `๐Ÿ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are sorry, but it seems we already have a ${reviewed ? 'community' : 'reviewed'} extension with that name. Extensions cannot share a name between the community and reviewed extensions list. If you are trying to update that other extension, please make sure you selected the correct review type. If the name clash is a coincidence, please update your original submission post with a new zip file containing your extension with a file and extension name that is not already taken ๐Ÿ™` }) if(code === "invalid-json") @@ -98,7 +102,23 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `๐Ÿ‘‹ Thanks for your submission! We are sorry, but your extension file inside the zip file seems to be damaged, as our system wasn't able to understand its content. Try to re-export the extension JSON file, or to create the zip with another software, and to update your original submission post with the new zip file. If that still doesn't work, ask a member of the extension team for help ๐Ÿ˜‰` + body: `๐Ÿ‘‹ Hey @${{ github.event.issue.user.login }}, thanks for your submission! We are sorry, but your extension file inside the zip file seems to be damaged, as our system wasn't able to understand its content. Try to re-export the extension JSON file, or to create the zip with another software, and to update your original submission post with the new zip file. If that still doesn't work, ask a member of the extension team for help ๐Ÿ˜‰` + }) + + if(code === "gdevelop-project-file") + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `๐Ÿ‘‹ Hey ${{ github.event.issue.user.login }}, thanks for your submission! It would seem you confused the extension file with your project file, and thus we cannot find your extension. Make sure you exported the extension itself from the extension editor as a standalone file, zip that standalone extension file, and make sure you did not confuse the "Example" and "Extension" fields while submitting!` + }) + + if(code === "unknown-json-contents") + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `๐Ÿ‘‹ Hey ${{ github.event.issue.user.login }}, thanks for your submission! It would seem your JSON file is not a valid GDevelop extension, although it is a JSON file. Please make sure you are exporting with the latest version of GDevelop and that you are not modifying the JSON incorrectly after the export.` }) if(code === "rule-break") @@ -106,7 +126,7 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: `๐Ÿ‘‹ Thanks for your submission! Unfortunately, all submitted extensions have to meet some minimal quality standard - the extension best practices - and our system has found that your extension does not fully comply ๐Ÿ˜”. You can find all of those rules on [the GDevelop wiki](https://wiki.gdevelop.io/gdevelop5/extensions/best-practices). \n\nThe following issues have been found by the system concerning the respect of those best practices by your extension: \n\`\`\`\n${errors.reduce((acc, error) => `${acc}\n โŸถ โŒ ${error}`, '').slice(1)}\n\`\`\`\nPlease update your original submission post with a new zip file containing your extensions updated to follow those guidelines ๐Ÿ™` + body: `๐Ÿ‘‹ Hey ${{ github.event.issue.user.login }}, thanks for your submission! Unfortunately, all submitted extensions have to meet some minimal quality standard - the extension best practices - and our system has found that your extension does not fully comply ๐Ÿ˜”. You can find all of those rules on [the GDevelop wiki](https://wiki.gdevelop.io/gdevelop5/extensions/best-practices). \n\nThe following issues have been found by the system concerning the respect of those best practices by your extension: \n\`\`\`\n${errors.reduce((acc, error) => `${acc}\n โŸถ โŒ ${error}`, '').slice(1)}\n\`\`\`\nPlease update your original submission post with a new zip file containing your extensions updated to follow those guidelines ๐Ÿ™` }) if(code !== "success") core.setFailed("Verification of the extension failed!"); @@ -116,13 +136,38 @@ jobs: uses: peter-evans/create-pull-request@v5 with: commit-message: 'Automated Extension submission for issue #${{ github.event.issue.number }}' - committer: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> - author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> - branch: extension/${{ github.actor }}/${{ github.event.issue.number }} + committer: ${{ github.event.issue.user.login }} <${{ github.event.issue.user.login }}@users.noreply.github.com> + author: ${{ github.event.issue.user.login }} <${{ github.event.issue.user.login }}@users.noreply.github.com> + branch: extension/${{ github.event.issue.user.login }}/${{ github.event.issue.number }} delete-branch: true title: '${{ github.event.issue.title }}' - body: ${{ github.event.issue.body }} - labels: โœจ New extension + body: > + ${{ github.event.issue.body }} + + + --- + + + Extension by @${{ github.event.issue.user.login }} + + + You can update the extension on this "Pull Request" by commenting the update command: + in the comment field, type `!update`, then drag and drop a zip file with your extension file in the + commenting field, like how you initially submitted the extension. It should look like this: + + + ``` + + !update [MyExtension.zip](https://github.com/GDevelopApp/GDevelop-extensions/files/12709661/MyExtension.zip) + + ``` + + + It can take a few seconds for the file to fully upload and show as the above. Once it is like shown above, + click "Comment" and let the bot do the rest! + labels: | + โœจ New extension + ${{(steps.prepare-extension.outputs.reviewed == 'true' && '๐Ÿ” Reviewed extension') || '๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Community extension'}} - name: Add card to pending review uses: peter-evans/create-or-update-project-card@v2 @@ -136,4 +181,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh issue close ${{ github.event.issue.number }} - gh issue comment ${{ github.event.issue.number }} --body "Hi @${{ github.actor }}! ๐Ÿ‘‹ This submission has passed all required tests, and has been moved to a PR as part of our submission pipeline. [You can see the progress of your submission on this page](${{ steps.cpr.outputs.pull-request-url }}). Community submissions are not reviewed by default, so your extension should be added once we've checked that your submission doesn't contain malicious code without further intervention on your part. If you wish for your extension to be reviewed (and thereby moved to the list of reviewed extensions), please follow the instructions written on the [README](https://github.com/GDevelopApp/GDevelop-extensions#get-your-extension-reviewed-extensions). Thanks again for your contribution to GDevelop!" + gh issue comment ${{ github.event.issue.number }} --body "Hi @${{ github.event.issue.user.login }}! ๐Ÿ‘‹ This submission has passed all required tests, and has been moved to a PR as part of our submission pipeline. [You can see the progress of your submission on this page](${{ steps.cpr.outputs.pull-request-url }}). Community submissions are not reviewed by default, so your extension should be added once we've checked that your submission doesn't contain malicious code without further intervention on your part. If you wish for your extension to be reviewed (and thereby moved to the list of reviewed extensions), please follow the instructions written on the [README](https://github.com/GDevelopApp/GDevelop-extensions#get-your-extension-reviewed-extensions). Thanks again for your contribution to GDevelop!" diff --git a/__tests__/auto-pr/auto-pr.spec.js b/__tests__/auto-pr/auto-pr.spec.js index c72834d94..ee91dc1d9 100644 --- a/__tests__/auto-pr/auto-pr.spec.js +++ b/__tests__/auto-pr/auto-pr.spec.js @@ -1,18 +1,19 @@ const { mkdir, rm } = require('fs/promises'); const { verifyExtension } = require('../../scripts/check-single-extension'); const { extractExtension } = require('../../scripts/extract-extension'); +const { readdirSync } = require('fs'); const TEMPORARY_MOCK_EXTENSIONS_FOLDER = __dirname + '/mock_extensions_folder'; const TEST_ZIPS_FOLDER = __dirname + '/test-zips'; const TEST_EXTENSIONS_FOLDER = __dirname + '/test-extensions'; /** @param {string} zipName */ -const wrappedExtractExtension = async (zipName) => +const wrappedExtractExtension = async (zipName, reviewed = false) => ( - await extractExtension( - `${TEST_ZIPS_FOLDER}/${zipName}.zip`, - TEMPORARY_MOCK_EXTENSIONS_FOLDER - ) + await extractExtension(`${TEST_ZIPS_FOLDER}/${zipName}.zip`, { + extensionsFolder: TEMPORARY_MOCK_EXTENSIONS_FOLDER, + reviewed, + }) ).error; /** @param {string} extensionName */ @@ -45,7 +46,19 @@ describe('Auto-pr pipeline', () => { 'too-many-files' ); + // As community extension expect(await wrappedExtractExtension(`valid-extension`)).toBeUndefined(); + expect( + readdirSync(TEMPORARY_MOCK_EXTENSIONS_FOLDER + '/community') + ).toContain('UUID.json'); + + // As reviewed extension + expect( + await wrappedExtractExtension(`valid-extension`, true) + ).toBeUndefined(); + expect( + readdirSync(TEMPORARY_MOCK_EXTENSIONS_FOLDER + '/reviewed') + ).toContain('UUID.json'); }); test(`verifyExtension()`, async () => { @@ -57,6 +70,8 @@ describe('Auto-pr pipeline', () => { expect(await wrappedVerifyExtension(`cri.png`)).toBe('invalid-file-name'); expect(await wrappedVerifyExtension(`RealExtension`)).toBe('invalid-json'); expect(await wrappedVerifyExtension(`Share`)).toBe('rule-break'); + expect(await wrappedVerifyExtension(`Fake`)).toBe('unknown-json-contents'); + expect(await wrappedVerifyExtension(`ArrayTools`)).toBe('gdevelop-project-file'); expect(await wrappedVerifyExtension(`UUID`)).toBe('success'); expect(await wrappedVerifyExtension(`Clipboard`)).toBe('success'); diff --git a/__tests__/auto-pr/test-extensions/community/Fake.json b/__tests__/auto-pr/test-extensions/community/Fake.json new file mode 100644 index 000000000..73a1a45d8 --- /dev/null +++ b/__tests__/auto-pr/test-extensions/community/Fake.json @@ -0,0 +1,4 @@ +{ + "link": "https://www.youtube.com/watch?v=xvFZjo5PgG0", + "rating": 5 +} \ No newline at end of file diff --git a/__tests__/auto-pr/test-extensions/reviewed/ArrayTools.json b/__tests__/auto-pr/test-extensions/reviewed/ArrayTools.json new file mode 100644 index 000000000..6dfc88935 --- /dev/null +++ b/__tests__/auto-pr/test-extensions/reviewed/ArrayTools.json @@ -0,0 +1,9088 @@ +{ + "firstLayout": "", + "gdVersion": { + "build": 99, + "major": 4, + "minor": 0, + "revision": 0 + }, + "properties": { + "adaptGameResolutionAtRuntime": true, + "antialiasingMode": "MSAA", + "antialisingEnabledOnMobile": false, + "folderProject": false, + "orientation": "landscape", + "packageName": "com.example.gamename", + "pixelsRounding": false, + "projectUuid": "6ff99bc6-9311-4c83-93b9-e09299e1d37b", + "scaleMode": "linear", + "sizeOnStartupMode": "", + "templateSlug": "", + "useExternalSourceFiles": false, + "version": "1.0.0", + "name": "Project", + "description": "", + "author": "", + "windowWidth": 800, + "windowHeight": 600, + "latestCompilationDirectory": "", + "maxFPS": 60, + "minFPS": 20, + "verticalSync": false, + "platformSpecificAssets": {}, + "loadingScreen": { + "backgroundColor": 0, + "backgroundFadeInDuration": 0.2, + "backgroundImageResourceName": "", + "gdevelopLogoStyle": "light", + "logoAndProgressFadeInDuration": 0, + "logoAndProgressLogoFadeInDelay": 0, + "minDuration": 1.5, + "progressBarColor": 13050145, + "progressBarHeight": 20, + "progressBarMaxWidth": 200, + "progressBarMinWidth": 40, + "progressBarWidthPercent": 30, + "showGDevelopSplash": true, + "showProgressBar": true + }, + "watermark": { + "placement": "bottom-left", + "showWatermark": true + }, + "authorIds": [], + "authorUsernames": [], + "categories": [], + "playableDevices": [], + "extensionProperties": [], + "platforms": [ + { + "name": "GDevelop JS platform" + } + ], + "currentPlatform": "GDevelop JS platform" + }, + "resources": { + "resources": [], + "resourceFolders": [] + }, + "objects": [], + "objectsGroups": [], + "variables": [], + "layouts": [ + { + "b": 209, + "disableInputWhenNotFocused": true, + "mangledName": "New_32scene", + "name": "New scene", + "r": 209, + "standardSortMethod": true, + "stopSoundsOnStartup": true, + "title": "", + "v": 209, + "uiSettings": { + "grid": false, + "gridType": "rectangular", + "gridWidth": 32, + "gridHeight": 32, + "gridOffsetX": 0, + "gridOffsetY": 0, + "gridColor": 10401023, + "gridAlpha": 0.8, + "snap": true, + "zoomFactor": 1, + "windowMask": false + }, + "objectsGroups": [], + "variables": [ + { + "name": "test", + "type": "array", + "children": [] + }, + { + "name": "test2", + "type": "array", + "children": [] + }, + { + "name": "test3", + "type": "array", + "children": [] + } + ], + "instances": [ + { + "angle": 0, + "customSize": true, + "height": 569, + "layer": "", + "name": "Logs", + "persistentUuid": "7fb8233b-e66c-448f-9165-2c3bb8251055", + "width": 778, + "x": 12, + "y": 15, + "zOrder": 1, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + } + ], + "objects": [ + { + "assetStoreId": "", + "bold": false, + "italic": false, + "name": "Logs", + "smoothed": true, + "tags": "", + "type": "TextObject::Text", + "underlined": false, + "variables": [], + "effects": [], + "behaviors": [], + "string": "Logs:\n", + "font": "", + "textAlignment": "", + "characterSize": 20, + "color": { + "b": 0, + "g": 0, + "r": 0 + } + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 35, + "g": 166, + "r": 245, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "This project is a collection of unit tests for the ArrayTools extension.\nThey use it in common scenarios and verify if their behavior match what is expected of it.\nThis allows to verify everything is working properly and as expected and make changes easier to do without risking breaking something, as breaking changes can be detected by the tests failing." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DepartScene" + }, + "parameters": [ + "" + ] + } + ], + "actions": [], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Contains", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, \\\"hello\\\", 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "JSONToObjectVariableStructure" + }, + "parameters": [ + "\"[1, 2, \\\"hello\\\", 4, 5]\"", + "Logs", + "test" + ] + }, + { + "type": { + "value": "JSONToGlobalVariableStructure" + }, + "parameters": [ + "\"[1, 2, \\\"hello\\\", 4, 5]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ArrayTools::GlobalHasString" + }, + "parameters": [ + "ToJSON(test)", + "test", + "\"hello\"", + "\"hello\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Contains Global] Expected 'hello' to be detected in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ArrayTools::ObjectHasString" + }, + "parameters": [ + "ToJSON(test)", + "Logs", + "test", + "\"hello\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Contains Object] Expected 'hello' to be detected in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect HasString to detect present string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ArrayTools::HasString" + }, + "parameters": [ + "ToJSON(test)", + "test", + "\"hello\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Contains 1] Expected 'hello' to be detected in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect HasString to not detect non-present string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ArrayTools::HasString" + }, + "parameters": [ + "ToJSON(test)", + "test", + "\"world\"", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Contains 2] Expected 'world' to not be detected in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect HasNumber to detect present string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ArrayTools::HasNumber" + }, + "parameters": [ + "ToJSON(test)", + "test", + "1", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Contains 3] Expected '1' to be detected in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "4. Expect HasNumber to not detect non-present string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ArrayTools::HasNumber" + }, + "parameters": [ + "ToJSON(test)", + "test", + "80", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Contains 4] Expected '80' to not be detected in array\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Index Of", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, \\\"hello\\\", 4, \\\"hello\\\", 5, 4]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect IndexOfStr to find the index of a present string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOfStr(test, \"hello\")", + "!=", + "2" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[IndexOf 1] Expected 'hello' to be found at index 2, instead found at \" + ToString(ArrayTools::IndexOfStr(test, \"hello\")) + \" in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect IndexOfStr to not find the index of a non-present string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOfStr(test, \"world\")", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[IndexOf 2] Expected 'world' to be not be found (index -1), instead found at \" + ToString(ArrayTools::IndexOfStr(test, \"world\")) + \" in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect IndexOf to find the index of a present number" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOf(test, 4)", + "!=", + "3" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[IndexOf 3] Expected '4' to be found at index 3, instead found at \" + ToString(ArrayTools::IndexOf(test, 4)) + \" in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "4. Expect IndexOf to not find the index of a non-present number" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOf(test, 80)", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[IndexOf 4] Expected '80' to not be found (index -2), instead found at \" + ToString(ArrayTools::IndexOf(test, 80)) + \" in array\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Last Index Of", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, \\\"hello\\\", 4, \\\"hello\\\", 5, 4]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect LastIndexOfStr to find the index of a present string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::LastIndexOfStr(test, \"hello\")", + "!=", + "4" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[LastIndexOf 1] Expected 'hello' to be found at index 4, instead found at \" + ToString(ArrayTools::LastIndexOfStr(test, \"hello\")) + \" in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect LastIndexOfStr to not find the index of a non-present string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::LastIndexOfStr(test, \"world\")", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[LastIndexOf 2] Expected 'world' to be not be found (index -1), instead found at \" + ToString(ArrayTools::LastIndexOfStr(test, \"world\")) + \" in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect LastIndexOf to find the index of a present number" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::LastIndexOf(test, 4)", + "!=", + "6" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[LastIndexOf 3] Expected '4' to be found at index 6, instead found at \" + ToString(ArrayTools::LastIndexOf(test, 4)) + \" in array\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "4. Expect LastIndexOf to not find the index of a non-present number" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::LastIndexOf(test, 80)", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[LastIndexOf 4] Expected '80' to not be found (index -1), instead found at \" + ToString(ArrayTools::LastIndexOf(test, 80)) + \" in array\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Flatten", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to flatten arrays" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[[1, 2], [3, 4], [5], []]\"", + "test" + ] + }, + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, [1, 2], 4, 5, [3, 4], [5], 4]\"", + "test2" + ] + }, + { + "type": { + "value": "ArrayTools::Flatten" + }, + "parameters": [ + "", + "test", + "0", + "" + ] + }, + { + "type": { + "value": "ArrayTools::Flatten" + }, + "parameters": [ + "", + "test2", + "0", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,3,4,5]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Flatten 1] Expected array test to be '[1,2,3,4,5]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test2)", + "!=", + "\"[1,1,2,4,5,3,4,5,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Flatten 1] Expected array test2 to be '[1,1,2,4,5,3,4,5,4]', got '\" + ToJSON(test2) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to flatten arrays a single level deep" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, [1, 2, [[], 1, 2]], 4, 5, [3, 4], [[], 5], 4]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Flatten" + }, + "parameters": [ + "", + "test", + "0", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,1,2,[[],1,2],4,5,3,4,[],5,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Flatten 2] Expected array to be '[1,1,2,[[],1,2],4,5,3,4,[],5,4]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect to flatten multiple levels deep" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, [1, 2, [[], 1, 2]], 4, 5, [3, 4], [[], 5], 4]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Flatten" + }, + "parameters": [ + "", + "test", + "yes", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,1,2,1,2,4,5,3,4,5,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Flatten 3] Expected array to be '[1,1,2,1,2,4,5,3,4,5,4]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Splice", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to clear an array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Splice" + }, + "parameters": [ + "", + "test", + "0", + "0", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Splice 1] Expected array to be cleared ('[]'), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to clear everything but the first element" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Splice" + }, + "parameters": [ + "", + "test", + "1", + "0", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Splice 2] Expected array to be '[1]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect to remove 2 elements after first index" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Splice" + }, + "parameters": [ + "", + "test", + "1", + "2", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,4,5]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Splice 3] Expected array to be '[1,4,5]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "4. Expect to remove last element" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Splice" + }, + "parameters": [ + "", + "test", + "-1", + "1", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,3,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Splice 4] Expected array to be '[1,2,3,4]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Slice", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to copy an array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Slice" + }, + "parameters": [ + "", + "test", + "test2", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "test[0]", + "=", + "55" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[55,2,3,4,5]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Slice 1] Expected original array to be changed ('[55,2,3,4,5]'), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test2)", + "!=", + "\"[1,2,3,4,5]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Slice 1] Expected copy array to be unchanged ('[1,2,3,4,5]'), got '\" + ToJSON(test2) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to copy only part of the array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Slice" + }, + "parameters": [ + "", + "test", + "test2", + "1", + "3", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,3,4,5]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Slice 2] Expected original array to be '[1,2,3,4,5]' (unmodified), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test2)", + "!=", + "\"[2,3]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Slice 2] Expected copy array to be '[2,3]', got '\" + ToJSON(test2) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect negative end index to work" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Slice" + }, + "parameters": [ + "", + "test", + "test2", + "0", + "-1", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test2)", + "!=", + "\"[1,2,3,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Slice 3] Expected copy array to be '[1,2,3,4]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Sum", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Calculates sum of an array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Sum(test)", + "!=", + "15" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Sum 1] Expected sum of all items to be 15, got \" + ToString(ArrayTools::Sum(test)) + \" instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Work with negative numbers" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[-1, -2, 3, 0, 5]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Sum(test)", + "!=", + "5" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Sum 2] Expected sum of all items to be 5, got \" + ToString(ArrayTools::Sum(test)) + \" instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Test with randomly generated array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "VariableClearChildren" + }, + "parameters": [ + "test" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "test2", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "20", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "tmp", + "=", + "RandomFloatInRange(-50, 50)" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "test2", + "+", + "Variable(tmp)" + ] + }, + { + "type": { + "value": "SceneVariablePushNumber" + }, + "parameters": [ + "test", + "Variable(tmp)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Sum(test)", + "!=", + "Variable(test2)" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Sum 1] Expected sum of all items ('\" + ToJSON(test) + \"') to be \" + VariableString(test2) + \", got \" + ToString(ArrayTools::Sum(test)) + \" instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Shuffle", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to not modify the array appart from shuffling" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Shuffle" + }, + "parameters": [ + "", + "test", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "VariableChildCount(test)", + "!=", + "5" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Shuffle 1] Expected length of array to stay 5, got \" + ToString(VariableChildCount(test)) + \" instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "inverted": true, + "value": "ArrayTools::HasNumber" + }, + "parameters": [ + "", + "test", + "1", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "ArrayTools::HasNumber" + }, + "parameters": [ + "", + "test", + "2", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "ArrayTools::HasNumber" + }, + "parameters": [ + "", + "test", + "3", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "ArrayTools::HasNumber" + }, + "parameters": [ + "", + "test", + "4", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "ArrayTools::HasNumber" + }, + "parameters": [ + "", + "test", + "5", + "" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Shuffle 1] Expected shuffled array to not miss any element it originally had\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to make a different array after 5 executions max" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "test2", + "=" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "5", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Shuffle" + }, + "parameters": [ + "", + "test", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,3,4,5]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "test2", + "True" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "SceneVariableAsBoolean" + }, + "parameters": [ + "test2", + "False" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Shuffle 2] Expected shuffle to change the array after max 5 executions\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Reverse", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to reverse the array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1, 2, 3, 4, 5]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Reverse" + }, + "parameters": [ + "", + "test", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[5,4,3,2,1]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Reverse 1] Expected array to be reversed ('[5,4,3,2,1]'), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Sort", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to sort array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[3,5,4,1,2]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Sort" + }, + "parameters": [ + "", + "test", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,3,4,5]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Sort 1] Expected array to be sorted ('[1,2,3,4,5]'), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to sort array with negative numbers" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[3,0,4,-1,2]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Sort" + }, + "parameters": [ + "", + "test", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[-1,0,2,3,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Sort 2] Expected array to be sorted ('[-1,0,2,3,4]'), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Min", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to get smallest number of array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[3,5,4,1,2]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Min(test)", + "!=", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Min 1] Expected smallest item to be 1, got '\" + ToString(ArrayTools::Min(test)) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to get smallest number of array with negative numbers" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[3,0,4,-1,2]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Min(test)", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Min 2] Expected smallest item to be -1, got '\" + ToString(ArrayTools::Min(test)) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Max", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to get biggest number of array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[3,5,4,1,2]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Max(test)", + "!=", + "5" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Max 1] Expected biggest item to be 5, got '\" + ToString(ArrayTools::Max(test)) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to get biggest number of array with negative numbers" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[3,0,4,-1,2]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Max(test)", + "!=", + "4" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Max 2] Expected biggest item to be 4, got '\" + ToString(ArrayTools::Max(test)) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Join", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Can join with a space" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[\\\"This was\\\", \\\"a triumph.\\\", \\\"I'm making\\\", \\\"a note here,\\\", \\\"HUGE SUCCESS!\\\"]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ArrayTools::Join(test, \" \")", + "!=", + "\"This was a triumph. I'm making a note here, HUGE SUCCESS!\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Join 1] Expected joined string to be 'This was a triumph. I'm making a note here, HUGE SUCCESS!', got '\" + ArrayTools::Join(test, \" \") + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Can join with an emoji" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[\\\"Congrats\\\", \\\"I\\\", \\\"like\\\", \\\"that\\\"]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ArrayTools::Join(test, \"๐Ÿ‘\")", + "!=", + "\"Congrats๐Ÿ‘I๐Ÿ‘like๐Ÿ‘that\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Join 2] Expected joined string to be 'Congrats๐Ÿ‘I๐Ÿ‘like๐Ÿ‘that', got '\" + ArrayTools::Join(test, \"๐Ÿ‘\") + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Split", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to be able to split by space" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ArrayTools::SplitString" + }, + "parameters": [ + "", + "\"I like skateboards\"", + "\" \"", + "test", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[\\\"I\\\",\\\"like\\\",\\\"skateboards\\\"]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Split 1] Expected splitted string array to be '[\\\"I\\\",\\\"like\\\",\\\"skateboards\\\"]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to be able to split by nothing" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ArrayTools::SplitString" + }, + "parameters": [ + "", + "\"yes\"", + "\"\"", + "test", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[\\\"y\\\",\\\"e\\\",\\\"s\\\"]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Split 2] Expected splitted string array to be '[\\\"y\\\",\\\"e\\\",\\\"s\\\"]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect to be able to split by emoji" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ArrayTools::SplitString" + }, + "parameters": [ + "", + "\"very๐Ÿ‘good\"", + "\"๐Ÿ‘\"", + "test", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[\\\"very\\\",\\\"good\\\"]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Split 3] Expected splitted string array to be '[\\\"very\\\",\\\"good\\\"]', got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Mean", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to find average of 2 numbers" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[2,6]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Mean(test)", + "!=", + "4" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Average 1] Expected average to be 4, got '\" + ToString(ArrayTools::Mean(test)) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to find average of more numbers" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[4,6,8]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Mean(test)", + "!=", + "6" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Average 2] Expected average to be 6, got '\" + ToString(ArrayTools::Mean(test)) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect to find average of random numbers" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "VariableClearChildren" + }, + "parameters": [ + "test" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "test2", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "10", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "tmp", + "=", + "RandomFloatInRange(-50, 50)" + ] + }, + { + "type": { + "value": "SceneVariablePushNumber" + }, + "parameters": [ + "test", + "Variable(tmp)" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "test2", + "+", + "Variable(tmp)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Mean(test)", + "!=", + "Variable(test2) / 10" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Average 3] Expected average to be \" + ToString(Variable(test2) / 10) + \", got '\" + ToString(ArrayTools::Mean(test)) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Median", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to get median in array with an uneven number of elements" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[2,8,3,9,12]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Median(test)", + "!=", + "8" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Median 1] Expected median to be 8, got '\" + ToString(ArrayTools::Median(test)) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to get median in array with an even number of elements" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[2,8,9,12]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::Median(test)", + "!=", + "8.5" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Median 2] Expected median to be 8.5, got '\" + ToString(ArrayTools::Median(test)) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Get Random Child", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect GetRandomString to get a string inside of the array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[\\\"yes\\\",\\\"no\\\",\\\"maybe\\\"]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ArrayTools::HasString" + }, + "parameters": [ + "", + "test", + "ArrayTools::RandomStringInArray(test)", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[GetRandomChild 1] Expected array to contain randomly selected item\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect GetRandomNumber to get a string inside of the array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[5,6,7]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ArrayTools::HasNumber" + }, + "parameters": [ + "", + "test", + "ArrayTools::RandomNumberInArray(test)", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[GetRandomChild 2] Expected array to contain randomly selected item\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Fill", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to fill an empty array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "VariableClearChildren" + }, + "parameters": [ + "test" + ] + }, + { + "type": { + "value": "ArrayTools::FillNumber" + }, + "parameters": [ + "", + "test", + "1", + "0", + "9", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,1,1,1,1,1,1,1,1,1]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Fill 1] Expected array to be [1,1,1,1,1,1,1,1,1,1], got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to fill an array with children in it" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ArrayTools::FillNumber" + }, + "parameters": [ + "", + "test", + "2", + "0", + "0", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[2,2,2,2,2,2,2,2,2,2]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Fill 2] Expected array to be [2,2,2,2,2,2,2,2,2,2], got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect to fill part of an array" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ArrayTools::FillNumber" + }, + "parameters": [ + "", + "test", + "4", + "1", + "3", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[2,4,4,4,2,2,2,2,2,2]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Fill 2] Expected array to be [2,4,4,4,2,2,2,2,2,2], got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Concat", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToObjectVariableStructure" + }, + "parameters": [ + "\"[1,2,3,4]\"", + "Logs", + "test" + ] + }, + { + "type": { + "value": "JSONToObjectVariableStructure" + }, + "parameters": [ + "\"[5,6,7,8]\"", + "Logs", + "test2" + ] + }, + { + "type": { + "value": "ArrayTools::ObjectConcatenate" + }, + "parameters": [ + "", + "Logs", + "test", + "Logs", + "test2", + "Logs", + "test3", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ObjectVarToJSON(Logs, test3)", + "!=", + "\"[1,2,3,4,5,6,7,8]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Concat Object] Expected array to be [1,2,3,4,5,6,7,8], got '\" + ObjectVarToJSON(Logs, test3) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to contain elements of both arrays" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1,2,3,4]\"", + "test" + ] + }, + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[5,6,7,8]\"", + "test2" + ] + }, + { + "type": { + "value": "ArrayTools::Concatenate" + }, + "parameters": [ + "", + "test", + "test2", + "test3", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test3)", + "!=", + "\"[1,2,3,4,5,6,7,8]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Concat 1] Expected array to be [1,2,3,4,5,6,7,8], got '\" + ToJSON(test3) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to be a copy (modifications on one shouldn't affect the other)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "test[0]", + "=", + "50" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "test3[0]", + "=", + "100" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[50,2,3,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Concat 2] Expected array test to be [50,2,3,4], got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test2)", + "!=", + "\"[5,6,7,8]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Concat 2] Expected array test2 to be [5,6,7,8], got '\" + ToJSON(test2) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test3)", + "!=", + "\"[100,2,3,4,5,6,7,8]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Concat 2] Expected array test3 to be [100,2,3,4,5,6,7,8], got '\" + ToJSON(test3) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Append To", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to contain elements of both arrays" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1,2,3,4]\"", + "test" + ] + }, + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[5,6,7,8]\"", + "test2" + ] + }, + { + "type": { + "value": "ArrayTools::AppendAll" + }, + "parameters": [ + "", + "test2", + "test", + "\"test3\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,3,4,5,6,7,8]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[AppendTo 1] Expected array to be [1,2,3,4,5,6,7,8], got '\" + ToJSON(test3) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to be a copy (modifications on one shouldn't affect the other)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "test[VariableChildCount(test)-1]", + "=", + "50" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "test2[0]", + "=", + "100" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,3,4,5,6,7,50]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[AppendTo 2] Expected array test to be [1,2,3,4,5,6,7,50], got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test2)", + "!=", + "\"[100,6,7,8]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[AppendTo 2] Expected array test2 to be [100,6,7,8], got '\" + ToJSON(test2) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Pop", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to pop from one array into a variable" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1,2,3,4]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Pop" + }, + "parameters": [ + "", + "test", + "test2", + "\"test3\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,3]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Pop 1] Expected array test to have the last child removed ([1,2,3]), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "test2", + "!=", + "4" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Pop 1] Expected test2 to have the removed value (4), got '\" + ToJSON(test2) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to pop a number" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1,2,3,4]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::PopNumber(test)", + "!=", + "4" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Pop 2] Expected popped value to be 4\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,3]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Pop 2] Expected array test to have the last child removed ([1,2,3]), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect to pop a string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[\\\"a\\\", \\\"b\\\", \\\"c\\\"]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ArrayTools::PopString(test)", + "!=", + "\"c\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Pop 3] Expected popped value to be 'c'\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[\\\"a\\\",\\\"b\\\"]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Pop 3] Expected array test to have the last child removed ([\\\"a\\\",\\\"b\\\"]), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Shift", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect to shift from one array into a variable" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1,2,3,4]\"", + "test" + ] + }, + { + "type": { + "value": "ArrayTools::Shift" + }, + "parameters": [ + "", + "test", + "test2", + "\"test3\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[2,3,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Shift 1] Expected array test to have the first child removed ([2,3,4]), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "test2", + "!=", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Shift 1] Expected test2 to have the removed value (1), got '\" + ToJSON(test2) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "2. Expect to shift a number" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1,2,3,4]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::ShiftNumber(test)", + "!=", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Shift 2] Expected shifted value to be 1\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[2,3,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Shift 2] Expected array test to have the first child removed ([2,3,4]), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "3. Expect to shift a string" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[\\\"a\\\", \\\"b\\\", \\\"c\\\"]\"", + "test" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ArrayTools::ShiftString(test)", + "!=", + "\"a\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Shift 3] Expected shifted value to be 'a'\" + NewLine()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[\\\"b\\\",\\\"c\\\"]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[Shift 3] Expected array test to have the first child removed ([\\\"b\\\",\\\"c\\\"]), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Insert variable at", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "1. Expect variable to be inserted at the correct position" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1,2,3,4]\"", + "test" + ] + }, + { + "type": { + "value": "JSONToVariableStructure" + }, + "parameters": [ + "\"[1]\"", + "test2" + ] + }, + { + "type": { + "value": "ArrayTools::InsertAt" + }, + "parameters": [ + "", + "test", + "2", + "test2", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StrEqual" + }, + "parameters": [ + "ToJSON(test)", + "!=", + "\"[1,2,[1],3,4]\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "+", + "\"[InsertAt 1] Expected array test to have [1] inserted ([1,2,[1],3,4]), got '\" + ToJSON(test) + \"' instead\" + NewLine()" + ] + } + ] + } + ], + "parameters": [] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "If there is no error log, all tests were successful." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "=", + "\"Logs:\" + NewLine()" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Logs", + "=", + "\"All tests passed successfully!\"" + ] + } + ] + } + ] + } + ], + "layers": [ + { + "ambientLightColorB": 0, + "ambientLightColorG": 0, + "ambientLightColorR": 0, + "camera3DFarPlaneDistance": 10000, + "camera3DFieldOfView": 45, + "camera3DNearPlaneDistance": 0.1, + "followBaseLayerCamera": false, + "isLightingLayer": false, + "isLocked": false, + "name": "", + "renderingType": "", + "visibility": true, + "cameras": [ + { + "defaultSize": true, + "defaultViewport": true, + "height": 0, + "viewportBottom": 1, + "viewportLeft": 0, + "viewportRight": 1, + "viewportTop": 0, + "width": 0 + } + ], + "effects": [] + } + ], + "behaviorsSharedData": [] + } + ], + "externalEvents": [], + "eventsFunctionsExtensions": [ + { + "author": "Arthur Pacaud (arthuro555)", + "category": "General", + "extensionNamespace": "", + "fullName": "Array tools", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQo8L3N0eWxlPg0KPGxpbmUgY2xhc3M9InN0MCIgeDE9IjExIiB5MT0iNyIgeDI9IjI5IiB5Mj0iNyIvPg0KPGxpbmUgY2xhc3M9InN0MCIgeDE9IjExIiB5MT0iMTYiIHgyPSIyMiIgeTI9IjE2Ii8+DQo8bGluZSBjbGFzcz0ic3QwIiB4MT0iMTEiIHkxPSIyNSIgeDI9IjI5IiB5Mj0iMjUiLz4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUiIGN5PSI3IiByPSIyIi8+DQo8Y2lyY2xlIGNsYXNzPSJzdDAiIGN4PSI1IiBjeT0iMTYiIHI9IjIiLz4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUiIGN5PSIyNSIgcj0iMiIvPg0KPC9zdmc+DQo=", + "name": "ArrayTools", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/Line Hero Pack/Master/SVG/Text Editing/9bfb52500e68d0fd164b1e30bc696e40566187245b80c345848379f40bb6fad7_Text Editing_bullet_points_list.svg", + "shortDescription": "A collection of utilities and tools for working with arrays.", + "version": "2.0.0", + "description": [ + "> Note: The v2.0.0 is not compatible with v1.0.0. If you update, you wil have to update ALL USAGES of the extension.", + "", + "This extension adds features like:", + "- Combining arrays (concatenate into new array, append all children to another array)", + "- Finding a value in an array (find index expression, contains condition)", + "- Reversing arrays", + "- Get a portion of an array (slice)", + "- Add and remove lots of children at specific indices at once (fill, splice, shift, pop, add at index)", + "- Randomness (shuffle children, get a random child)", + "- Mathematical operations using arrays (sum of all numbers, biggest/smallest number, average number, median number)", + "- Sort numbers in an array", + "- String inter-operation (split string into array, join array array children to string)" + ], + "origin": { + "identifier": "ArrayTools", + "name": "gdevelop-extension-store" + }, + "tags": [ + "array", + "variable", + "index", + "tool", + "math", + "string", + "sort", + "find", + "slice", + "cut", + "random", + "copy", + "combine", + "concat", + "append", + "insert" + ], + "authorIds": [ + "ZgrsWuRTAkXgeuPV9bo0zuEcA2w1" + ], + "dependencies": [], + "eventsFunctions": [ + { + "description": "The index of the first variable that equals to a specific number in an array.", + "fullName": "Index of number", + "functionType": "ExpressionAndCondition", + "group": "Scene variables/Array search", + "name": "IndexOf", + "sentence": "The first index where _PARAM2_ can be found in _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue =", + " array.getAllChildrenArray().findIndex(child => child.getAsNumber() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "scenevar" + }, + { + "description": "Number to search in the array", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the first variable that equals to a specific text in an array.", + "fullName": "Index of text", + "functionType": "ExpressionAndCondition", + "group": "Scene variables/Array search", + "name": "IndexOfStr", + "sentence": "The first index where _PARAM2_ can be found in _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue =", + " array.getAllChildrenArray().findIndex(child => child.getAsString() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "scenevar" + }, + { + "description": "String to search in the array", + "name": "Value", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the last variable that equals to a specific number in an array.", + "fullName": "Last index of number", + "functionType": "ExpressionAndCondition", + "group": "Scene variables/Array search", + "name": "LastIndexOf", + "sentence": "The last index where _PARAM2_ can be found in _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue = ", + " array.getAllChildrenArray().findLastIndex(child => child.getAsNumber() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "scenevar" + }, + { + "description": "Number to search in the array", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the last variable that equals to a specific text in an array.", + "fullName": "Last index of text", + "functionType": "ExpressionAndCondition", + "group": "Scene variables/Array search", + "name": "LastIndexOfStr", + "sentence": "The last index where _PARAM2_ can be found in _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue =", + " array.getAllChildrenArray().findLastIndex(child => child.getAsString() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "scenevar" + }, + { + "description": "String to search in the array", + "name": "Value", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Returns a random number of an array of numbers.", + "fullName": "Random number in array", + "functionType": "ExpressionAndCondition", + "group": "Scene variables/Array access", + "name": "RandomNumberInArray", + "sentence": "A randomly picked number of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const internalArray = array.getAllChildrenArray();", + "", + "eventsFunctionContext.returnValue = internalArray.length === 0", + " ? 0", + " : internalArray[Math.floor(Math.random() * internalArray.length)].getAsNumber();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to get a number from", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "a random string of an array of strings.", + "fullName": "Random string in array", + "functionType": "ExpressionAndCondition", + "group": "Scene variables/Array access", + "name": "RandomStringInArray", + "sentence": "A randomly picked string of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const internalArray = array.getAllChildrenArray();", + "", + "eventsFunctionContext.returnValue = internalArray.length === 0", + " ? \"\"", + " : internalArray[Math.floor(Math.random() * internalArray.length)].getAsString();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Array to get a string from", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the last array child of an array, and return it as a number.", + "fullName": "Get and remove last variable from array (as number)", + "functionType": "ExpressionAndCondition", + "group": "Scene variables/Array access", + "name": "PopNumber", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().pop().getAsNumber();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to pop a child from", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the last array child of an array, and return it as a string.", + "fullName": "Pop string from array", + "functionType": "StringExpression", + "group": "Scene variables/Array access", + "name": "PopString", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().pop().getAsString();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Array to pop a child from", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the first array child of an array, and return it as a number.", + "fullName": "Shift number from array", + "functionType": "Expression", + "group": "Scene variables/Array access", + "name": "ShiftNumber", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().shift().getAsNumber();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to shift a child from", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the first array child of an array, and return it as a string.", + "fullName": "Shift string from array", + "functionType": "StringExpression", + "group": "Scene variables/Array access", + "name": "ShiftString", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().shift().getAsString();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Array to shift a child from", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Checks if an array contains a specific number.", + "fullName": "Array has number", + "functionType": "Condition", + "group": "Scene variables/Array search", + "name": "HasNumber", + "sentence": "Array _PARAM1_ has number _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CopyArgumentToVariable" + }, + "parameters": [ + "\"Array\"", + "__ArrayTools.Temp" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOf(__ArrayTools.Temp, GetArgumentAsNumber(\"Value\"))", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The number to search", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Checks if an array contains a specific string.", + "fullName": "Array has string", + "functionType": "Condition", + "group": "Scene variables/Array search", + "name": "HasString", + "sentence": "Array _PARAM1_ has string _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CopyArgumentToVariable" + }, + "parameters": [ + "\"Array\"", + "__ArrayTools.Temp" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOfStr(__ArrayTools.Temp, GetArgumentAsString(\"Value\"))", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The text to search", + "name": "Value", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Copies a portion of a scene array variable into a new scene array variable.", + "fullName": "Slice an array", + "functionType": "Action", + "group": "Scene variables/Array creation", + "name": "Slice", + "sentence": "Slice array _PARAM1_ from indices _PARAM3_ to _PARAM4_ into _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Ensure the target is a clean new array", + "target.castTo(\"array\");", + "target.clearChildren();", + "", + "// Slice the original array", + "const slice = array", + " .getAllChildrenArray()", + " .slice(", + " eventsFunctionContext.getArgument(\"Begin\"),", + " // The `|| undefined` replaces 0 with undefined, as having the argument as 0 ", + " // would make the array empty and is therefore useless.", + " // With undefined though, it doesn't stop until the end of the array,", + " // which is purposeful.", + " eventsFunctionContext.getArgument(\"End\") || undefined", + " );", + "", + "// Copy each variable of the slice into the new array", + "for (const variable of slice)", + " target.pushVariableCopy(variable);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to take a slice from", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The array to store the slice into", + "name": "Target", + "type": "scenevar" + }, + { + "description": "The index to start the slice from", + "name": "Begin", + "type": "expression" + }, + { + "description": "The index to end the slice at", + "longDescription": "Set to 0 to copy all of the array. If you use a negative value, the index will be selected beginning from the end. \nFor example, slicing an array with 5 elements from 0 to -1 would take only elements from indices 0 to 3.", + "name": "End", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Cuts a portion of an array off.", + "fullName": "Splice an array", + "functionType": "Action", + "group": "Scene variables/Array manipulation", + "name": "Splice", + "sentence": "Remove _PARAM3_ items from array _PARAM1_ starting from index _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "const internalArray = array.getAllChildrenArray();", + "", + "internalArray.splice(", + " eventsFunctionContext.getArgument(\"Begin\"),", + " // Replaces 0 with the legth of the array, as having the argument as 0 ", + " // would not remove anything and is therefore useless.", + " eventsFunctionContext.getArgument(\"Count\") || internalArray.length", + ");", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to remove items from", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The index to start removing from", + "longDescription": "If you use a negative value, the index will be selected beginning from the end.", + "name": "Begin", + "type": "expression" + }, + { + "description": "The amount of elements to remove", + "longDescription": "Set to 0 to remove until the end of the array.", + "name": "Count", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Combines all elements of 2 scene arrays into one new scene array.", + "fullName": "Combine 2 arrays", + "functionType": "Action", + "group": "Scene variables/Array creation", + "name": "Concatenate", + "sentence": "Combine array _PARAM1_ and _PARAM2_ into _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const otherArray = eventsFunctionContext.getArgument(\"OtherArray\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Ensure the target is a clean new array", + "target.castTo(\"array\");", + "target.clearChildren();", + "", + "// Copy both arrays inside the new one", + "for (const variable of array.getAllChildrenArray())", + " target.pushVariableCopy(variable);", + "", + "for (const variable of otherArray.getAllChildrenArray())", + " target.pushVariableCopy(variable);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The first array", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The second array", + "name": "OtherArray", + "type": "scenevar" + }, + { + "description": "The variable to store the new array in", + "name": "Target", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Appends a copy of all variables of one array to another array.", + "fullName": "Append all variable to another array", + "functionType": "Action", + "group": "Scene variables/Array manipulation", + "name": "AppendAll", + "sentence": "Append all elements from array _PARAM1_ into _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Copy both arrays inside the new one", + "for (const variable of array.getAllChildrenArray())", + " target.pushVariableCopy(variable);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to get the variables from", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The variable to append the variables in", + "name": "Target", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Reverses children of an array. The first array child becomes the last, and the last array child becomes the first.", + "fullName": "Reverse an array", + "functionType": "Action", + "group": "Scene variables/Array manipulation", + "name": "Reverse", + "sentence": "Reverse array _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "array.getAllChildrenArray().reverse();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to reverse", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Fill an element with a number.", + "fullName": "Fill array with number", + "functionType": "Action", + "group": "Scene variables/Array creation", + "name": "FillNumber", + "sentence": "Fill array _PARAM1_ with _PARAM2_ from index _PARAM3_ to index _PARAM4_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "const internalArray = array.getAllChildrenArray();", + "const end = eventsFunctionContext.getArgument(\"End\") || internalArray.length - 1;", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "for (let i = eventsFunctionContext.getArgument(\"Begin\"); i <= end; i++)", + " internalArray[i] = new gdjs.Variable({", + " type: \"number\",", + " value,", + " });", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to fill", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The number to fill", + "name": "Value", + "type": "expression" + }, + { + "description": "The index to start filling from", + "name": "Begin", + "type": "expression" + }, + { + "description": "The index to stop filling at", + "longDescription": "Set to 0 to fill until the end of the array.", + "name": "End", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Shuffles all children of an array.", + "fullName": "Shuffle array", + "functionType": "Action", + "group": "Scene variables/Array manipulation", + "name": "Shuffle", + "sentence": "Shuffle array _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "array.getAllChildrenArray().sort(() => Math.random() - 0.5);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to shuffle", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Replaces all arrays inside of an array with their children. For example, [[1,2], [3,4]] becomes [1,2,3,4].", + "fullName": "Flatten array", + "functionType": "Action", + "group": "Scene variables/Array manipulation", + "name": "Flatten", + "sentence": "Flatten array _PARAM1_ (Deeply flatten: _PARAM2_)", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "const internalArray = array.getAllChildrenArray();", + "const deep = eventsFunctionContext.getArgument(\"Deep\");", + "", + "for (let i = 0; i < internalArray.length; i++) {", + " if (internalArray[i].getType() === \"array\") {", + " const childArray = internalArray[i].getAllChildrenArray();", + " // At the position of the array (i), remove 1 element (the array), ", + " // and insert elements of b (the contents of the array) in-place of the array.", + " internalArray.splice(i, 1, ...childArray);", + " // Skip over the elements that were just added as we are flattening only 1 level deep ", + " if (!deep) i += childArray.length;", + " // If deep, the current element has been replaced with another, we need to recheck it on next iteration.", + " // If not deep, the current element is now the one after the array elements and needs to be checked too.", + " // In both case, decreasing by 1 is necessary.", + " i--;", + " }", + "}", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to flatten", + "name": "Array", + "type": "scenevar" + }, + { + "description": "Deeply flatten", + "longDescription": "If yes, will continue flattening until there is no arrays in the array anymore.", + "name": "Deep", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the last array child of an array, and stores it in another variable.", + "fullName": "Pop array child", + "functionType": "Action", + "group": "Scene variables/Array access", + "name": "Pop", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "gdjs.Variable.copy(array.getAllChildrenArray().pop(), target, false);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to pop a child from", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The variable to store the popped value into", + "name": "Target", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the first array child of an array, and stores it in another variable.", + "fullName": "Shift array child", + "functionType": "Action", + "group": "Scene variables/Array access", + "name": "Shift", + "sentence": "Remove first child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "gdjs.Variable.copy(array.getAllChildrenArray().shift(), target, false);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to shift a child from", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The variable to store the shifted value into", + "name": "Target", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Insert a variable at a specific index of an array.", + "fullName": "Insert variable at", + "functionType": "Action", + "group": "Scene variables/Array manipulation", + "name": "InsertAt", + "sentence": "Insert variable _PARAM3_ in _PARAM1_ at index _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */\r", + "const array = eventsFunctionContext.getArgument(\"Array\");\r", + "/** @type {gdjs.Variable} */\r", + "const target = eventsFunctionContext.getArgument(\"Target\");\r", + "\r", + "// Cast to array to ensure getAllChildrenArray returns the real array\r", + "array.castTo(\"array\");\r", + "\r", + "array\r", + " .getAllChildrenArray()\r", + " .splice(eventsFunctionContext.getArgument(\"Index\"), 0, target.clone());\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to insert a variable in", + "name": "Array", + "type": "scenevar" + }, + { + "description": "The index to insert the variable at", + "name": "Index", + "type": "expression" + }, + { + "description": "The name of the variable to insert", + "name": "Target", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Split a string into an array of strings via a separator.", + "fullName": "Split string into array", + "functionType": "Action", + "group": "Scene variables/Array creation", + "name": "SplitString", + "sentence": "Split string _PARAM1_ via separator _PARAM2_ into array _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const stringToSplit = eventsFunctionContext.getArgument(\"String\");", + "const separator = eventsFunctionContext.getArgument(\"Separator\");", + "", + "// Ensure the target is a clean new array", + "array.castTo(\"array\");", + "array.clearChildren();", + "", + "for (const stringFragment of stringToSplit.split(separator))", + " array.pushValue(stringFragment);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The string to split", + "name": "String", + "type": "string" + }, + { + "description": "The separator to use to split the string", + "longDescription": "For example, if you have a string \"Hello World\", and the separator is a space (\" \"), the resulting array would be [\"Hello\", \"World\"]. If the separator is an empty string (\"\"), it will make an element per character ([\"H\", \"e\", \"l\", \"l\", \"o\", \" \", \"W\", \"o\", \"r\", \"l\", \"d\"]).", + "name": "Separator", + "type": "string" + }, + { + "description": "Array where to store the results", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Returns a string made from all strings in an array.", + "fullName": "Join all elements of an array together into a string", + "functionType": "StringExpression", + "group": "Scene variables/String arrays", + "name": "Join", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */\r", + "const array = eventsFunctionContext.getArgument(\"Array\");\r", + "const separator = eventsFunctionContext.getArgument(\"Separator\");\r", + "\r", + "eventsFunctionContext.returnValue = array\r", + " .getAllChildrenArray()\r", + " .reduce((accumulator, current) => accumulator + separator + current.getAsString(), \"\")\r", + " // Remove first separator as it should be only between the strings\r", + " .slice(separator.length);\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "The name of the array to join into a string", + "name": "Array", + "type": "scenevar" + }, + { + "description": "Optional separator text between each element", + "name": "Separator", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Get the sum of all numbers in an array.", + "fullName": "Sum of array children", + "functionType": "Expression", + "group": "Scene variables/Number arrays", + "name": "Sum", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "eventsFunctionContext.returnValue =", + " eventsFunctionContext.getArgument(\"Array\")", + " .getAllChildrenArray()", + " .reduce((accumulator, current) => accumulator + current.getAsNumber(), 0);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the smallest number in an array.", + "fullName": "Smallest value", + "functionType": "Expression", + "group": "Scene variables/Number arrays", + "name": "Min", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "const len = internalArray.length;\r", + "\r", + "if (len === 0) {\r", + " eventsFunctionContext.returnValue = 0;\r", + " return;\r", + "}\r", + "\r", + "let min = internalArray[0].getAsNumber();\r", + "\r", + "if (len === 1) {\r", + " eventsFunctionContext.returnValue = min;\r", + " return;\r", + "}\r", + "\r", + "for (let i = 1; i < len; i++) {\r", + " const num = internalArray[i].getAsNumber();\r", + " if (num < min) min = num;\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = min;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the biggest number in an array.", + "fullName": "Biggest value", + "functionType": "Expression", + "group": "Scene variables/Number arrays", + "name": "Max", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "const len = internalArray.length;\r", + "\r", + "if (len === 0) {\r", + " eventsFunctionContext.returnValue = 0;\r", + " return;\r", + "}\r", + "\r", + "let max = internalArray[0].getAsNumber();\r", + "\r", + "if (len === 1) {\r", + " eventsFunctionContext.returnValue = max;\r", + " return;\r", + "}\r", + "\r", + "for (let i = 1; i < len; i++) {\r", + " const num = internalArray[i].getAsNumber();\r", + " if (num > max) max = num;\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = max;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the average number in an array.", + "fullName": "Average value", + "functionType": "Expression", + "group": "Scene variables/Number arrays", + "name": "Mean", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "\r", + "eventsFunctionContext.returnValue =\r", + " internalArray.reduce(\r", + " (accumulator, current) => accumulator + current.getAsNumber(), 0\r", + " ) / internalArray.length;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the median number in an array.", + "fullName": "Median value", + "functionType": "Expression", + "group": "Scene variables/Number arrays", + "name": "Median", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "\r", + "const sortedCopy = internalArray.slice().sort((a, b) => {\r", + " const na = a.getAsNumber();\r", + " const nb = b.getAsNumber();\r", + " return na < nb ? -1 : na > nb ? 1 : 0;\r", + "})\r", + "const i = sortedCopy.length / 2;\r", + "\r", + "eventsFunctionContext.returnValue =\r", + " i % 1 === 0\r", + " ? (sortedCopy[i - 1].getAsNumber() + sortedCopy[i].getAsNumber()) / 2\r", + " : sortedCopy[Math.trunc(i)].getAsNumber();\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "Sort an array of number from smallest to biggest.", + "fullName": "Sort an array", + "functionType": "Action", + "group": "Scene variables/Number arrays", + "name": "Sort", + "sentence": "Sort array _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "array.getAllChildrenArray()", + " .sort((a, b) => {", + " const na = a.getAsNumber();", + " const nb = b.getAsNumber();", + " return na < nb ? -1 : na > nb ? 1 : 0;", + " });", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The array to sort", + "name": "Array", + "type": "scenevar" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the first variable that equals to a specific number in an array.", + "fullName": "Index of number", + "functionType": "ExpressionAndCondition", + "group": "Global variables/Array search", + "name": "GlobalIndexOf", + "sentence": "The first index where _PARAM2_ can be found in _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue =", + " array.getAllChildrenArray().findIndex(child => child.getAsNumber() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "globalvar" + }, + { + "description": "Number to search in the array", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the first variable that equals to a specific text in an array.", + "fullName": "Index of text", + "functionType": "ExpressionAndCondition", + "group": "Global variables/Array search", + "name": "GlobalIndexOfStr", + "sentence": "The first index where _PARAM2_ can be found in _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue =", + " array.getAllChildrenArray().findIndex(child => child.getAsString() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "globalvar" + }, + { + "description": "String to search in the array", + "name": "Value", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the last variable that equals to a specific number in an array.", + "fullName": "Last index of number", + "functionType": "ExpressionAndCondition", + "group": "Global variables/Array search", + "name": "GlobalLastIndexOf", + "sentence": "The last index where _PARAM2_ can be found in _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue = ", + " array.getAllChildrenArray().findLastIndex(child => child.getAsNumber() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "globalvar" + }, + { + "description": "Number to search in the array", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the last variable that equals to a specific text in an array.", + "fullName": "Last index of text", + "functionType": "ExpressionAndCondition", + "group": "Global variables/Array search", + "name": "GlobalLastIndexOfStr", + "sentence": "The last index where _PARAM2_ can be found in _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue =", + " array.getAllChildrenArray().findLastIndex(child => child.getAsString() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "globalvar" + }, + { + "description": "String to search in the array", + "name": "Value", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Returns a random number of an array of numbers.", + "fullName": "Random number in array", + "functionType": "ExpressionAndCondition", + "group": "Global variables/Array access", + "name": "GlobalRandomNumberInArray", + "sentence": "A randomly picked number of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const internalArray = array.getAllChildrenArray();", + "", + "eventsFunctionContext.returnValue = internalArray.length === 0", + " ? 0", + " : internalArray[Math.floor(Math.random() * internalArray.length)].getAsNumber();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to get a number from", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "a random string of an array of strings.", + "fullName": "Random string in array", + "functionType": "ExpressionAndCondition", + "group": "Global variables/Array access", + "name": "GlobalRandomStringInArray", + "sentence": "A randomly picked string of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const internalArray = array.getAllChildrenArray();", + "", + "eventsFunctionContext.returnValue = internalArray.length === 0", + " ? \"\"", + " : internalArray[Math.floor(Math.random() * internalArray.length)].getAsString();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Array to get a string from", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the last array child of an array, and return it as a number.", + "fullName": "Get and remove last variable from array (as number)", + "functionType": "ExpressionAndCondition", + "group": "Global variables/Array access", + "name": "GlobalPopNumber", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().pop().getAsNumber();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to pop a child from", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the last array child of an array, and return it as a string.", + "fullName": "Pop string from array", + "functionType": "StringExpression", + "group": "Global variables/Array access", + "name": "GlobalPopString", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().pop().getAsString();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Array to pop a child from", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the first array child of an array, and return it as a number.", + "fullName": "Shift number from array", + "functionType": "Expression", + "group": "Global variables/Array access", + "name": "GlobalShiftNumber", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().shift().getAsNumber();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Array to shift a child from", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the first array child of an array, and return it as a string.", + "fullName": "Shift string from array", + "functionType": "StringExpression", + "group": "Global variables/Array access", + "name": "GlobalShiftString", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().shift().getAsString();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Array to shift a child from", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Checks if an array contains a specific number.", + "fullName": "Array has number", + "functionType": "Condition", + "group": "Global variables/Array search", + "name": "GlobalHasNumber", + "sentence": "Array _PARAM1_ has number _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CopyArgumentToVariable" + }, + "parameters": [ + "\"Array\"", + "__ArrayTools.Temp" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOf(__ArrayTools.Temp, GetArgumentAsNumber(\"Value\"))", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The number to search", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Checks if an array contains a specific string.", + "fullName": "Array has string", + "functionType": "Condition", + "group": "Global variables/Array search", + "name": "GlobalHasString", + "sentence": "Array _PARAM1_ has string _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CopyArgumentToVariable" + }, + "parameters": [ + "\"Array\"", + "__ArrayTools.Temp" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOfStr(__ArrayTools.Temp, GetArgumentAsString(\"Value\"))", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Array to search the value in", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The text to search", + "name": "Value", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Copies a portion of a scene array variable into a new scene array variable.", + "fullName": "Slice an array", + "functionType": "Action", + "group": "Global variables/Array creation", + "name": "GlobalSlice", + "sentence": "Slice array _PARAM1_ from indices _PARAM3_ to _PARAM4_ into _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Ensure the target is a clean new array", + "target.castTo(\"array\");", + "target.clearChildren();", + "", + "// Slice the original array", + "const slice = array", + " .getAllChildrenArray()", + " .slice(", + " eventsFunctionContext.getArgument(\"Begin\"),", + " // The `|| undefined` replaces 0 with undefined, as having the argument as 0 ", + " // would make the array empty and is therefore useless.", + " // With undefined though, it doesn't stop until the end of the array,", + " // which is purposeful.", + " eventsFunctionContext.getArgument(\"End\") || undefined", + " );", + "", + "// Copy each variable of the slice into the new array", + "for (const variable of slice)", + " target.pushVariableCopy(variable);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to take a slice from", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The array to store the slice into", + "name": "Target", + "type": "globalvar" + }, + { + "description": "The index to start the slice from", + "name": "Begin", + "type": "expression" + }, + { + "description": "The index to end the slice at", + "longDescription": "Set to 0 to copy all of the array. If you use a negative value, the index will be selected beginning from the end. \nFor example, slicing an array with 5 elements from 0 to -1 would take only elements from indices 0 to 3.", + "name": "End", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Cuts a portion of an array off.", + "fullName": "Splice an array", + "functionType": "Action", + "group": "Global variables/Array manipulation", + "name": "GlobalSplice", + "sentence": "Remove _PARAM3_ items from array _PARAM1_ starting from index _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "const internalArray = array.getAllChildrenArray();", + "", + "internalArray.splice(", + " eventsFunctionContext.getArgument(\"Begin\"),", + " // Replaces 0 with the legth of the array, as having the argument as 0 ", + " // would not remove anything and is therefore useless.", + " eventsFunctionContext.getArgument(\"Count\") || internalArray.length", + ");", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to remove items from", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The index to start removing from", + "longDescription": "If you use a negative value, the index will be selected beginning from the end.", + "name": "Begin", + "type": "expression" + }, + { + "description": "The amount of elements to remove", + "longDescription": "Set to 0 to remove until the end of the array.", + "name": "Count", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Combines all elements of 2 scene arrays into one new scene array.", + "fullName": "Combine 2 arrays", + "functionType": "Action", + "group": "Global variables/Array creation", + "name": "GlobalConcatenate", + "sentence": "Combine array _PARAM1_ and _PARAM2_ into _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const otherArray = eventsFunctionContext.getArgument(\"OtherArray\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Ensure the target is a clean new array", + "target.castTo(\"array\");", + "target.clearChildren();", + "", + "// Copy both arrays inside the new one", + "for (const variable of array.getAllChildrenArray())", + " target.pushVariableCopy(variable);", + "", + "for (const variable of otherArray.getAllChildrenArray())", + " target.pushVariableCopy(variable);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The first array", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The second array", + "name": "OtherArray", + "type": "globalvar" + }, + { + "description": "The variable to store the new array in", + "name": "Target", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Appends a copy of all variables of one array to another array.", + "fullName": "Append all variable to another array", + "functionType": "Action", + "group": "Global variables/Array manipulation", + "name": "GlobalAppendAll", + "sentence": "Append all elements from array _PARAM1_ into _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Copy both arrays inside the new one", + "for (const variable of array.getAllChildrenArray())", + " target.pushVariableCopy(variable);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to get the variables from", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The variable to append the variables in", + "name": "Target", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Reverses children of an array. The first array child becomes the last, and the last array child becomes the first.", + "fullName": "Reverse an array", + "functionType": "Action", + "group": "Global variables/Array manipulation", + "name": "GlobalReverse", + "sentence": "Reverse array _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "array.getAllChildrenArray().reverse();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to reverse", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Fill an element with a number.", + "fullName": "Fill array with number", + "functionType": "Action", + "group": "Global variables/Array creation", + "name": "GlobalFillNumber", + "sentence": "Fill array _PARAM1_ with _PARAM2_ from index _PARAM3_ to index _PARAM4_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "const internalArray = array.getAllChildrenArray();", + "const end = eventsFunctionContext.getArgument(\"End\") || internalArray.length - 1;", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "for (let i = eventsFunctionContext.getArgument(\"Begin\"); i <= end; i++)", + " internalArray[i] = new gdjs.Variable({", + " type: \"number\",", + " value,", + " });", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to fill", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The number to fill", + "name": "Value", + "type": "expression" + }, + { + "description": "The index to start filling from", + "name": "Begin", + "type": "expression" + }, + { + "description": "The index to stop filling at", + "longDescription": "Set to 0 to fill until the end of the array.", + "name": "End", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Shuffles all children of an array.", + "fullName": "Shuffle array", + "functionType": "Action", + "group": "Global variables/Array manipulation", + "name": "GlobalShuffle", + "sentence": "Shuffle array _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "array.getAllChildrenArray().sort(() => Math.random() - 0.5);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to shuffle", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Replaces all arrays inside of an array with their children. For example, [[1,2], [3,4]] becomes [1,2,3,4].", + "fullName": "Flatten array", + "functionType": "Action", + "group": "Global variables/Array manipulation", + "name": "GlobalFlatten", + "sentence": "Flatten array _PARAM1_ (Deeply flatten: _PARAM2_)", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "const internalArray = array.getAllChildrenArray();", + "const deep = eventsFunctionContext.getArgument(\"Deep\");", + "", + "for (let i = 0; i < internalArray.length; i++) {", + " if (internalArray[i].getType() === \"array\") {", + " const childArray = internalArray[i].getAllChildrenArray();", + " // At the position of the array (i), remove 1 element (the array), ", + " // and insert elements of b (the contents of the array) in-place of the array.", + " internalArray.splice(i, 1, ...childArray);", + " // Skip over the elements that were just added as we are flattening only 1 level deep ", + " if (!deep) i += childArray.length;", + " // If deep, the current element has been replaced with another, we need to recheck it on next iteration.", + " // If not deep, the current element is now the one after the array elements and needs to be checked too.", + " // In both case, decreasing by 1 is necessary.", + " i--;", + " }", + "}", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to flatten", + "name": "Array", + "type": "globalvar" + }, + { + "description": "Deeply flatten", + "longDescription": "If yes, will continue flattening until there is no arrays in the array anymore.", + "name": "Deep", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the last array child of an array, and stores it in another variable.", + "fullName": "Pop array child", + "functionType": "Action", + "group": "Global variables/Array access", + "name": "GlobalPop", + "sentence": "Remove last child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "gdjs.Variable.copy(array.getAllChildrenArray().pop(), target, false);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to pop a child from", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The variable to store the popped value into", + "name": "Target", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the first array child of an array, and stores it in another variable.", + "fullName": "Shift array child", + "functionType": "Action", + "group": "Global variables/Array access", + "name": "GlobalShift", + "sentence": "Remove first child of _PARAM1_ and store it in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "gdjs.Variable.copy(array.getAllChildrenArray().shift(), target, false);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to shift a child from", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The variable to store the shifted value into", + "name": "Target", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Insert a variable at a specific index of an array.", + "fullName": "Insert variable at", + "functionType": "Action", + "group": "Global variables/Array manipulation", + "name": "GlobalInsertAt", + "sentence": "Insert variable _PARAM3_ in _PARAM1_ at index _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */\r", + "const array = eventsFunctionContext.getArgument(\"Array\");\r", + "/** @type {gdjs.Variable} */\r", + "const target = eventsFunctionContext.getArgument(\"Target\");\r", + "\r", + "// Cast to array to ensure getAllChildrenArray returns the real array\r", + "array.castTo(\"array\");\r", + "\r", + "array\r", + " .getAllChildrenArray()\r", + " .splice(eventsFunctionContext.getArgument(\"Index\"), 0, target.clone());\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The array to insert a variable in", + "name": "Array", + "type": "globalvar" + }, + { + "description": "The index to insert the variable at", + "name": "Index", + "type": "expression" + }, + { + "description": "The name of the variable to insert", + "name": "Target", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Split a string into an array of strings via a separator.", + "fullName": "Split string into array", + "functionType": "Action", + "group": "Global variables/Array creation", + "name": "GlobalSplitString", + "sentence": "Split string _PARAM1_ via separator _PARAM2_ into array _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const stringToSplit = eventsFunctionContext.getArgument(\"String\");", + "const separator = eventsFunctionContext.getArgument(\"Separator\");", + "", + "// Ensure the target is a clean new array", + "array.castTo(\"array\");", + "array.clearChildren();", + "", + "for (const stringFragment of stringToSplit.split(separator))", + " array.pushValue(stringFragment);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The string to split", + "name": "String", + "type": "string" + }, + { + "description": "The separator to use to split the string", + "longDescription": "For example, if you have a string \"Hello World\", and the separator is a space (\" \"), the resulting array would be [\"Hello\", \"World\"]. If the separator is an empty string (\"\"), it will make an element per character ([\"H\", \"e\", \"l\", \"l\", \"o\", \" \", \"W\", \"o\", \"r\", \"l\", \"d\"]).", + "name": "Separator", + "type": "string" + }, + { + "description": "Array where to store the results", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Returns a string made from all strings in an array.", + "fullName": "Join all elements of an array together into a string", + "functionType": "StringExpression", + "group": "Global variables/String arrays", + "name": "GlobalJoin", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */\r", + "const array = eventsFunctionContext.getArgument(\"Array\");\r", + "const separator = eventsFunctionContext.getArgument(\"Separator\");\r", + "\r", + "eventsFunctionContext.returnValue = array\r", + " .getAllChildrenArray()\r", + " .reduce((accumulator, current) => accumulator + separator + current.getAsString(), \"\")\r", + " // Remove first separator as it should be only between the strings\r", + " .slice(separator.length);\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "The name of the array to join into a string", + "name": "Array", + "type": "globalvar" + }, + { + "description": "Optional separator text between each element", + "name": "Separator", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Get the sum of all numbers in an array.", + "fullName": "Sum of array children", + "functionType": "Expression", + "group": "Global variables/Number arrays", + "name": "GlobalSum", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "eventsFunctionContext.returnValue =", + " eventsFunctionContext.getArgument(\"Array\")", + " .getAllChildrenArray()", + " .reduce((accumulator, current) => accumulator + current.getAsNumber(), 0);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the smallest number in an array.", + "fullName": "Smallest value", + "functionType": "Expression", + "group": "Global variables/Number arrays", + "name": "GlobalMin", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "const len = internalArray.length;\r", + "\r", + "if (len === 0) {\r", + " eventsFunctionContext.returnValue = 0;\r", + " return;\r", + "}\r", + "\r", + "let min = internalArray[0].getAsNumber();\r", + "\r", + "if (len === 1) {\r", + " eventsFunctionContext.returnValue = min;\r", + " return;\r", + "}\r", + "\r", + "for (let i = 1; i < len; i++) {\r", + " const num = internalArray[i].getAsNumber();\r", + " if (num < min) min = num;\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = min;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the biggest number in an array.", + "fullName": "Biggest value", + "functionType": "Expression", + "group": "Global variables/Number arrays", + "name": "GlobalMax", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "const len = internalArray.length;\r", + "\r", + "if (len === 0) {\r", + " eventsFunctionContext.returnValue = 0;\r", + " return;\r", + "}\r", + "\r", + "let max = internalArray[0].getAsNumber();\r", + "\r", + "if (len === 1) {\r", + " eventsFunctionContext.returnValue = max;\r", + " return;\r", + "}\r", + "\r", + "for (let i = 1; i < len; i++) {\r", + " const num = internalArray[i].getAsNumber();\r", + " if (num > max) max = num;\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = max;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the average number in an array.", + "fullName": "Average value", + "functionType": "Expression", + "group": "Global variables/Number arrays", + "name": "GlobalMean", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "\r", + "eventsFunctionContext.returnValue =\r", + " internalArray.reduce(\r", + " (accumulator, current) => accumulator + current.getAsNumber(), 0\r", + " ) / internalArray.length;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the median number in an array.", + "fullName": "Median value", + "functionType": "Expression", + "group": "Global variables/Number arrays", + "name": "GlobalMedian", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "\r", + "const sortedCopy = internalArray.slice().sort((a, b) => {\r", + " const na = a.getAsNumber();\r", + " const nb = b.getAsNumber();\r", + " return na < nb ? -1 : na > nb ? 1 : 0;\r", + "})\r", + "const i = sortedCopy.length / 2;\r", + "\r", + "eventsFunctionContext.returnValue =\r", + " i % 1 === 0\r", + " ? (sortedCopy[i - 1].getAsNumber() + sortedCopy[i].getAsNumber()) / 2\r", + " : sortedCopy[Math.trunc(i)].getAsNumber();\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The array", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "Sort an array of number from smallest to biggest.", + "fullName": "Sort an array", + "functionType": "Action", + "group": "Global variables/Number arrays", + "name": "GlobalSort", + "sentence": "Sort array _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "array.getAllChildrenArray()", + " .sort((a, b) => {", + " const na = a.getAsNumber();", + " const nb = b.getAsNumber();", + " return na < nb ? -1 : na > nb ? 1 : 0;", + " });", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The array to sort", + "name": "Array", + "type": "globalvar" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the first variable that equals to a specific number in an array.", + "fullName": "Index of number", + "functionType": "ExpressionAndCondition", + "group": "Object variables/Array search", + "name": "ObjectIndexOf", + "sentence": "The first index where _PARAM3_ can be found in _PARAM2_ of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue =", + " array.getAllChildrenArray().findIndex(child => child.getAsNumber() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to search the value in", + "name": "Array", + "type": "objectvar" + }, + { + "description": "Number to search in the array", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the first variable that equals to a specific text in an array.", + "fullName": "Index of text", + "functionType": "ExpressionAndCondition", + "group": "Object variables/Array search", + "name": "ObjectIndexOfStr", + "sentence": "The first index where _PARAM3_ can be found in _PARAM2_ of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue =", + " array.getAllChildrenArray().findIndex(child => child.getAsString() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to search the value in", + "name": "Array", + "type": "objectvar" + }, + { + "description": "String to search in the array", + "name": "Value", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the last variable that equals to a specific number in an array.", + "fullName": "Last index of number", + "functionType": "ExpressionAndCondition", + "group": "Object variables/Array search", + "name": "ObjectLastIndexOf", + "sentence": "The last index where _PARAM3_ can be found in _PARAM2_ of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue = ", + " array.getAllChildrenArray().findLastIndex(child => child.getAsNumber() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to search the value in", + "name": "Array", + "type": "objectvar" + }, + { + "description": "Number to search in the array", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "The index of the last variable that equals to a specific text in an array.", + "fullName": "Last index of text", + "functionType": "ExpressionAndCondition", + "group": "Object variables/Array search", + "name": "ObjectLastIndexOfStr", + "sentence": "The last index where _PARAM3_ can be found in _PARAM2_ of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "eventsFunctionContext.returnValue =", + " array.getAllChildrenArray().findLastIndex(child => child.getAsString() === value);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to search the value in", + "name": "Array", + "type": "objectvar" + }, + { + "description": "String to search in the array", + "name": "Value", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Returns a random number of an array of numbers.", + "fullName": "Random number in array", + "functionType": "ExpressionAndCondition", + "group": "Object variables/Array access", + "name": "ObjectRandomNumberInArray", + "sentence": "A randomly picked number of _PARAM2_ of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const internalArray = array.getAllChildrenArray();", + "", + "eventsFunctionContext.returnValue = internalArray.length === 0", + " ? 0", + " : internalArray[Math.floor(Math.random() * internalArray.length)].getAsNumber();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to get a number from", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "a random string of an array of strings.", + "fullName": "Random string in array", + "functionType": "ExpressionAndCondition", + "group": "Object variables/Array access", + "name": "ObjectRandomStringInArray", + "sentence": "A randomly picked string of _PARAM2_ of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const internalArray = array.getAllChildrenArray();", + "", + "eventsFunctionContext.returnValue = internalArray.length === 0", + " ? \"\"", + " : internalArray[Math.floor(Math.random() * internalArray.length)].getAsString();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to get a string from", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the last array child of an array, and return it as a number.", + "fullName": "Get and remove last variable from array (as number)", + "functionType": "ExpressionAndCondition", + "group": "Object variables/Array access", + "name": "ObjectPopNumber", + "sentence": "Remove last child of _PARAM2_ of _PARAM1_ and store it in _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().pop().getAsNumber();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to pop a child from", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the last array child of an array, and return it as a string.", + "fullName": "Pop string from array", + "functionType": "StringExpression", + "group": "Object variables/Array access", + "name": "ObjectPopString", + "sentence": "Remove last child of _PARAM2_ of _PARAM1_ and store it in _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().pop().getAsString();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to pop a child from", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the first array child of an array, and return it as a number.", + "fullName": "Shift number from array", + "functionType": "Expression", + "group": "Object variables/Array access", + "name": "ObjectShiftNumber", + "sentence": "Remove last child of _PARAM2_ of _PARAM1_ and store it in _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().shift().getAsNumber();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to shift a child from", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the first array child of an array, and return it as a string.", + "fullName": "Shift string from array", + "functionType": "StringExpression", + "group": "Object variables/Array access", + "name": "ObjectShiftString", + "sentence": "Remove last child of _PARAM2_ of _PARAM1_ and store it in _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "eventsFunctionContext.returnValue = array.getAllChildrenArray().shift().getAsString();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to shift a child from", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Checks if an array contains a specific number.", + "fullName": "Array has number", + "functionType": "Condition", + "group": "Object variables/Array search", + "name": "ObjectHasNumber", + "sentence": "Array _PARAM2_ of _PARAM1_ has number _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CopyArgumentToVariable" + }, + "parameters": [ + "\"Array\"", + "__ArrayTools.Temp" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOf(__ArrayTools.Temp, GetArgumentAsNumber(\"Value\"))", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to search the value in", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The number to search", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Checks if an array contains a specific string.", + "fullName": "Array has string", + "functionType": "Condition", + "group": "Object variables/Array search", + "name": "ObjectHasString", + "sentence": "Array _PARAM2_ of _PARAM1_ has string _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CopyArgumentToVariable" + }, + "parameters": [ + "\"Array\"", + "__ArrayTools.Temp" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "ArrayTools::IndexOfStr(__ArrayTools.Temp, GetArgumentAsString(\"Value\"))", + "!=", + "-1" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array to search the value in", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The text to search", + "name": "Value", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Copies a portion of a scene array variable into a new scene array variable.", + "fullName": "Slice an array", + "functionType": "Action", + "group": "Object variables/Array creation", + "name": "ObjectSlice", + "sentence": "Slice array _PARAM2_ of _PARAM1_ from indices _PARAM5_ to _PARAM6_ into _PARAM4_ of _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Ensure the target is a clean new array", + "target.castTo(\"array\");", + "target.clearChildren();", + "", + "// Slice the original array", + "const slice = array", + " .getAllChildrenArray()", + " .slice(", + " eventsFunctionContext.getArgument(\"Begin\"),", + " // The `|| undefined` replaces 0 with undefined, as having the argument as 0 ", + " // would make the array empty and is therefore useless.", + " // With undefined though, it doesn't stop until the end of the array,", + " // which is purposeful.", + " eventsFunctionContext.getArgument(\"End\") || undefined", + " );", + "", + "// Copy each variable of the slice into the new array", + "for (const variable of slice)", + " target.pushVariableCopy(variable);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to take a slice from", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to store the slice into", + "name": "Target", + "type": "objectvar" + }, + { + "description": "The index to start the slice from", + "name": "Begin", + "type": "expression" + }, + { + "description": "The index to end the slice at", + "longDescription": "Set to 0 to copy all of the array. If you use a negative value, the index will be selected beginning from the end. \nFor example, slicing an array with 5 elements from 0 to -1 would take only elements from indices 0 to 3.", + "name": "End", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Cuts a portion of an array off.", + "fullName": "Splice an array", + "functionType": "Action", + "group": "Object variables/Array manipulation", + "name": "ObjectSplice", + "sentence": "Remove _PARAM4_ items from array _PARAM2_ of _PARAM1_ starting from index _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "const internalArray = array.getAllChildrenArray();", + "", + "internalArray.splice(", + " eventsFunctionContext.getArgument(\"Begin\"),", + " // Replaces 0 with the legth of the array, as having the argument as 0 ", + " // would not remove anything and is therefore useless.", + " eventsFunctionContext.getArgument(\"Count\") || internalArray.length", + ");", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to remove items from", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The index to start removing from", + "longDescription": "If you use a negative value, the index will be selected beginning from the end.", + "name": "Begin", + "type": "expression" + }, + { + "description": "The amount of elements to remove", + "longDescription": "Set to 0 to remove until the end of the array.", + "name": "Count", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Combines all elements of 2 scene arrays into one new scene array.", + "fullName": "Combine 2 arrays", + "functionType": "Action", + "group": "Object variables/Array creation", + "name": "ObjectConcatenate", + "sentence": "Combine array _PARAM2_ of _PARAM1_ and _PARAM4_ of _PARAM3_ into _PARAM6_ of _PARAM5_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const otherArray = eventsFunctionContext.getArgument(\"OtherArray\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Ensure the target is a clean new array", + "target.castTo(\"array\");", + "target.clearChildren();", + "", + "// Copy both arrays inside the new one", + "for (const variable of array.getAllChildrenArray())", + " target.pushVariableCopy(variable);", + "", + "for (const variable of otherArray.getAllChildrenArray())", + " target.pushVariableCopy(variable);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The first array", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The second array", + "name": "OtherArray", + "type": "objectvar" + }, + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The variable to store the new array in", + "name": "Target", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Appends a copy of all variables of one array to another array.", + "fullName": "Append all variable to another array", + "functionType": "Action", + "group": "Object variables/Array manipulation", + "name": "ObjectAppendAll", + "sentence": "Append all elements from array _PARAM2_ of _PARAM1_ into _PARAM4_ of _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Copy both arrays inside the new one", + "for (const variable of array.getAllChildrenArray())", + " target.pushVariableCopy(variable);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to get the variables from", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The variable to append the variables in", + "name": "Target", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Reverses children of an array. The first array child becomes the last, and the last array child becomes the first.", + "fullName": "Reverse an array", + "functionType": "Action", + "group": "Object variables/Array manipulation", + "name": "ObjectReverse", + "sentence": "Reverse array _PARAM2_ of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "array.getAllChildrenArray().reverse();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to reverse", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Fill an element with a number.", + "fullName": "Fill array with number", + "functionType": "Action", + "group": "Object variables/Array creation", + "name": "ObjectFillNumber", + "sentence": "Fill array _PARAM2_ of _PARAM1_ with _PARAM3_ from index _PARAM4_ to index _PARAM5_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "const internalArray = array.getAllChildrenArray();", + "const end = eventsFunctionContext.getArgument(\"End\") || internalArray.length - 1;", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "for (let i = eventsFunctionContext.getArgument(\"Begin\"); i <= end; i++)", + " internalArray[i] = new gdjs.Variable({", + " type: \"number\",", + " value,", + " });", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to fill", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The number to fill", + "name": "Value", + "type": "expression" + }, + { + "description": "The index to start filling from", + "name": "Begin", + "type": "expression" + }, + { + "description": "The index to stop filling at", + "longDescription": "Set to 0 to fill until the end of the array.", + "name": "End", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Shuffles all children of an array.", + "fullName": "Shuffle array", + "functionType": "Action", + "group": "Object variables/Array manipulation", + "name": "ObjectShuffle", + "sentence": "Shuffle array _PARAM2_ of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "array.getAllChildrenArray().sort(() => Math.random() - 0.5);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to shuffle", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Replaces all arrays inside of an array with their children. For example, [[1,2], [3,4]] becomes [1,2,3,4].", + "fullName": "Flatten array", + "functionType": "Action", + "group": "Object variables/Array manipulation", + "name": "ObjectFlatten", + "sentence": "Flatten array _PARAM2_ of _PARAM1_ (Deeply flatten: _PARAM3_)", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "const internalArray = array.getAllChildrenArray();", + "const deep = eventsFunctionContext.getArgument(\"Deep\");", + "", + "for (let i = 0; i < internalArray.length; i++) {", + " if (internalArray[i].getType() === \"array\") {", + " const childArray = internalArray[i].getAllChildrenArray();", + " // At the position of the array (i), remove 1 element (the array), ", + " // and insert elements of b (the contents of the array) in-place of the array.", + " internalArray.splice(i, 1, ...childArray);", + " // Skip over the elements that were just added as we are flattening only 1 level deep ", + " if (!deep) i += childArray.length;", + " // If deep, the current element has been replaced with another, we need to recheck it on next iteration.", + " // If not deep, the current element is now the one after the array elements and needs to be checked too.", + " // In both case, decreasing by 1 is necessary.", + " i--;", + " }", + "}", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to flatten", + "name": "Array", + "type": "objectvar" + }, + { + "description": "Deeply flatten", + "longDescription": "If yes, will continue flattening until there is no arrays in the array anymore.", + "name": "Deep", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the last array child of an array, and stores it in another variable.", + "fullName": "Pop array child", + "functionType": "Action", + "group": "Object variables/Array access", + "name": "ObjectPop", + "sentence": "Remove last child of _PARAM2_ of _PARAM1_ and store it in _PARAM4_ of _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "gdjs.Variable.copy(array.getAllChildrenArray().pop(), target, false);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to pop a child from", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The variable to store the popped value into", + "name": "Target", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Removes the first array child of an array, and stores it in another variable.", + "fullName": "Shift array child", + "functionType": "Action", + "group": "Object variables/Array access", + "name": "ObjectShift", + "sentence": "Remove first child of _PARAM2_ of _PARAM1_ and store it in _PARAM4_ of _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "/** @type {gdjs.Variable} */", + "const target = eventsFunctionContext.getArgument(\"Target\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "gdjs.Variable.copy(array.getAllChildrenArray().shift(), target, false);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to shift a child from", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The variable to store the shifted value into", + "name": "Target", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Insert a variable at a specific index of an array.", + "fullName": "Insert variable at", + "functionType": "Action", + "group": "Object variables/Array manipulation", + "name": "ObjectInsertAt", + "sentence": "Insert variable _PARAM5_ of _PARAM4_ in _PARAM2_ of _PARAM1_ at index _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */\r", + "const array = eventsFunctionContext.getArgument(\"Array\");\r", + "/** @type {gdjs.Variable} */\r", + "const target = eventsFunctionContext.getArgument(\"Target\");\r", + "\r", + "// Cast to array to ensure getAllChildrenArray returns the real array\r", + "array.castTo(\"array\");\r", + "\r", + "array\r", + " .getAllChildrenArray()\r", + " .splice(eventsFunctionContext.getArgument(\"Index\"), 0, target.clone());\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to insert a variable in", + "name": "Array", + "type": "objectvar" + }, + { + "description": "The index to insert the variable at", + "name": "Index", + "type": "expression" + }, + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The name of the variable to insert", + "name": "Target", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Split a string into an array of strings via a separator.", + "fullName": "Split string into array", + "functionType": "Action", + "group": "Object variables/Array creation", + "name": "ObjectSplitString", + "sentence": "Split string _PARAM1_ via separator _PARAM2_ into array _PARAM4_ of _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "const stringToSplit = eventsFunctionContext.getArgument(\"String\");", + "const separator = eventsFunctionContext.getArgument(\"Separator\");", + "", + "// Ensure the target is a clean new array", + "array.castTo(\"array\");", + "array.clearChildren();", + "", + "for (const stringFragment of stringToSplit.split(separator))", + " array.pushValue(stringFragment);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "The string to split", + "name": "String", + "type": "string" + }, + { + "description": "The separator to use to split the string", + "longDescription": "For example, if you have a string \"Hello World\", and the separator is a space (\" \"), the resulting array would be [\"Hello\", \"World\"]. If the separator is an empty string (\"\"), it will make an element per character ([\"H\", \"e\", \"l\", \"l\", \"o\", \" \", \"W\", \"o\", \"r\", \"l\", \"d\"]).", + "name": "Separator", + "type": "string" + }, + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "Array where to store the results", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Returns a string made from all strings in an array.", + "fullName": "Join all elements of an array together into a string", + "functionType": "StringExpression", + "group": "Object variables/String arrays", + "name": "ObjectJoin", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */\r", + "const array = eventsFunctionContext.getArgument(\"Array\");\r", + "const separator = eventsFunctionContext.getArgument(\"Separator\");\r", + "\r", + "eventsFunctionContext.returnValue = array\r", + " .getAllChildrenArray()\r", + " .reduce((accumulator, current) => accumulator + separator + current.getAsString(), \"\")\r", + " // Remove first separator as it should be only between the strings\r", + " .slice(separator.length);\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The name of the array to join into a string", + "name": "Array", + "type": "objectvar" + }, + { + "description": "Optional separator text between each element", + "name": "Separator", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Get the sum of all numbers in an array.", + "fullName": "Sum of array children", + "functionType": "Expression", + "group": "Object variables/Number arrays", + "name": "ObjectSum", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "eventsFunctionContext.returnValue =", + " eventsFunctionContext.getArgument(\"Array\")", + " .getAllChildrenArray()", + " .reduce((accumulator, current) => accumulator + current.getAsNumber(), 0);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the smallest number in an array.", + "fullName": "Smallest value", + "functionType": "Expression", + "group": "Object variables/Number arrays", + "name": "ObjectMin", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "const len = internalArray.length;\r", + "\r", + "if (len === 0) {\r", + " eventsFunctionContext.returnValue = 0;\r", + " return;\r", + "}\r", + "\r", + "let min = internalArray[0].getAsNumber();\r", + "\r", + "if (len === 1) {\r", + " eventsFunctionContext.returnValue = min;\r", + " return;\r", + "}\r", + "\r", + "for (let i = 1; i < len; i++) {\r", + " const num = internalArray[i].getAsNumber();\r", + " if (num < min) min = num;\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = min;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the biggest number in an array.", + "fullName": "Biggest value", + "functionType": "Expression", + "group": "Object variables/Number arrays", + "name": "ObjectMax", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "const len = internalArray.length;\r", + "\r", + "if (len === 0) {\r", + " eventsFunctionContext.returnValue = 0;\r", + " return;\r", + "}\r", + "\r", + "let max = internalArray[0].getAsNumber();\r", + "\r", + "if (len === 1) {\r", + " eventsFunctionContext.returnValue = max;\r", + " return;\r", + "}\r", + "\r", + "for (let i = 1; i < len; i++) {\r", + " const num = internalArray[i].getAsNumber();\r", + " if (num > max) max = num;\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = max;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the average number in an array.", + "fullName": "Average value", + "functionType": "Expression", + "group": "Object variables/Number arrays", + "name": "ObjectMean", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "\r", + "eventsFunctionContext.returnValue =\r", + " internalArray.reduce(\r", + " (accumulator, current) => accumulator + current.getAsNumber(), 0\r", + " ) / internalArray.length;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Gets the median number in an array.", + "fullName": "Median value", + "functionType": "Expression", + "group": "Object variables/Number arrays", + "name": "ObjectMedian", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable[]} */\r", + "const internalArray = eventsFunctionContext.getArgument(\"Array\").getAllChildrenArray();\r", + "\r", + "const sortedCopy = internalArray.slice().sort((a, b) => {\r", + " const na = a.getAsNumber();\r", + " const nb = b.getAsNumber();\r", + " return na < nb ? -1 : na > nb ? 1 : 0;\r", + "})\r", + "const i = sortedCopy.length / 2;\r", + "\r", + "eventsFunctionContext.returnValue =\r", + " i % 1 === 0\r", + " ? (sortedCopy[i - 1].getAsNumber() + sortedCopy[i].getAsNumber()) / 2\r", + " : sortedCopy[Math.trunc(i)].getAsNumber();\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + }, + { + "description": "Sort an array of number from smallest to biggest.", + "fullName": "Sort an array", + "functionType": "Action", + "group": "Object variables/Number arrays", + "name": "ObjectSort", + "sentence": "Sort array _PARAM2_ of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.Variable} */", + "const array = eventsFunctionContext.getArgument(\"Array\");", + "", + "// Cast to array to ensure getAllChildrenArray returns the real array", + "array.castTo(\"array\");", + "", + "array.getAllChildrenArray()", + " .sort((a, b) => {", + " const na = a.getAsNumber();", + " const nb = b.getAsNumber();", + " return na < nb ? -1 : na > nb ? 1 : 0;", + " });", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "The object the variable is from", + "name": "Object", + "type": "objectList" + }, + { + "description": "The array to sort", + "name": "Array", + "type": "objectvar" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [], + "eventsBasedObjects": [] + } + ], + "externalLayouts": [], + "externalSourceFiles": [] +} \ No newline at end of file diff --git a/scripts/check-single-extension.js b/scripts/check-single-extension.js index 7fbd186bc..01c453b5e 100644 --- a/scripts/check-single-extension.js +++ b/scripts/check-single-extension.js @@ -6,7 +6,7 @@ const { validateExtension } = require('./lib/ExtensionValidator'); * A function used by the CI to check for issues in a single extension. * @param {string} extensionName * @param {{extensionsFolder?: string, preliminaryCheck?: boolean}} [options] - * @returns {Promise<{code: "invalid-file-name" | "not-found" | "duplicated" | "invalid-json" | "success"} | {code: "rule-break", errors: string[]}>} + * @returns {Promise<{code: "invalid-file-name" | "not-found" | "duplicated" | "invalid-json" | "unknown-json-contents" | "gdevelop-project-file" | "success"} | {code: "rule-break", errors: string[]}>} */ exports.verifyExtension = async function (extensionName, options) { const { @@ -43,6 +43,25 @@ exports.verifyExtension = async function (extensionName, options) { return { code: 'invalid-json' }; } + // Basic check to see if it is a GDevelop project + if ( + typeof extension.properties === 'object' && + typeof extension.properties.name === 'string' + ) { + return { code: 'gdevelop-project-file' }; + } + + // Basic check to see if it is a GDevelop extension + if ( + !( + Array.isArray(extension.eventsFunctions) && + Array.isArray(extension.eventsBasedBehaviors) && + typeof extension.name === 'string' + ) + ) { + return { code: 'unknown-json-contents' }; + } + const validationDetails = await validateExtension( { state: 'success', diff --git a/scripts/extract-extension.js b/scripts/extract-extension.js index bf50cc413..e0f68a52e 100644 --- a/scripts/extract-extension.js +++ b/scripts/extract-extension.js @@ -8,13 +8,13 @@ const pipeline = require('util').promisify(require('stream').pipeline); /** * Extracts exactly one extension into the community extensions folder from a zip file. * @param {string} zipPath The path to the zip file to extract. - * @param {string} [extensionsFolder] The folder with the extensions. + * @param {{extensionsFolder?: string, reviewed?: boolean}} [options] * @returns {Promise<{error: "too-many-files" | "no-json-found"| "invalid-file-name" | "zip-error", details?: any} | {error?: undefined,extensionName: string}>} the name of the extracted extension if successful, else a generic error code. */ -exports.extractExtension = async function ( - zipPath, - extensionsFolder = `${__dirname}/../extensions` -) { +exports.extractExtension = async function (zipPath, options) { + const { extensionsFolder = `${__dirname}/../extensions`, reviewed = false } = + options || {}; + // Load in the archive with JSZip const zip = await JSZip.loadAsync(await readFile(zipPath)).catch((e) => { console.warn(`JSZip loading error caught: `, e); @@ -43,7 +43,11 @@ exports.extractExtension = async function ( // Write the extension to the community extensions folder await pipeline( file.nodeStream(), - createWriteStream(`${extensionsFolder}/community/${file.name}`) + createWriteStream( + `${extensionsFolder}/${reviewed ? 'reviewed' : 'community'}/${ + file.name + }` + ) ); } catch (e) { console.warn(`JSZip extraction error caught: `, e);