diff --git a/examples/smoothy/README.md b/examples/smoothy/README.md new file mode 100644 index 000000000..2a282e923 --- /dev/null +++ b/examples/smoothy/README.md @@ -0,0 +1 @@ +A Zuma clone to show how to orginize a project with behaviors. \ No newline at end of file diff --git a/examples/smoothy/TAGS.md b/examples/smoothy/TAGS.md new file mode 100644 index 000000000..2c8ca5111 --- /dev/null +++ b/examples/smoothy/TAGS.md @@ -0,0 +1 @@ +game, expert \ No newline at end of file diff --git a/examples/smoothy/assets/BlueBubble.png b/examples/smoothy/assets/BlueBubble.png new file mode 100644 index 000000000..9df3950d1 Binary files /dev/null and b/examples/smoothy/assets/BlueBubble.png differ diff --git a/examples/smoothy/assets/GreenBubble.png b/examples/smoothy/assets/GreenBubble.png new file mode 100644 index 000000000..7fb14084e Binary files /dev/null and b/examples/smoothy/assets/GreenBubble.png differ diff --git a/examples/smoothy/assets/Grey Button_Hovered.png b/examples/smoothy/assets/Grey Button_Hovered.png new file mode 100644 index 000000000..8065deaec Binary files /dev/null and b/examples/smoothy/assets/Grey Button_Hovered.png differ diff --git a/examples/smoothy/assets/Grey Button_Idle.png b/examples/smoothy/assets/Grey Button_Idle.png new file mode 100644 index 000000000..efbb5d131 Binary files /dev/null and b/examples/smoothy/assets/Grey Button_Idle.png differ diff --git a/examples/smoothy/assets/Grey Button_Pressed.png b/examples/smoothy/assets/Grey Button_Pressed.png new file mode 100644 index 000000000..6735c8e5e Binary files /dev/null and b/examples/smoothy/assets/Grey Button_Pressed.png differ diff --git a/examples/smoothy/assets/GreyBubble.png b/examples/smoothy/assets/GreyBubble.png new file mode 100644 index 000000000..1ce60cca6 Binary files /dev/null and b/examples/smoothy/assets/GreyBubble.png differ diff --git a/examples/smoothy/assets/Hole.png b/examples/smoothy/assets/Hole.png new file mode 100644 index 000000000..cd4285095 Binary files /dev/null and b/examples/smoothy/assets/Hole.png differ diff --git a/examples/smoothy/assets/Launcher.png b/examples/smoothy/assets/Launcher.png new file mode 100644 index 000000000..12acfba41 Binary files /dev/null and b/examples/smoothy/assets/Launcher.png differ diff --git a/examples/smoothy/assets/LevelBackground.png b/examples/smoothy/assets/LevelBackground.png new file mode 100644 index 000000000..f7cf3109f Binary files /dev/null and b/examples/smoothy/assets/LevelBackground.png differ diff --git a/examples/smoothy/assets/NewSprite.png b/examples/smoothy/assets/NewSprite.png new file mode 100644 index 000000000..bf4408fa1 Binary files /dev/null and b/examples/smoothy/assets/NewSprite.png differ diff --git a/examples/smoothy/assets/PurpuleBubble.png b/examples/smoothy/assets/PurpuleBubble.png new file mode 100644 index 000000000..8a53297fd Binary files /dev/null and b/examples/smoothy/assets/PurpuleBubble.png differ diff --git a/examples/smoothy/assets/RedBubble.png b/examples/smoothy/assets/RedBubble.png new file mode 100644 index 000000000..6af35899f Binary files /dev/null and b/examples/smoothy/assets/RedBubble.png differ diff --git a/examples/smoothy/assets/SideBorder.png b/examples/smoothy/assets/SideBorder.png new file mode 100644 index 000000000..f1fbf4d33 Binary files /dev/null and b/examples/smoothy/assets/SideBorder.png differ diff --git a/examples/smoothy/assets/TopBorder.png b/examples/smoothy/assets/TopBorder.png new file mode 100644 index 000000000..c6c4cf8f1 Binary files /dev/null and b/examples/smoothy/assets/TopBorder.png differ diff --git a/examples/smoothy/assets/YellowBubble.png b/examples/smoothy/assets/YellowBubble.png new file mode 100644 index 000000000..4000fa698 Binary files /dev/null and b/examples/smoothy/assets/YellowBubble.png differ diff --git a/examples/smoothy/preview.png b/examples/smoothy/preview.png new file mode 100644 index 000000000..dd454447b Binary files /dev/null and b/examples/smoothy/preview.png differ diff --git a/examples/smoothy/smoothy.json b/examples/smoothy/smoothy.json new file mode 100644 index 000000000..e4f5e7299 --- /dev/null +++ b/examples/smoothy/smoothy.json @@ -0,0 +1,34881 @@ +{ + "firstLayout": "LevelSelection", + "gdVersion": { + "build": 99, + "major": 4, + "minor": 0, + "revision": 0 + }, + "properties": { + "adaptGameResolutionAtRuntime": true, + "antialiasingMode": "MSAA", + "antialisingEnabledOnMobile": false, + "folderProject": false, + "orientation": "landscape", + "packageName": "com.example.smoothy", + "pixelsRounding": false, + "projectUuid": "14f2c425-ec16-42f0-9cf9-160a087b5e26", + "scaleMode": "linear", + "sizeOnStartupMode": "", + "templateSlug": "", + "useExternalSourceFiles": false, + "version": "1.0.0", + "name": "Smoothy", + "description": "A Zuma clone to show how to orginize a project with behaviors.", + "author": "", + "windowWidth": 854, + "windowHeight": 480, + "latestCompilationDirectory": "", + "maxFPS": 60, + "minFPS": 20, + "verticalSync": false, + "platformSpecificAssets": { + "android-icon-144": "", + "android-icon-192": "", + "android-icon-36": "", + "android-icon-48": "", + "android-icon-72": "", + "android-icon-96": "", + "android-windowSplashScreenAnimatedIcon": "", + "desktop-icon-512": "", + "ios-icon-100": "", + "ios-icon-1024": "", + "ios-icon-114": "", + "ios-icon-120": "", + "ios-icon-144": "", + "ios-icon-152": "", + "ios-icon-167": "", + "ios-icon-180": "", + "ios-icon-20": "", + "ios-icon-29": "", + "ios-icon-40": "", + "ios-icon-50": "", + "ios-icon-57": "", + "ios-icon-58": "", + "ios-icon-60": "", + "ios-icon-72": "", + "ios-icon-76": "", + "ios-icon-80": "", + "ios-icon-87": "", + "liluo-thumbnail": "preview.png" + }, + "loadingScreen": { + "backgroundColor": 0, + "backgroundFadeInDuration": 0.2, + "backgroundImageResourceName": "", + "gdevelopLogoStyle": "light", + "logoAndProgressFadeInDuration": 0.2, + "logoAndProgressLogoFadeInDelay": 0.2, + "minDuration": 0, + "progressBarColor": 16777215, + "progressBarHeight": 20, + "progressBarMaxWidth": 200, + "progressBarMinWidth": 40, + "progressBarWidthPercent": 30, + "showGDevelopSplash": false, + "showProgressBar": false + }, + "watermark": { + "placement": "bottom-left", + "showWatermark": true + }, + "authorIds": [ + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2", + "1thy3mefIBWCy8u4h1ApC1PTF4F2" + ], + "authorUsernames": [ + "D8H", + "Metatempo" + ], + "categories": [ + "action", + "puzzle" + ], + "playableDevices": [ + "mobile" + ], + "extensionProperties": [], + "platforms": [ + { + "name": "GDevelop JS platform" + } + ], + "currentPlatform": "GDevelop JS platform" + }, + "resources": { + "resources": [ + { + "alwaysLoaded": false, + "file": "assets/BlueBubble.png", + "kind": "image", + "metadata": "", + "name": "BlueBubble.png", + "smoothed": true, + "userAdded": false + }, + { + "alwaysLoaded": false, + "file": "assets/GreenBubble.png", + "kind": "image", + "metadata": "", + "name": "GreenBubble.png", + "smoothed": true, + "userAdded": false + }, + { + "alwaysLoaded": false, + "file": "assets/PurpuleBubble.png", + "kind": "image", + "metadata": "", + "name": "PurpuleBubble.png", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/RedBubble.png", + "kind": "image", + "metadata": "", + "name": "RedBubble.png", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/YellowBubble.png", + "kind": "image", + "metadata": "", + "name": "YellowBubble.png", + "smoothed": true, + "userAdded": false + }, + { + "alwaysLoaded": false, + "file": "assets/Launcher.png", + "kind": "image", + "metadata": "", + "name": "Launcher.png", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/SideBorder.png", + "kind": "image", + "metadata": "", + "name": "SideBorder.png", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/TopBorder.png", + "kind": "image", + "metadata": "", + "name": "TopBorder.png", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/NewSprite.png", + "kind": "image", + "metadata": "{\"extension\":\".png\"}", + "name": "NewSprite", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/GreyBubble.png", + "kind": "image", + "metadata": "", + "name": "assets\\GreyBubble.png", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/LevelBackground.png", + "kind": "image", + "metadata": "{\"extension\":\".png\"}", + "name": "LevelBackground", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/LevelBackground.png", + "kind": "image", + "metadata": "", + "name": "assets\\LevelBackground.png", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/Grey Button_Hovered.png", + "kind": "image", + "metadata": "", + "name": "Grey Button_Hovered.png", + "smoothed": true, + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/Menu buttons/b43e0035dca80ea2fad5c5d65de926dae0185038e5f9cb21d5f20234f30d1c76_Grey Button_Hovered.png", + "name": "Grey Button_Hovered.png" + } + }, + { + "alwaysLoaded": false, + "file": "assets/Grey Button_Idle.png", + "kind": "image", + "metadata": "", + "name": "Grey Button_Idle.png", + "smoothed": true, + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/Menu buttons/da7fc2efa0882eb5dfa0266315f2483c2f68d86a6751dc309ea9e9d0dd4759ba_Grey Button_Idle.png", + "name": "Grey Button_Idle.png" + } + }, + { + "alwaysLoaded": false, + "file": "assets/Grey Button_Pressed.png", + "kind": "image", + "metadata": "", + "name": "Grey Button_Pressed.png", + "smoothed": true, + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/Menu buttons/49c35e14af0e1f7aae407455cb944de96328955870e5f1500f63723ad879a42e_Grey Button_Pressed.png", + "name": "Grey Button_Pressed.png" + } + }, + { + "alwaysLoaded": false, + "file": "assets/Hole.png", + "kind": "image", + "metadata": "", + "name": "assets\\Hole.png", + "smoothed": true, + "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "preview.png", + "kind": "image", + "metadata": "", + "name": "preview.png", + "smoothed": true, + "userAdded": true + } + ], + "resourceFolders": [] + }, + "objects": [], + "objectsGroups": [], + "variables": [ + { + "name": "Level", + "type": "number", + "value": 0 + }, + { + "name": "Levels", + "type": "array", + "children": [ + { + "type": "structure", + "children": [ + { + "name": "Gutters", + "type": "array", + "children": [ + { + "type": "structure", + "children": [ + { + "folded": true, + "name": "Path", + "type": "string", + "value": "m-16 233s72.5-23.5 123 81c50.3 104 193 128 329 129 135 0.349 334-44.8 336-205 1.3-160-230-211-358-209s-248 64.6-249 176c-0.465 112 158 163 260 164s205-56.8 205-131c0.682-74.4-89.5-128-206-128" + }, + { + "name": "StartX", + "type": "number", + "value": -16 + }, + { + "folded": true, + "name": "StartY", + "type": "number", + "value": 233 + } + ] + } + ] + }, + { + "folded": true, + "name": "LauncherX", + "type": "number", + "value": 427 + }, + { + "name": "LauncherY", + "type": "number", + "value": 240 + }, + { + "folded": true, + "name": "LeaderboardId", + "type": "string", + "value": "6415f008-1a8f-4cae-857e-00e38983cd7a" + } + ] + }, + { + "type": "structure", + "children": [ + { + "name": "Gutters", + "type": "array", + "children": [ + { + "type": "structure", + "children": [ + { + "folded": true, + "name": "Path", + "type": "string", + "value": "m-16 57.3s96.9-10.8 102 97.3c-7.68 239 37.9 291 258 289 103-1.27 91.3-125-14.5-85.1-128 48.5-184-33.1-176-166 8-147 229-152 290-153 51.4-0.759 350-24.4 356 200 4.96 207-145 200-243 200-93.7-0.285-97.4-126 20.8-86.9 81.2 26.6 159 12.2 153-108-5.36-105-104-132-178-132-85.1-0.0173-84.7 106-5.43 85.1 78.7-20.8 111 9.5 112 47.1 1.34 57.4-67.1 59.6-135 26.2" + }, + { + "name": "StartX", + "type": "number", + "value": -16 + }, + { + "folded": true, + "name": "StartY", + "type": "number", + "value": 57.3 + } + ] + } + ] + }, + { + "folded": true, + "name": "LauncherX", + "type": "number", + "value": 327 + }, + { + "name": "LauncherY", + "type": "number", + "value": 220 + }, + { + "folded": true, + "name": "LeaderboardId", + "type": "string", + "value": "3140c9fb-fa30-4451-8f2a-45efe16d5512" + } + ] + }, + { + "type": "structure", + "children": [ + { + "name": "Gutters", + "type": "array", + "children": [ + { + "type": "structure", + "children": [ + { + "folded": true, + "name": "Path", + "type": "string", + "value": "m300-16c-0.192 75.1-60.5 84.9-150 111-108 31.9-101 140-100 166 1.32 89.4 41.9 187 187 188 127 0.601 186-25.6 252-61.4 157-85.4 16.8-170 189-261" + }, + { + "name": "StartX", + "type": "number", + "value": 300 + }, + { + "folded": true, + "name": "StartY", + "type": "number", + "value": -16 + } + ] + }, + { + "type": "structure", + "children": [ + { + "folded": true, + "name": "Path", + "type": "string", + "value": "m540 505c0.192-75.1 60.5-84.9 150-111 108-31.9 101-140 100-166-1.32-89.4-41.9-187-187-188-127-0.601-186 25.6-252 61.4-157 85.4-16.8 170-189 261" + }, + { + "name": "StartX", + "type": "number", + "value": 540 + }, + { + "folded": true, + "name": "StartY", + "type": "number", + "value": 505 + } + ] + } + ] + }, + { + "folded": true, + "name": "LauncherX", + "type": "number", + "value": 427 + }, + { + "name": "LauncherY", + "type": "number", + "value": 240 + }, + { + "folded": true, + "name": "LeaderboardId", + "type": "string", + "value": "7122d867-1f40-4c35-989a-2c55f15f7e49" + } + ] + } + ] + } + ], + "layouts": [ + { + "b": 49, + "disableInputWhenNotFocused": true, + "mangledName": "Game", + "name": "Game", + "r": 99, + "standardSortMethod": true, + "stopSoundsOnStartup": true, + "title": "", + "v": 84, + "uiSettings": { + "grid": true, + "gridType": "rectangular", + "gridWidth": 16, + "gridHeight": 28, + "gridOffsetX": 0, + "gridOffsetY": 0, + "gridColor": 10401023, + "gridAlpha": 0.8, + "snap": true, + "zoomFactor": 0.8086342783490704, + "windowMask": false + }, + "objectsGroups": [], + "variables": [ + { + "name": "ColorNames", + "type": "array", + "children": [ + { + "type": "string", + "value": "Yellow" + }, + { + "type": "string", + "value": "Green" + }, + { + "type": "string", + "value": "Blue" + }, + { + "type": "string", + "value": "Red" + }, + { + "type": "string", + "value": "Purple" + }, + { + "folded": true, + "type": "string", + "value": "Grey" + } + ] + }, + { + "name": "ColorValues", + "type": "array", + "children": [ + { + "folded": true, + "type": "string", + "value": "242;209;67" + }, + { + "folded": true, + "type": "string", + "value": "166;242;67" + }, + { + "folded": true, + "type": "string", + "value": "67;201;242" + }, + { + "folded": true, + "type": "string", + "value": "242;111;67" + }, + { + "folded": true, + "type": "string", + "value": "173;67;242" + }, + { + "folded": true, + "type": "string", + "value": "242;233;200" + } + ] + } + ], + "instances": [ + { + "angle": 0, + "customSize": false, + "height": 0, + "layer": "", + "name": "GutterPainter", + "persistentUuid": "f0753a74-8af3-4f34-8e31-ca589091383d", + "width": 0, + "x": 16, + "y": -56, + "zOrder": 91, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": false, + "height": 0, + "layer": "", + "name": "BubbleClipboard", + "persistentUuid": "558430dc-2ac8-4bd3-87b8-de53fbb4e056", + "width": 0, + "x": -208, + "y": -28, + "zOrder": 96, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": false, + "height": 0, + "layer": "", + "name": "Score", + "persistentUuid": "676db6fe-999e-454a-a69c-e1f290b05ee0", + "width": 0, + "x": 24, + "y": 16, + "zOrder": 97, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": false, + "height": 0, + "layer": "", + "name": "Countdown", + "persistentUuid": "60b40b4e-219c-41e6-9cd8-85997e02916d", + "width": 0, + "x": 784, + "y": 16, + "zOrder": 98, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + } + ], + "objects": [ + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "BoardBubble", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "BoardBubbleBehavior", + "type": "Smoothy::BoardBubbleBehavior" + }, + { + "name": "SpeedPathMovement", + "type": "CurvedMovement::SpeedPathMovement", + "Rotation": false, + "RotationOffset": 0, + "Speed": 0, + "PathOriginX": 0, + "PathOriginY": 0, + "PathName": "", + "TargetedSpeed": 0, + "Acceleration": 0, + "DrawingElementIndex": 0, + "X": 0, + "Y": 0, + "PathAngle": 0, + "PathScale": 0, + "RepetitionCount": 0, + "ShouldLoop": false, + "DrawingPathOriginX": 0, + "DrawingPathOriginY": 0, + "DebugLineStrokeWidth": 0, + "PreviousSpeed": 0, + "CurrentLength": 0, + "IsLookingBack": false, + "Viewpoint": "Top-Down" + } + ], + "animations": [ + { + "name": "Yellow", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "YellowBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 23.5, + "y": 6.5 + }, + { + "x": 28, + "y": 15 + }, + { + "x": 23.5, + "y": 23.5 + }, + { + "x": 15, + "y": 28 + }, + { + "x": 6.5, + "y": 23.5 + }, + { + "x": 2, + "y": 15 + }, + { + "x": 6.5, + "y": 6.5 + }, + { + "x": 15, + "y": 2 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Green", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "GreenBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 23.5, + "y": 6.5 + }, + { + "x": 28, + "y": 15 + }, + { + "x": 23.5, + "y": 23.5 + }, + { + "x": 15, + "y": 28 + }, + { + "x": 6.5, + "y": 23.5 + }, + { + "x": 2, + "y": 15 + }, + { + "x": 6.5, + "y": 6.5 + }, + { + "x": 15, + "y": 2 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Blue", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "BlueBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 23.5, + "y": 6.5 + }, + { + "x": 28, + "y": 15 + }, + { + "x": 23.5, + "y": 23.5 + }, + { + "x": 15, + "y": 28 + }, + { + "x": 6.5, + "y": 23.5 + }, + { + "x": 2, + "y": 15 + }, + { + "x": 6.5, + "y": 6.5 + }, + { + "x": 15, + "y": 2 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Red", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "RedBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 23.5, + "y": 6.5 + }, + { + "x": 28, + "y": 15 + }, + { + "x": 23.5, + "y": 23.5 + }, + { + "x": 15, + "y": 28 + }, + { + "x": 6.5, + "y": 23.5 + }, + { + "x": 2, + "y": 15 + }, + { + "x": 6.5, + "y": 6.5 + }, + { + "x": 15, + "y": 2 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Purple", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "PurpuleBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 23.5, + "y": 6.5 + }, + { + "x": 28, + "y": 15 + }, + { + "x": 23.5, + "y": 23.5 + }, + { + "x": 15, + "y": 28 + }, + { + "x": 6.5, + "y": 23.5 + }, + { + "x": 2, + "y": 15 + }, + { + "x": 6.5, + "y": 6.5 + }, + { + "x": 15, + "y": 2 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Grey", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "assets\\GreyBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "Spawner", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "ObjectStack", + "type": "ObjectStack::ObjectStack" + }, + { + "name": "SpeedPathMovement", + "type": "CurvedMovement::SpeedPathMovement", + "Rotation": true, + "RotationOffset": 0, + "Speed": 0, + "PathOriginX": 0, + "PathOriginY": 0, + "PathName": "", + "TargetedSpeed": 0, + "Acceleration": 0, + "DrawingElementIndex": 0, + "X": 0, + "Y": 0, + "PathAngle": 0, + "PathScale": 0, + "RepetitionCount": 0, + "ShouldLoop": false, + "DrawingPathOriginX": 0, + "DrawingPathOriginY": 0, + "DebugLineStrokeWidth": 0, + "PreviousSpeed": 0, + "CurrentLength": 0, + "IsLookingBack": false, + "Viewpoint": "Top-Down" + }, + { + "name": "SpwanerBehavior", + "type": "Smoothy::SpwanerBehavior", + "ObjectStack": "ObjectStack", + "ColorCount": 4 + } + ], + "animations": [ + { + "name": "Green", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "GreenBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Yellow", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "YellowBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Blue", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "BlueBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Purple", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "PurpuleBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Red", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "RedBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "AimingBubble", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "FireBullet", + "type": "FireBullet::FireBullet", + "FireCooldown": 0.35, + "HasJustFired": false + } + ], + "animations": [ + { + "name": "Blue", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "BlueBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Yellow", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "YellowBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Green", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "GreenBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Purple", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "PurpuleBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Red", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "RedBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Grey", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "assets\\GreyBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "MovingBubble", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "DestroyOutside", + "type": "DestroyOutsideBehavior::DestroyOutside", + "extraBorder": 32 + } + ], + "animations": [ + { + "name": "Purple", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "PurpuleBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 25, + "y": 5 + }, + { + "x": 30, + "y": 15 + }, + { + "x": 25, + "y": 25 + }, + { + "x": 15, + "y": 30 + }, + { + "x": 5, + "y": 25 + }, + { + "x": 0, + "y": 15 + }, + { + "x": 5, + "y": 5 + }, + { + "x": 15, + "y": 0 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Yellow", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "YellowBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 25, + "y": 5 + }, + { + "x": 30, + "y": 15 + }, + { + "x": 25, + "y": 25 + }, + { + "x": 15, + "y": 30 + }, + { + "x": 5, + "y": 25 + }, + { + "x": 0, + "y": 15 + }, + { + "x": 5, + "y": 5 + }, + { + "x": 15, + "y": 0 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Blue", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "BlueBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 25, + "y": 5 + }, + { + "x": 30, + "y": 15 + }, + { + "x": 25, + "y": 25 + }, + { + "x": 15, + "y": 30 + }, + { + "x": 5, + "y": 25 + }, + { + "x": 0, + "y": 15 + }, + { + "x": 5, + "y": 5 + }, + { + "x": 15, + "y": 0 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Green", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "GreenBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 25, + "y": 5 + }, + { + "x": 30, + "y": 15 + }, + { + "x": 25, + "y": 25 + }, + { + "x": 15, + "y": 30 + }, + { + "x": 5, + "y": 25 + }, + { + "x": 0, + "y": 15 + }, + { + "x": 5, + "y": 5 + }, + { + "x": 15, + "y": 0 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Red", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": true, + "image": "RedBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [ + [ + { + "x": 25, + "y": 5 + }, + { + "x": 30, + "y": 15 + }, + { + "x": 25, + "y": 25 + }, + { + "x": 15, + "y": 30 + }, + { + "x": 5, + "y": 25 + }, + { + "x": 0, + "y": 15 + }, + { + "x": 5, + "y": 5 + }, + { + "x": 15, + "y": 0 + } + ] + ] + } + ] + } + ] + }, + { + "name": "Grey", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "assets\\GreyBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "InsertedBubble", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "InsertedBubble", + "type": "Smoothy::InsertedBubbleBehavior", + "SpeedPathMovement": "SpeedPathMovement" + }, + { + "name": "SpeedPathMovement", + "type": "CurvedMovement::SpeedPathMovement", + "Rotation": true, + "RotationOffset": 0, + "Speed": 0, + "PathOriginX": 0, + "PathOriginY": 0, + "PathName": "", + "TargetedSpeed": 0, + "Acceleration": 0, + "DrawingElementIndex": 0, + "X": 0, + "Y": 0, + "PathAngle": 0, + "PathScale": 0, + "RepetitionCount": 0, + "ShouldLoop": false, + "DrawingPathOriginX": 0, + "DrawingPathOriginY": 0, + "DebugLineStrokeWidth": 0, + "PreviousSpeed": 0, + "CurrentLength": 0, + "IsLookingBack": false, + "Viewpoint": "Top-Down" + } + ], + "animations": [ + { + "name": "Red", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "RedBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Yellow", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "YellowBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Blue", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "BlueBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Green", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "GreenBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Purple", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "PurpuleBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Grey", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "assets\\GreyBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "PreviewBubble", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "ButtonFSM", + "type": "ButtonStates::ButtonFSM", + "ShouldCheckHovering": true, + "State": "Idle", + "TouchId": 0, + "TouchIsInside": false, + "MouseIsInside": false, + "Index": 0 + }, + { + "name": "InsertedBubble", + "type": "Smoothy::InsertedBubbleBehavior", + "SpeedPathMovement": "SpeedPathMovement" + }, + { + "name": "SpeedPathMovement", + "type": "CurvedMovement::SpeedPathMovement", + "Rotation": true, + "RotationOffset": 0, + "Speed": 0, + "PathOriginX": 0, + "PathOriginY": 0, + "PathName": "", + "TargetedSpeed": 0, + "Acceleration": 0, + "DrawingElementIndex": 0, + "X": 0, + "Y": 0, + "PathAngle": 0, + "PathScale": 0, + "RepetitionCount": 0, + "ShouldLoop": false, + "DrawingPathOriginX": 0, + "DrawingPathOriginY": 0, + "DebugLineStrokeWidth": 0, + "PreviousSpeed": 0, + "CurrentLength": 0, + "IsLookingBack": false, + "Viewpoint": "Top-Down" + } + ], + "animations": [ + { + "name": "Grey", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "assets\\GreyBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Red", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "RedBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Yellow", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "YellowBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Blue", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "BlueBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Green", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "GreenBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Purple", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "PurpuleBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "Launcher", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [], + "animations": [ + { + "name": "", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "Launcher.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 75, + "y": 75 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "Gutter", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "GutterBehavior", + "type": "Smoothy::GutterBehavior", + "ObjectStack": "ObjectStack", + "FirstQueueHeadPosition": 0, + "NearDeathLengthRatio": 0.75, + "AccelerationDuration": 1 + }, + { + "name": "ObjectStack", + "type": "ObjectStack::ObjectStack" + } + ], + "animations": [ + { + "name": "NewObject", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.07999999821186066, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "SideBorder.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 0, + "y": 0 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "BubbleQueue", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "BubbleQueueBehavior", + "type": "Smoothy::BubbleQueueBehavior", + "TailState": "Idle", + "HeadState": "Idle", + "TailComboLevel": 0, + "HeadComboLevel": 0, + "HitStopDuration": 0.1, + "RewindDelay": 0.3, + "HitStopAfterComboDuration": 0.3 + }, + { + "name": "ObjectStack", + "type": "ObjectStack::ObjectStack" + } + ], + "animations": [ + { + "name": "NewObject", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.07999999821186066, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "TopBorder.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 0, + "y": 0 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "assetStoreId": "", + "name": "GutterPainter", + "tags": "", + "type": "PrimitiveDrawing::Drawer", + "variables": [], + "effects": [], + "behaviors": [], + "fillOpacity": 255, + "outlineSize": 32, + "outlineOpacity": 255, + "fillColor": { + "b": 27, + "g": 46, + "r": 54 + }, + "outlineColor": { + "b": 27, + "g": 46, + "r": 54 + }, + "absoluteCoordinates": true, + "clearBetweenFrames": false, + "antialiasing": "none" + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "BubbleClipboard", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "ObjectStack", + "type": "ObjectStack::ObjectStack" + } + ], + "animations": [ + { + "name": "NewSprite", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "metadata": "{\"pskl\":{}}", + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "NewSprite", + "points": [], + "originPoint": { + "name": "origine", + "x": 0, + "y": 0 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "additive": false, + "assetStoreId": "", + "destroyWhenNoParticles": true, + "emitterAngleA": 0, + "emitterAngleB": 360, + "emitterForceMax": 200, + "emitterForceMin": 50, + "flow": 1280, + "jumpForwardInTimeOnCreation": 0, + "maxParticleNb": 64, + "name": "BubbleExplosion", + "particleAlpha1": 204, + "particleAlpha2": 0, + "particleAlphaRandomness1": 0, + "particleAlphaRandomness2": 0, + "particleAngle1": 0, + "particleAngle2": 0, + "particleAngleRandomness1": 0, + "particleAngleRandomness2": 0, + "particleBlue1": 51, + "particleBlue2": 0, + "particleGravityX": 0, + "particleGravityY": 0, + "particleGreen1": 51, + "particleGreen2": 255, + "particleLifeTimeMax": 0.2, + "particleLifeTimeMin": 0.1, + "particleRed1": 255, + "particleRed2": 255, + "particleSize1": 25, + "particleSize2": 100, + "particleSizeRandomness1": 0, + "particleSizeRandomness2": 0, + "rendererParam1": 8, + "rendererParam2": 1, + "rendererType": "Point", + "tags": "", + "tank": 64, + "textureParticleName": "", + "type": "ParticleSystem::ParticleEmitter", + "zoneRadius": 8, + "variables": [], + "effects": [], + "behaviors": [] + }, + { + "assetStoreId": "", + "bold": false, + "italic": false, + "name": "Score", + "smoothed": true, + "tags": "", + "type": "TextObject::Text", + "underlined": false, + "variables": [], + "effects": [], + "behaviors": [], + "string": "0000", + "font": "", + "textAlignment": "left", + "characterSize": 20, + "color": { + "b": 255, + "g": 255, + "r": 255 + } + }, + { + "assetStoreId": "", + "bold": false, + "italic": false, + "name": "Countdown", + "smoothed": true, + "tags": "", + "type": "TextObject::Text", + "underlined": false, + "variables": [], + "effects": [], + "behaviors": [], + "string": "3:00", + "font": "", + "textAlignment": "left", + "characterSize": 20, + "color": { + "b": 255, + "g": 255, + "r": 255 + } + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "Hole", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [], + "animations": [ + { + "name": "", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "assets\\Hole.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 16, + "y": 16 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "\nObjects on the board:\n- BoardBubble are bubbles that move on the gutter.\n- BubbleQueue contain BoardBubble that are touching one to another.\n- Gutter contain BubbleQueue\n- Spawner create new BoardBubble in the gutter.\n\nObjects for player actions:\n- AimingBubble rotates according to how the player is aiming.\n- PreviewBubble shows the next color.\n- InsertedBubble handle the insertion animation.\n\nA big part of the events is inside the Smoothy extension.\nMost of the objects have dedicated behaviors:\n- BoardBubble animate explosions.\n- BubbleQueueBehavior contains bubbles bonded to each other. Each end of the queue has a FSM for the combo movement.\n- GutterBehavior contains bubbles queues and push the queue at the beginning of the gutter.\n- SpawnerBehavior generate bubbles to add in its gutter.\n- InsertedBubbleBehavior animates bubble insertions by pushing leading bubbles from the same queue.\n\nThe \"Curved movement\" extension is used to move bubbles on a path.\nThe \"Object stack\" extension is used to keep track of the bubbles order.\n\n" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DepartScene" + }, + "parameters": [ + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarSceneTxt" + }, + "parameters": [ + "GameState", + "=", + "\"Playing\"" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "Countdown", + "=", + "3 * 60" + ] + }, + { + "type": { + "value": "Smoothy::CreateLevel" + }, + "parameters": [ + "", + "GlobalVariable(Level)", + "Launcher", + "Gutter", + "GutterBehavior", + "ObjectStack", + "BubbleQueue", + "GutterPainter", + "Hole", + "Spawner", + "SpwanerBehavior", + "ObjectStack", + "SpeedPathMovement", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "StartLocation", + "PreviewBubble", + "Launcher.X()", + "Launcher.Y()", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "StartLocation", + "AimingBubble", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "PreviewBubble", + "VariableString(ColorNames[RandomInRange(0, Spawner.SpwanerBehavior::ColorCount() - 1)])" + ] + }, + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "AimingBubble", + "VariableString(ColorNames[RandomInRange(0, Spawner.SpwanerBehavior::ColorCount() - 1)])" + ] + } + ], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Debug", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ChangeTimeScale" + }, + "parameters": [ + "", + "0.25" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ZoomCamera" + }, + "parameters": [ + "", + "0.9", + "", + "" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "AimingBubble", + "\"Purple\"" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "MettreXY" + }, + "parameters": [ + "Launcher", + "=", + "50", + "=", + "150" + ] + } + ] + } + ], + "parameters": [] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Playing", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "VarSceneTxt" + }, + "parameters": [ + "GameState", + "=", + "\"Playing\"" + ] + } + ], + "actions": [], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Spawn bubbles", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::SpwanerBehavior::CanSpawnBubble" + }, + "parameters": [ + "Spawner", + "SpwanerBehavior", + "Gutter", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::SpwanerBehavior::SpawnBubble" + }, + "parameters": [ + "Spawner", + "SpwanerBehavior", + "Gutter", + "GutterBehavior", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::SpwanerBehavior::CanUnspawnBubble" + }, + "parameters": [ + "Spawner", + "SpwanerBehavior", + "Gutter", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::SpwanerBehavior::UnspawnBubble" + }, + "parameters": [ + "Spawner", + "SpwanerBehavior", + "Gutter", + "GutterBehavior", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Controls", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "MettreAutour" + }, + "parameters": [ + "AimingBubble", + "Launcher", + "48", + "AngleBetweenPositions(Launcher.X(), Launcher.Y(), CursorX(), CursorY())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "KeyReleased" + }, + "parameters": [ + "", + "Space" + ] + }, + { + "type": { + "value": "MouseButtonReleased" + }, + "parameters": [ + "", + "Left" + ] + } + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::IsReadyToShoot" + }, + "parameters": [ + "AimingBubble", + "FireBullet", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "ButtonStates::ButtonFSM::IsPressed" + }, + "parameters": [ + "PreviewBubble", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "AjoutObjConcern" + }, + "parameters": [ + "", + "PreviewBubble" + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::Fire" + }, + "parameters": [ + "AimingBubble", + "FireBullet", + "AimingBubble.X()", + "AimingBubble.Y()", + "MovingBubble", + "AngleBetweenPositions(Launcher.X(), Launcher.Y(), CursorX(), CursorY())", + "690", + "" + ] + }, + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "MovingBubble", + "AimingBubble.AnimationName()" + ] + }, + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "AimingBubble", + "PreviewBubble.AnimationName()" + ] + }, + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "PreviewBubble", + "VariableString(ColorNames[RandomInRange(0, Spawner.SpwanerBehavior::ColorCount() - 1)])" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "MouseButtonReleased" + }, + "parameters": [ + "", + "Right" + ] + }, + { + "type": { + "value": "KeyReleased" + }, + "parameters": [ + "", + "LShift" + ] + }, + { + "type": { + "value": "ButtonStates::ButtonFSM::IsClicked" + }, + "parameters": [ + "PreviewBubble", + "ButtonFSM", + "" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "AjoutObjConcern" + }, + "parameters": [ + "", + "PreviewBubble" + ] + }, + { + "type": { + "value": "ModVarSceneTxt" + }, + "parameters": [ + "animationName", + "=", + "PreviewBubble.AnimationName()" + ] + }, + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "PreviewBubble", + "AimingBubble.AnimationName()" + ] + }, + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "AimingBubble", + "VariableString(animationName)" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Insert bubbles", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CollisionNP" + }, + "parameters": [ + "MovingBubble", + "BoardBubble", + "", + "", + "yes" + ] + }, + { + "type": { + "value": "AjoutHasard" + }, + "parameters": [ + "", + "BoardBubble" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "InsertedBubble", + "Gutter.X()", + "Gutter.Y()", + "" + ] + }, + { + "type": { + "value": "LinkedObjects::LinkObjects" + }, + "parameters": [ + "", + "InsertedBubble", + "BoardBubble" + ] + }, + { + "type": { + "value": "AjoutObjConcern" + }, + "parameters": [ + "", + "BoardBubble" + ] + }, + { + "type": { + "value": "Smoothy::InsertedBubbleBehavior::Initialize" + }, + "parameters": [ + "InsertedBubble", + "InsertedBubble", + "Gutter", + "GutterBehavior", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "MovingBubble", + "" + ] + }, + { + "type": { + "value": "Delete" + }, + "parameters": [ + "MovingBubble", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "Smoothy::InsertedBubbleBehavior::IsAnimationFinished" + }, + "parameters": [ + "InsertedBubble", + "InsertedBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::InsertedBubbleBehavior::PlayInsertion" + }, + "parameters": [ + "InsertedBubble", + "InsertedBubble", + "Gutter", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::InsertedBubbleBehavior::IsAnimationFinished" + }, + "parameters": [ + "InsertedBubble", + "InsertedBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::InsertedBubbleBehavior::CreateBubble" + }, + "parameters": [ + "InsertedBubble", + "InsertedBubble", + "Gutter", + "", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::Identifier" + }, + "parameters": [ + "Gutter", + "GutterBehavior", + "=", + "InsertedBubble.InsertedBubble::GutterIdentifier()", + "" + ] + }, + { + "type": { + "value": "Smoothy::MatchBubbles" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "BubbleQueueBehavior", + "ObjectStack", + "BoardBubble", + "InsertedBubble.InsertedBubble::QueueIndex()", + "InsertedBubble.InsertedBubble::BubbleIndex()", + "BubbleClipboard", + "ObjectStack", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "Score", + "+", + "10 * PickedInstancesCount(BoardBubble)" + ] + }, + { + "type": { + "value": "Smoothy::BoardBubbleBehavior::Explode" + }, + "parameters": [ + "BoardBubble", + "BoardBubbleBehavior", + "BubbleExplosion", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Queues collision", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::ForEach", + "object": "Gutter", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "queueIndex", + "=", + "Gutter.ObjectStack::Height() - 1" + ] + } + ], + "events": [ + { + "infiniteLoopWarning": true, + "type": "BuiltinCommonInstructions::While", + "whileConditions": [ + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "queueIndex", + ">", + "0" + ] + } + ], + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::IsQueueColliding" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "BoardBubbleBehavior", + "SpeedPathMovement", + "Variable(queueIndex)", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "areBubblesMatched", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::MatchBubblesBetween" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "BubbleQueueBehavior", + "ObjectStack", + "BoardBubble", + "Variable(queueIndex)", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "areBubblesMatched", + "True" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "Score", + "+", + "10 * PickedInstancesCount(BoardBubble)" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "Score", + "+", + "100 * BubbleQueue.BubbleQueueBehavior::HeadComboLevel()" + ] + }, + { + "type": { + "value": "Smoothy::BoardBubbleBehavior::Explode" + }, + "parameters": [ + "BoardBubble", + "BoardBubbleBehavior", + "BubbleExplosion", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "SceneVariableAsBoolean" + }, + "parameters": [ + "areBubblesMatched", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::MergeQueue" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "BubbleQueueBehavior", + "ObjectStack", + "BoardBubble", + "BoardBubbleBehavior", + "SpeedPathMovement", + "Variable(queueIndex)", + "BubbleClipboard", + "ObjectStack", + "" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "queueIndex", + "-", + "1" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "queueIndex", + "-", + "1" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Combo", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::UpdateMatchingQueue" + }, + "parameters": [ + "Gutter", + "GutterBehavior", + "BubbleQueue", + "BubbleQueueBehavior", + "ObjectStack", + "BoardBubble", + "BoardBubbleBehavior", + "SpeedPathMovement", + "" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Move bubbles", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::UpdateFirstHeadPosition" + }, + "parameters": [ + "Gutter", + "GutterBehavior", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetBubblesSpeed" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "Gutter", + "GutterBehavior", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "UI", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Score", + "=", + "VariableString(Score)" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "Countdown", + "=", + "max(0, Variable(Countdown) - TimeDelta())" + ] + }, + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Countdown", + "=", + "TimeFormatter::SecondsToHHMMSS(Variable(Countdown))" + ] + } + ] + } + ], + "parameters": [] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "TODO: Wait combo end before checking game over conditions." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "Countdown", + "=", + "0" + ] + }, + { + "type": { + "value": "Smoothy::GutterBehavior::IsAnyBubbleReachHole" + }, + "parameters": [ + "Gutter", + "GutterBehavior", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarSceneTxt" + }, + "parameters": [ + "GameState", + "=", + "\"GameOver\"" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Gameover", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "VarSceneTxt" + }, + "parameters": [ + "GameState", + "=", + "\"GameOver\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::AccelarateAt" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "2000", + "2000", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "InsertedBubble" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedTarget" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Cache" + }, + "parameters": [ + "BoardBubble" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedAnEnd" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Wait" + }, + "parameters": [ + "0.5" + ] + }, + { + "type": { + "value": "ModVarGlobal" + }, + "parameters": [ + "Score", + "=", + "Variable(Score)" + ] + }, + { + "type": { + "value": "Scene" + }, + "parameters": [ + "", + "\"Leaderboard\"", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "layers": [ + { + "ambientLightColorB": 36, + "ambientLightColorG": 7379992, + "ambientLightColorR": 32, + "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": [ + { + "name": "BoardBubbleBehavior", + "type": "Smoothy::BoardBubbleBehavior" + }, + { + "name": "BubbleQueueBehavior", + "type": "Smoothy::BubbleQueueBehavior" + }, + { + "name": "ButtonFSM", + "type": "ButtonStates::ButtonFSM" + }, + { + "name": "FireBullet", + "type": "FireBullet::FireBullet" + }, + { + "name": "GutterBehavior", + "type": "Smoothy::GutterBehavior" + }, + { + "name": "InsertedBubble", + "type": "Smoothy::InsertedBubbleBehavior" + }, + { + "name": "ObjectStack", + "type": "ObjectStack::ObjectStack" + }, + { + "name": "SpeedPathMovement", + "type": "CurvedMovement::SpeedPathMovement" + }, + { + "name": "SpwanerBehavior", + "type": "Smoothy::SpwanerBehavior" + } + ] + }, + { + "b": 27, + "disableInputWhenNotFocused": true, + "mangledName": "LevelSelection", + "name": "LevelSelection", + "r": 54, + "standardSortMethod": true, + "stopSoundsOnStartup": true, + "title": "", + "v": 46, + "uiSettings": { + "grid": true, + "gridType": "rectangular", + "gridWidth": 95, + "gridHeight": 53, + "gridOffsetX": 0, + "gridOffsetY": 0, + "gridColor": 10401023, + "gridAlpha": 0.8, + "snap": true, + "zoomFactor": 0.819672131147541, + "windowMask": false + }, + "objectsGroups": [], + "variables": [], + "instances": [ + { + "angle": 0, + "customSize": false, + "height": 0, + "layer": "", + "name": "Level", + "persistentUuid": "95fdeef0-b7dc-44c6-8328-6de1d9eff71b", + "width": 0, + "x": 95, + "y": 53, + "zOrder": 1, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": false, + "height": 0, + "layer": "", + "name": "Level", + "persistentUuid": "3f55e0f1-f0b3-4abb-8e43-3dc482f80577", + "width": 0, + "x": 285, + "y": 265, + "zOrder": 1, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [ + { + "folded": true, + "name": "Level", + "type": "number", + "value": 2 + } + ] + }, + { + "angle": 0, + "customSize": false, + "height": 0, + "layer": "", + "name": "Level", + "persistentUuid": "91084239-d120-4429-b752-32855ab88205", + "width": 0, + "x": 475, + "y": 52, + "zOrder": 1, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [ + { + "folded": true, + "name": "Level", + "type": "number", + "value": 1 + } + ] + } + ], + "objects": [ + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "Level", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [ + { + "folded": true, + "name": "Level", + "type": "number", + "value": 0 + } + ], + "effects": [], + "behaviors": [ + { + "name": "ButtonFSM", + "type": "ButtonStates::ButtonFSM", + "ShouldCheckHovering": true, + "State": "Idle", + "TouchId": 0, + "TouchIsInside": false, + "MouseIsInside": false, + "Index": 0 + } + ], + "animations": [ + { + "name": "LevelBackground", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "metadata": "{\"pskl\":{}}", + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "assets\\LevelBackground.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 0, + "y": 0 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "Launcher", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [], + "animations": [ + { + "name": "", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "Launcher.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 75, + "y": 75 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "assetStoreId": "", + "name": "GutterPainter", + "tags": "", + "type": "PrimitiveDrawing::Drawer", + "variables": [], + "effects": [], + "behaviors": [], + "fillOpacity": 255, + "outlineSize": 11, + "outlineOpacity": 255, + "fillColor": { + "b": 27, + "g": 46, + "r": 54 + }, + "outlineColor": { + "b": 27, + "g": 46, + "r": 54 + }, + "absoluteCoordinates": true, + "clearBetweenFrames": false, + "antialiasing": "none" + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "StartLocation", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "SpeedPathMovement", + "type": "CurvedMovement::SpeedPathMovement", + "Rotation": true, + "RotationOffset": 0, + "Speed": 0, + "PathOriginX": 0, + "PathOriginY": 0, + "PathName": "", + "TargetedSpeed": 0, + "Acceleration": 0, + "DrawingElementIndex": 0, + "X": 0, + "Y": 0, + "PathAngle": 0, + "PathScale": 0, + "RepetitionCount": 0, + "ShouldLoop": false, + "DrawingPathOriginX": 0, + "DrawingPathOriginY": 0, + "DebugLineStrokeWidth": 0, + "PreviousSpeed": 0, + "CurrentLength": 0, + "IsLookingBack": false, + "Viewpoint": "Top-Down" + } + ], + "animations": [ + { + "name": "Green", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "GreenBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Yellow", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "YellowBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Blue", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "BlueBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Purple", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "PurpuleBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + }, + { + "name": "Red", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "RedBubble.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 15, + "y": 15 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + }, + { + "adaptCollisionMaskAutomatically": false, + "assetStoreId": "", + "name": "Hole", + "tags": "", + "type": "Sprite", + "updateIfNotVisible": false, + "variables": [], + "effects": [], + "behaviors": [], + "animations": [ + { + "name": "", + "useMultipleDirections": false, + "directions": [ + { + "looping": false, + "timeBetweenFrames": 0.08, + "sprites": [ + { + "hasCustomCollisionMask": false, + "image": "assets\\Hole.png", + "points": [], + "originPoint": { + "name": "origine", + "x": 16, + "y": 16 + }, + "centerPoint": { + "automatic": true, + "name": "centre", + "x": 0, + "y": 0 + }, + "customCollisionMask": [] + } + ] + } + ] + } + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DepartScene" + }, + "parameters": [ + "" + ] + } + ], + "actions": [], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Level thumbnails", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::ForEach", + "object": "Level", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "GutterPainter", + "Level.X()", + "Level.Y()", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Launcher", + "Level.X() + GlobalVariable(Levels[Level.Variable(Level)].LauncherX) / 3", + "Level.Y() + GlobalVariable(Levels[Level.Variable(Level)].LauncherY) / 3", + "" + ] + }, + { + "type": { + "value": "ChangeScale" + }, + "parameters": [ + "Launcher", + "=", + "1/3" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "index", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "GlobalVariableChildCount(Levels[Level.Variable(Level)].Gutters)", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "StartLocation", + "Level.X() + GlobalVariable(Levels[Level.Variable(Level)].Gutters[Variable(index)].StartX) / 3", + "Level.Y() + GlobalVariable(Levels[Level.Variable(Level)].Gutters[Variable(index)].StartY) / 3", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "StartLocation" + ] + }, + { + "type": { + "value": "ModVarSceneTxt" + }, + "parameters": [ + "pathName", + "=", + "Level.VariableString(Level) + \"-\" + VariableString(index)" + ] + }, + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "VariableString(pathName)", + "", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::CreatePathFromSvg" + }, + "parameters": [ + "", + "VariableString(pathName)", + "GlobalVariableString(Levels[Level.Variable(Level)].Gutters[Variable(index)].Path)", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPathTo" + }, + "parameters": [ + "StartLocation", + "SpeedPathMovement", + "VariableString(pathName)", + "1", + "", + "Level.X() + (GlobalVariable(Levels[Level.Variable(Level)].Gutters[Variable(index)].StartX) + CurvedMovement::PathEndX(VariableString(pathName))) / 3", + "Level.Y() + (GlobalVariable(Levels[Level.Variable(Level)].Gutters[Variable(index)].StartY) + CurvedMovement::PathEndY(VariableString(pathName))) / 3", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::DrawDebug" + }, + "parameters": [ + "StartLocation", + "SpeedPathMovement", + "GutterPainter", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "StartLocation", + "Hole", + "Level.X() + (GlobalVariable(Levels[Level.Variable(Level)].Gutters[Variable(index)].StartX) + CurvedMovement::PathEndX(VariableString(pathName))) / 3", + "Level.Y() + (GlobalVariable(Levels[Level.Variable(Level)].Gutters[Variable(index)].StartY) + CurvedMovement::PathEndY(VariableString(pathName))) / 3", + "" + ] + }, + { + "type": { + "value": "ChangeScale" + }, + "parameters": [ + "Hole", + "=", + "1/3" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "index", + "+", + "1" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "UI", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::IsClicked" + }, + "parameters": [ + "Level", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarGlobal" + }, + "parameters": [ + "Level", + "=", + "Level.Variable(Level)" + ] + }, + { + "type": { + "value": "Scene" + }, + "parameters": [ + "", + "\"Game\"", + "" + ] + } + ] + } + ], + "parameters": [] + } + ], + "layers": [ + { + "ambientLightColorB": 200, + "ambientLightColorG": 200, + "ambientLightColorR": 200, + "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": [ + { + "name": "ButtonFSM", + "type": "ButtonStates::ButtonFSM" + }, + { + "name": "SpeedPathMovement", + "type": "CurvedMovement::SpeedPathMovement" + } + ] + }, + { + "b": 49, + "disableInputWhenNotFocused": true, + "mangledName": "Leaderboard", + "name": "Leaderboard", + "r": 99, + "standardSortMethod": true, + "stopSoundsOnStartup": true, + "title": "", + "v": 84, + "uiSettings": { + "grid": true, + "gridType": "rectangular", + "gridWidth": 32, + "gridHeight": 32, + "gridOffsetX": 0, + "gridOffsetY": 0, + "gridColor": 10401023, + "gridAlpha": 0.8, + "snap": true, + "zoomFactor": 0.5452538663326276, + "windowMask": false + }, + "objectsGroups": [], + "variables": [ + { + "name": "LeaderboardScore", + "type": "string", + "value": "" + } + ], + "instances": [ + { + "angle": 0, + "customSize": true, + "height": 64, + "layer": "", + "name": "Platform", + "persistentUuid": "c2c6a11c-e8f8-4ee6-aedb-369f62303136", + "width": 1152, + "x": -96, + "y": 512, + "zOrder": 14, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": true, + "height": 896, + "layer": "Background", + "name": "Background", + "persistentUuid": "968c9c47-08c4-44eb-917a-906d2ecee36b", + "width": 1024, + "x": -32, + "y": -320, + "zOrder": 15, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": true, + "height": 67, + "layer": "", + "name": "ScoreText", + "persistentUuid": "722f1233-75ba-4128-8905-4ac5dd26bc1e", + "width": 384, + "x": 170, + "y": 76, + "zOrder": 18, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": true, + "height": 96, + "layer": "", + "name": "PlayerNameInput", + "persistentUuid": "a681abd2-5235-4165-a003-4a9553d79cb5", + "width": 416, + "x": 128, + "y": 192, + "zOrder": 19, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": false, + "height": 0, + "layer": "", + "name": "RestartButton", + "persistentUuid": "9e303562-d182-4829-a5eb-148a1af72803", + "width": 0, + "x": 480, + "y": 342, + "zOrder": 35, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": false, + "height": 106, + "layer": "", + "name": "MainMenuButton", + "persistentUuid": "17a7607a-736f-4ef3-b228-4affa90849ec", + "width": 352, + "x": 128, + "y": 342, + "zOrder": 36, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": true, + "height": 106, + "layer": "", + "name": "SubmitButton", + "persistentUuid": "3aa859c1-2135-4384-a300-bfb28b424a52", + "width": 128, + "x": 608, + "y": 182, + "zOrder": 37, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + } + ], + "objects": [ + { + "assetStoreId": "", + "bold": false, + "italic": false, + "name": "ScoreText", + "smoothed": true, + "tags": "", + "type": "TextObject::Text", + "underlined": false, + "variables": [], + "effects": [], + "behaviors": [], + "string": "Score", + "font": "", + "textAlignment": "", + "characterSize": 60, + "color": { + "b": 255, + "g": 255, + "r": 255 + } + }, + { + "assetStoreId": "", + "name": "PlayerNameInput", + "tags": "", + "type": "TextInput::TextInputObject", + "variables": [], + "effects": [], + "behaviors": [], + "content": { + "initialValue": "", + "placeholder": "PlayerName", + "fontResourceName": "", + "fontSize": 60, + "inputType": "text", + "textColor": "255;255;255", + "fillColor": "54;46;27", + "fillOpacity": 255, + "borderColor": "36;30;18", + "borderOpacity": 255, + "borderWidth": 6, + "readOnly": false, + "disabled": false + } + }, + { + "assetStoreId": "bfab3a269992cf43081e2cb8053c28aaef11f2f9e0d0cbdc00207ea271f69c2c", + "name": "SubmitButton", + "tags": "", + "type": "PanelSpriteButton::PanelSpriteButton", + "variables": [], + "effects": [], + "behaviors": [], + "content": { + "LeftPadding": 16, + "RightPadding": 16, + "PressedLabelOffsetY": 10, + "BottomPadding": 32, + "TopPadding": 16, + "HoveredFadeOutDuration": 0.25 + }, + "childrenContent": { + "Hovered": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Hovered.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Idle": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Idle.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Label": { + "bold": false, + "italic": false, + "smoothed": true, + "underlined": false, + "string": "🡲", + "font": "", + "textAlignment": "center", + "characterSize": 60, + "color": { + "b": 79, + "g": 72, + "r": 72 + } + }, + "Pressed": { + "bottomMargin": 16, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Pressed.png", + "tiled": true, + "topMargin": 32, + "width": 256 + } + } + }, + { + "assetStoreId": "bfab3a269992cf43081e2cb8053c28aaef11f2f9e0d0cbdc00207ea271f69c2c", + "name": "MainMenuButton", + "tags": "", + "type": "PanelSpriteButton::PanelSpriteButton", + "variables": [], + "effects": [], + "behaviors": [], + "content": { + "LeftPadding": 16, + "RightPadding": 16, + "PressedLabelOffsetY": 10, + "BottomPadding": 32, + "TopPadding": 16, + "HoveredFadeOutDuration": 0.25 + }, + "childrenContent": { + "Hovered": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Hovered.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Idle": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Idle.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Label": { + "bold": false, + "italic": false, + "smoothed": true, + "underlined": false, + "string": "Menu", + "font": "", + "textAlignment": "center", + "characterSize": 60, + "color": { + "b": 79, + "g": 72, + "r": 72 + } + }, + "Pressed": { + "bottomMargin": 16, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Pressed.png", + "tiled": true, + "topMargin": 32, + "width": 256 + } + } + }, + { + "assetStoreId": "bfab3a269992cf43081e2cb8053c28aaef11f2f9e0d0cbdc00207ea271f69c2c", + "name": "RestartButton", + "tags": "", + "type": "PanelSpriteButton::PanelSpriteButton", + "variables": [], + "effects": [], + "behaviors": [], + "content": { + "LeftPadding": 16, + "RightPadding": 16, + "PressedLabelOffsetY": 10, + "BottomPadding": 32, + "TopPadding": 16, + "HoveredFadeOutDuration": 0.25 + }, + "childrenContent": { + "Hovered": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Hovered.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Idle": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Idle.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Label": { + "bold": false, + "italic": false, + "smoothed": true, + "underlined": false, + "string": "Restart", + "font": "", + "textAlignment": "center", + "characterSize": 60, + "color": { + "b": 79, + "g": 72, + "r": 72 + } + }, + "Pressed": { + "bottomMargin": 16, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Pressed.png", + "tiled": true, + "topMargin": 32, + "width": 256 + } + } + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DepartScene" + }, + "parameters": [ + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "ScoreText", + "=", + "\"Score \" + GlobalVariableString(Score)" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlayerAuthentication::DisplayAuthenticationBanner" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlayerAuthentication::IsPlayerAuthenticated" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "TextInput::TextInputObject::SetText" + }, + "parameters": [ + "PlayerNameInput", + "=", + "PlayerAuthentication::Username()" + ] + }, + { + "type": { + "value": "TextInput::TextInputObject::SetDisabled" + }, + "parameters": [ + "PlayerNameInput", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlayerAuthentication::IsPlayerAuthenticated" + }, + "parameters": [] + }, + { + "type": { + "value": "VarGlobalTxt" + }, + "parameters": [ + "PlayerName", + "!=", + "\"0\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextInput::TextInputObject::SetText" + }, + "parameters": [ + "PlayerNameInput", + "=", + "GlobalVariableString(PlayerName)" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlayerAuthentication::HasPlayerLoggedIn" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "TextInput::TextInputObject::SetText" + }, + "parameters": [ + "PlayerNameInput", + "=", + "PlayerAuthentication::Username()" + ] + }, + { + "type": { + "value": "TextInput::TextInputObject::SetDisabled" + }, + "parameters": [ + "PlayerNameInput", + "yes" + ] + }, + { + "type": { + "value": "PlayerAuthentication::DisplayAuthenticationBanner" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Leaderboards::IsLeaderboardViewErrored" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "PlayerAuthentication::DisplayAuthenticationBanner" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsClicked" + }, + "parameters": [ + "RestartButton", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlayerAuthentication::HideAuthenticationBanner" + }, + "parameters": [ + "" + ] + }, + { + "type": { + "value": "Scene" + }, + "parameters": [ + "", + "\"Game\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsClicked" + }, + "parameters": [ + "MainMenuButton", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlayerAuthentication::HideAuthenticationBanner" + }, + "parameters": [ + "" + ] + }, + { + "type": { + "value": "Scene" + }, + "parameters": [ + "", + "\"LevelSelection\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Handle leaderboards.\nTo create a leaderboard, make sure your game is registered in Home > Profile > Games Dashboard and then, click on \"Manage game\" > Leaderboards. When a leaderboard is created, it should be available in the actions." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsClicked" + }, + "parameters": [ + "SubmitButton", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlayerAuthentication::IsPlayerAuthenticated" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "Leaderboards::SaveConnectedPlayerScore" + }, + "parameters": [ + "", + "GlobalVariableString(Levels[GlobalVariable(Level)].LeaderboardId)", + "GlobalVariable(Score)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlayerAuthentication::IsPlayerAuthenticated" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "Leaderboards::SavePlayerScore" + }, + "parameters": [ + "", + "GlobalVariableString(Levels[GlobalVariable(Level)].LeaderboardId)", + "GlobalVariable(Score)", + "PlayerNameInput.Text()" + ] + }, + { + "type": { + "value": "ModVarGlobalTxt" + }, + "parameters": [ + "PlayerName", + "=", + "PlayerNameInput.Text()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlayerAuthentication::HideAuthenticationBanner" + }, + "parameters": [ + "" + ] + }, + { + "type": { + "value": "Leaderboards::DisplayLeaderboard" + }, + "parameters": [ + "", + "GlobalVariableString(Levels[GlobalVariable(Level)].LeaderboardId)", + "yes" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Allow to try and submit again in case of error." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Leaderboards::HasPlayerJustClosedLeaderboardView" + }, + "parameters": [] + }, + { + "type": { + "value": "Leaderboards::HasLastSaveSucceeded" + }, + "parameters": [ + "GlobalVariableString(Levels[GlobalVariable(Level)].LeaderboardId)" + ] + } + ], + "actions": [ + { + "type": { + "value": "Scene" + }, + "parameters": [ + "", + "\"LevelSelection\"", + "" + ] + } + ] + } + ], + "layers": [ + { + "ambientLightColorB": 167797870, + "ambientLightColorG": 6032144, + "ambientLightColorR": 8563600, + "camera3DFarPlaneDistance": 10000, + "camera3DFieldOfView": 45, + "camera3DNearPlaneDistance": 0.1, + "followBaseLayerCamera": false, + "isLightingLayer": false, + "isLocked": false, + "name": "Background", + "renderingType": "", + "visibility": true, + "cameras": [], + "effects": [] + }, + { + "ambientLightColorB": 3, + "ambientLightColorG": 134217728, + "ambientLightColorR": 1597197633, + "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": [ + { + "associatedLayout": "Game", + "lastChangeTimeStamp": 0, + "name": "UpdateRemainingColors", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Find which colors are still on the board because only these colors will be given to the player when he shoots." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "VariableClearChildren" + }, + "parameters": [ + "remainingColors" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::ForEachChildVariable", + "iterableVariableName": "colors", + "valueIteratorVariableName": "color", + "keyIteratorVariableName": "index", + "conditions": [ + { + "type": { + "value": "AnimationName" + }, + "parameters": [ + "BoardBubble", + "VariableString(color)" + ] + } + ], + "actions": [ + { + "type": { + "value": "SceneVariablePushString" + }, + "parameters": [ + "remainingColors", + "VariableString(color)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "VariableChildCount(remainingColors)", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "levelCompleted", + "True" + ] + } + ] + } + ] + } + ], + "eventsFunctionsExtensions": [ + { + "author": "add_, @Jurfix", + "category": "Advanced", + "extensionNamespace": "", + "fullName": "Extended math support", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWZ1bmN0aW9uLXZhcmlhbnQiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTIuNDIsNS4yOUMxMS4zMiw1LjE5IDEwLjM1LDYgMTAuMjUsNy4xMUwxMCwxMEgxMi44MlYxMkg5LjgyTDkuMzgsMTcuMDdDOS4xOCwxOS4yNyA3LjI0LDIwLjkgNS4wNCwyMC43QzMuNzksMjAuNTkgMi42NiwxOS45IDIsMTguODNMMy41LDE3LjMzQzMuODMsMTguMzggNC45NiwxOC45NyA2LDE4LjYzQzYuNzgsMTguMzkgNy4zMywxNy43IDcuNCwxNi44OUw3LjgyLDEySDQuODJWMTBIOEw4LjI3LDYuOTNDOC40Niw0LjczIDEwLjM5LDMuMSAxMi42LDMuMjhDMTMuODYsMy4zOSAxNSw0LjA5IDE1LjY2LDUuMTdMMTQuMTYsNi42N0MxMy45MSw1LjkgMTMuMjMsNS4zNiAxMi40Miw1LjI5TTIyLDEzLjY1TDIwLjU5LDEyLjI0TDE3Ljc2LDE1LjA3TDE0LjkzLDEyLjI0TDEzLjUsMTMuNjVMMTYuMzUsMTYuNUwxMy41LDE5LjMxTDE0LjkzLDIwLjcyTDE3Ljc2LDE3Ljg5TDIwLjU5LDIwLjcyTDIyLDE5LjMxTDE5LjE3LDE2LjVMMjIsMTMuNjVaIiAvPjwvc3ZnPg==", + "name": "ExtendedMath", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/function-variant.svg", + "shortDescription": "Additional math functions and constants as expressions and conditions.", + "version": "1.1.0", + "description": [ + "Expressions:", + " - Mathematical constants", + " - Greatest common factor/Lowest common multiple", + " - Factorial", + " - Coordinates conversion for polar and isometric systems", + " - ToFixedString: Formats a number into a string with the specified number of decimal places", + " - ToFixed: (Deprecated) Formats a number to use the specified number of decimal places", + "", + "Conditions:", + "- IsEven: Check if the number is even (divisible by 2)", + "", + "Release Notes:", + "", + "Version 1.0.7", + "- Added ToFixedString()", + "- Deprecated ToFixed() because it does not show any trailing zeros for whole numbers. Prefer using ToFixedString() to set values in text objects.", + "" + ], + "origin": { + "identifier": "ExtendedMath", + "name": "gdevelop-extension-store" + }, + "tags": [ + "math", + "constants", + "conversion", + "coordinates", + "convert", + "format", + "modulus" + ], + "authorIds": [ + "AlZ3D1xkH0QDao7T37VZZUeYNpn1", + "dt0tRnf2kHWJnjkrpnzTzNj9Yc63" + ], + "dependencies": [], + "eventsFunctions": [ + { + "description": "Returns a term from the Fibonacci sequence.", + "fullName": "Fibonacci numbers", + "functionType": "Expression", + "name": "Fibonacci", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "function fibonacci(n) {", + " let initial = 0;", + " let final = 1;", + " let sum = 0;", + "", + " let i = 0;", + " for(i = 2; i <= n; i++) {", + " sum = initial + final;", + "", + " initial = final;", + " final = sum;", + " }", + " return n ? final : initial;", + "}", + "", + "const n = eventsFunctionContext.getArgument(\"n\");", + "", + "eventsFunctionContext.returnValue = fibonacci(n);" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The desired term in the sequence", + "name": "n", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Calculates the steepness of a line between two points.", + "fullName": "Slope", + "functionType": "Expression", + "name": "Slope", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const x1 = eventsFunctionContext.getArgument(\"x1\");\r", + "const y1 = eventsFunctionContext.getArgument(\"y1\");\r", + "const x2 = eventsFunctionContext.getArgument(\"x2\");\r", + "const y2 = eventsFunctionContext.getArgument(\"y2\");\r", + "\r", + "eventsFunctionContext.returnValue = (y2 - y1) / (x2 - x1);" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "X value of the first point", + "name": "x1", + "type": "expression" + }, + { + "description": "Y value of the first point", + "name": "y1", + "type": "expression" + }, + { + "description": "X value of the second point", + "name": "x2", + "type": "expression" + }, + { + "description": "Y value of the second point", + "name": "y2", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Converts a number of one range e.g. 0-1 to another 0-255.", + "fullName": "Map", + "functionType": "Expression", + "name": "Map", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const n = eventsFunctionContext.getArgument(\"n\");", + "const min1 = eventsFunctionContext.getArgument(\"min1\");", + "const max1 = eventsFunctionContext.getArgument(\"max1\");", + "const min2 = eventsFunctionContext.getArgument(\"min2\");", + "const max2 = eventsFunctionContext.getArgument(\"max2\");", + "", + "eventsFunctionContext.returnValue = (n - min1) * (max2 - min2) / (max1 - min1) + min2;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The value to convert", + "name": "n", + "type": "expression" + }, + { + "description": "The lowest value of the first range", + "name": "min1", + "type": "expression" + }, + { + "description": "The highest value of the first range", + "name": "max1", + "type": "expression" + }, + { + "description": "The lowest value of the second range", + "name": "min2", + "type": "expression" + }, + { + "description": "The highest value of the second range", + "name": "max2", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Returns the value of the length of the hypotenuse.", + "fullName": "Hypotenuse length", + "functionType": "Expression", + "name": "Hypot", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const a = eventsFunctionContext.getArgument(\"a\");\r", + "const b = eventsFunctionContext.getArgument(\"b\");\r", + "\r", + "eventsFunctionContext.returnValue = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "First side of the triangle", + "name": "a", + "type": "expression" + }, + { + "description": "Second side of the triangle", + "name": "b", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Returns the greatest common factor of two numbers.", + "fullName": "Greatest common factor (gcf)", + "functionType": "Expression", + "name": "Gcf", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//uses Euclid's algorithm", + "function gcf(a, b) {", + " while (a != b) {", + " if (a > b) {", + " a = a - b;", + " } else {", + " b = b - a;", + " }", + " }", + " return a;", + "}", + "", + "const a = eventsFunctionContext.getArgument(\"a\");", + "const b = eventsFunctionContext.getArgument(\"b\");", + "", + "if (Number.isInteger(a) === false || Number.isInteger(b) === false) {", + " eventsFunctionContext.returnValue = 0;", + "} ", + "else if (a === 0) {", + " eventsFunctionContext.returnValue = b;", + "} ", + "else if (b === 0) {", + " eventsFunctionContext.returnValue = a;", + "} else {", + " eventsFunctionContext.returnValue = gcf(a, b);", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Any integer", + "name": "a", + "type": "expression" + }, + { + "description": "Any integer", + "name": "b", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Returns the lowest common multiple of two numbers.", + "fullName": "Lowest common multiple (lcm)", + "functionType": "Expression", + "name": "Lcm", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "function gcf(a, b) {\r", + " while (a != b) {\r", + " if (a > b) {\r", + " a = a - b;\r", + " } else {\r", + " b = b - a;\r", + " }\r", + " }\r", + " return a;\r", + "}\r", + "\r", + "function lcm(a, b) {\r", + " return Math.abs(a * b) / gcf(a, b);\r", + "}\r", + "\r", + "const a = eventsFunctionContext.getArgument(\"a\");\r", + "const b = eventsFunctionContext.getArgument(\"b\");\r", + "\r", + "if (Number.isInteger(a) === false || Number.isInteger(b) === false) {\r", + " eventsFunctionContext.returnValue = 0;\r", + "} \r", + "else if (a === 0) {\r", + " eventsFunctionContext.returnValue = b;\r", + "} \r", + "else if (b === 0) {\r", + " eventsFunctionContext.returnValue = a;\r", + "} else {\r", + " eventsFunctionContext.returnValue = lcm(a, b);\r", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Any integer", + "name": "a", + "type": "expression" + }, + { + "description": "Any integer", + "name": "b", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Returns the input multiplied by all the previous whole numbers.", + "fullName": "Factorial", + "functionType": "Expression", + "name": "Factorial", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "function factorial(n) {\r", + " let result = 1;\r", + "\r", + " let i = 1;\r", + " for (i = 1; i <= n; i++) {\r", + " result *= i;\r", + " }\r", + "\r", + " return result;\r", + "}\r", + "\r", + "const n = eventsFunctionContext.getArgument(\"n\");\r", + "\r", + "eventsFunctionContext.returnValue = factorial(n);" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Any positive integer", + "name": "n", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Converts a polar coordinate into the Cartesian x value.", + "fullName": "Polar coordinate to Cartesian X value", + "functionType": "Expression", + "name": "PolarToCartesianX", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const r = eventsFunctionContext.getArgument(\"r\");", + "const theta = eventsFunctionContext.getArgument(\"theta\");", + "", + "eventsFunctionContext.returnValue = r * Math.cos(theta);" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Radius", + "name": "r", + "type": "expression" + }, + { + "description": "Angle or theta in radians", + "name": "theta", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Converts a polar coordinate into the Cartesian y value.", + "fullName": "Polar coordinate to Cartesian Y value", + "functionType": "Expression", + "name": "PolarToCartesianY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const r = eventsFunctionContext.getArgument(\"r\");", + "const theta = eventsFunctionContext.getArgument(\"theta\");", + "", + "eventsFunctionContext.returnValue = r * Math.sin(theta);" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Radius ", + "name": "r", + "type": "expression" + }, + { + "description": "Angle or theta in radians", + "name": "theta", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Converts a isometric coordinate into the Cartesian x value.", + "fullName": "Isometric coordinate to Cartesian X value", + "functionType": "Expression", + "name": "IsoToCartesianX", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const x = eventsFunctionContext.getArgument(\"x\");", + "const y = eventsFunctionContext.getArgument(\"y\");", + "", + "eventsFunctionContext.returnValue = (2 * y + x) * 0.5;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Position on the x axis", + "name": "x", + "type": "expression" + }, + { + "description": "Position on the y axis", + "name": "y", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Converts a isometric coordinate into the Cartesian y value.", + "fullName": "Isometric coordinate to Cartesian Y value", + "functionType": "Expression", + "name": "IisoToCartesianY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const x = eventsFunctionContext.getArgument(\"x\");", + "const y = eventsFunctionContext.getArgument(\"y\");", + "", + "eventsFunctionContext.returnValue = (2 * y - x) * 0.5;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Position on the x axis", + "name": "x", + "type": "expression" + }, + { + "description": "Position on the y axis", + "name": "y", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Returns the golden ratio.", + "fullName": "Golden ratio", + "functionType": "Expression", + "name": "GoldenRatio", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "1.618033988749894" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns Pi (π).", + "fullName": "Pi (π)", + "functionType": "Expression", + "name": "Pi", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.PI;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns half Pi.", + "fullName": "Half Pi", + "functionType": "Expression", + "name": "HalfPi", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.PI / 2;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns the natural logarithm of e. (Euler's number).", + "fullName": "Natural logarithm of e", + "functionType": "Expression", + "name": "E", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.E;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns the natural logarithm of 2.", + "fullName": "Natural logarithm of 2", + "functionType": "Expression", + "name": "Ln2", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.LN2;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns the natural logarithm of 10.", + "fullName": "Natural logarithm of 10", + "functionType": "Expression", + "name": "Ln10", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.LN10;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns the base 2 logarithm of e. (Euler's number).", + "fullName": "Base 2 logarithm of e", + "functionType": "Expression", + "name": "Log2e", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.LOG10E;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns the base 10 logarithm of e. (Euler's number).", + "fullName": "Base 10 logarithm of e", + "functionType": "Expression", + "name": "Log10e", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.LOG10E;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns square root of 2.", + "fullName": "Square root of 2", + "functionType": "Expression", + "name": "Sqrt2", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.SQRT2;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns square root of 1/2.", + "fullName": "Square root of 1/2", + "functionType": "Expression", + "name": "Sqrt1_2", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.SQRT1_2;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Returns quarter Pi.", + "fullName": "Quarter Pi", + "functionType": "Expression", + "name": "QuarterPi", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = Math.PI / 4;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "description": "Formats a number to use the specified number of decimal places (Deprecated).", + "fullName": "ToFixed", + "functionType": "Expression", + "name": "ToFixed", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const valueToBeRounded = eventsFunctionContext.getArgument(\"ValueToBeRounded\");", + "const numberOfDecimalPlaces = eventsFunctionContext.getArgument(\"NumberOfDecimalPlaces\");", + "eventsFunctionContext.returnValue = Number(valueToBeRounded.toFixed(numberOfDecimalPlaces));" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "The value to be rounded", + "name": "ValueToBeRounded", + "type": "expression" + }, + { + "description": "Number of decimal places", + "name": "NumberOfDecimalPlaces", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Formats a number to a string with the specified number of decimal places.", + "fullName": "ToFixed", + "functionType": "StringExpression", + "name": "ToFixedString", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const valueToBeRounded = eventsFunctionContext.getArgument(\"ValueToBeRounded\");", + "const numberOfDecimalPlaces = eventsFunctionContext.getArgument(\"NumberOfDecimalPlaces\");", + "eventsFunctionContext.returnValue = valueToBeRounded.toFixed(numberOfDecimalPlaces);" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "The value to be rounded", + "name": "ValueToBeRounded", + "type": "expression" + }, + { + "description": "Number of decimal places", + "name": "NumberOfDecimalPlaces", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the number is even (divisible by 2). To check for odd numbers, invert this condition.", + "fullName": "Is even?", + "functionType": "Condition", + "name": "IsEven", + "sentence": "_PARAM1_ is even", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Egal" + }, + "parameters": [ + "mod(GetArgumentAsNumber(\"Value\"),2)", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [], + "eventsBasedObjects": [] + }, + { + "author": "", + "category": "User interface", + "extensionNamespace": "", + "fullName": "Panel sprite button", + "helpPath": "/objects/button", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQo8L3N0eWxlPg0KPHBhdGggY2xhc3M9InN0MCIgZD0iTTI5LDIzSDNjLTEuMSwwLTItMC45LTItMlYxMWMwLTEuMSwwLjktMiwyLTJoMjZjMS4xLDAsMiwwLjksMiwydjEwQzMxLDIyLjEsMzAuMSwyMywyOSwyM3oiLz4NCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xMywxOUwxMywxOWMtMS4xLDAtMi0wLjktMi0ydi0yYzAtMS4xLDAuOS0yLDItMmgwYzEuMSwwLDIsMC45LDIsMnYyQzE1LDE4LjEsMTQuMSwxOSwxMywxOXoiLz4NCjxsaW5lIGNsYXNzPSJzdDAiIHgxPSIxOCIgeTE9IjEzIiB4Mj0iMTgiIHkyPSIxOSIvPg0KPGxpbmUgY2xhc3M9InN0MCIgeDE9IjIxIiB5MT0iMTMiIHgyPSIxOCIgeTI9IjE3Ii8+DQo8bGluZSBjbGFzcz0ic3QwIiB4MT0iMjEiIHkxPSIxOSIgeDI9IjE5IiB5Mj0iMTYiLz4NCjwvc3ZnPg0K", + "name": "PanelSpriteButton", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/Line Hero Pack/Master/SVG/Interface Elements/Interface Elements_interface_ui_button_ok_cta_clock_tap.svg", + "shortDescription": "A button that can be customized.", + "version": "1.4.4", + "description": [ + "The button can be customized with a background for each state and a label. It handles user interactions and a simple condition can be used to check if it is clicked.", + "", + "There are ready-to-use buttons in the asset-store [menu buttons pack](https://editor.gdevelop.io/?initial-dialog=asset-store&asset-pack=menu-buttons-menu-buttons)." + ], + "origin": { + "identifier": "PanelSpriteButton", + "name": "gdevelop-extension-store" + }, + "tags": [ + "button", + "ui" + ], + "authorIds": [ + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "The finite state machine used internally by the button object.", + "fullName": "Button finite state machine", + "name": "ButtonFSM", + "objectType": "", + "private": true, + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Finite state machine", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "The \"Validated\" state only last one frame." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Check position", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Make sure the cursor position is only checked once per frame." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyShouldCheckHovering" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "CollisionPoint" + }, + "parameters": [ + "Object", + "MouseOnlyCursorX(Object.Layer(), 0)", + "MouseOnlyCursorY(Object.Layer(), 0)" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Touches are always pressed, so ShouldCheckHovering doesn't matter." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + }, + { + "type": { + "value": "CollisionPoint" + }, + "parameters": [ + "Object", + "TouchX(Object.Behavior::PropertyTouchId(), Object.Layer(), 0)", + "TouchY(Object.Behavior::PropertyTouchId(), Object.Layer(), 0)" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Handle touch start", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "HasAnyTouchOrMouseStarted" + }, + "parameters": [ + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "StartedTouchOrMouseCount()", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CollisionPoint" + }, + "parameters": [ + "Object", + "TouchX(StartedTouchOrMouseId(Object.Behavior::PropertyIndex()), Object.Layer(), 0)", + "TouchY(StartedTouchOrMouseId(Object.Behavior::PropertyIndex()), Object.Layer(), 0)" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "StartedTouchOrMouseId(Object.Behavior::PropertyIndex())" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Apply position changes", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PanelSpriteButton::ButtonFSM::PropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PanelSpriteButton::ButtonFSM::PropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Handle touch end", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "HasTouchEnded" + }, + "parameters": [ + "", + "Object.Behavior::PropertyTouchId()" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + }, + { + "type": { + "inverted": true, + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onDeActivate", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::ResetState" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Reset the state of the button.", + "fullName": "Reset state", + "functionType": "Action", + "name": "ResetState", + "private": true, + "sentence": "Reset the button state of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is not used.", + "fullName": "Is idle", + "functionType": "Condition", + "name": "IsIdle", + "sentence": "_PARAM0_ is idle", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button was just clicked.", + "fullName": "Is clicked", + "functionType": "Condition", + "name": "IsClicked", + "sentence": "_PARAM0_ is clicked", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the cursor is hovered over the button.", + "fullName": "Is hovered", + "functionType": "Condition", + "name": "IsHovered", + "sentence": "_PARAM0_ is hovered", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is either hovered or pressed but not hovered.", + "fullName": "Is focused", + "functionType": "Condition", + "name": "IsFocused", + "sentence": "_PARAM0_ is focused", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is currently being pressed with mouse or touch.", + "fullName": "Is pressed", + "functionType": "Condition", + "name": "IsPressed", + "sentence": "_PARAM0_ is pressed", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is currently being pressed outside with mouse or touch.", + "fullName": "Is held outside", + "functionType": "Condition", + "name": "IsPressedOutside", + "sentence": "_PARAM0_ is held outside", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the touch id that is using the button or 0 if none.", + "fullName": "Touch id", + "functionType": "ExpressionAndCondition", + "name": "TouchId", + "sentence": "the touch id", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTouchId()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "true", + "type": "Boolean", + "label": "", + "description": "Should check hovering", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ShouldCheckHovering" + }, + { + "value": "Idle", + "type": "Choice", + "label": "State", + "description": "", + "group": "", + "extraInformation": [ + "Idle", + "Hovered", + "PressedInside", + "PressedOutside", + "Validated" + ], + "hidden": true, + "name": "State" + }, + { + "value": "0", + "type": "Number", + "label": "Touch id", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TouchId" + }, + { + "value": "", + "type": "Boolean", + "label": "Touch is inside", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TouchIsInside" + }, + { + "value": "", + "type": "Boolean", + "label": "Mouse is inside", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "MouseIsInside" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Index" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [ + { + "defaultName": "Button", + "description": "A button that can be customized.", + "fullName": "Button (panel sprite)", + "name": "PanelSpriteButton", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Create one background instance for of each state.\nOnly the instance for the current state is shown." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Idle", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Hovered", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Pressed", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Hovered" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Pressed" + ] + }, + { + "type": { + "value": "ChangePlan" + }, + "parameters": [ + "Hovered", + "=", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Place the label over the backgrounds." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Label", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "ChangePlan" + }, + "parameters": [ + "Label", + "=", + "2" + ] + }, + { + "type": { + "value": "TextObject::SetWrapping" + }, + "parameters": [ + "Label", + "yes" + ] + }, + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::CenterLabel" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [ + { + "name": "Background", + "objects": [ + { + "name": "Idle" + }, + { + "name": "Hovered" + }, + { + "name": "Pressed" + } + ] + } + ] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onHotReloading", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::CenterLabel" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Apply states", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Show the right background accordingly to the new state." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsIdle" + }, + "parameters": [ + "Object", + "ButtonFSM" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY()" + ] + }, + { + "type": { + "value": "Montre" + }, + "parameters": [ + "Idle", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Pressed" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Visible" + }, + "parameters": [ + "Hovered" + ] + }, + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::PropertyHoveredFadeOutDuration" + }, + "parameters": [ + "Object", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "Tween::AddObjectOpacityTween" + }, + "parameters": [ + "Hovered", + "Tween", + "\"Fadeout\"", + "0", + "\"linear\"", + "Object.PropertyHoveredFadeOutDuration() * 1000", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::PropertyHoveredFadeOutDuration" + }, + "parameters": [ + "Object", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Hovered" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteObject::Opacity" + }, + "parameters": [ + "Hovered", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Hovered" + ] + }, + { + "type": { + "value": "PanelSpriteObject::SetOpacity" + }, + "parameters": [ + "Hovered", + "=", + "255" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsHovered" + }, + "parameters": [ + "Object", + "ButtonFSM" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY()" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Idle" + ] + }, + { + "type": { + "value": "Montre" + }, + "parameters": [ + "Hovered", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Pressed" + ] + }, + { + "type": { + "value": "Tween::RemoveTween" + }, + "parameters": [ + "Hovered", + "Tween", + "\"Fadeout\"" + ] + }, + { + "type": { + "value": "PanelSpriteObject::SetOpacity" + }, + "parameters": [ + "Hovered", + "=", + "255" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsPressed" + }, + "parameters": [ + "Object", + "ButtonFSM" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY() + Object.PropertyPressedLabelOffsetY()" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Idle" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Hovered" + ] + }, + { + "type": { + "value": "Montre" + }, + "parameters": [ + "Pressed", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsFocused" + }, + "parameters": [ + "Object", + "ButtonFSM" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY()" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Idle" + ] + }, + { + "type": { + "value": "Montre" + }, + "parameters": [ + "Hovered", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Pressed" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Resize", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Children instances must be resized when the button size change:\n- backgrounds for each state are resized to take the full dimensions of the button\n- the label is put back at the center of the button\n\nThe scale is set back to 1 because it means that the parent instance has the same dimensions as the union of its children instances." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Width()", + "!=", + "max(Idle.BoundingBoxRight(), Label.BoundingBoxRight()) - min(Idle.BoundingBoxLeft(), Label.BoundingBoxLeft())" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Height()", + "!=", + "max(Idle.BoundingBoxBottom(), Label.BoundingBoxBottom()) - min(Idle.BoundingBoxTop(), Label.BoundingBoxTop())" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Idle", + "Width", + "=", + "Object.Width()" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Idle", + "Height", + "=", + "Object.Height()" + ] + }, + { + "type": { + "value": "PanelSpriteButton::Scale" + }, + "parameters": [ + "Object", + "=", + "1" + ] + }, + { + "type": { + "value": "PanelSpriteObject::Width" + }, + "parameters": [ + "Background", + "=", + "Idle.Variable(Width)" + ] + }, + { + "type": { + "value": "PanelSpriteObject::Height" + }, + "parameters": [ + "Background", + "=", + "Idle.Variable(Height)" + ] + }, + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::CenterLabel" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [ + { + "name": "Background", + "objects": [ + { + "name": "Idle" + }, + { + "name": "Hovered" + }, + { + "name": "Pressed" + } + ] + } + ] + }, + { + "description": "Check if the button is not used.", + "fullName": "Is idle", + "functionType": "Condition", + "name": "IsIdle", + "sentence": "_PARAM0_ is idle", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsIdle" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button was just clicked.", + "fullName": "Is clicked", + "functionType": "Condition", + "name": "IsClicked", + "sentence": "_PARAM0_ is clicked", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsClicked" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the cursor is hovered over the button.", + "fullName": "Is hovered", + "functionType": "Condition", + "name": "IsHovered", + "sentence": "_PARAM0_ is hovered", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsHovered" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is either hovered or pressed but not hovered.", + "fullName": "Is focused", + "functionType": "Condition", + "name": "IsFocused", + "sentence": "_PARAM0_ is focused", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsFocused" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is currently being pressed with mouse or touch.", + "fullName": "Is pressed", + "functionType": "Condition", + "name": "IsPressed", + "sentence": "_PARAM0_ is pressed", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsPressed" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Change the text of the button label.", + "fullName": "Label text", + "functionType": "Action", + "name": "SetLabelText", + "sentence": "Change the text of _PARAM0_ to _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Label", + "=", + "GetArgumentAsString(\"LabelText\")" + ] + }, + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::CenterLabel" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + }, + { + "description": "Text", + "name": "LabelText", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Return the label text.", + "fullName": "Label text", + "functionType": "StringExpression", + "name": "LabelText", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "Label.String()" + ] + } + ] + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Return the label center Y according to the button configuration. This expression is used in doStepPostEvents when the button is pressed or released.", + "fullName": "", + "functionType": "Expression", + "name": "CenterWithPaddingY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Idle.CenterY() + (Object.PropertyTopPadding() - Object.PropertyBottomPadding()) / 2" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Center the label according to the button configuration. This is used in doStepPostEvents when the button is resized.", + "fullName": "", + "functionType": "Action", + "name": "CenterLabel", + "private": true, + "sentence": "Center the label of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "MettreXY" + }, + "parameters": [ + "Label", + "=", + "Object.PropertyLeftPadding()", + "=", + "Object.PropertyTopPadding()" + ] + }, + { + "type": { + "value": "TextObject::WrappingWidth" + }, + "parameters": [ + "Label", + "=", + "Idle.Width() - Object.PropertyLeftPadding() - Object.PropertyRightPadding()" + ] + }, + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY()" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetCenterX" + }, + "parameters": [ + "Label", + "=", + "Background.CenterX() + (Object.PropertyLeftPadding() - Object.PropertyRightPadding()) / 2" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsPressed" + }, + "parameters": [ + "Object", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "MettreY" + }, + "parameters": [ + "Label", + "+", + "Object.PropertyPressedLabelOffsetY()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [ + { + "name": "Background", + "objects": [ + { + "name": "Idle" + }, + { + "name": "Hovered" + }, + { + "name": "Pressed" + } + ] + } + ] + }, + { + "description": "De/activate interactions with the button.", + "fullName": "De/activate interactions", + "functionType": "Action", + "name": "Activate", + "sentence": "Activate interactions with _PARAM0_: _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldActivate\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ActivateBehavior" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldActivate\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ActivateBehavior" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "no" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + }, + { + "description": "Activate", + "name": "ShouldActivate", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Check if interactions are activated on the button.", + "fullName": "Interactions activated", + "functionType": "Condition", + "name": "IsActivated", + "sentence": "Interactions on _PARAM0_ are activated", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BehaviorActivated" + }, + "parameters": [ + "Idle", + "ButtonFSM" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "0", + "type": "Number", + "label": "Label offset on Y axis when pressed", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "PressedLabelOffsetY" + }, + { + "value": "0", + "type": "Number", + "label": "Left padding", + "description": "", + "group": "Padding", + "extraInformation": [ + "Label" + ], + "hidden": false, + "name": "LeftPadding" + }, + { + "value": "0", + "type": "Number", + "label": "Right padding", + "description": "", + "group": "Padding", + "extraInformation": [ + "Label" + ], + "hidden": false, + "name": "RightPadding" + }, + { + "value": "0", + "type": "Number", + "label": "Top padding", + "description": "", + "group": "Padding", + "extraInformation": [ + "Label" + ], + "hidden": false, + "name": "TopPadding" + }, + { + "value": "0", + "type": "Number", + "label": "Bottom padding", + "description": "", + "group": "Padding", + "extraInformation": [ + "Label" + ], + "hidden": false, + "name": "BottomPadding" + }, + { + "value": "0.25", + "type": "Number", + "label": "Hovered fade out duration (in seconds)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "HoveredFadeOutDuration" + } + ], + "objects": [ + { + "assetStoreId": "", + "bold": false, + "italic": false, + "name": "Label", + "smoothed": true, + "tags": "", + "type": "TextObject::Text", + "underlined": false, + "variables": [], + "effects": [], + "behaviors": [], + "string": "Text", + "font": "", + "textAlignment": "", + "characterSize": 20, + "color": { + "b": 0, + "g": 0, + "r": 0 + } + }, + { + "assetStoreId": "", + "bottomMargin": 0, + "height": 32, + "leftMargin": 0, + "name": "Idle", + "rightMargin": 0, + "tags": "", + "texture": "", + "tiled": false, + "topMargin": 0, + "type": "PanelSpriteObject::PanelSprite", + "width": 32, + "variables": [ + { + "folded": true, + "name": "State", + "type": "string", + "value": "Idle" + } + ], + "effects": [], + "behaviors": [ + { + "name": "ButtonFSM", + "type": "PanelSpriteButton::ButtonFSM", + "ShouldCheckHovering": true + } + ] + }, + { + "assetStoreId": "", + "bottomMargin": 0, + "height": 32, + "leftMargin": 0, + "name": "Hovered", + "rightMargin": 0, + "tags": "", + "texture": "", + "tiled": false, + "topMargin": 0, + "type": "PanelSpriteObject::PanelSprite", + "width": 32, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "Tween", + "type": "Tween::TweenBehavior" + } + ] + }, + { + "assetStoreId": "", + "bottomMargin": 0, + "height": 32, + "leftMargin": 0, + "name": "Pressed", + "rightMargin": 0, + "tags": "", + "texture": "", + "tiled": false, + "topMargin": 0, + "type": "PanelSpriteObject::PanelSprite", + "width": 32, + "variables": [], + "effects": [], + "behaviors": [] + } + ] + } + ] + }, + { + "author": "@Bouh", + "category": "User interface", + "extensionNamespace": "", + "fullName": "Time formatting", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWNsb2NrLWRpZ2l0YWwiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMiw2QTIsMiAwIDAsMCAwLDhWMTZBMiwyIDAgMCwwIDIsMThIMjJBMiwyIDAgMCwwIDI0LDE2VjhBMiwyIDAgMCwwIDIyLDZNMiw4SDIyVjE2SDJNMyw5VjEwLjVINi4yNUwzLDE1SDQuNzVMOCwxMC41VjlNOS4yNSw5VjEwLjVIMTAuNzVWOU0xMiw5VjEwLjVIMTMuNVYxNUgxNVY5TTE3LDlBMSwxIDAgMCwwIDE2LDEwVjE0QTEsMSAwIDAsMCAxNywxNUgyMEExLDEgMCAwLDAgMjEsMTRWMTBBMSwxIDAgMCwwIDIwLDlNMTcuNSwxMC41SDE5LjVWMTMuNUgxNy41TTkuMjUsMTMuNVYxNUgxMC43NVYxMy41IiAvPjwvc3ZnPg==", + "name": "TimeFormatter", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/clock-digital.svg", + "shortDescription": "Converts seconds into standard time formats, such as HH:MM:SS. ", + "version": "0.0.2", + "description": [ + "Ideal for displaying timers on screen.", + "", + "Formats included:", + "* HH:MM:SS", + "* HH:MM:SS.000 (displays milliseconds)" + ], + "origin": { + "identifier": "TimeFormatter", + "name": "gdevelop-extension-store" + }, + "tags": [ + "time", + "timer", + "format", + "hours", + "minutes", + "seconds", + "milliseconds" + ], + "authorIds": [ + "2OwwM8ToR9dx9RJ2sAKTcrLmCB92" + ], + "dependencies": [], + "eventsFunctions": [ + { + "description": "Format time in seconds to HH:MM:SS.", + "fullName": "Format time in seconds to HH:MM:SS", + "functionType": "StringExpression", + "name": "SecondsToHHMMSS", + "sentence": "Format time _PARAM1_ to HH:MM:SS in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "var format_time = function (time_second) {\r", + " date = new Date(null);\r", + " date.setSeconds(time_second);\r", + " if (time_second >= 3600) {\r", + " return date.toISOString().substr(11, 8); // MM:SS\r", + " } else {\r", + " return date.toISOString().substr(14, 5); // HH:MM:SS\r", + " }\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = format_time(eventsFunctionContext.getArgument(\"TimeInSeconds\"));" + ], + "parameterObjects": "", + "useStrict": false, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Time, in seconds", + "name": "TimeInSeconds", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Format time in seconds to HH:MM:SS.000, including milliseconds.", + "fullName": "Format time in seconds to HH:MM:SS.000", + "functionType": "StringExpression", + "name": "SecondsToHHMMSS000", + "sentence": "Format time _PARAM1_ to HH:MM:SS in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "var format_time = function (time_second) {\r", + " date = new Date(null);\r", + " date.setMilliseconds(1000*time_second);\r", + " if (time_second >= 3600) {\r", + " return date.toISOString().substr(11, 12); // MM:SS.000\r", + " } else {\r", + " return date.toISOString().substr(14, 9); // HH:MM:SS.000\r", + " }\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = format_time(eventsFunctionContext.getArgument(\"TimeInSeconds\"));" + ], + "parameterObjects": "", + "useStrict": false, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Time, in seconds", + "name": "TimeInSeconds", + "type": "expression" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [], + "eventsBasedObjects": [] + }, + { + "author": "", + "category": "User interface", + "extensionNamespace": "", + "fullName": "Button States", + "helpPath": "/objects/button", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWdlc3R1cmUtdGFwLWJ1dHRvbiIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik0xMyA1QzE1LjIxIDUgMTcgNi43OSAxNyA5QzE3IDEwLjUgMTYuMiAxMS43NyAxNSAxMi40NlYxMS4yNEMxNS42MSAxMC42OSAxNiA5Ljg5IDE2IDlDMTYgNy4zNCAxNC42NiA2IDEzIDZTMTAgNy4zNCAxMCA5QzEwIDkuODkgMTAuMzkgMTAuNjkgMTEgMTEuMjRWMTIuNDZDOS44IDExLjc3IDkgMTAuNSA5IDlDOSA2Ljc5IDEwLjc5IDUgMTMgNU0yMCAyMC41QzE5Ljk3IDIxLjMyIDE5LjMyIDIxLjk3IDE4LjUgMjJIMTNDMTIuNjIgMjIgMTIuMjYgMjEuODUgMTIgMjEuNTdMOCAxNy4zN0w4Ljc0IDE2LjZDOC45MyAxNi4zOSA5LjIgMTYuMjggOS41IDE2LjI4SDkuN0wxMiAxOFY5QzEyIDguNDUgMTIuNDUgOCAxMyA4UzE0IDguNDUgMTQgOVYxMy40N0wxNS4yMSAxMy42TDE5LjE1IDE1Ljc5QzE5LjY4IDE2LjAzIDIwIDE2LjU2IDIwIDE3LjE0VjIwLjVNMjAgMkg0QzIuOSAyIDIgMi45IDIgNFYxMkMyIDEzLjExIDIuOSAxNCA0IDE0SDhWMTJMNCAxMkw0IDRIMjBMMjAgMTJIMThWMTRIMjBWMTMuOTZMMjAuMDQgMTRDMjEuMTMgMTQgMjIgMTMuMDkgMjIgMTJWNEMyMiAyLjkgMjEuMTEgMiAyMCAyWiIgLz48L3N2Zz4=", + "name": "ButtonStates", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/753a9a794bd885058159b7509f06f5a8f67f72decfccb9a1b0efee26f41c3c4c_gesture-tap-button.svg", + "shortDescription": "Use any object as a button.", + "version": "1.0.0", + "description": [ + "Tracks player interaction with an object, including:", + "- hovered", + "- pressed", + "- clicked" + ], + "origin": { + "identifier": "ButtonStates", + "name": "gdevelop-extension-store" + }, + "tags": [ + "ui", + "button", + "fsm" + ], + "authorIds": [ + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "Use objects as buttons.", + "fullName": "Button states", + "name": "ButtonFSM", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Finite state machine", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "The \"Validated\" state only last one frame." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Check position", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Make sure the cursor position is only checked once per frame." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyShouldCheckHovering" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "CollisionPoint" + }, + "parameters": [ + "Object", + "MouseOnlyCursorX(Object.Layer(), 0)", + "MouseOnlyCursorY(Object.Layer(), 0)" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Touches are always pressed, so ShouldCheckHovering doesn't matter." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + }, + { + "type": { + "value": "CollisionPoint" + }, + "parameters": [ + "Object", + "TouchX(Object.Behavior::PropertyTouchId(), Object.Layer(), 0)", + "TouchY(Object.Behavior::PropertyTouchId(), Object.Layer(), 0)" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Handle touch start", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "HasAnyTouchOrMouseStarted" + }, + "parameters": [ + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "StartedTouchOrMouseCount()", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CollisionPoint" + }, + "parameters": [ + "Object", + "TouchX(StartedTouchOrMouseId(Object.Behavior::PropertyIndex()), Object.Layer(), 0)", + "TouchY(StartedTouchOrMouseId(Object.Behavior::PropertyIndex()), Object.Layer(), 0)" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "StartedTouchOrMouseId(Object.Behavior::PropertyIndex())" + ] + }, + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + }, + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Apply position changes", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ButtonStates::ButtonFSM::PropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ButtonStates::ButtonFSM::PropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Handle touch end", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "HasTouchEnded" + }, + "parameters": [ + "", + "Object.Behavior::PropertyTouchId()" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + }, + { + "type": { + "inverted": true, + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onDeActivate", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::ResetState" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Reset the state of the button.", + "fullName": "Reset state", + "functionType": "Action", + "name": "ResetState", + "private": true, + "sentence": "Reset the button state of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + }, + { + "type": { + "value": "ButtonStates::ButtonFSM::SetPropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is not used.", + "fullName": "Is idle", + "functionType": "Condition", + "name": "IsIdle", + "sentence": "_PARAM0_ is idle", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button was just clicked.", + "fullName": "Is clicked", + "functionType": "Condition", + "name": "IsClicked", + "sentence": "_PARAM0_ is clicked", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the cursor is hovered over the button.", + "fullName": "Is hovered", + "functionType": "Condition", + "name": "IsHovered", + "sentence": "_PARAM0_ is hovered", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is either hovered or pressed but not hovered.", + "fullName": "Is focused", + "functionType": "Condition", + "name": "IsFocused", + "sentence": "_PARAM0_ is focused", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is currently being pressed with mouse or touch.", + "fullName": "Is pressed", + "functionType": "Condition", + "name": "IsPressed", + "sentence": "_PARAM0_ is pressed", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is currently being pressed outside with mouse or touch.", + "fullName": "Is held outside", + "functionType": "Condition", + "name": "IsPressedOutside", + "sentence": "_PARAM0_ is held outside", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ButtonStates::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the touch id that is using the button or 0 if none.", + "fullName": "Touch id", + "functionType": "ExpressionAndCondition", + "name": "TouchId", + "sentence": "the touch id", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTouchId()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ButtonStates::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "true", + "type": "Boolean", + "label": "", + "description": "Should check hovering", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ShouldCheckHovering" + }, + { + "value": "Idle", + "type": "Choice", + "label": "State", + "description": "", + "group": "", + "extraInformation": [ + "Idle", + "Hovered", + "PressedInside", + "PressedOutside", + "Validated" + ], + "hidden": true, + "name": "State" + }, + { + "value": "0", + "type": "Number", + "label": "Touch id", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TouchId" + }, + { + "value": "", + "type": "Boolean", + "label": "Touch is inside", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TouchIsInside" + }, + { + "value": "", + "type": "Boolean", + "label": "Mouse is inside", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "MouseIsInside" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Index" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "", + "category": "", + "extensionNamespace": "", + "fullName": "Smoothy", + "helpPath": "", + "iconUrl": "", + "name": "Smoothy", + "previewIconUrl": "", + "shortDescription": "", + "version": "", + "description": "Originally automatically extracted from events of the project", + "tags": [], + "authorIds": [], + "dependencies": [], + "eventsFunctions": [ + { + "description": "Create a level according to the \"Levels\" global variable.", + "fullName": "Create level", + "functionType": "Action", + "name": "CreateLevel", + "sentence": "Create level _PARAM1_ with _PARAM2_ and _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "StartLocation", + "Launcher", + "GlobalVariable(Levels[GetArgumentAsNumber(\"Level\")].LauncherX)", + "GlobalVariable(Levels[GetArgumentAsNumber(\"Level\")].LauncherY)", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "index", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "GlobalVariableChildCount(Levels[GetArgumentAsNumber(\"Level\")].Gutters)", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Gutter", + "GlobalVariable(Levels[GetArgumentAsNumber(\"Level\")].Gutters[VariableString(index)].StartX)", + "GlobalVariable(Levels[GetArgumentAsNumber(\"Level\")].Gutters[VariableString(index)].StartY)", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "BubbleQueue", + "-100", + "-100", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::AddOnTop" + }, + "parameters": [ + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + }, + { + "type": { + "value": "Smoothy::GutterBehavior::SetPathName" + }, + "parameters": [ + "Gutter", + "GutterBehavior", + "=", + "\"Gutter\" + VariableString(index)", + "" + ] + }, + { + "type": { + "value": "Smoothy::GutterBehavior::SetIdentifier" + }, + "parameters": [ + "Gutter", + "GutterBehavior", + "=", + "Variable(index)", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::CreatePathFromSvg" + }, + "parameters": [ + "", + "Gutter.GutterBehavior::PathName()", + "GlobalVariableString(Levels[GetArgumentAsNumber(\"Level\")].Gutters[VariableString(index)].Path)", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "StartLocation", + "Spawner", + "Gutter.X()", + "Gutter.Y()", + "" + ] + }, + { + "type": { + "value": "LinkedObjects::LinkObjects" + }, + "parameters": [ + "", + "Spawner", + "Gutter" + ] + }, + { + "type": { + "value": "Smoothy::SpwanerBehavior::SetPathName" + }, + "parameters": [ + "Spawner", + "SpwanerBehavior", + "=", + "Gutter.GutterBehavior::PathName()", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPath" + }, + "parameters": [ + "Spawner", + "SpeedPathMovement", + "Gutter.GutterBehavior::PathName()", + "1", + "", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Spawner" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Gutter" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "BubbleQueue" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "The gutter path is drawn with a shape painter." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::DrawDebug" + }, + "parameters": [ + "Spawner", + "SpeedPathMovement", + "GutterPainter", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "StartLocation", + "Hole", + "GlobalVariable(Levels[GetArgumentAsNumber(\"Level\")].Gutters[VariableString(index)].StartX) + CurvedMovement::PathEndX(Gutter.GutterBehavior::PathName())", + "GlobalVariable(Levels[GetArgumentAsNumber(\"Level\")].Gutters[VariableString(index)].StartY) + CurvedMovement::PathEndY(Gutter.GutterBehavior::PathName())", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "index", + "+", + "1" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Level number", + "name": "Level", + "type": "expression" + }, + { + "description": "Launcher", + "name": "Launcher", + "type": "objectList" + }, + { + "description": "Gutter", + "name": "Gutter", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Gutter behavior", + "name": "GutterBehavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Gutter painter", + "name": "GutterPainter", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "objectList" + }, + { + "description": "Hole", + "name": "Hole", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Spawner", + "name": "Spawner", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Spwaner behavior", + "name": "SpwanerBehavior", + "supplementaryInformation": "Smoothy::SpwanerBehavior", + "type": "behavior" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Movement on a curve", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the inserted bubble matches the color of at least 2 other bubble next to it.", + "fullName": "Match bubbles", + "functionType": "Condition", + "name": "MatchBubbles", + "sentence": "Match bubbles from _PARAM1_ at _PARAM3_ number _PARAM7_ and _PARAM6_ number _PARAM8_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"InsertedBubbleQueueIndex\")", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "GetArgumentAsNumber(\"InsertedBubbleIndex\")", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarSceneTxt" + }, + "parameters": [ + "_SmoothyExtension.BubbleColor", + "=", + "BoardBubble.AnimationName()" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Color: \" + VariableString(_SmoothyExtension.BubbleColor)", + "", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Scan bubbles of the same color toward the head." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "lowerIndex", + "=", + "GetArgumentAsNumber(\"InsertedBubbleIndex\")" + ] + }, + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "False" + ] + } + ] + }, + { + "infiniteLoopWarning": true, + "type": "BuiltinCommonInstructions::While", + "whileConditions": [ + { + "type": { + "value": "SceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "" + ] + }, + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "lowerIndex", + ">", + "0" + ] + } + ], + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "lowerIndex", + "-", + "1" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "Variable(lowerIndex)", + "Variable(lowerIndex)", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "AnimationName" + }, + "parameters": [ + "BoardBubble", + "VariableString(_SmoothyExtension.BubbleColor)" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "True" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "lowerIndex", + "+", + "1" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Scan bubbles of the same color toward the tail." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "upperIndex", + "=", + "GetArgumentAsNumber(\"InsertedBubbleIndex\")" + ] + }, + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "False" + ] + } + ] + }, + { + "infiniteLoopWarning": true, + "type": "BuiltinCommonInstructions::While", + "whileConditions": [ + { + "type": { + "value": "SceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "" + ] + }, + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "upperIndex", + "<", + "BubbleQueue.ObjectStack::Height() - 1" + ] + } + ], + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "upperIndex", + "+", + "1" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "Variable(upperIndex)", + "Variable(upperIndex)", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "AnimationName" + }, + "parameters": [ + "BoardBubble", + "VariableString(_SmoothyExtension.BubbleColor)" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "True" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "upperIndex", + "-", + "1" + ] + } + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "VariableString(lowerIndex) + \" --> \" + VariableString(upperIndex)", + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Move the leading bubbles in a new BubbleQueue.\n\nA new BubbleQueue can't be modified directly because another BubbleQueue is already picked.\nInstead, the leading bubbles are moved into a temporary queue BubbleClipboard." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "Variable(lowerIndex)", + "Variable(upperIndex)", + "" + ] + }, + { + "type": { + "value": "PickedInstancesCount" + }, + "parameters": [ + "BoardBubble", + ">=", + "3" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::Remove" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::MoveInto" + }, + "parameters": [ + "BubbleClipboard", + "ObjectStack", + "0", + "BubbleQueue", + "ObjectStack", + "0", + "Variable(lowerIndex) -1", + "" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadJustSplit" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "// Pick the the matched BoardBubble to handle them in the event sheet. ", + "for (const object of objects) {", + " object.pick = true;", + "}", + "const pickedObjectsLists = eventsFunctionContext.getObjectsLists(\"BoardBubble\");", + "/** @type {Array} */", + "const objectNames = [];", + "pickedObjectsLists.keys(objectNames);", + "for (const objectName of objectNames)", + "{", + " const pickedObjectsList = pickedObjectsLists.get(objectName);", + " gdjs.evtTools.object.filterPickedObjectsList(pickedObjectsList);", + "}", + "" + ], + "parameterObjects": "BoardBubble", + "useStrict": true, + "eventsSheetExpanded": false + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Save the head state." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarSceneTxt" + }, + "parameters": [ + "headState", + "=", + "BubbleQueue.BubbleQueueBehavior::HeadState()" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "headComboLevel", + "=", + "BubbleQueue.BubbleQueueBehavior::HeadComboLevel()" + ] + }, + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "headSplitTimerExists", + "False" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "BubbleQueue", + "\"HeadSplit\"", + ">=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "headSplitTimerExists", + "True" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "headSplitTimerValue", + "=", + "BubbleQueue.ObjectTimerElapsedTime(\"HeadSplit\")" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "When the bubbles are matched at the tail of the queue, the original queue is left empty an must be deleted.\n\nThe tailing queue should never be deleted becausebubble spawn inside it." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::IsEmpty" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "0", + "Gutter.ObjectStack::Height() - 2", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::Remove" + }, + "parameters": [ + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + }, + { + "type": { + "value": "Delete" + }, + "parameters": [ + "BubbleQueue", + "" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Remove the tail part\"", + "", + "" + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Now that no BubbleQueue is picked, a new one can be created." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ObjectStack::ObjectStack::IsEmpty" + }, + "parameters": [ + "BubbleClipboard", + "ObjectStack", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "BubbleQueue", + "-64", + "-64", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::Insert" + }, + "parameters": [ + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"InsertedBubbleQueueIndex\")", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::MoveAllInto" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "0", + "BubbleClipboard", + "ObjectStack", + "" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailJustSplit" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Set back the head state." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadState" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "=", + "VariableString(headState)", + "" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadComboLevel" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "=", + "Variable(headComboLevel)", + "" + ] + }, + { + "type": { + "value": "RemoveObjectTimer" + }, + "parameters": [ + "BubbleQueue", + "\"HeadSplit\"" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "SceneVariableAsBoolean" + }, + "parameters": [ + "headSplitTimerExists", + "True" + ] + } + ], + "actions": [ + { + "type": { + "value": "AdvancedTimer::SetObjectTimerElapsedTime" + }, + "parameters": [ + "", + "=", + "Variable(headSplitTimerValue)", + "BubbleQueue", + "\"HeadSplit\"", + "" + ] + } + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Insert in Gutter\"", + "", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Bubble queue behavior", + "name": "BubbleQueueBehavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Inserted bubble queue index", + "name": "InsertedBubbleQueueIndex", + "type": "expression" + }, + { + "description": "Inserted bubble index", + "name": "InsertedBubbleIndex", + "supplementaryInformation": "Sprite", + "type": "expression" + }, + { + "description": "Bubble clipboard", + "name": "BubbleClipboard", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if there is at least 3 bubbles of the same color at the impact between 2 queues.", + "fullName": "Match bubbles bewteen 2 queues", + "functionType": "Condition", + "name": "MatchBubblesBetween", + "sentence": "Match _PARAM6_ from _PARAM1_ at _PARAM3_ number _PARAM7_ and the bubble queue ahead", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Scan bubbles", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Scan the leading queue." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\") - 1", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarSceneTxt" + }, + "parameters": [ + "bubbleColor", + "=", + "BoardBubble.AnimationName()" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Color: \" + VariableString(bubbleColor)", + "", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Scan bubbles of the same color toward the head." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "lowerIndex", + "=", + "BubbleQueue.ObjectStack::Height()" + ] + }, + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "False" + ] + } + ] + }, + { + "infiniteLoopWarning": true, + "type": "BuiltinCommonInstructions::While", + "whileConditions": [ + { + "type": { + "value": "SceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "" + ] + }, + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "lowerIndex", + ">", + "0" + ] + } + ], + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "lowerIndex", + "-", + "1" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "Variable(lowerIndex)", + "Variable(lowerIndex)", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "AnimationName" + }, + "parameters": [ + "BoardBubble", + "VariableString(bubbleColor)" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "True" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "lowerIndex", + "+", + "1" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "headMatchingBubbleCount", + "=", + "BubbleQueue.ObjectStack::Height() - Variable(lowerIndex)" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Scan the tailling queue." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\")", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Scan bubbles of the same color toward the tail." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "upperIndex", + "=", + "-1" + ] + }, + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "False" + ] + } + ] + }, + { + "infiniteLoopWarning": true, + "type": "BuiltinCommonInstructions::While", + "whileConditions": [ + { + "type": { + "value": "SceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "" + ] + }, + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "upperIndex", + "<", + "BubbleQueue.ObjectStack::Height() - 1" + ] + } + ], + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "upperIndex", + "+", + "1" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "Variable(upperIndex)", + "Variable(upperIndex)", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "AnimationName" + }, + "parameters": [ + "BoardBubble", + "VariableString(bubbleColor)" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetSceneVariableAsBoolean" + }, + "parameters": [ + "foundOtherColor", + "True" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "upperIndex", + "-", + "1" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "tailMatchingBubbleCount", + "=", + "Variable(upperIndex) + 1" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"matchingBubbleCount: \" + VariableString(headMatchingBubbleCount) + \" + \" + VariableString(tailMatchingBubbleCount)", + "", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Remove bubbles", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "headMatchingBubbleCount", + ">", + "0" + ] + }, + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "tailMatchingBubbleCount", + ">", + "0" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Variable(headMatchingBubbleCount) + Variable(tailMatchingBubbleCount)", + ">=", + "3" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\") - 1", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailJustHit" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "Variable(lowerIndex)", + "BubbleQueue.ObjectStack::Height() - 1", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::Remove" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "// Pick the the matched BoardBubble to handle them in the event sheet.", + "gdjs.__SmoothyExtension = gdjs.__SmoothyExtension || {};", + "gdjs.__SmoothyExtension.pickedBubbles = [...objects];", + "" + ], + "parameterObjects": "BoardBubble", + "useStrict": true, + "eventsSheetExpanded": false + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\")", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadJustHit" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "0", + "Variable(upperIndex)", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::Remove" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "// Pick the the matched BoardBubble to handle them in the event sheet.", + "for (const object of gdjs.__SmoothyExtension.pickedBubbles) {", + " object.pick = true;", + "}", + "for (const object of objects) {", + " object.pick = true;", + "}", + "const pickedObjectsLists = eventsFunctionContext.getObjectsLists(\"BoardBubble\");", + "/** @type {Array} */", + "const objectNames = [];", + "pickedObjectsLists.keys(objectNames);", + "for (const objectName of objectNames)", + "{", + " const pickedObjectsList = pickedObjectsLists.get(objectName);", + " gdjs.evtTools.object.filterPickedObjectsList(pickedObjectsList);", + "}", + "" + ], + "parameterObjects": "BoardBubble", + "useStrict": true, + "eventsSheetExpanded": false + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "When the bubbles are matched at the tail of the queue, the original queue is left empty an must be deleted.\n\nThe tailing queue should never be deleted becausebubble spawn inside it." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::IsEmpty" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "0", + "Gutter.ObjectStack::Height() - 2", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::Remove" + }, + "parameters": [ + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + }, + { + "type": { + "value": "Delete" + }, + "parameters": [ + "BubbleQueue", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Bubble queue behavior", + "name": "BubbleQueueBehavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Tailling queue index", + "name": "TaillingQueueIndex", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if 2 queues are colliding with each other.", + "fullName": "Queue collision", + "functionType": "Condition", + "name": "IsQueueColliding", + "sentence": "_PARAM5_ from _PARAM1_ at _PARAM3_ number _PARAM8_ is in collision with the bubble queue ahaed", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "firstBubblePathPosition variable is only used locally to this condition.\n\nIt's set to 0 in case the queue is empty. It can happens for the queue at the beginning of the path because it's never deleted as bubble are spawned inside it." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "firstBubblePathPosition", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\")", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "0", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "firstBubblePathPosition", + "=", + "BoardBubble.SpeedPathMovement::PositionOnPath()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\") - 1", + "" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PositionOnPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "<=", + "Variable(firstBubblePathPosition) + BoardBubble.BoardBubbleBehavior::BubbleSize()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Board bubble behavior", + "name": "BoardBubbleBehavior", + "supplementaryInformation": "Smoothy::BoardBubbleBehavior", + "type": "behavior" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Tailling bubble queue index", + "name": "TaillingQueueIndex", + "supplementaryInformation": "Sprite", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Merge 2 queues. This action is called when 2 queues are colliding.", + "fullName": "Merge queue", + "functionType": "Action", + "name": "MergeQueue", + "sentence": "Merge _PARAM6_ from _PARAM1_ at _PARAM3_ number _PARAM9_ with the bubble queue ahead", + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Merge\"", + "", + "" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Fix the gap", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Get information about the queue positions." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\")", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "0", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "firstBubblePathPosition", + "=", + "BoardBubble.SpeedPathMovement::PositionOnPath()" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "firstBubbleSpeed", + "=", + "BoardBubble.SpeedPathMovement::Speed()" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"firstBubblePathPosition: \" + VariableString(firstBubblePathPosition)", + "", + "" + ] + }, + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"firstBubblePathColor: \" + BoardBubble.AnimationName()", + "", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\") - 1", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "lastBubblePathPosition", + "=", + "BoardBubble.SpeedPathMovement::PositionOnPath()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Fix the gap between the 2 bubble queues." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPositionOnPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "+", + "Variable(firstBubblePathPosition) + BoardBubble.BoardBubbleBehavior::BubbleSize() - Variable(lastBubblePathPosition)", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Variable(firstBubbleSpeed)", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Merge the queues", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\")", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::MoveAllOnTop" + }, + "parameters": [ + "BubbleClipboard", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "ObjectStack" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::Remove" + }, + "parameters": [ + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + }, + { + "type": { + "value": "Delete" + }, + "parameters": [ + "BubbleQueue", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Save the tail state." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarSceneTxt" + }, + "parameters": [ + "tailState", + "=", + "BubbleQueue.BubbleQueueBehavior::TailState()" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "tailComboLevel", + "=", + "BubbleQueue.BubbleQueueBehavior::TailComboLevel()" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "tailSplitTimerValue", + "=", + "-1" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "BubbleQueue", + "\"TimeFromTailImpact\"", + ">=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "tailSplitTimerValue", + "=", + "BubbleQueue.ObjectTimerElapsedTime(\"TimeFromTailImpact\")" + ] + } + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"TaillingQueueIndex\") - 1", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::MoveAllOnTop" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "BubbleClipboard", + "ObjectStack", + "ObjectStack" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetJustMerged" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "VariableString(tailState)", + "Variable(tailComboLevel)", + "Variable(tailSplitTimerValue)", + "" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Bubble queue behavior", + "name": "BubbleQueueBehavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Board bubble behavior", + "name": "BoardBubbleBehavior", + "supplementaryInformation": "Smoothy::BoardBubbleBehavior", + "type": "behavior" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Tailling bubble queue index", + "name": "TaillingQueueIndex", + "type": "expression" + }, + { + "description": "Bubble clipboard", + "name": "BubbleClipboard", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the bubble at 2 end of queues are matching and the leading one must be rewinded.", + "fullName": "Queue match", + "functionType": "Condition", + "name": "IsQueueMatching", + "sentence": "_PARAM5_ from _PARAM1_ at the tail of _PARAM3_ number _PARAM7_ is matching the bubble at the head of the previous queue", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "firstBubbleColor variable is only used locally to this condition." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"LeadingQueueIndex\") + 1", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "0", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarSceneTxt" + }, + "parameters": [ + "firstBubbleColor", + "=", + "BoardBubble.AnimationName()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "GetArgumentAsNumber(\"LeadingQueueIndex\")", + "" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "AnimationName" + }, + "parameters": [ + "BoardBubble", + "VariableString(firstBubbleColor)" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Leading bubble queue index", + "name": "LeadingQueueIndex", + "supplementaryInformation": "Sprite", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the speed necessary to cover a distance according to the deceleration.", + "fullName": "Speed to reach", + "functionType": "Expression", + "name": "SpeedToReach", + "sentence": "Braking distance from an initial speed: _PARAM2_ and a deceleration: _PARAM3_ is less than _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "This system:\n\ntargetedSpeed = initialSpeed + acceleration * t\ndistance = initialSpeed * t + acceleration * t² / 2\n\nallows to find this formula:\n\ninitialSpeed = sqrt(- 2 * distance * acceleration + targetedSpeed²)\n\n" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "GetArgumentAsNumber(\"Distance\")", + ">=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "sqrt(2 * GetArgumentAsNumber(\"Distance\") * GetArgumentAsNumber(\"Deceleration\") + GetArgumentAsNumber(\"TargetedSpeed\") * GetArgumentAsNumber(\"TargetedSpeed\"))" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "GetArgumentAsNumber(\"Distance\")", + "<", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "-sqrt(-2 * GetArgumentAsNumber(\"Distance\") * GetArgumentAsNumber(\"Deceleration\") + GetArgumentAsNumber(\"TargetedSpeed\") * GetArgumentAsNumber(\"TargetedSpeed\"))" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Final distance", + "name": "Distance", + "type": "expression" + }, + { + "description": "Deceleration", + "name": "Deceleration", + "type": "expression" + }, + { + "description": "Targeted speed", + "name": "TargetedSpeed", + "type": "expression" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [ + { + "description": "Animate bubble insertions by pushing leading bubbles from the same queue.", + "fullName": "Inserted bubble", + "name": "InsertedBubbleBehavior", + "objectType": "Sprite", + "eventsFunctions": [ + { + "description": "Initialize the insertion animation.", + "fullName": "Initialize", + "functionType": "Action", + "name": "Initialize", + "sentence": "Initialize the animation of _PARAM0_ for the insertion of _PARAM8_ next to _PARAM6_ in _PARAM4_ of _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "BoardBubble", + "Object", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "abs(AngleDifference(AngleBetweenPositions(BoardBubble.X(), BoardBubble.Y(), MovingBubble.X(), MovingBubble.Y()), BoardBubble.SpeedPathMovement::MovementAngle()))", + ">", + "90" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Insert before the hit bubble instead of after." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "BubbleIndex", + "=", + "BubbleQueue.ObjectStack::HeightOf(BoardBubble) + 1" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "TODO Handle insersion at the tail." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "BubbleIndex", + "<", + "BubbleQueue.ObjectStack::Height()" + ] + } + ], + "actions": [ + { + "type": { + "value": "LinkedObjects::RemoveLinkBetween" + }, + "parameters": [ + "", + "Object", + "BoardBubble" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "AjoutObjConcern" + }, + "parameters": [ + "", + "BoardBubble" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "Variable(BubbleIndex)", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "LinkedObjects::LinkObjects" + }, + "parameters": [ + "", + "Object", + "BoardBubble" + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "BoardBubble", + "Object", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPath" + }, + "parameters": [ + "Object", + "SpeedPathMovement", + "Gutter.GutterBehavior::PathName()", + "1", + "", + "" + ] + }, + { + "type": { + "value": "SeparateFromObjects" + }, + "parameters": [ + "MovingBubble", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "Object", + "MovingBubble.AnimationName()" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "FreedDistance", + "=", + "0" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "InitialDeltaX", + "=", + "MovingBubble.X() - BoardBubble.X()" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "InitialDeltaY", + "=", + "MovingBubble.Y() - BoardBubble.Y()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::InsertedBubbleBehavior", + "type": "behavior" + }, + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Gutter behavior", + "name": "GutterBehavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Moving bubble", + "name": "MovingBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Play the insertion animation. Leading bubbles from the same queue are pushed to make room for the inserted bubble.", + "fullName": "Play insertion animation", + "functionType": "Action", + "name": "PlayInsertion", + "sentence": "Play the insertion animation of _PARAM0_ in _PARAM6_ from _PARAM4_ of _PARAM2_", + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"FreedDistance: \" + Object.VariableString(FreedDistance)", + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "VarObjet" + }, + "parameters": [ + "Object", + "FreedDistance", + "<", + "Object.Behavior::PropertyBubbleSize()" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "PreviousFreedDistance", + "=", + "Object.Variable(FreedDistance)" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "FreedDistance", + "=", + "min(Object.Variable(FreedDistance) + Object.Behavior::PropertyBubbleSize() * TimeDelta() / Object.Behavior::PropertyInsertionDuration(), Object.Behavior::PropertyBubbleSize())" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Move the inserted bubble ahead of the bubble it collides." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "BoardBubble", + "Object", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPositionOnPath" + }, + "parameters": [ + "Object", + "SpeedPathMovement", + "=", + "BoardBubble.SpeedPathMovement::PositionOnPath() + Object.Variable(FreedDistance)", + "" + ] + }, + { + "type": { + "value": "MettreXY" + }, + "parameters": [ + "Object", + "=", + "lerp(BoardBubble.X() + Object.Variable(InitialDeltaX), Object.X(), Object.Variable(FreedDistance) / Object.Behavior::PropertyBubbleSize())", + "=", + "lerp(BoardBubble.Y() + Object.Variable(InitialDeltaY), Object.Y(), Object.Variable(FreedDistance) / Object.Behavior::PropertyBubbleSize())" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "ToString(Object.X()) + \" \" + ToString(Object.Y())", + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "BubbleIndex", + "=", + "BubbleQueue.ObjectStack::HeightOf(BoardBubble)" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"BubbleIndex: \" + Object.VariableString(BubbleIndex)", + "", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Push all the bubbles of the queue head." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "AjoutObjConcern" + }, + "parameters": [ + "", + "BoardBubble" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "0", + "Object.Variable(BubbleIndex) - 1", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPositionOnPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "+", + "Object.Variable(FreedDistance) - Object.Variable(PreviousFreedDistance)", + "" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Push: \" + ToString(PickedInstancesCount(BoardBubble))", + "", + "" + ] + } + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::InsertedBubbleBehavior", + "type": "behavior" + }, + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the insertion animation is finished.", + "fullName": "Animation finished", + "functionType": "Condition", + "name": "IsAnimationFinished", + "sentence": "The insertion animation of _PARAM0_ is finished", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "VarObjet" + }, + "parameters": [ + "Object", + "FreedDistance", + "=", + "Object.Behavior::PropertyBubbleSize()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::InsertedBubbleBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Create a BoardBubble in place of the InsertedBubble in the queue.", + "fullName": "Create bubble", + "functionType": "Action", + "name": "CreateBubble", + "sentence": "Replace _PARAM0_ by a new _PARAM7_ into _PARAM5_ from _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Get the information on the inserted bubble because a BoardBubble can only be initialized when an other BoardBubble is picked." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "BoardBubble", + "Object", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "PositionOnPath", + "=", + "BoardBubble.SpeedPathMovement::PositionOnPath() + Object.Behavior::PropertyBubbleSize()" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "Speed", + "=", + "BoardBubble.SpeedPathMovement::Speed()" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "BubbleIndex", + "=", + "BubbleQueue.ObjectStack::HeightOf(BoardBubble)" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "QueueIndex", + "=", + "Gutter.ObjectStack::HeightOf(BubbleQueue)" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "GutterIdentifier", + "=", + "Gutter.GutterBehavior::Identifier()" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"BubbleIndex: \" + Object.VariableString(BubbleIndex)", + "", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Actually insert the bubble in the queue." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::Identifier" + }, + "parameters": [ + "Gutter", + "GutterBehavior", + "=", + "Object.Variable(GutterIdentifier)", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsBetween" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "Object.Variable(QueueIndex)", + "Object.Variable(QueueIndex)", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "BoardBubble", + "Object.SpeedPathMovement::PathOriginX()", + "Object.SpeedPathMovement::PathOriginY()", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "Gutter.GutterBehavior::PathName()", + "1", + "", + "" + ] + }, + { + "type": { + "value": "SetAnimationName" + }, + "parameters": [ + "BoardBubble", + "Object.AnimationName()" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPositionOnPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Object.Variable(PositionOnPath)", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Object.Variable(Speed)", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::Insert" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "Object.Variable(BubbleIndex)", + "" + ] + }, + { + "type": { + "value": "Delete" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::InsertedBubbleBehavior", + "type": "behavior" + }, + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Gutter behavior", + "name": "GutterBehavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the index of the queue where the bubble was inserted.", + "fullName": "Queue index", + "functionType": "Expression", + "name": "QueueIndex", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Variable(QueueIndex)" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::InsertedBubbleBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the index of the inserted bubble in the queue.", + "fullName": "Bubble index", + "functionType": "Expression", + "name": "BubbleIndex", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Variable(BubbleIndex)" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::InsertedBubbleBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the identifier of the gutter where the bubble is inserted.", + "fullName": "Gutter identifier", + "functionType": "Expression", + "name": "GutterIdentifier", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Variable(GutterIdentifier)" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::InsertedBubbleBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "Behavior", + "label": "Speed path movement", + "description": "", + "group": "", + "extraInformation": [ + "CurvedMovement::SpeedPathMovement" + ], + "hidden": false, + "name": "SpeedPathMovement" + }, + { + "value": "32", + "type": "Number", + "unit": "Pixel", + "label": "Bubble size", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BubbleSize" + }, + { + "value": "0.2", + "type": "Number", + "unit": "Second", + "label": "Insertion duration", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "InsertionDuration" + } + ], + "sharedPropertyDescriptors": [] + }, + { + "description": "Contain bubbles bonded to each other. Each end of the queue has a FSM for the combo movement.", + "fullName": "Bubble queue", + "name": "BubbleQueueBehavior", + "objectType": "", + "eventsFunctions": [ + { + "description": "Update the bubble speed of the queue according to the state of the combo animation.", + "fullName": "Update bubble speed", + "functionType": "Action", + "name": "SetBubblesSpeed", + "sentence": "Update the speed of _PARAM5_ from _PARAM0_ for the rewind animation in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "States are explained in doStepPreEvents." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "Object", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "actions": [], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "ToString(Gutter.ObjectStack::HeightOf(Object)) + \": \" + Object.Behavior::PropertyTailState() + \" - \" + Object.Behavior::PropertyHeadState()", + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Tail state have precedence over head state." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "Object", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "0", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Gutter push" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "Object", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::Speed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "<=", + "Gutter.GutterBehavior::PushSpeed()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::AccelarateAt" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "Gutter.GutterBehavior::PushSpeed()", + "Gutter.GutterBehavior::PushAcceleration()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::Speed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + ">", + "Gutter.GutterBehavior::PushSpeed()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Gutter.GutterBehavior::PushSpeed()", + "" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Push speed: \" + ToString(Gutter.GutterBehavior::PushSpeed())", + "", + "" + ] + } + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Keep the same speed." + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"JustSplit\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"WillMagnet\"" + ] + } + ] + } + ], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"StopOrTaillingPush\"" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "Object", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "0", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "Object", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Gutter.GutterBehavior::PushSpeed()", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeIdle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "0", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeRewind\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "0", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "Object", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::AccelarateAt" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "Gutter.GutterBehavior::PushAcceleration()", + "Gutter.GutterBehavior::PushSpeed()", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RewindImpact\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Object.Behavior::ImpactSpeed(Object.Behavior::PropertyHeadComboLevel())", + "" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Combo level for the head imact: \" + ToString(Object.Behavior::PropertyHeadComboLevel())", + "", + "" + ] + } + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Keep the same speed." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"WillMagnet\"" + ] + } + ], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"JustSplit\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::AccelarateAt" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "0", + "-Gutter.GutterBehavior::PushAcceleration()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"StopOrTaillingPush\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "0", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeRewind\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "0", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopEndBeforeRewind\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Object.Behavior::ImpactSpeed(max(1, Object.Behavior::PropertyTailComboLevel() - 1))", + "" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Set speed for the tail for rewind: \" + ToString(Object.Behavior::ImpactSpeed(max(1, Object.Behavior::PropertyTailComboLevel() - 1)))", + "", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::AccelarateAt" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "-Object.Behavior::PropertyRewindingSpeedMax()", + "-Object.Behavior::PropertyRewindingAcceleration()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RewindImpact\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Object.Behavior::ImpactSpeed(Object.Behavior::PropertyTailComboLevel())", + "" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Set speed for the tail impact: \" + ToString(Object.Behavior::ImpactSpeed(Object.Behavior::PropertyTailComboLevel()))", + "", + "" + ] + } + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Head speed:: \" + ToString(BoardBubble.SpeedPathMovement::Speed())", + "", + "" + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Tail speed:: \" + ToString(BoardBubble.SpeedPathMovement::Speed())", + "", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + }, + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Gutter behavior", + "name": "GutterBehavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Bubble queues have 2 finite state machines:\n- one for the queue tail\n- one for the queue head\n\nAs stated in the SetBubbleSpeed action, the tail state has precedence over the head state to choose the speed.\n\nThe states are the following:\n- Idle, there is no combo animation\n- JustSplit, the queue was split and the magnet check is not yet done or color don't match.\n- WillMagnet, the queues are matching but they keep their current speed during a small delay.\n- HitStopBeforeIdle, at the end of a combo, the queues are stopping for a small amount of time to put emphasis to the animation before starting back to push.\n- HitStopBeforeRewind, the queues are stopping for a small amount of time to put emphasis to the animation.\n- HitStopEndBeforeRewind, the end of the hit stop. The tailing queue start back at the previous impact speed.\n- Rewinding, the leading queue is going backward until it reaches its tailing queue.\n- RewindImpact, the queues are colliding, when combo are chained the tailing queue is given more and more speed at the impact.\n- StopOrTaillingPush, change the speed before going back to the idle state." + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Tail state", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"StopOrTaillingPush\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RewindImpact\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"AfterImpact\"", + "" + ] + }, + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromTailImpact\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopEndBeforeRewind\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromTailImpact\"", + ">=", + "Object.Behavior::PropertyRewindDelay()" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"JustSplit\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"", + "" + ] + }, + { + "type": { + "value": "RemoveObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromTailImpact\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"AfterImpact\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"StopOrTaillingPush\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"WillMagnet\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeRewind\"", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromTailImpact\"", + ">=", + "Object.Behavior::PropertyRewindDelay() + Object.Behavior::PropertyHitStopBeforeRewindDuration()" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeRewind\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopEndBeforeRewind\"", + "" + ] + }, + { + "type": { + "value": "RemoveObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromTailImpact\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "There is no hit-stop before the first rewinding but the total delay is still the same." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"WillMagnet\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "<=", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopEndBeforeRewind\"", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Head state", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"StopOrTaillingPush\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RewindImpact\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"AfterImpact\"", + "" + ] + }, + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromHeadImpact\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromHeadImpact\"", + ">=", + "Object.Behavior::PropertyRewindDelay()" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"AfterImpact\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeIdle\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"WillMagnet\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeRewind\"", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeRewind\"" + ] + }, + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromHeadImpact\"", + ">=", + "Object.Behavior::PropertyRewindDelay() + Object.Behavior::PropertyHitStopBeforeRewindDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"", + "" + ] + }, + { + "type": { + "value": "RemoveObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromHeadImpact\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeIdle\"" + ] + }, + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromHeadImpact\"", + ">=", + "Object.Behavior::PropertyRewindDelay() + Object.Behavior::PropertyHitStopAfterComboDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"", + "" + ] + }, + { + "type": { + "value": "RemoveObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromHeadImpact\"" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the speed to give to the queue when it collides after a rewind.", + "fullName": "Impact speed", + "functionType": "Expression", + "name": "ImpactSpeed", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "max(-Object.Behavior::PropertyImpactSpeedMax(), -Object.Behavior:: PropertyImpactSpeedGain() * GetArgumentAsNumber(\"ComboLevel\"))" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + }, + { + "description": "Combo level", + "name": "ComboLevel", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the state of the tail according to whether its color matches the tailing queue head.", + "fullName": "Tail is matching", + "functionType": "Action", + "name": "SetTailMatching", + "sentence": "_PARAM0_ tail is matching: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldRewind\"" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"AfterImpact\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"JustSplit\"" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"WillMagnet\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + }, + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromTailImpact\"" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Tail combo: \" + ToString(Object.Behavior::TailComboLevel())", + "", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldRewind\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailIdle" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Reset tail combo level\"", + "", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + }, + { + "description": "Should rewind", + "name": "ShouldRewind", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Change the state of the head according to whether its color matches the leading queue tail.", + "fullName": "Head is matching", + "functionType": "Action", + "name": "SetHeadMatching", + "sentence": "_PARAM0_ head is matching: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldRewind\"" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"HitStopBeforeIdle\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"AfterImpact\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"JustSplit\"" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"WillMagnet\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyHeadComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + }, + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromHeadImpact\"" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Head combo: \" + ToString(Object.Behavior::HeadComboLevel())", + "", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldRewind\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyHeadComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadIdle" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Reset head combo level\"", + "", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + }, + { + "description": "Should rewind", + "name": "ShouldRewind", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "fullName": "Tail is matching", + "functionType": "Condition", + "name": "IsTailMatching", + "sentence": "_PARAM0_ tail is matching", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "Head is matching", + "functionType": "Condition", + "name": "IsHeadMatching", + "sentence": "_PARAM0_ head is matching", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the state of the tail when the queue was split because bubbles exploded.", + "fullName": "Tail just split", + "functionType": "Action", + "name": "SetTailJustSplit", + "sentence": "Change tail state of _PARAM0_ to just split", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"JustSplit\"" + ] + }, + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromTailImpact\"" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the state of the head when the queue was split because bubbles exploded.", + "fullName": "Head just split", + "functionType": "Action", + "name": "SetHeadJustSplit", + "sentence": "Change head state of _PARAM0_ to just split", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadIdle" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the state of the tail when the queue collided its tailing queue and bubbles exploded.", + "fullName": "Tail just hit", + "functionType": "Action", + "name": "SetTailJustHit", + "sentence": "Change tail state of _PARAM0_ to just hit", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RewindImpact\"" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Tail just hit\"", + "", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the state of the head when the queue was collided by its leading queue and bubbles exploded.", + "fullName": "Head just hit", + "functionType": "Action", + "name": "SetHeadJustHit", + "sentence": "Change head state of _PARAM0_ to just hit", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RewindImpact\"" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Head just hit\"", + "", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the state of the tail when the queue merge with anothe one.", + "fullName": "Just merged", + "functionType": "Action", + "name": "SetJustMerged", + "sentence": "Change tail state of _PARAM0_ after a merge of a queue with tail state: _PARAM2_, tail combo level: _PARAM3_ and time from tail impact: _PARAM4_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "The leading queue rewind back to the tailing queue and they merged (because there were only 2 bubbles of the same color)." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RewindImpact\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "The tailing queue reached the leading queue and they merged." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Rewinding\"" + ] + }, + { + "type": { + "inverted": true, + "value": "Smoothy::BubbleQueueBehavior::PropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"RewindImpact\"" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Set back the tail state." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"TailState\")", + "" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"TailComboLevel\")", + "" + ] + }, + { + "type": { + "value": "RemoveObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromTailImpact\"" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CompareArgumentAsNumber" + }, + "parameters": [ + "\"TimeFromTailImpact\"", + ">=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "AdvancedTimer::SetObjectTimerElapsedTime" + }, + "parameters": [ + "", + "=", + "GetArgumentAsNumber(\"TimeFromTailImpact\")", + "Object", + "\"TimeFromTailImpact\"", + "" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + }, + { + "description": "Tail state", + "name": "TailState", + "type": "string" + }, + { + "description": "Tail combo level", + "name": "TailComboLevel", + "type": "expression" + }, + { + "description": "Time from tail impact", + "name": "TimeFromTailImpact", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the state of the tail to \"StopOrTaillingPush\" to go back to idle.", + "fullName": "Tail idle", + "functionType": "Action", + "name": "SetTailIdle", + "private": true, + "sentence": "Change tail state of _PARAM0_ to idle", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"StopOrTaillingPush\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "RemoveObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromTailImpact\"" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\" --> Idle\"", + "", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the state of the head to \"StopOrTaillingPush\" to go back to idle.", + "fullName": "Head idle", + "functionType": "Action", + "name": "SetHeadIdle", + "private": true, + "sentence": "Change head state of _PARAM0_ to idle", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"StopOrTaillingPush\"" + ] + }, + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyHeadComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "RemoveObjectTimer" + }, + "parameters": [ + "Object", + "\"TimeFromHeadImpact\"" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the tail state of the queue. It should only be used by this extension when merging or splitting queues.", + "fullName": "Tail state", + "functionType": "ExpressionAndCondition", + "group": "Bubble queue (private)", + "name": "TailState", + "sentence": "the tail state", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "Object.Behavior::PropertyTailState()" + ] + } + ] + } + ], + "expressionType": { + "supplementaryInformation": "[\"Idle\",\"JustSplit\",\"HitStop\",\"HitStopEnd\",\"Rewinding\"]", + "type": "stringWithSelector" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "TailState", + "name": "SetTailState", + "private": true, + "sentence": "", + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Tail: \" + Object. Behavior::PropertyTailState() + \" --> \" + GetArgumentAsString(\"Value\")", + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the head state of the queue. It should only be used by this extension when merging or splitting queues.", + "fullName": "Head state", + "functionType": "ExpressionAndCondition", + "group": "Bubble queue (private)", + "name": "HeadState", + "sentence": "the head state", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "Object.Behavior::PropertyHeadState()" + ] + } + ] + } + ], + "expressionType": { + "supplementaryInformation": "[\"Idle\",\"JustSplit\",\"HitStop\"]", + "type": "stringWithSelector" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "HeadState", + "name": "SetHeadState", + "private": true, + "sentence": "", + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Head: \" + Object. Behavior::PropertyHeadState() + \" --> \" + GetArgumentAsString(\"Value\")", + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyHeadState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the tail combo level.", + "fullName": "Tail combo level", + "functionType": "ExpressionAndCondition", + "name": "TailComboLevel", + "sentence": "the tail combo level", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTailComboLevel()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "TailComboLevel", + "name": "SetTailComboLevel", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyTailComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the head combo level.", + "fullName": "Head combo level", + "functionType": "ExpressionAndCondition", + "name": "HeadComboLevel", + "sentence": "the head combo level", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyHeadComboLevel()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "HeadComboLevel", + "name": "SetHeadComboLevel", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetPropertyHeadComboLevel" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "Idle", + "type": "Choice", + "label": "Tail state", + "description": "", + "group": "", + "extraInformation": [ + "Idle", + "JustSplit", + "StopOrTaillingPush", + "WillMagnet", + "HitStop", + "HitStopEnd", + "Rewinding", + "RewindImpact" + ], + "hidden": true, + "name": "TailState" + }, + { + "value": "Idle", + "type": "Choice", + "label": "Head state", + "description": "", + "group": "", + "extraInformation": [ + "Idle", + "JustSplit", + "StopOrTaillingPush", + "WillMagnet", + "HitStop", + "Rewinding", + "RewindImpact" + ], + "hidden": true, + "name": "HeadState" + }, + { + "value": "0", + "type": "Number", + "unit": "Dimensionless", + "label": "Tail combo level", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TailComboLevel" + }, + { + "value": "0", + "type": "Number", + "unit": "Dimensionless", + "label": "Head combo level", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "HeadComboLevel" + }, + { + "value": "444", + "type": "Number", + "unit": "PixelSpeed", + "label": "Rewinding maximum speed", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "RewindingSpeedMax" + }, + { + "value": "1333", + "type": "Number", + "unit": "PixelAcceleration", + "label": "Rewinding acceleration", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "RewindingAcceleration" + }, + { + "value": "0.3", + "type": "Number", + "unit": "Second", + "label": "Rewind delay", + "description": "Before the hit-stop", + "group": "Hit-stop", + "extraInformation": [], + "hidden": false, + "name": "RewindDelay" + }, + { + "value": "0.1", + "type": "Number", + "unit": "Second", + "label": "Hit-stop duration before rewinding", + "description": "", + "group": "Hit-stop", + "extraInformation": [], + "hidden": false, + "name": "HitStopBeforeRewindDuration" + }, + { + "value": "0.4", + "type": "Number", + "unit": "Second", + "label": "Hit-stop at the end of a combo", + "description": "", + "group": "Hit-stop", + "extraInformation": [], + "hidden": false, + "name": "HitStopAfterComboDuration" + }, + { + "value": "133.3", + "type": "Number", + "unit": "PixelSpeed", + "label": "Impact speed gain at each combo level", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "ImpactSpeedGain" + }, + { + "value": "400", + "type": "Number", + "unit": "PixelSpeed", + "label": "Impact speed maximum", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "ImpactSpeedMax" + } + ], + "sharedPropertyDescriptors": [] + }, + { + "description": "Generate bubbles to add in its gutter.", + "fullName": "Spawner", + "name": "SpwanerBehavior", + "objectType": "", + "eventsFunctions": [ + { + "description": "Create and stack bubbles. Bubbles are created by group of 1 or 2 bubbles of the same color. 2 groups with the same color can follow each other which create a smaller chance of bigger groups.", + "fullName": "Refill", + "functionType": "Action", + "name": "Refill", + "sentence": "Refill _PARAM0_ with _PARAM2_", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Debug", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Enable this event to test the combos." + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::Height" + }, + "parameters": [ + "Object", + "ObjectStack", + "<", + "4", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "index", + "=", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "2", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "4", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "BoardBubble", + "Object.X()", + "Object.Y()", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "BoardBubble", + "Object.X()", + "Object.Y()", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "Object.Behavior::PathName()", + "1", + "", + "" + ] + }, + { + "type": { + "value": "ChangeAnimation" + }, + "parameters": [ + "BoardBubble", + "=", + "Variable(index)" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::Insert" + }, + "parameters": [ + "Object", + "ObjectStack", + "BoardBubble", + "0", + "" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "index", + "+", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "4", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "index", + "-", + "1" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "BoardBubble", + "Object.X()", + "Object.Y()", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "BoardBubble", + "Object.X()", + "Object.Y()", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "Object.Behavior::PathName()", + "1", + "", + "" + ] + }, + { + "type": { + "value": "ChangeAnimation" + }, + "parameters": [ + "BoardBubble", + "=", + "Variable(index)" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::Insert" + }, + "parameters": [ + "Object", + "ObjectStack", + "BoardBubble", + "0", + "" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "infiniteLoopWarning": true, + "type": "BuiltinCommonInstructions::While", + "whileConditions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::Height" + }, + "parameters": [ + "Object", + "ObjectStack", + "<", + "4", + "" + ] + } + ], + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "randomColorIndex", + "=", + "Random(Object.Behavior::ColorCount() - 1)" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "RandomInRange(1, 2)", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "BoardBubble", + "Object.X()", + "Object.Y()", + "\"\"" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "Object.Behavior::PathName()", + "1", + "", + "" + ] + }, + { + "type": { + "value": "ChangeAnimation" + }, + "parameters": [ + "BoardBubble", + "=", + "Variable(randomColorIndex)" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::Insert" + }, + "parameters": [ + "Object", + "ObjectStack", + "BoardBubble", + "0", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::SpwanerBehavior", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if there is enough room at the beginning of the gutter to spawn a new bubble.", + "fullName": "Can spawn bubble", + "functionType": "Condition", + "name": "CanSpawnBubble", + "sentence": "_PARAM0_ can spawn _PARAM6_ into _PARAM4_ of _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "Gutter", + "Object", + "" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PositionOnPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + ">=", + "Object.Behavior::PropertyBubbleSize()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::IsEmpty" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "ObjectStack" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::SpwanerBehavior", + "type": "behavior" + }, + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Spawn a bubble at the gutter beginning.", + "fullName": "Spawn bubble", + "functionType": "Action", + "name": "SpawnBubble", + "sentence": "_PARAM0_ spawn _PARAM7_ into _PARAM5_ of _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::SpwanerBehavior::Refill" + }, + "parameters": [ + "Object", + "Behavior", + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "Gutter", + "Object", + "" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "lastBubblePathPosition", + "=", + "BoardBubble.SpeedPathMovement::PositionOnPath()" + ] + }, + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "lastBubbleSpeed", + "=", + "BoardBubble.SpeedPathMovement::Speed()" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "AjoutObjConcern" + }, + "parameters": [ + "", + "BoardBubble" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::Remove" + }, + "parameters": [ + "Object", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::AddOnTop" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPositionOnPath" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Variable(lastBubblePathPosition) - Object.Behavior::PropertyBubbleSize()", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Variable(lastBubbleSpeed)", + "" + ] + }, + { + "type": { + "value": "Smoothy::SpwanerBehavior::SetSharedPropertySpawnedBubbleCount" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::IsEmpty" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "ObjectStack" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Add the first bubble with some speed because it would have been detected as being rewinding otherwise." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::Remove" + }, + "parameters": [ + "Object", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::AddOnTop" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "Smoothy::SpwanerBehavior::SetSharedPropertySpawnedBubbleCount" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "Gutter.GutterBehavior::PushSpeed()", + "" + ] + } + ] + } + ] + } + ] + }, + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Spawned bubbles: \" + VariableString(SpawnedBubbleCount)", + "", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::SpwanerBehavior", + "type": "behavior" + }, + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Gutter behavior", + "name": "GutterBehavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if a bubble was rewinded to the beginning of the path and should go back inside the spawner.", + "fullName": "Can unspawn bubble", + "functionType": "Condition", + "name": "CanUnspawnBubble", + "sentence": "_PARAM0_ can unspawn _PARAM6_ from _PARAM4_ of _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "Gutter", + "Object", + "" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedOrigin" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::SpwanerBehavior", + "type": "behavior" + }, + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Make a bubble go back inside the spawner. It happens when the bubble was rewinded to the beginning of the gutter.", + "fullName": "Unspawn bubble", + "functionType": "Action", + "name": "UnspawnBubble", + "sentence": "_PARAM0_ unspawn _PARAM7_ from _PARAM5_ of _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "LinkedObjects::PickObjectsLinkedTo" + }, + "parameters": [ + "", + "Gutter", + "Object", + "" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Gutter", + "ObjectStack", + "BubbleQueue", + "" + ] + }, + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::Remove" + }, + "parameters": [ + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ObjectStack::AddOnTop" + }, + "parameters": [ + "Object", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetSpeed" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "=", + "0", + "" + ] + }, + { + "type": { + "value": "Smoothy::SpwanerBehavior::SetSharedPropertySpawnedBubbleCount" + }, + "parameters": [ + "Object", + "Behavior", + "-", + "1" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::SpwanerBehavior", + "type": "behavior" + }, + { + "description": "Gutter", + "name": "Gutter", + "type": "objectList" + }, + { + "description": "Gutter behavior", + "name": "GutterBehavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Object stack", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the number of color that can be spwaned.", + "fullName": "Color count", + "functionType": "ExpressionAndCondition", + "group": "SpwanerBehavior configuration", + "name": "ColorCount", + "sentence": "the color count", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyColorCount()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::SpwanerBehavior::SharedPropertySpawnedBubbleCount" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "Object.Behavior::PropertyFirstNewColorBubbleCount()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyColorCount() + 1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::SpwanerBehavior::SharedPropertySpawnedBubbleCount" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "Object.Behavior::PropertySecondNewColorBubbleCount()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyColorCount() + 2" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::SpwanerBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the path name of the associated gutter.", + "fullName": "Path name", + "functionType": "ExpressionAndCondition", + "group": "SpwanerBehavior configuration", + "name": "PathName", + "sentence": "the path name", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "Object.Behavior::PropertyPathName()" + ] + } + ] + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::SpwanerBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "PathName", + "name": "SetPathName", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::SpwanerBehavior::SetPropertyPathName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::SpwanerBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "Behavior", + "label": "Object stack", + "description": "", + "group": "", + "extraInformation": [ + "ObjectStack::ObjectStack" + ], + "hidden": false, + "name": "ObjectStack" + }, + { + "value": "4", + "type": "Number", + "unit": "Dimensionless", + "label": "Color count", + "description": "", + "group": "Colors", + "extraInformation": [], + "hidden": false, + "name": "ColorCount" + }, + { + "value": "", + "type": "String", + "label": "Path name", + "description": "", + "group": "Colors", + "extraInformation": [], + "hidden": true, + "name": "PathName" + }, + { + "value": "128", + "type": "Number", + "unit": "Dimensionless", + "label": "Spawned bubbles count before 1st new color", + "description": "", + "group": "Colors", + "extraInformation": [], + "hidden": false, + "name": "FirstNewColorBubbleCount" + }, + { + "value": "256", + "type": "Number", + "unit": "Dimensionless", + "label": "Spawned bubbles count before 2nd new color", + "description": "", + "group": "Colors", + "extraInformation": [], + "hidden": false, + "name": "SecondNewColorBubbleCount" + }, + { + "value": "32", + "type": "Number", + "unit": "Pixel", + "label": "Bubble size", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BubbleSize" + } + ], + "sharedPropertyDescriptors": [ + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "SpawnedBubbleCount" + } + ] + }, + { + "description": "Contains bubbles queues and push the queue at the beginning of the gutter.", + "fullName": "Gutter", + "name": "GutterBehavior", + "objectType": "", + "eventsFunctions": [ + { + "description": "Update the position of the leading bubble from the tailing queue. This behavior uses it to choose the push speed.", + "fullName": "Update first head position", + "functionType": "Action", + "name": "UpdateFirstHeadPosition", + "sentence": "Update the position value of the _PARAM4_ at the head of _PARAM2_ from _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::HasOnTop" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BubbleQueue", + "" + ] + }, + { + "type": { + "value": "ObjectStack::Contains" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "0", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::SetPropertyPushingQueueProgression" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "BoardBubble.SpeedPathMovement::PositionOnPath() / CurvedMovement::PathLength(Object.Behavior::PropertyPathName())" + ] + } + ], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Head position: \" + ToString(Object.Behavior::PropertyPushingQueueProgression())", + "", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::PushingQueueProgression" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "Object.Behavior::PropertyBeginningFillRatio()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::SetPropertyIsStartBoostEnabled" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "The PushingQueueProgression property is used to calculate the initial boost speed.\nThis is to make sure the boost doesn't start back to full speed when a match happens during the boost." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::SetPropertyPushingQueueFarestProgression" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(Object.Behavior::PropertyPushingQueueFarestProgression(), Object.Behavior::PropertyPushingQueueProgression())" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the pushing queue progression in the gutter.", + "fullName": "Pushing queue progression", + "functionType": "ExpressionAndCondition", + "name": "PushingQueueProgression", + "sentence": "the pushing queue progression", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyPushingQueueProgression()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if any bubble reach the end of the gutter.", + "fullName": "Bubble reach hole", + "functionType": "Condition", + "name": "IsAnyBubbleReachHole", + "sentence": "_PARAM4_ from _PARAM2_ reach the hole of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BubbleQueue", + "0", + "" + ] + }, + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "0", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedTarget" + }, + "parameters": [ + "BoardBubble", + "SpeedPathMovement", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "type": "objectList" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the bubble color at the end of the queue are matching and update the queues state accordingly.", + "fullName": "Update queue matching status", + "functionType": "Action", + "name": "UpdateMatchingQueue", + "sentence": "Update matching status between _PARAM2_ from _PARAM0_ according to _PARAM5_ colors", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "queueIndex", + "=", + "Object.ObjectStack::Height() - 2" + ] + } + ] + }, + { + "infiniteLoopWarning": true, + "type": "BuiltinCommonInstructions::While", + "whileConditions": [ + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "queueIndex", + ">=", + "0" + ] + } + ], + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::IsQueueMatching" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "Variable(queueIndex)", + "" + ] + } + ], + "actions": [], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Rewind\"", + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BubbleQueue", + "Variable(queueIndex)", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailMatching" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "yes", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BubbleQueue", + "Variable(queueIndex) + 1", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadMatching" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "yes", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "Smoothy::IsQueueMatching" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BubbleQueue", + "ObjectStack", + "BoardBubble", + "SpeedPathMovement", + "Variable(queueIndex)", + "" + ] + } + ], + "actions": [], + "events": [ + { + "disabled": true, + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "DebuggerTools::ConsoleLog" + }, + "parameters": [ + "\"Stop rewind\"", + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BubbleQueue", + "Variable(queueIndex)", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetTailMatching" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "no", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ObjectStack::ContainsAt" + }, + "parameters": [ + "", + "Object", + "ObjectStack", + "BubbleQueue", + "Variable(queueIndex) + 1", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Smoothy::BubbleQueueBehavior::SetHeadMatching" + }, + "parameters": [ + "BubbleQueue", + "BubbleQueueBehavior", + "no", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarScene" + }, + "parameters": [ + "queueIndex", + "-", + "1" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + }, + { + "description": "Bubble queue", + "name": "BubbleQueue", + "type": "objectList" + }, + { + "description": "Bubble queue behavior", + "name": "BubbleQueueBehavior", + "supplementaryInformation": "Smoothy::BubbleQueueBehavior", + "type": "behavior" + }, + { + "description": "Object stack behavior", + "name": "ObjectStack", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Board bubble", + "name": "BoardBubble", + "supplementaryInformation": "Sprite", + "type": "objectList" + }, + { + "description": "Board bubble behavior", + "name": "BoardBubbleBehavior", + "supplementaryInformation": "Smoothy::BoardBubbleBehavior", + "type": "behavior" + }, + { + "description": "Speed path movement", + "name": "SpeedPathMovement", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the path name of the gutter.", + "fullName": "Path name", + "functionType": "ExpressionAndCondition", + "name": "PathName", + "sentence": "the path name", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "Object.Behavior::PropertyPathName()" + ] + } + ] + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "PathName", + "name": "SetPathName", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::SetPropertyPathName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the beginning boost is enabled.", + "fullName": "Beginning boost is enabled", + "functionType": "Condition", + "name": "IsBeginningBostEnabled", + "sentence": "Beginning boost is enabled for _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::PropertyIsStartBoostEnabled" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if bubbles are near to the end of gutter and the push speed should slow down.", + "fullName": "Near death", + "functionType": "Condition", + "name": "IsNearDeath", + "sentence": "_PARAM0_ is near to death", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::PushingQueueProgression" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "Object.Behavior:: PropertyNearDeathLengthRatio()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the identifier of the gutter.", + "fullName": "Identifier", + "functionType": "ExpressionAndCondition", + "group": "Gutter configuration", + "name": "Identifier", + "sentence": "the identifier", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyIdentifier()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Identifier", + "name": "SetIdentifier", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::SetPropertyIdentifier" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the push speed", + "fullName": "Push speed", + "functionType": "ExpressionAndCondition", + "name": "PushSpeed", + "sentence": "the push speed", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::IsBeginningBostEnabled" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ExtendedMath::Map(Object.Behavior::PropertyPushingQueueFarestProgression(), 0, Object.Behavior::PropertyBeginningFillRatio(), Object.Behavior::BoostBeginningSpeed(), Object.Behavior::PropertySafeZoneEndSpeed())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "Smoothy::GutterBehavior::IsBeginningBostEnabled" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::PushingQueueProgression" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "Object.Behavior::PropertySafeZoneEndLengthRatio()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ExtendedMath::Map(Object.Behavior::PropertyPushingQueueProgression(), 0, Object.Behavior::PropertySafeZoneEndLengthRatio(), Object.Behavior::PropertyBeginningSpeed(), Object.Behavior::PropertySafeZoneEndSpeed())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::PushingQueueProgression" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "Object.Behavior::PropertySafeZoneEndLengthRatio()", + "" + ] + }, + { + "type": { + "value": "Smoothy::GutterBehavior::PushingQueueProgression" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "Object.Behavior::PropertyNormalZoneEndLengthRatio()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ExtendedMath::Map(Object.Behavior::PropertyPushingQueueProgression(), Object.Behavior::PropertySafeZoneEndLengthRatio(), Object.Behavior::PropertyNormalZoneEndLengthRatio(), Object.Behavior::PropertySafeZoneEndSpeed(), Object.Behavior::PropertyNormalZoneEndSpeed())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::PushingQueueProgression" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "Object.Behavior::PropertyNormalZoneEndLengthRatio()", + "" + ] + }, + { + "type": { + "value": "Smoothy::GutterBehavior::PushingQueueProgression" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "Object.Behavior::PropertyNearDeathZoneBeginningLengthRatio()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ExtendedMath::Map(Object.Behavior::PropertyPushingQueueProgression(), Object.Behavior::PropertyNormalZoneEndLengthRatio(), Object.Behavior::PropertyNearDeathZoneBeginningLengthRatio(), Object.Behavior::PropertyNormalZoneEndSpeed(), Object.Behavior::PropertyNearDeathZoneBeginningSpeed())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Smoothy::GutterBehavior::PushingQueueProgression" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "Object.Behavior::PropertyNearDeathZoneBeginningLengthRatio()", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ExtendedMath::Map(Object.Behavior::PropertyPushingQueueProgression(), Object.Behavior::PropertyNearDeathZoneBeginningLengthRatio(), 1, Object.Behavior::PropertyNearDeathZoneBeginningSpeed(), Object.Behavior::PropertyEndSpeed())" + ] + } + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the push acceleration", + "fullName": "Push acceleration", + "functionType": "ExpressionAndCondition", + "name": "PushAcceleration", + "sentence": "the push acceleration", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PushSpeed() / Object.Behavior::PropertyAccelerationDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the push deceleration", + "fullName": "Push deceleration", + "functionType": "ExpressionAndCondition", + "name": "PushDeceleration", + "sentence": "the push deceleration", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PushSpeed() / Object.Behavior::PropertyAccelerationDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the speed at the beginning of the game.", + "fullName": "Boost beggining speed", + "functionType": "ExpressionAndCondition", + "name": "BoostBeginningSpeed", + "private": true, + "sentence": "the beginning speed ", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Smoothy::SpeedToReach(Object.Behavior::PropertyBeginningFillRatio() * CurvedMovement::PathLength(Object.Behavior::PathName()), Object.Behavior::PropertyStartBoostDeceleration(), Object.Behavior::PropertyBeginningSpeed())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::GutterBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "Behavior", + "label": "Object stack", + "description": "", + "group": "", + "extraInformation": [ + "ObjectStack::ObjectStack" + ], + "hidden": false, + "name": "ObjectStack" + }, + { + "value": "0", + "type": "Number", + "unit": "Dimensionless", + "label": "Pushing queue progression", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PushingQueueProgression" + }, + { + "value": "", + "type": "String", + "label": "Path name", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathName" + }, + { + "value": "true", + "type": "Boolean", + "label": "Start boost is enabled", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "IsStartBoostEnabled" + }, + { + "value": "64", + "type": "Number", + "unit": "PixelSpeed", + "label": "Beginning push speed", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "BeginningSpeed" + }, + { + "value": "17.8", + "type": "Number", + "unit": "PixelSpeed", + "label": "End push speed", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "EndSpeed" + }, + { + "value": "0", + "type": "Number", + "unit": "Dimensionless", + "label": "Identifier", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Identifier" + }, + { + "value": "2", + "type": "Number", + "unit": "Second", + "label": "Time to get to full speed", + "description": "", + "group": "Acceleration", + "extraInformation": [], + "hidden": false, + "name": "AccelerationDuration" + }, + { + "value": "0.5", + "type": "Number", + "unit": "Dimensionless", + "label": "Beggining fill ratio", + "description": "", + "group": "Start boost", + "extraInformation": [], + "hidden": false, + "name": "BeginningFillRatio" + }, + { + "value": "889", + "type": "Number", + "unit": "PixelAcceleration", + "label": "Start boost deceleration", + "description": "", + "group": "Start boost", + "extraInformation": [], + "hidden": false, + "name": "StartBoostDeceleration" + }, + { + "value": "64", + "type": "Number", + "unit": "PixelSpeed", + "label": "Safe zone end push speed", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "SafeZoneEndSpeed" + }, + { + "value": "0", + "type": "Number", + "label": "Safe zone end length ratio", + "description": "", + "group": "Speed zone", + "extraInformation": [], + "hidden": false, + "name": "SafeZoneEndLengthRatio" + }, + { + "value": "64", + "type": "Number", + "unit": "PixelSpeed", + "label": "Normal zone end push speed", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "NormalZoneEndSpeed" + }, + { + "value": "0.87", + "type": "Number", + "label": "Normal zone end length ratio", + "description": "", + "group": "Speed zone", + "extraInformation": [], + "hidden": false, + "name": "NormalZoneEndLengthRatio" + }, + { + "value": "17.8", + "type": "Number", + "unit": "PixelSpeed", + "label": "Near death zone beginning push speed", + "description": "", + "group": "Speed", + "extraInformation": [], + "hidden": false, + "name": "NearDeathZoneBeginningSpeed" + }, + { + "value": "0.88", + "type": "Number", + "unit": "Dimensionless", + "label": "Near death zone beginning length ratio", + "description": "", + "group": "Speed zone", + "extraInformation": [], + "hidden": false, + "name": "NearDeathZoneBeginningLengthRatio" + }, + { + "value": "0", + "type": "Number", + "unit": "Dimensionless", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PushingQueueFarestProgression" + } + ], + "sharedPropertyDescriptors": [] + }, + { + "description": "Animate explosions.", + "fullName": "Board bubble", + "name": "BoardBubbleBehavior", + "objectType": "Sprite", + "eventsFunctions": [ + { + "description": "Change the particle emmiter color according to the bubble and delete the bubble.", + "fullName": "Explode", + "functionType": "Action", + "name": "Explode", + "sentence": "Explode _PARAM0_ into _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "BubbleExplosion", + "Object.X()", + "Object.Y()", + "" + ] + }, + { + "type": { + "value": "ParticleSystem::ParticleColor1" + }, + "parameters": [ + "BubbleExplosion", + "VariableString(ColorValues[Object.Animation()])" + ] + }, + { + "type": { + "value": "ParticleSystem::ParticleColor2" + }, + "parameters": [ + "BubbleExplosion", + "VariableString(ColorValues[Object.Animation()])" + ] + }, + { + "type": { + "value": "Delete" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BoardBubbleBehavior", + "type": "behavior" + }, + { + "description": "Bubble explosion", + "name": "BubbleExplosion", + "supplementaryInformation": "ParticleSystem::ParticleEmitter", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "the bubble size.", + "fullName": "Bubble size", + "functionType": "ExpressionAndCondition", + "name": "BubbleSize", + "sentence": "the bubble size", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBubbleSize()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Smoothy::BoardBubbleBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "32", + "type": "Number", + "unit": "Pixel", + "label": "Bubble size", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BubbleSize" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "D8H", + "category": "Game mechanic", + "extensionNamespace": "", + "fullName": "Object Stack", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQo8L3N0eWxlPg0KPHBhdGggY2xhc3M9InN0MCIgZD0iTTE4LDI5SDhjLTIuMiwwLTQtMS44LTQtNFY3YzAtMi4yLDEuOC00LDQtNGgxMGMyLjIsMCw0LDEuOCw0LDR2MThDMjIsMjcuMiwyMC4yLDI5LDE4LDI5eiIvPg0KPHBhdGggY2xhc3M9InN0MCIgZD0iTTIyLDYuNGw1LDNjMS45LDEuMSwyLjUsMy42LDEuMyw1LjVMMjIsMjUuNSIvPg0KPHBhdGggY2xhc3M9InN0MCIgZD0iTTI4LDE2bDAuNSwwLjdjMS4zLDEuOCwwLjgsNC4zLTEsNS42bC01LjcsNCIvPg0KPGxpbmUgY2xhc3M9InN0MCIgeDE9IjgiIHkxPSI3IiB4Mj0iOCIgeTI9IjkiLz4NCjxsaW5lIGNsYXNzPSJzdDAiIHgxPSIxOCIgeTE9IjIzIiB4Mj0iMTgiIHkyPSIyNSIvPg0KPHBhdGggY2xhc3M9InN0MCIgZD0iTTEwLjQsMTYuNmMwLjUsMC41LDEuMywwLjUsMS44LDBsMC44LTAuOGwwLjgsMC44YzAuNSwwLjUsMS4zLDAuNSwxLjgsMGMwLjUtMC41LDAuNS0xLjQsMC0xLjlsLTAuOC0wLjhMMTMsMTINCglsLTEuOCwxLjlsLTAuOCwwLjhDOS45LDE1LjIsOS45LDE2LjEsMTAuNCwxNi42eiIvPg0KPGxpbmUgY2xhc3M9InN0MCIgeDE9IjEyIiB5MT0iMjAiIHgyPSIxNCIgeTI9IjIwIi8+DQo8bGluZSBjbGFzcz0ic3QwIiB4MT0iMTMiIHkxPSIxNyIgeDI9IjEzIiB5Mj0iMTkiLz4NCjwvc3ZnPg0K", + "name": "ObjectStack", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/Line Hero Pack/Master/SVG/Videogames/Videogames_cards_game_solitaire_poker_blackjack_casino.svg", + "shortDescription": "An ordered list of objects and a shuffle action.", + "version": "0.1.0", + "description": [ + "It provides:", + "* Actions to modify a stack of objects", + "* Conditions to access the objects of a stack", + "* A shuffle action", + "", + "It can be helpful for:", + "* Card games", + "* Fair randomness (for instance, to create a stack of predetermined bonus and randomize the order they appear)", + "", + "2 examples use it:", + "* A card system demonstration ([open the project online](https://editor.gdevelop.io/?project=example://card-system))", + "* A Klondike solitaire ([open the project online](https://editor.gdevelop.io/?project=example://klondike-solitaire))" + ], + "origin": { + "identifier": "ObjectStack", + "name": "gdevelop-extension-store" + }, + "tags": [ + "card", + "stack", + "pick", + "list", + "queue" + ], + "authorIds": [ + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "dependencies": [], + "eventsFunctions": [ + { + "description": "Check if the stack contains the object between a range. The lower and upper bounds are included.", + "fullName": "Contain between a range", + "functionType": "Condition", + "name": "ContainsBetween", + "sentence": "_PARAM3_ is into the stack of _PARAM1_ between _PARAM4_ and _PARAM5_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const stackBehaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "/** @type {Hashtable} */", + "const stackObjectsLists = eventsFunctionContext.getObjectsLists(\"Object\");", + "/** @type {Hashtable} */", + "const elementObjectsLists = eventsFunctionContext.getObjectsLists(\"Element\");", + "const lowerBound = Math.max(0, eventsFunctionContext.getArgument(\"LowerBound\"));", + "let upperBound = eventsFunctionContext.getArgument(\"UpperBound\");", + "", + "eventsFunctionContext.returnValue = gdjs.evtTools.object.twoListsTest(", + " (stackObject, element, stackBehaviorName) => {", + " const behavior = stackObject.getBehavior(stackBehaviorName);", + " /** @type {gdjs.RuntimeObject[]} */", + " const stack = behavior.objectStack;", + " let found = false;", + " upperBound = Math.min(upperBound, stack.length - 1);", + " for (let i = lowerBound; i <= upperBound && !found; i++) {", + " found = stack[i] === element;", + " }", + " return found;", + " },", + " stackObjectsLists,", + " elementObjectsLists,", + " false,", + " stackBehaviorName", + ");" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Stack", + "name": "Object", + "type": "objectList" + }, + { + "description": "Stack behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Element", + "name": "Element", + "type": "objectList" + }, + { + "description": "Lower bound", + "name": "LowerBound", + "type": "expression" + }, + { + "description": "Upper bound", + "name": "UpperBound", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the stack contains the object at a height.", + "fullName": "Contain at", + "functionType": "Condition", + "name": "ContainsAt", + "sentence": "_PARAM3_ is into the stack of _PARAM1_ at _PARAM4_ ", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const stackBehaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "/** @type {Hashtable} */", + "const stackObjectsLists = eventsFunctionContext.getObjectsLists(\"Object\");", + "/** @type {Hashtable} */", + "const elementObjectsLists = eventsFunctionContext.getObjectsLists(\"Element\");", + "", + "// This code is duplicated from ContainsBetween because the picking wouldn't pass from one function to the other.", + "const lowerBound = Math.max(0, eventsFunctionContext.getArgument(\"Height\"));", + "let upperBound = eventsFunctionContext.getArgument(\"Height\");", + "", + "eventsFunctionContext.returnValue = gdjs.evtTools.object.twoListsTest(", + " (stackObject, element, stackBehaviorName) => {", + " const behavior = stackObject.getBehavior(stackBehaviorName);", + " /** @type {gdjs.RuntimeObject[]} */", + " const stack = behavior.objectStack;", + " let found = false;", + " upperBound = Math.min(upperBound, stack.length - 1);", + " for (let i = lowerBound; i <= upperBound && !found; i++) {", + " found = stack[i] === element;", + " }", + " return found;", + " },", + " stackObjectsLists,", + " elementObjectsLists,", + " false,", + " stackBehaviorName", + ");" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Stack", + "name": "Object", + "type": "objectList" + }, + { + "description": "Stack behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Element", + "name": "Element", + "type": "objectList" + }, + { + "description": "Height", + "name": "Height", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if an object is on the stack top.", + "fullName": "Stack top", + "functionType": "Condition", + "name": "HasOnTop", + "sentence": "_PARAM3_ is on top of the stack of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const stackBehaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "/** @type {Hashtable} */", + "const stackObjectsLists = eventsFunctionContext.getObjectsLists(\"Object\");", + "/** @type {Hashtable} */", + "const elementObjectsLists = eventsFunctionContext.getObjectsLists(\"Element\");", + "", + "eventsFunctionContext.returnValue = gdjs.evtTools.object.twoListsTest(", + " (stackObject, element, stackBehaviorName) => {", + " const behavior = stackObject.getBehavior(stackBehaviorName);", + " /** @type {gdjs.RuntimeObject[]} */", + " const stack = behavior.objectStack;", + " return stack.length > 0 && stack[stack.length - 1] === element;", + " },", + " stackObjectsLists,", + " elementObjectsLists,", + " false,", + " stackBehaviorName", + ");" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Stack", + "name": "Object", + "type": "objectList" + }, + { + "description": "Stack behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Element", + "name": "Element", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the stack contains the object.", + "fullName": "Contain", + "functionType": "Condition", + "name": "Contains", + "sentence": "_PARAM3_ is into the stack of _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const stackBehaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "/** @type {Hashtable} */", + "const stackObjectsLists = eventsFunctionContext.getObjectsLists(\"Object\");", + "/** @type {Hashtable} */", + "const elementObjectsLists = eventsFunctionContext.getObjectsLists(\"Element\");", + "", + "eventsFunctionContext.returnValue = gdjs.evtTools.object.twoListsTest(", + " (stackObject, element, stackBehaviorName) => {", + " const behavior = stackObject.getBehavior(stackBehaviorName);", + " /** @type {Map */", + " const objectSet = behavior.objectSet;", + " return objectSet.has(element);", + " },", + " stackObjectsLists,", + " elementObjectsLists,", + " false,", + " stackBehaviorName", + ");" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Stack", + "name": "Object", + "type": "objectList" + }, + { + "description": "Stack behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Element", + "name": "Element", + "type": "objectList" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [ + { + "description": "Hold an ordered list of objects.", + "fullName": "Object Stack", + "name": "ObjectStack", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "", + "behavior.objectStack = [];", + "// Make contains(), remove() and unicity checks more efficients.", + "behavior.objectSet = new Set();", + "", + "if (!runtimeScene.__allObjectStacks) {", + " runtimeScene.__allObjectStacks = new Set();", + " // Its only use is to have a O(1) check for", + " // deleted objects that have never been in a stack.", + " runtimeScene.__objectStacks_allUsedObjects = new Set();", + " // Remove from deleted objects from stacks.", + " gdjs.registerObjectDeletedFromSceneCallback(function (runtimeScene, obj) {", + " if (runtimeScene.__objectStacks_allUsedObjects.has(obj)) {", + " runtimeScene.__objectStacks_allUsedObjects.delete(obj);", + " for (const behavior of runtimeScene.__allObjectStacks) {", + " /** @type {gdjs.RuntimeObject[]} */", + " const stack = behavior.objectStack;", + " /** @type {Map */", + " const objectSet = behavior.objectSet;", + " if (objectSet.has(obj)) {", + " // There should be only one occurrence, but check the whole array just in case.", + " for (let index = stack.indexOf(obj); index >= 0; index = stack.indexOf(obj, index)) {", + " stack.splice(index, 1);", + " }", + " objectSet.delete(obj);", + " }", + " }", + " }", + " });", + "}", + "runtimeScene.__allObjectStacks.add(behavior);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onDestroy", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "", + "runtimeScene.__allObjectStacks.delete(behavior);", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Add the object on the top of the stack.", + "fullName": "Add on top", + "functionType": "Action", + "name": "AddOnTop", + "sentence": "Add _PARAM2_ on top of the stack of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "const elements = eventsFunctionContext.getObjects(\"Elements\");", + "", + "/** @type {gdjs.RuntimeObject[]} */", + "const stack = behavior.objectStack;", + "/** @type {Map */", + "const objectSet = behavior.objectSet;", + "for (const element of elements) {", + " if (!objectSet.has(element)) {", + " stack.push(element);", + " behavior.objectSet.add(element);", + " runtimeScene.__objectStacks_allUsedObjects.add(element);", + " }", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Object", + "name": "Elements", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Insert the object into the stack.", + "fullName": "Insert into the stack", + "functionType": "Action", + "name": "Insert", + "sentence": "Insert _PARAM2_ into the stack of _PARAM0_ at height: _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "const elements = eventsFunctionContext.getObjects(\"Elements\");", + "const height = eventsFunctionContext.getArgument(\"Height\");", + "", + "/** @type {gdjs.RuntimeObject[]} */", + "const stack = behavior.objectStack;", + "/** @type {Map */", + "const objectSet = behavior.objectSet;", + "if (height < 0 || height > stack.length) {", + " console.error(`Tried to insert in the stack at ${height} where the stack is ${stack.length} height.`);", + " return;", + "}", + "for (const element of elements) {", + " if (!objectSet.has(element)) {", + " stack.splice(height, 0, element);", + " objectSet.add(element);", + " runtimeScene.__objectStacks_allUsedObjects.add(element);", + " }", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Object", + "name": "Elements", + "type": "objectList" + }, + { + "description": "Height", + "name": "Height", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Remove the object from the stack.", + "fullName": "Remove from the stack", + "functionType": "Action", + "name": "Remove", + "sentence": "Remove _PARAM2_ from the stack of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "const elements = eventsFunctionContext.getObjects(\"Elements\");", + "", + "/** @type {gdjs.RuntimeObject[]} */", + "const stack = behavior.objectStack;", + "/** @type {Map */", + "const objectSet = behavior.objectSet;", + "for (const element of elements) {", + " if (objectSet.has(element)) {", + " // The top element is likely to be removed from the stack.", + " // Make its removal O(1)", + " if (element === stack[stack.length - 1]) {", + " stack.pop();", + " }", + " else {", + " const index = stack.indexOf(element);", + " if (index >= 0) {", + " stack.splice(index, 1);", + " }", + " }", + " objectSet.delete(element);", + " }", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Object", + "name": "Elements", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Remove any object from the stack.", + "fullName": "Clear", + "functionType": "Action", + "name": "Clear", + "sentence": "Remove every object of the stack of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "", + "/** @type {gdjs.RuntimeObject[]} */", + "const stack = behavior.objectStack;", + "/** @type {Map */", + "const objectSet = behavior.objectSet;", + "", + "stack.length = 0;", + "objectSet.clear();" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Move the object from a stack into another.", + "fullName": "Move into the stack", + "functionType": "Action", + "name": "MoveInto", + "sentence": "Move the objects of the stack of _PARAM3_ from:_PARAM5_ to:_PARAM6_ into the stack of _PARAM0_ at height: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "const stacks = eventsFunctionContext.getObjects(\"Stack\");", + "const stackBehaviorName = eventsFunctionContext.getBehaviorName(\"StackBehavior\");", + "let insertHeight = eventsFunctionContext.getArgument(\"Height\");", + "const lowerBound = Math.max(0, eventsFunctionContext.getArgument(\"LowerBound\"));", + "let upperBound = eventsFunctionContext.getArgument(\"UpperBound\");", + "", + "if (stacks && stacks.length > 0) {", + " /** @type {gdjs.RuntimeObject[]} */", + " const otherStack = stacks[0].getBehavior(stackBehaviorName).objectStack;", + " /** @type {Map */", + " const otherObjectSet = stacks[0].getBehavior(stackBehaviorName).objectSet;", + " /** @type {gdjs.RuntimeObject[]} */", + " const stack = behavior.objectStack;", + " /** @type {Map */", + " const objectSet = behavior.objectSet;", + " if (insertHeight < 0 || insertHeight > stack.length) {", + " console.error(`Tried to insert in the stack at ${insertHeight} where the stack is ${stack.length} height.`);", + " return;", + " }", + " upperBound = Math.min(upperBound, otherStack.length - 1);", + " for (let height = lowerBound; height <= upperBound; height++) {", + " const insertedElement = otherStack[height];", + " stack.splice(insertHeight, 0, insertedElement);", + " objectSet.add(insertedElement);", + " insertHeight++;", + " }", + " if (lowerBound <= upperBound) {", + " for (let height = lowerBound; height <= upperBound; height++) {", + " otherObjectSet.delete(otherStack[height]);", + " }", + " otherStack.splice(lowerBound, upperBound - lowerBound + 1);", + " }", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Height", + "name": "Height", + "type": "expression" + }, + { + "description": "Stack", + "name": "Stack", + "type": "objectList" + }, + { + "description": "Stack behavior", + "name": "StackBehavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Lower bound", + "name": "LowerBound", + "type": "expression" + }, + { + "description": "Upper bound", + "name": "UpperBound", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Move all the object from a stack into another.", + "fullName": "Move all into the stack", + "functionType": "Action", + "name": "MoveAllInto", + "sentence": "Move all the objects of the stack of _PARAM3_ into the stack of _PARAM0_ at height: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::MoveInto" + }, + "parameters": [ + "Object", + "Behavior", + "GetArgumentAsNumber(\"Height\")", + "Stack", + "StackBehavior", + "0", + "Stack.StackBehavior::Height() - 1", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Height", + "name": "Height", + "type": "expression" + }, + { + "description": "Stack", + "name": "Stack", + "type": "objectList" + }, + { + "description": "Stack behavior", + "name": "StackBehavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Move all the object from a stack into another one at the top.", + "fullName": "Move all on top of the stack", + "functionType": "Action", + "name": "MoveAllOnTop", + "sentence": "Move all the objects of the stack of _PARAM2_ on the top of the stack of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ObjectStack::ObjectStack::MoveInto" + }, + "parameters": [ + "Object", + "Behavior", + "Object.Behavior::Height()", + "Stack", + "StackBehavior", + "0", + "Stack.StackBehavior::Height() - 1", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Stack", + "name": "Stack", + "type": "objectList" + }, + { + "description": "Stack behavior", + "name": "StackBehavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Shuffle the stack.", + "fullName": "Shuffle", + "functionType": "Action", + "name": "Shuffle", + "sentence": "Shuffle the stack of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "", + "/** @type {gdjs.RuntimeObject[]} */", + "const stack = behavior.objectStack;", + "", + "// Fisher–Yates shuffle", + "for (let i = stack.length - 1; i >= 1; i--) {", + " // TODO use a seed", + " const j = Math.floor(Math.random() * (i + 1));", + " const swap = stack[i];", + " stack[i] = stack[j]", + " stack[j] = swap;", + "}" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "The height of an element in the stack.", + "fullName": "Height of a stack element", + "functionType": "Expression", + "name": "HeightOf", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = objects[0].getBehavior(behaviorName);", + "const elements = eventsFunctionContext.getObjects(\"Elements\");", + "", + "/** @type {gdjs.RuntimeObject[]} */", + "const stack = behavior.objectStack;", + "eventsFunctionContext.returnValue = stack.indexOf(elements[0]);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Object", + "name": "Elements", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "the number of objects in the stack.", + "fullName": "Stack height", + "functionType": "ExpressionAndCondition", + "name": "Height", + "sentence": "the number of objects in the stack", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = objects[0].getBehavior(behaviorName);", + "", + "/** @type {gdjs.RuntimeObject[]} */", + "const stack = behavior.objectStack;", + "eventsFunctionContext.returnValue = stack.length;", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Compare the number of objects in the stack.", + "fullName": "Stack height (deprecated)", + "functionType": "Condition", + "name": "CheckHeight", + "private": true, + "sentence": "_PARAM0_ has _PARAM2_ objects in its stack", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = objects[0].getBehavior(behaviorName);", + "const height = eventsFunctionContext.getArgument(\"Height\");", + "", + "/** @type {gdjs.RuntimeObject[]} */", + "const stack = behavior.objectStack;", + "eventsFunctionContext.returnValue = stack.length === height;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + }, + { + "description": "Stack height", + "name": "Height", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the stack is empty.", + "fullName": "Is empty", + "functionType": "Condition", + "name": "IsEmpty", + "sentence": "The stack of _PARAM0_ is empty", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "", + "/** @type {gdjs.RuntimeObject[]} */", + "const stack = behavior.objectStack;", + "eventsFunctionContext.returnValue = stack.length === 0;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ObjectStack::ObjectStack", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "", + "category": "Movement", + "extensionNamespace": "", + "fullName": "Curved movement", + "helpPath": "/extensions/curved-movement/details/", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQoJLnN0MXtmaWxsOm5vbmU7c3Ryb2tlOiMwMDAwMDA7c3Ryb2tlLXdpZHRoOjI7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO30NCgkuc3Qye2ZpbGw6bm9uZTtzdHJva2U6IzAwMDAwMDtzdHJva2Utd2lkdGg6MjtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLWRhc2hhcnJheTo2LDY7fQ0KCS5zdDN7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtZGFzaGFycmF5OjQsNDt9DQoJLnN0NHtmaWxsOm5vbmU7c3Ryb2tlOiMwMDAwMDA7c3Ryb2tlLXdpZHRoOjI7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7fQ0KCS5zdDV7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1kYXNoYXJyYXk6My4xMDgxLDMuMTA4MTt9DQoJDQoJCS5zdDZ7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDtzdHJva2UtZGFzaGFycmF5OjQsMzt9DQo8L3N0eWxlPg0KPHJlY3QgeD0iMyIgeT0iMjUiIGNsYXNzPSJzdDAiIHdpZHRoPSI0IiBoZWlnaHQ9IjQiLz4NCjxyZWN0IHg9IjI1IiB5PSIzIiBjbGFzcz0ic3QwIiB3aWR0aD0iNCIgaGVpZ2h0PSI0Ii8+DQo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjUsNUwyNSw1QzE0LDUsNSwxNCw1LDI1djAiLz4NCjwvc3ZnPg0K", + "name": "CurvedMovement", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/Line Hero Pack/Master/SVG/Graphic Design/Graphic Design_bezier_curve.svg", + "shortDescription": "Move objects on curved paths.", + "version": "1.0.4", + "description": [ + "This extension allows to move objects on Bézier curve paths.", + "- Paths can be built dynamically or from predetermined paths in SVG format.", + "- A behavior moves objects in a given duration a bit like the Tween extension does.", + "- Another behavior moves objects using a speed and an acceleration.", + "- Expressions give access to the path trajectory values for more complex movements.", + "", + "This extension can be used to:", + "- Move enemies that follow a pattern", + "- Animate decorations", + "", + "A collection of [small examples](https://editor.gdevelop.io/?project=example://curved-movement) show how to use this extension." + ], + "origin": { + "identifier": "CurvedMovement", + "name": "gdevelop-extension-store" + }, + "tags": [ + "bezier", + "curve", + "path", + "movement", + "animate", + "animation", + "smooth" + ], + "authorIds": [ + "AX15J5TSnpSLUglk4nQVamviftr2", + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "dependencies": [], + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onFirstSceneLoaded", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::DefineHelperClasses" + }, + "parameters": [ + "", + "" + ] + } + ] + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "Define helper classes JavaScript code.", + "fullName": "Define helper classes", + "functionType": "Action", + "name": "DefineHelperClasses", + "private": true, + "sentence": "Define helper classes JavaScript code", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/**", + " * @param {number[]} array ", + " * @param {number} value", + " */", + "const findLowerIndex = function (array, value) {", + " let low = 0;", + " let high = array.length - 1;", + " let index = 0;", + " while (low < high) {", + " index = low + (((high - low) / 2) | 0);", + " if (array[index] < value) {", + " low = index + 1;", + " } else {", + " high = index;", + " }", + " }", + " if (array[index] > value) {", + " index--;", + " }", + " return index;", + "};", + "", + "const CurvedPath = /** @class */ (function () {", + " /**", + " * @param {number} speedScaleY Set it to 0.5 for pixel isometry.", + " */", + " function CurvedPath(speedScaleY = 1) {", + " /**", + " * @type {CubicBezierCurve[]}", + " */", + " this.curves = [];", + " /**", + " * @type {number[]}", + " */", + " this.curvePreviousLengths = [0];", + " /**", + " * Set it to 0.5 for pixel isometry.", + " */", + " this.speedScaleY = speedScaleY;", + " };", + "", + " CurvedPath.prototype.getCurvePreviousLengths = function () {", + " if (this.curvePreviousLengths.length === 0) {", + " let lengthSum = 0;", + " this.curvePreviousLengths.push(0);", + " for (const curve of this.curves) {", + " lengthSum += curve.getLength();", + " this.curvePreviousLengths.push(lengthSum);", + " }", + " }", + " return this.curvePreviousLengths;", + " }", + "", + " CurvedPath.prototype.clone = function () {", + " const clone = new CurvedPath();", + " clone.curves = this.curves.map(curve => curve.clone());", + " clone.curvePreviousLengths = [...this.curvePreviousLengths];", + " return clone;", + " };", + "", + " CurvedPath.prototype.getSpeedScaleY = function () {", + " return this.speedScaleY;", + " };", + "", + " /**", + " * @param {number} speedScaleY Set it to 0.5 for pixel isometry.", + " */", + " CurvedPath.prototype.setSpeedScaleY = function (speedScaleY) {", + " if (this.speedScaleY === speedScaleY) {", + " return;", + " }", + " this.scale(1, this.speedScaleY / speedScaleY);", + " this.speedScaleY = speedScaleY;", + " };", + "", + " /**", + " * @param {CubicBezierCurve} curve", + " */", + " CurvedPath.prototype._add = function (curve) {", + " this.curves.push(curve);", + " if (this.curvePreviousLengths.length > 0) {", + " this.curvePreviousLengths.push(this.getLength() + curve.getLength());", + " }", + " };", + "", + " /**", + " * @param {number} firstControlX", + " * @param {number} firstControlY", + " * @param {number} secondControlX", + " * @param {number} secondControlY", + " * @param {number} destinationX", + " * @param {number} destinationY", + " * @param {boolean} isRelative", + " */", + " CurvedPath.prototype.addCurve = function (", + " firstControlX,", + " firstControlY,", + " secondControlX,", + " secondControlY,", + " destinationX,", + " destinationY,", + " isRelative) {", + " const endX = this.getEndX();", + " const endY = this.getEndY();", + " if (isRelative) {", + " firstControlX += endX;", + " firstControlY += endY;", + " secondControlX += endX;", + " secondControlY += endY;", + " destinationX += endX;", + " destinationY += endY;", + " }", + " this._add(new CubicBezierCurve(", + " endX,", + " endY / this.speedScaleY,", + " firstControlX,", + " firstControlY / this.speedScaleY,", + " secondControlX,", + " secondControlY / this.speedScaleY,", + " destinationX,", + " destinationY / this.speedScaleY", + " ));", + " }", + "", + " /**", + " * @param {number} secondControlX", + " * @param {number} secondControlY", + " * @param {number} destinationX", + " * @param {number} destinationY", + " * @param {boolean} isRelative", + " */", + " CurvedPath.prototype.addSmoothCurve = function (", + " secondControlX,", + " secondControlY,", + " destinationX,", + " destinationY,", + " isRelative) {", + " const endX = this.getEndX();", + " const endY = this.getEndY();", + " if (isRelative) {", + " secondControlX += endX;", + " secondControlY += endY;", + " destinationX += endX;", + " destinationY += endY;", + " }", + " const lastControlX = this.getLastControlX();", + " const lastControlY = this.getLastControlY();", + " let firstControlX = 2 * endX - lastControlX;", + " let firstControlY = 2 * endY - lastControlY;", + "", + " this._add(new CubicBezierCurve(", + " endX,", + " endY / this.speedScaleY,", + " firstControlX,", + " firstControlY / this.speedScaleY,", + " secondControlX,", + " secondControlY / this.speedScaleY,", + " destinationX,", + " destinationY / this.speedScaleY", + " ));", + " }", + "", + "", + " /**", + " * @param {number} destinationX", + " * @param {number} destinationY", + " * @param {boolean} isRelative", + " */", + " CurvedPath.prototype.addLine = function (", + " destinationX,", + " destinationY,", + " isRelative) {", + " const endX = this.getEndX();", + " const endY = this.getEndY();", + " if (isRelative) {", + " destinationX += endX;", + " destinationY += endY;", + " }", + " const lengthX = destinationX - endX;", + " const lengthY = destinationY - endY;", + "", + " // TODO Optimize it with an object dedicated to lines.", + " this._add(new CubicBezierCurve(", + " endX,", + " endY / this.speedScaleY,", + " endX + lengthX / 3,", + " (endY + lengthY / 3) / this.speedScaleY,", + " endX + lengthX * 2 / 3,", + " (endY + lengthY * 2 / 3) / this.speedScaleY,", + " destinationX,", + " destinationY / this.speedScaleY", + " ));", + " }", + "", + " CurvedPath.prototype.close = function () {", + " if (this.curves.length === 0) {", + " return;", + " }", + " const firstCurve = this.curves[0];", + " this.addLine(firstCurve.getOriginX(), firstCurve.getOriginY(), false);", + " }", + "", + " /**", + " * @param {CurvedPath} path", + " */", + " CurvedPath.prototype.append = function (path) {", + " const endX = this.getEndX();", + " const endY = this.getEndY();", + " for (const curve of path.curves) {", + " const clone = curve.clone();", + " for (const point of clone.points) {", + " point[0] += endX;", + " point[1] *= path.scaleY / this.speedScaleY;", + " point[1] += endY;", + " }", + " this.add(clone);", + " }", + " };", + "", + " /**", + " * @param {CurvedPath} path", + " * @param {boolean} shouldFlip", + " */", + " CurvedPath.prototype.appendRotatedPath = function (path, shouldFlip) {", + " const startAngle = Math.atan2(path.curves[0].getFirstControlY(), path.curves[0].getFirstControlX());", + " const rotatedPath = path.clone();", + " rotatedPath.rotate(this.getEndAngle() - startAngle);", + " if (shouldFlip) {", + " rotatedPath.flip();", + " }", + " this.append(rotatedPath, false);", + " };", + "", + " CurvedPath.prototype.clear = function () {", + " this.curves.length = 0;", + " this.curvePreviousLengths.length = 1;", + " this.curvePreviousLengths[0] = 0;", + " };", + "", + " CurvedPath.prototype.getLength = function () {", + " const curvePreviousLengths = this.getCurvePreviousLengths();", + " return curvePreviousLengths[curvePreviousLengths.length - 1];", + " };", + "", + " CurvedPath.prototype.isClosed = function () {", + " if (this.curves.length === 0) {", + " return true;", + " }", + " const firstCurve = this.curves[0];", + " const lastCurve = this.curves[this.curves.length - 1];", + " return firstCurve.getOriginX() === lastCurve.getTargetX() &&", + " firstCurve.getOriginY() === lastCurve.getTargetY();", + " };", + "", + " /**", + " * @param {number} length", + " */", + " CurvedPath.prototype.getCurveIndex = function (length) {", + " const curvePreviousLengths = this.getCurvePreviousLengths();", + " return Math.min(this.curves.length - 1, findLowerIndex(curvePreviousLengths, length));", + " };", + "", + " /**", + " * @param {number} length", + " */", + " CurvedPath.prototype.getX = function (length) {", + " const curvePreviousLengths = this.getCurvePreviousLengths();", + " if (length >= this.getLength()) {", + " return this.getEndX();", + " }", + " const curveIndex = this.getCurveIndex(length);", + " const curve = this.curves[curveIndex];", + " const curveStartLength = curvePreviousLengths[curveIndex];", + " const u = (length - curveStartLength) / curve.getLength();", + " return curve.getX(u);", + " };", + "", + " /**", + " * @param {number} length", + " */", + " CurvedPath.prototype.getY = function (length) {", + " const curvePreviousLengths = this.getCurvePreviousLengths();", + " if (length >= this.getLength()) {", + " return this.getEndY();", + " }", + " const curveIndex = this.getCurveIndex(length);", + " const curve = this.curves[curveIndex];", + " const curveStartLength = curvePreviousLengths[curveIndex];", + " const u = (length - curveStartLength) / curve.getLength();", + " return curve.getY(u) * this.speedScaleY;", + " };", + "", + " const workingPoint = [0, 0];", + " /**", + " * @param {number} length", + " * @param {gdjs.AffineTransformation} transformation", + " * @param {[number, number]} transformation", + " */", + " CurvedPath.prototype.getTransformedPosition = function (length, transformation, result) {", + " if (!result) {", + " result = workingPoint;", + " }", + " const curvePreviousLengths = this.getCurvePreviousLengths();", + " if (length >= this.getLength()) {", + " result[0] = this.getEndX();", + " result[1] = this.getEndY();", + " }", + " else {", + " const curveIndex = this.getCurveIndex(length);", + " const curve = this.curves[curveIndex];", + " const curveStartLength = curvePreviousLengths[curveIndex];", + " const u = (length - curveStartLength) / curve.getLength();", + " result[0] = curve.getX(u);", + " result[1] = curve.getY(u);", + " }", + " transformation.transform(result, result);", + " result[1] *= this.speedScaleY;", + " return result;", + " };", + "", + " /**", + " * @param {number} x", + " * @param {number} y", + " * @param {gdjs.AffineTransformation} transformation", + " * @param {[number, number]} transformation", + " */", + " CurvedPath.prototype.transformPosition = function (x, y, transformation, result) {", + " if (!result) {", + " result = workingPoint;", + " }", + " result[0] = x;", + " result[1] = y / this.speedScaleY;", + " transformation.transform(result, result);", + " result[1] *= this.speedScaleY;", + " return result;", + " };", + "", + " /**", + " * @param {number} length", + " */", + " CurvedPath.prototype.getAngle = function (length) {", + " const curvePreviousLengths = this.getCurvePreviousLengths();", + " if (this.curves.length === 0) {", + " return 0;", + " }", + " const curveIndex = this.getCurveIndex(length);", + " const curve = this.curves[curveIndex];", + " const curveStartLength = curvePreviousLengths[curveIndex];", + " const u = (length - curveStartLength) / curve.getLength();", + " return curve.getAngle(u);", + " };", + "", + " CurvedPath.prototype.getOriginX = function (curveIndex) {", + " return this.curves.length === 0 ? 0 : this.curves[curveIndex].getOriginX();", + " };", + "", + " CurvedPath.prototype.getOriginY = function (curveIndex) {", + " return this.curves.length === 0 ? 0 : this.curves[curveIndex].getOriginY() * this.speedScaleY;", + " };", + "", + " CurvedPath.prototype.getFirstControlX = function (curveIndex) {", + " return this.curves.length === 0 ? 0 : this.curves[curveIndex].getFirstControlX();", + " };", + "", + " CurvedPath.prototype.getFirstControlY = function (curveIndex) {", + " return this.curves.length === 0 ? 0 : this.curves[curveIndex].getFirstControlY() * this.speedScaleY;", + " };", + "", + " CurvedPath.prototype.getSecondControlX = function (curveIndex) {", + " return this.curves.length === 0 ? 0 : this.curves[curveIndex].getSecondControlX();", + " };", + "", + " CurvedPath.prototype.getSecondControlY = function (curveIndex) {", + " return this.curves.length === 0 ? 0 : this.curves[curveIndex].getSecondControlY() * this.speedScaleY;", + " };", + "", + " CurvedPath.prototype.getTargetX = function (curveIndex) {", + " return this.curves.length === 0 ? 0 : this.curves[curveIndex].getTargetX();", + " };", + "", + " CurvedPath.prototype.getTargetY = function (curveIndex) {", + " return this.curves.length === 0 ? 0 : this.curves[curveIndex].getTargetY() * this.speedScaleY;", + " };", + "", + " CurvedPath.prototype.getLastControlX = function () {", + " return this.getSecondControlX(this.curves.length - 1);", + " };", + "", + " CurvedPath.prototype.getLastControlY = function () {", + " return this.getSecondControlY(this.curves.length - 1);", + " };", + "", + " CurvedPath.prototype.getEndX = function () {", + " return this.getTargetX(this.curves.length - 1);", + " };", + "", + " CurvedPath.prototype.getEndY = function () {", + " return this.getTargetY(this.curves.length - 1);", + " };", + "", + " CurvedPath.prototype.getEndAngle = function () {", + " if (this.curves.length === 0) {", + " return 0;", + " }", + " const lastCurve = this.curves[this.curves.length - 1];", + " return Math.atan2(", + " lastCurve.getTargetY() - lastCurve.getSecondControlY(),", + " lastCurve.getTargetX() - lastCurve.getSecondControlX());", + " };", + "", + " /**", + " * @param {number} translationX", + " * @param {number} translationY", + " */", + " CurvedPath.prototype.translate = function (translationX, translationY) {", + " for (const curve of this.curves) {", + " for (const point of curve.points) {", + " point[0] += translationX;", + " point[1] += translationY / this.speedScaleY;", + " }", + " }", + " };", + "", + " /**", + " * @param {number} scaleX", + " * @param {number} scaleY", + " */", + " CurvedPath.prototype.scale = function (scaleX, scaleY) {", + " for (const curve of this.curves) {", + " for (const point of curve.points) {", + " point[0] *= scaleX;", + " point[1] *= scaleY;", + " }", + " curve.arcLengths.length = 0;", + " }", + " this.curvePreviousLengths.length = 0;", + " };", + "", + " /**", + " * @param {number} angle", + " */", + " CurvedPath.prototype.rotate = function (angle) {", + " const cos = Math.cos(angle);", + " const sin = Math.sin(angle);", + " for (const curve of this.curves) {", + " for (const point of curve.points) {", + " const x = point[0];", + " const y = point[1];", + " point[0] = x * cos - y * sin;", + " point[1] = x * sin + y * cos;", + " }", + " curve.arcLengths.length = 0;", + " }", + " this.curvePreviousLengths.length = 0;", + " };", + "", + " CurvedPath.prototype.invert = function () {", + " const endX = this.getEndX();", + " const endY = this.getEndY();", + " for (const curve of this.curves) {", + " for (const point of curve.points) {", + " point[0] = point[0] - endX;", + " point[1] = point[1] - endY;", + " }", + " curve.points.reverse();", + " curve.arcLengths.length = 0;", + " }", + " this.curves.reverse();", + " this.curvePreviousLengths.length = 0;", + " };", + "", + " /**", + " * Do a symetry around the first control vector.", + " */", + " CurvedPath.prototype.flip = function () {", + " const axisX = this.curves[0].getFirstControlX();", + " const axisY = this.curves[0].getFirstControlY();", + " const axisLength = Math.hypot(axisX, axisY);", + " const ux = axisX / axisLength;", + " const uy = axisY / axisLength;", + "", + " const sx = 2 * ux * ux - 1;", + " const sy = 2 * uy * uy - 1;", + " const rx = 2 * uy * ux;", + " const ry = rx;", + "", + " for (const curve of this.curves) {", + " for (const point of curve.points) {", + " const x = point[0];", + " const y = point[1];", + " point[0] = x * sx + y * rx;", + " point[1] = x * ry + y * sy;", + " }", + " curve.arcLengths.length = 0;", + " }", + " this.curvePreviousLengths.length = 0;", + " };", + "", + " return CurvedPath;", + "})();", + "", + "/**", + " * @param {number} t", + " * @param {number} a", + " * @param {number} b", + " * @param {number} c", + " * @param {number} d", + " */", + "const interpolateCubicCurve = function (t, a, b, c, d) {", + " return (", + " (1 - t) ** 3 * a +", + " 3 * (1 - t) ** 2 * t * b +", + " 3 * (1 - t) * t ** 2 * c +", + " t ** 3 * d", + " );", + "};", + "/**", + " * @param {number} t", + " * @param {number} a", + " * @param {number} b", + " * @param {number} c", + " * @param {number} d", + " */", + "const interpolateCubicCurveDirection = function (t, a, b, c, d) {", + " return (", + " 3 * (1 - t) ** 2 * (b - a) +", + " 6 * (1 - t) * t * (c - b) +", + " 3 * t ** 2 * (d - c)", + " );", + "};", + "", + "", + "const CubicBezierCurve = /** @class */ (function () {", + " /**", + " * @param {number} aX", + " * @param {number} aY", + " * @param {number} bX", + " * @param {number} bY", + " * @param {number} cX", + " * @param {number} cY", + " * @param {number} dX", + " * @param {number} dY", + " */", + " function CubicBezierCurve(aX, aY, bX, bY, cX, cY, dX, dY) {", + " /** @type {[FloatPoint, FloatPoint, FloatPoint, FloatPoint]} */", + " this.points = [[aX, aY], [bX, bY], [cX, cY], [dX, dY]];", + "", + " /** @type {number[]} */", + " this.arcLengths = [];", + " };", + "", + " CubicBezierCurve.prototype.clone = function () {", + " const clone = new CubicBezierCurve();", + " clone.points = this.points.map(point => [...point]);", + " clone.arcLengths = [...this.arcLengths];", + " return clone;", + " }", + "", + " CubicBezierCurve.prototype.getArcLengths = function () {", + " if (this.arcLengths.length === 0) {", + " const segmentsCount = 100;", + " this.arcLengths.length = segmentsCount + 1;", + " this.arcLengths[0] = 0;", + "", + " const aX = this.points[0][0];", + " const aY = this.points[0][1];", + " const bX = this.points[1][0];", + " const bY = this.points[1][1];", + " const cX = this.points[2][0];", + " const cY = this.points[2][1];", + " const dX = this.points[3][0];", + " const dY = this.points[3][1];", + "", + " let oldX = aX;", + " let oldY = aY;", + " let currentLength = 0;", + " for (let i = 1; i <= segmentsCount; i += 1) {", + " const x = interpolateCubicCurve(i * 0.01, aX, bX, cX, dX);", + " const y = interpolateCubicCurve(i * 0.01, aY, bY, cY, dY);", + " currentLength += Math.hypot(x - oldX, y - oldY);", + " this.arcLengths[i] = currentLength;", + " oldX = x;", + " oldY = y;", + " }", + " }", + " return this.arcLengths;", + " };", + "", + " /**", + " * @param {number} u", + " */", + " CubicBezierCurve.prototype.reparametrizeByArcLength = function (u) {", + " const arcLengths = this.getArcLengths();", + " const segmentsCount = arcLengths.length - 1;", + " const targetLength = u * arcLengths[segmentsCount];", + " const index = findLowerIndex(arcLengths, targetLength);", + "", + " const lengthBefore = arcLengths[index];", + " if (lengthBefore === targetLength) {", + " return index / segmentsCount;", + " } else {", + " return (", + " (index +", + " (targetLength - lengthBefore) /", + " (arcLengths[index + 1] - lengthBefore)) /", + " segmentsCount", + " );", + " }", + " };", + "", + " /**", + " * @param {number} u", + " */", + " CubicBezierCurve.prototype.getX = function (u) {", + " return interpolateCubicCurve(", + " this.reparametrizeByArcLength(u),", + " this.points[0][0],", + " this.points[1][0],", + " this.points[2][0],", + " this.points[3][0]", + " );", + " };", + "", + " /**", + " * @param {number} u", + " */", + " CubicBezierCurve.prototype.getY = function (u) {", + " return interpolateCubicCurve(", + " this.reparametrizeByArcLength(u),", + " this.points[0][1],", + " this.points[1][1],", + " this.points[2][1],", + " this.points[3][1]", + " );", + " };", + "", + " /**", + " * @param {number} u", + " */", + " CubicBezierCurve.prototype.getAngle = function (u) {", + " const t = this.reparametrizeByArcLength(u);", + " const directionX = interpolateCubicCurveDirection(", + " t,", + " this.points[0][0],", + " this.points[1][0],", + " this.points[2][0],", + " this.points[3][0]", + " );", + " const directionY = interpolateCubicCurveDirection(", + " t,", + " this.points[0][1],", + " this.points[1][1],", + " this.points[2][1],", + " this.points[3][1]", + " );", + " return Math.atan2(directionY, directionX);", + " };", + "", + " CubicBezierCurve.prototype.getLength = function () {", + " const arcLengths = this.getArcLengths();", + " return arcLengths[arcLengths.length - 1];", + " };", + "", + " CubicBezierCurve.prototype.getOriginX = function () {", + " return this.points[0][0];", + " };", + "", + " CubicBezierCurve.prototype.getOriginY = function () {", + " return this.points[0][1];", + " };", + "", + " CubicBezierCurve.prototype.getFirstControlX = function () {", + " return this.points[1][0];", + " };", + "", + " CubicBezierCurve.prototype.getFirstControlY = function () {", + " return this.points[1][1];", + " };", + "", + " CubicBezierCurve.prototype.getSecondControlX = function () {", + " return this.points[2][0];", + " };", + "", + " CubicBezierCurve.prototype.getSecondControlY = function () {", + " return this.points[2][1];", + " };", + "", + " CubicBezierCurve.prototype.getTargetX = function () {", + " return this.points[3][0];", + " };", + "", + " CubicBezierCurve.prototype.getTargetY = function () {", + " return this.points[3][1];", + " };", + "", + " return CubicBezierCurve;", + "})();", + "", + "const pathRegex = /[CcSsLlMmHhVvZz]|(?:-?\\d+(?:\\.\\d+)?(?:e-?\\d+)?)/g;", + "const svgActions = [\"c\", \"s\", \"l\", \"m\", \"v\", \"h\", \"z\"];", + "", + "/**", + " * @param {string} svgComandsString", + " */", + "CurvedPath.parsePath = function (svgComandsString) {", + " const regExpResults = svgComandsString.match(pathRegex);", + " if (!regExpResults) {", + " return null;", + " }", + " const path = new CurvedPath();", + " let currentAction = \"\";", + " let isRelative = false;", + " let originX = 0;", + " let originY = 0;", + " for (let index = 0; index < regExpResults.length; index++) {", + " const regExpResult = regExpResults[index];", + " if (regExpResult.length === 1) {", + " const lowerCaseRegExpResult = regExpResult.toLowerCase();", + " if (svgActions.indexOf(lowerCaseRegExpResult) >= 0) {", + " currentAction = lowerCaseRegExpResult;", + " isRelative = lowerCaseRegExpResult === regExpResult;", + " index++;", + " }", + " }", + " switch (currentAction) {", + " case \"c\":", + " {", + " if (regExpResults.length < index + 5) {", + " break;", + " }", + " const firstControlX = Number.parseFloat(regExpResults[index + 0]);", + " const firstControlY = Number.parseFloat(regExpResults[index + 1]);", + " const secondControlX = Number.parseFloat(regExpResults[index + 2]);", + " const secondControlY = Number.parseFloat(regExpResults[index + 3]);", + " const destinationX = Number.parseFloat(regExpResults[index + 4]);", + " const destinationY = Number.parseFloat(regExpResults[index + 5]);", + " index += 5;", + " if (isRelative) {", + " path.addCurve(", + " firstControlX,", + " firstControlY,", + " secondControlX,", + " secondControlY,", + " destinationX,", + " destinationY,", + " isRelative);", + " }", + " else {", + " // Movement paths always start at (0;0).", + " path.addCurve(", + " -originX + firstControlX,", + " -originY + firstControlY,", + " -originX + secondControlX,", + " -originY + secondControlY,", + " -originX + destinationX,", + " -originY + destinationY,", + " isRelative);", + " }", + " break;", + " }", + " case \"s\":", + " {", + " if (regExpResults.length < index + 3) {", + " break;", + " }", + " const secondControlX = Number.parseFloat(regExpResults[index + 0]);", + " const secondControlY = Number.parseFloat(regExpResults[index + 1]);", + " const destinationX = Number.parseFloat(regExpResults[index + 2]);", + " const destinationY = Number.parseFloat(regExpResults[index + 3]);", + " index += 3;", + " if (isRelative) {", + " path.addSmoothCurve(", + " secondControlX,", + " secondControlY,", + " destinationX,", + " destinationY,", + " isRelative);", + " }", + " else {", + " // Movement paths always start at (0;0).", + " path.addSmoothCurve(", + " -originX + secondControlX,", + " -originY + secondControlY,", + " -originX + destinationX,", + " -originY + destinationY,", + " isRelative);", + " }", + " break;", + " }", + " case \"l\":", + " {", + " if (regExpResults.length < index + 1) {", + " break;", + " }", + " const destinationX = Number.parseFloat(regExpResults[index + 0]);", + " const destinationY = Number.parseFloat(regExpResults[index + 1]);", + " index++;", + " if (isRelative) {", + " path.addLine(", + " destinationX,", + " destinationY,", + " isRelative);", + " }", + " else {", + " // Movement paths always start at (0;0).", + " path.addLine(", + " -originX + destinationX,", + " -originY + destinationY,", + " isRelative);", + " }", + " break;", + " }", + " case \"m\":", + " {", + " if (regExpResults.length < index + 1) {", + " break;", + " }", + " if (index === 1) {", + " originX = Number.parseFloat(regExpResults[index + 0]) || 0;", + " originY = Number.parseFloat(regExpResults[index + 1]) || 0;", + " }", + " index++;", + " currentAction = \"l\";", + " break;", + " }", + " case \"h\":", + " {", + " if (regExpResults.length < index) {", + " break;", + " }", + " const destinationX = Number.parseFloat(regExpResults[index + 0]);", + " const destinationY = 0;", + " if (isRelative) {", + " path.addLine(", + " destinationX,", + " destinationY,", + " isRelative);", + " }", + " else {", + " // Movement paths always start at (0;0).", + " path.addLine(", + " -originX + destinationX,", + " -originY + destinationY,", + " isRelative);", + " }", + " break;", + " }", + " case \"v\":", + " {", + " if (regExpResults.length < index) {", + " break;", + " }", + " const destinationX = 0;", + " const destinationY = Number.parseFloat(regExpResults[index + 0]);", + " if (isRelative) {", + " path.addLine(", + " destinationX,", + " destinationY,", + " isRelative);", + " }", + " else {", + " // Movement paths always start at (0;0).", + " path.addLine(", + " -originX + destinationX,", + " -originY + destinationY,", + " isRelative);", + " }", + " break;", + " }", + " case \"z\":", + " {", + " path.close();", + " break;", + " }", + " default:", + " break;", + " }", + " }", + "// if (originX !== 0 && originY !== 0) {", + "// path.translate(-originX, -originY);", + "// path.curves[0].getOriginX = 0;", + "// }", + " return path;", + "}", + "", + "/**", + " * @param {CurvedPath} path", + " */", + "CurvedPath.toSvg = function (path) {", + " let svgString = 'C';", + " for (const curve of path.curves) {", + " for (const point of curve.points) {", + " svgString += `${point[0]},${point[0]}`;", + " }", + " svgString += ' ';", + " }", + " return path;", + "}", + "", + "gdjs.__curvedMovementExtension = gdjs.__curvedMovementExtension || {};", + "gdjs.__curvedMovementExtension.CurvedPath = CurvedPath;", + "", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onSceneLoaded", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {Map} */\r", + "runtimeScene.__curvedMovementExtension = { curvedPaths: new Map() };" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "Append a cubic Bezier curve at the end of the path.", + "fullName": "Append a curve", + "functionType": "Action", + "name": "AddCubicCurve", + "sentence": "Append a curve to the path _PARAM1_ relatively to the end: _PARAM8_, first control point: _PARAM2_ ; _PARAM3_, second control point: _PARAM4_ ; _PARAM5_, destination: _PARAM6_ ; _PARAM7_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let curvedPath = curvedPaths.get(pathName);", + "if (!curvedPath) {", + " curvedPath = new gdjs.__curvedMovementExtension.CurvedPath();", + " curvedPaths.set(pathName, curvedPath);", + "}", + "", + "let firstControlX = eventsFunctionContext.getArgument(\"FirstControlX\");", + "let firstControlY = eventsFunctionContext.getArgument(\"FirstControlY\");", + "let secondControlX = eventsFunctionContext.getArgument(\"SecondControlX\");", + "let secondControlY = eventsFunctionContext.getArgument(\"SecondControlY\");", + "let destinationX = eventsFunctionContext.getArgument(\"DestinationX\");", + "let destinationY = eventsFunctionContext.getArgument(\"DestinationY\");", + "let isRelative = eventsFunctionContext.getArgument(\"IsRelative\");", + "", + "curvedPath.addCurve(", + " firstControlX,", + " firstControlY,", + " secondControlX,", + " secondControlY,", + " destinationX,", + " destinationY,", + " isRelative", + ");", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "First control point X", + "name": "FirstControlX", + "type": "expression" + }, + { + "description": "First control point Y", + "name": "FirstControlY", + "type": "expression" + }, + { + "description": "Second Control point X", + "name": "SecondControlX", + "type": "expression" + }, + { + "description": "Second Control point Y", + "name": "SecondControlY", + "type": "expression" + }, + { + "description": "Destination point X", + "name": "DestinationX", + "type": "expression" + }, + { + "description": "Destination point Y", + "name": "DestinationY", + "type": "expression" + }, + { + "defaultValue": "yes", + "description": "Relative", + "name": "IsRelative", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Append a cubic Bezier curve to the end of an object's path. The first control point is symmetrical to the last control point of the path.", + "fullName": "Append a smooth curve", + "functionType": "Action", + "name": "AddSmoothCubicCurve", + "sentence": "Append a smooth curve to the path _PARAM1_ relatively to the end: _PARAM6_, second control point: _PARAM2_ ; _PARAM3_, destination: _PARAM4_ ; _PARAM5_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let curvedPath = curvedPaths.get(pathName);", + "if (!curvedPath) {", + " curvedPath = new gdjs.__curvedMovementExtension.CurvedPath();", + " curvedPaths.set(pathName, curvedPath);", + "}", + "", + "let secondControlX = eventsFunctionContext.getArgument(\"SecondControlX\");", + "let secondControlY = eventsFunctionContext.getArgument(\"SecondControlY\");", + "let destinationX = eventsFunctionContext.getArgument(\"DestinationX\");", + "let destinationY = eventsFunctionContext.getArgument(\"DestinationY\");", + "let isRelative = eventsFunctionContext.getArgument(\"IsRelative\");", + "", + "curvedPath.addSmoothCurve(", + " secondControlX,", + " secondControlY,", + " destinationX,", + " destinationY,", + " isRelative", + ");", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Second Control point X", + "name": "SecondControlX", + "type": "expression" + }, + { + "description": "Second Control point Y", + "name": "SecondControlY", + "type": "expression" + }, + { + "description": "Destination point X", + "name": "DestinationX", + "type": "expression" + }, + { + "description": "Destination point Y", + "name": "DestinationY", + "type": "expression" + }, + { + "defaultValue": "yes", + "description": "Relative", + "name": "IsRelative", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Append a line at the end of the path.", + "fullName": "Append a line", + "functionType": "Action", + "name": "AddLine", + "sentence": "Append a line to the path _PARAM1_ relatively to the end: _PARAM4_, destination: _PARAM2_ ; _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let curvedPath = curvedPaths.get(pathName);", + "if (!curvedPath) {", + " curvedPath = new gdjs.__curvedMovementExtension.CurvedPath();", + " curvedPaths.set(pathName, curvedPath);", + "}", + "", + "let destinationX = eventsFunctionContext.getArgument(\"DestinationX\");", + "let destinationY = eventsFunctionContext.getArgument(\"DestinationY\");", + "let isRelative = eventsFunctionContext.getArgument(\"IsRelative\");", + "", + "curvedPath.addLine(", + " destinationX,", + " destinationY,", + " isRelative", + ");", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Destination point X", + "name": "DestinationX", + "type": "expression" + }, + { + "description": "Destination point Y", + "name": "DestinationY", + "type": "expression" + }, + { + "defaultValue": "yes", + "description": "Relative", + "name": "IsRelative", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Append a line to close the path.", + "fullName": "Close a path", + "functionType": "Action", + "name": "ClosePath", + "sentence": "Close the path _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let curvedPath = curvedPaths.get(pathName);", + "if (!curvedPath) {", + " curvedPath = new gdjs.__curvedMovementExtension.CurvedPath();", + " curvedPaths.set(pathName, curvedPath);", + "}", + "", + "curvedPath.close();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Create a path from SVG commands, for instance \"M 0,0 C 55,0 100,45 100,100\". Commands are: M = Move, C = Curve, S = Smooth, L = Line. Lower case is for relative positions. The preferred way to build the commands is to use an external SVG editor like Inkscape.", + "fullName": "Create a path from SVG", + "functionType": "Action", + "name": "CreatePathFromSvg", + "sentence": "Create the path _PARAM1_ from the SVG path commands _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "\r", + "const svgCommandsString = eventsFunctionContext.getArgument(\"SvgCommandsString\");\r", + "\r", + "curvedPaths.set(pathName, gdjs.__curvedMovementExtension.CurvedPath.parsePath(svgCommandsString));\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "SVG commands", + "name": "SvgCommandsString", + "supplementaryInformation": "scene", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Return the SVG commands of a path.", + "fullName": "SVG path commands", + "functionType": "StringExpression", + "name": "ToSvg", + "sentence": "Create the path _PARAM1_ from the SVG path commands _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "\r", + "let curvedPath = curvedPaths.get(pathName);\r", + "eventsFunctionContext.returnValue = curvedPath ? gdjs.__curvedMovementExtension.CurvedPath.toSvg(curvedPath) : '';\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Delete a path from the memory.", + "fullName": "Delete a path", + "functionType": "Action", + "name": "DeletePath", + "sentence": "Delete the path: _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "curvedPaths.delete(pathName);", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Append a path to another path.", + "fullName": "Append a path", + "functionType": "Action", + "name": "AppendPath", + "sentence": "Append the path _PARAM2_ to the path _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const modifiedPathName = eventsFunctionContext.getArgument(\"ModifiedPathName\");", + "const addedPathName = eventsFunctionContext.getArgument(\"AddedPathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let addedPath = curvedPaths.get(addedPathName);", + "if (addedPath) {", + " let modifiedPath = curvedPaths.get(modifiedPathName);", + " if (!modifiedPath) {", + " modifiedPath = new gdjs.__curvedMovementExtension.CurvedPath();", + " curvedPaths.set(modifiedPathName, modifiedPath);", + " }", + " modifiedPath.append(addedPath);", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Name of the path to modify", + "name": "ModifiedPathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Name of the path to add to the first one", + "name": "AddedPathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Append a path to another path. The appended path is rotated to have a smooth junction.", + "fullName": "Append a rotated path", + "functionType": "Action", + "name": "AppendRotatedPath", + "sentence": "Append the path _PARAM2_ rotated to connect to the path _PARAM1_ flip: _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const modifiedPathName = eventsFunctionContext.getArgument(\"ModifiedPathName\");", + "const addedPathName = eventsFunctionContext.getArgument(\"AddedPathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let addedPath = curvedPaths.get(addedPathName);", + "if (addedPath) {", + " let modifiedPath = curvedPaths.get(modifiedPathName);", + " if (!modifiedPath) {", + " modifiedPath = new gdjs.__curvedMovementExtension.CurvedPath();", + " curvedPaths.set(modifiedPathName, modifiedPath);", + " }", + " const shouldFlip = eventsFunctionContext.getArgument(\"ShouldFlip\");", + " modifiedPath.appendRotatedPath(addedPath, shouldFlip);", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Name of the path to modify", + "name": "ModifiedPathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Name of the path to add to the first one", + "name": "AddedPathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Flip the appended path", + "name": "ShouldFlip", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Return the speed scale on Y axis. This is used to change the view point of a path (top-dwon or isometry).", + "fullName": "Speed scale Y", + "functionType": "Expression", + "group": "Path transformation", + "name": "SpeedScaleY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "const curvedPath = curvedPaths.get(pathName);", + "eventsFunctionContext.returnValue = curvedPath ? curvedPath.getSpeedScaleY() : 0;", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Change the speed scale on Y axis. This allows to change the view point of a path (top-dwon or isometry).", + "fullName": "Speed scale Y", + "functionType": "Action", + "group": "Path transformation", + "name": "SetSpeedScaleY", + "sentence": "Change the speed scale Y of the path _PARAM1_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let curvedPath = curvedPaths.get(pathName);", + "if (curvedPath) {", + " const scaleY = eventsFunctionContext.getArgument(\"ScaleY\");", + " curvedPath.setSpeedScaleY(scaleY);", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Speed scale on Y axis (0.5 for pixel isometry)", + "name": "ScaleY", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Invert a path, the end becomes the beginning.", + "fullName": "Invert a path", + "functionType": "Action", + "group": "Path transformation", + "name": "InvertPath", + "sentence": "Invert the path _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let curvedPath = curvedPaths.get(pathName);", + "if (curvedPath) {", + " curvedPath.invert();", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Flip a path.", + "fullName": "Flip a path", + "functionType": "Action", + "group": "Path transformation", + "name": "FlipPath", + "private": true, + "sentence": "Flip the path _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let curvedPath = curvedPaths.get(pathName);", + "if (curvedPath) {", + " curvedPath.flip();", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Flip a path horizontally.", + "fullName": "Flip a path horizontally", + "functionType": "Action", + "group": "Path transformation", + "name": "FlipPathX", + "private": true, + "sentence": "Flip the path _PARAM1_ horizontally", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::ScalePath" + }, + "parameters": [ + "", + "\"\"", + "-1", + "1", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Flip a path vertically.", + "fullName": "Flip a path vertically", + "functionType": "Action", + "group": "Path transformation", + "name": "FlipPathY", + "private": true, + "sentence": "Flip the path _PARAM1_ vertically", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::ScalePath" + }, + "parameters": [ + "", + "\"\"", + "1", + "-1", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Scale a path.", + "fullName": "Scale a path", + "functionType": "Action", + "group": "Path transformation", + "name": "ScalePath", + "sentence": "Scale the path _PARAM1_ by _PARAM2_ ; _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let curvedPath = curvedPaths.get(pathName);", + "if (curvedPath) {", + " const scaleX = eventsFunctionContext.getArgument(\"ScaleX\");", + " const scaleY = eventsFunctionContext.getArgument(\"ScaleY\");", + " curvedPath.scale(scaleX, scaleY);", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Scale on X axis", + "name": "ScaleX", + "type": "expression" + }, + { + "description": "Scale on Y axis", + "name": "ScaleY", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Rotate a path.", + "fullName": "Rotate a path", + "functionType": "Action", + "group": "Path transformation", + "name": "RotatePath", + "sentence": "Rotate _PARAM2_° the path _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "let curvedPath = curvedPaths.get(pathName);", + "if (curvedPath) {", + " const angle = eventsFunctionContext.getArgument(\"Angle\") * Math.PI / 180;", + " curvedPath.rotate(angle);", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Rotation angle", + "name": "Angle", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if a path is closed.", + "fullName": "Is closed", + "functionType": "Condition", + "name": "IsClosed", + "sentence": "The path _PARAM1_ is closed", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "", + "const curvedPath = curvedPaths.get(pathName);", + "eventsFunctionContext.returnValue = curvedPath && curvedPath.isClosed();", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Return the position on X axis of the path for a given length.", + "fullName": "Path X", + "functionType": "Expression", + "name": "PathX", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "const curvedPath = curvedPaths.get(pathName);", + "", + "const length = eventsFunctionContext.getArgument(\"Length\");", + "", + "eventsFunctionContext.returnValue = curvedPath ? curvedPath.getX(length) : 0;", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Length on the path", + "name": "Length", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the position on Y axis of the path for a given length.", + "fullName": "Path Y", + "functionType": "Expression", + "name": "PathY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "const curvedPath = curvedPaths.get(pathName);", + "", + "const length = eventsFunctionContext.getArgument(\"Length\");", + "", + "eventsFunctionContext.returnValue = curvedPath ? curvedPath.getY(length) : 0;", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Length on the path", + "name": "Length", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the direction angle of the path for a given length (in degree).", + "fullName": "Path angle", + "functionType": "Expression", + "name": "PathAngle", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "const curvedPath = curvedPaths.get(pathName);", + "", + "const length = eventsFunctionContext.getArgument(\"Length\");", + "", + "eventsFunctionContext.returnValue = curvedPath ? curvedPath.getAngle(length) * 180 / Math.PI : 0;", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Length on the path", + "name": "Length", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the length of the path.", + "fullName": "Path length", + "functionType": "Expression", + "name": "PathLength", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const pathName = eventsFunctionContext.getArgument(\"PathName\");", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "const curvedPath = curvedPaths.get(pathName);", + "", + "eventsFunctionContext.returnValue = curvedPath ? curvedPath.getLength() : 0;", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Return the displacement on X axis of the path end.", + "fullName": "Path end X", + "functionType": "Expression", + "name": "PathEndX", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "eventsFunctionContext.returnValue = curvedPath ? curvedPath.getEndX() : 0;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Return the displacement on Y axis of the path end.", + "fullName": "Path end Y", + "functionType": "Expression", + "name": "PathEndY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "eventsFunctionContext.returnValue = curvedPath ? curvedPath.getEndY() : 0;\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Return the number of lines or curves that make the path.", + "fullName": "Path element count", + "functionType": "Expression", + "group": "Path element", + "name": "ElementCount", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "eventsFunctionContext.returnValue = curvedPath ? curvedPath.curves.length : 0;\r", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + }, + { + "description": "Return the origin position on X axis of a curve.", + "fullName": "Origin X", + "functionType": "Expression", + "group": "Path element", + "name": "OriginX", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "/** @type {number} */\r", + "const index = eventsFunctionContext.getArgument(\"Index\");\r", + "\r", + "eventsFunctionContext.returnValue = (\r", + " (curvedPath && curvedPath && index >= 0 && index < curvedPath.curves.length)\r", + " ? curvedPath.getOriginX(index) : 0);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Curve index", + "name": "Index", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the origin position on Y axis of a curve.", + "fullName": "Origin Y", + "functionType": "Expression", + "group": "Path element", + "name": "OriginY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "/** @type {number} */\r", + "const index = eventsFunctionContext.getArgument(\"Index\");\r", + "\r", + "eventsFunctionContext.returnValue = (\r", + " (curvedPath && index >= 0 && index < curvedPath.curves.length)\r", + " ? curvedPath.getOriginY(index) : 0);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Curve index", + "name": "Index", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the first control point position on X axis of a curve.", + "fullName": "First control X", + "functionType": "Expression", + "group": "Path element", + "name": "FirstControlX", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "/** @type {number} */\r", + "const index = eventsFunctionContext.getArgument(\"Index\");\r", + "\r", + "eventsFunctionContext.returnValue = (\r", + " (curvedPath && index >= 0 && index < curvedPath.curves.length)\r", + " ? curvedPath.getFirstControlX(index) : 0);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Curve index", + "name": "Index", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the first control point position on Y axis of a curve.", + "fullName": "First control Y", + "functionType": "Expression", + "group": "Path element", + "name": "FirstControlY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "/** @type {number} */\r", + "const index = eventsFunctionContext.getArgument(\"Index\");\r", + "\r", + "eventsFunctionContext.returnValue = (\r", + " (curvedPath && index >= 0 && index < curvedPath.curves.length)\r", + " ? curvedPath.getFirstControlY(index) : 0);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Curve index", + "name": "Index", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the second control point position on X axis of a curve.", + "fullName": "Second control X", + "functionType": "Expression", + "group": "Path element", + "name": "SecondControlX", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "/** @type {number} */\r", + "const index = eventsFunctionContext.getArgument(\"Index\");\r", + "\r", + "eventsFunctionContext.returnValue = (\r", + " (curvedPath && index >= 0 && index < curvedPath.curves.length)\r", + " ? curvedPath.getSecondControlX(index) : 0);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Curve index", + "name": "Index", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the second control point position on Y axis of a curve.", + "fullName": "Second control Y", + "functionType": "Expression", + "group": "Path element", + "name": "SecondControlY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "/** @type {number} */\r", + "const index = eventsFunctionContext.getArgument(\"Index\");\r", + "\r", + "eventsFunctionContext.returnValue = (\r", + " (curvedPath && index >= 0 && index < curvedPath.curves.length)\r", + " ? curvedPath.getSecondControlY(index) : 0);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Curve index", + "name": "Index", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the target position on X axis of a curve.", + "fullName": "Target X", + "functionType": "Expression", + "group": "Path element", + "name": "TargetX", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "/** @type {number} */\r", + "const index = eventsFunctionContext.getArgument(\"Index\");\r", + "\r", + "eventsFunctionContext.returnValue = (\r", + " (curvedPath && index >= 0 && index < curvedPath.curves.length)\r", + " ? curvedPath.getTargetX(index) : 0);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Curve index", + "name": "Index", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Return the target position on Y axis of a curve.", + "fullName": "Target Y", + "functionType": "Expression", + "group": "Path element", + "name": "TargetY", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "/** @type {number} */\r", + "const index = eventsFunctionContext.getArgument(\"Index\");\r", + "\r", + "eventsFunctionContext.returnValue = (\r", + " (curvedPath && index >= 0 && index < curvedPath.curves.length)\r", + " ? curvedPath.getTargetY(index) : 0);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Curve index", + "name": "Index", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Path exists.", + "fullName": "Path exists", + "functionType": "Condition", + "name": "PathExists", + "sentence": "Path _PARAM1_ exists", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "\r", + "const pathName = eventsFunctionContext.getArgument(\"PathName\");\r", + "/** @type {Map} */\r", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;\r", + "const curvedPath = curvedPaths.get(pathName);\r", + "\r", + "eventsFunctionContext.returnValue = !!curvedPath;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Path name", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [ + { + "description": "Move objects on curved paths in a given duration and tween easing function.", + "fullName": "Movement on a curve (duration-based)", + "name": "TweenPathMovement", + "objectType": "Sprite", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Back and forth states", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::HasReachedAnEnd" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyShouldGoBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Wait", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyPauseDurationBeforeGoingBack" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + }, + { + "type": { + "inverted": true, + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"__CurvedMovement.Wait\"", + ">=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"__CurvedMovement.Wait\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"__CurvedMovement.Wait\"", + ">=", + "Object.Behavior::PropertyPauseDurationBeforeGoingBack()" + ] + } + ], + "actions": [ + { + "type": { + "value": "RemoveObjectTimer" + }, + "parameters": [ + "Object", + "\"__CurvedMovement.Wait\"" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Change of direction", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"__CurvedMovement.Wait\"", + ">=", + "0" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::TweenPathMovement::PropertyIsGoingBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"__CurvedMovement.Time\"" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::TweenPathMovement::PropertyIsGoingBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyOrigin" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "1" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyTarget" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyIsGoingBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyOrigin" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyTarget" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyTarget" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyIsGoingBack" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyFlipXToGoBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "FlipX" + }, + "parameters": [ + "Object", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyFlipYToGoBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "FlipY" + }, + "parameters": [ + "Object", + "no" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyTarget" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyIsGoingBack" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyFlipXToGoBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "FlipX" + }, + "parameters": [ + "Object", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyFlipYToGoBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "FlipY" + }, + "parameters": [ + "Object", + "yes" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Move on the path", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::TweenPathMovement::HasReachedAnEnd" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::UpdatePosition" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyRotation" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetAngle" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyPathAngle() + CurvedMovement::PathAngle(Object.Behavior::PropertyPathName(), Object.Behavior::RepeatedPathPosition()) + Object.Behavior::PropertyRotationOffset() + Object.Behavior::BackOrForthAngle()" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Set the the object on the path according to the current length.", + "fullName": "Update position", + "functionType": "Action", + "name": "UpdatePosition", + "private": true, + "sentence": "Update the position of _PARAM0_ on the path", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "", + "/** @type {string} */", + "const pathName = behavior._getPathName();", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "const curvedPath = curvedPaths.get(pathName);", + "if (!curvedPath) {", + " return;", + "}", + "", + "behavior.workingTransformation = behavior.workingTransformation || new gdjs.AffineTransformation();", + "/** @type {gdjs.AffineTransformation} */", + "const transformation = behavior.workingTransformation;", + "", + "const repetitionDone = behavior.RepetitionDone();", + "transformation.setToTranslation(", + " repetitionDone * behavior.PathEndX(),", + " repetitionDone * behavior.PathEndY() / behavior.PathSpeedScaleY()", + ");", + "transformation.preConcatenate(behavior.curvedMovementTransformation);", + "", + "/** @type {number} */", + "const length = behavior.RepeatedPathPosition();", + "/** @type {[number, number]} */", + "const point = curvedPath.getTransformedPosition(length, transformation);", + "const x = point[0] + behavior._getPathOriginX();", + "const y = point[1] + behavior._getPathOriginY();", + "object.setPosition(x, y);", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Move the object to a position by following a path.", + "fullName": "Move on path to a position", + "functionType": "Action", + "name": "MoveTo", + "sentence": "Move _PARAM0_ to _PARAM6_ ; _PARAM7_ on the path: _PARAM2_ repeated _PARAM3_ times in _PARAM4_ seconds with _PARAM5_ easing", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"PathName\")" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyDuration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Duration\")" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyEasing" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Easing\")" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyRepetitionCount" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"RepetitionCount\")" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldGoBack" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathOriginX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X()" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathOriginY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y()" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathAngle" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "AngleBetweenPositions(Object.X(), Object.Y(), GetArgumentAsNumber(\"DestinationX\"), Object.Y() + (GetArgumentAsNumber(\"DestinationY\") - Object.Y()) / Object.Behavior::PathSpeedScaleY()) - AngleBetweenPositions(0, 0, Object.Behavior::PathEndX(), Object.Behavior::PathEndY() / Object.Behavior::PathSpeedScaleY())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathScale" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "DistanceBetweenPositions(Object.X(), Object.Y(), GetArgumentAsNumber(\"DestinationX\"), Object.Y() + (GetArgumentAsNumber(\"DestinationY\") - Object.Y()) / Object.Behavior::PathSpeedScaleY()) / DistanceBetweenPositions(0, 0, Object.Behavior::PathEndX(), Object.Behavior::PathEndY() / Object.Behavior::PathSpeedScaleY()) / GetArgumentAsNumber(\"RepetitionCount\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::InitializeMovement" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + }, + { + "description": "Path name", + "longDescription": "The path can be define with the \"Append curve\" action.", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Number of repetitions", + "name": "RepetitionCount", + "type": "expression" + }, + { + "description": "Duration in seconds", + "name": "Duration", + "type": "expression" + }, + { + "description": "Easing", + "name": "Easing", + "supplementaryInformation": "[\"linear\",\"easeInQuad\",\"easeOutQuad\",\"easeInOutQuad\",\"easeInCubic\",\"easeOutCubic\",\"easeInOutCubic\",\"easeInQuart\",\"easeOutQuart\",\"easeInOutQuart\",\"easeInQuint\",\"easeOutQuint\",\"easeInOutQuint\",\"easeInOutSine\",\"easeInExpo\",\"easeOutExpo\",\"easeInOutExpo\",\"easeInCirc\",\"easeOutCirc\",\"easeInOutCirc\",\"easeOutBounce\",\"easeInBack\",\"easeOutBack\",\"easeInOutBack\",\"elastic\",\"swingFromTo\",\"swingFrom\",\"swingTo\",\"bounce\",\"bouncePast\",\"easeFromTo\",\"easeFrom\",\"easeTo\"]", + "type": "stringWithSelector" + }, + { + "description": "Destination X", + "name": "DestinationX", + "type": "expression" + }, + { + "description": "Destination Y", + "name": "DestinationY", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Move the object to a position by following a path and go back.", + "fullName": "Move back and forth to a position", + "functionType": "Action", + "name": "MoveToAndGoBack", + "sentence": "Move back and forth _PARAM0_ to _PARAM6_ ; _PARAM7_ on the path: _PARAM2_ repeated _PARAM3_ times in _PARAM4_ seconds with _PARAM5_ easing, wait _PARAM8_ seconds before going back and loop: _PARAM9_ ", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::MoveTo" + }, + "parameters": [ + "Object", + "Behavior", + "GetArgumentAsString(\"PathName\")", + "GetArgumentAsNumber(\"RepetitionCount\")", + "GetArgumentAsNumber(\"Duration\")", + "GetArgumentAsString(\"Easing\")", + "GetArgumentAsNumber(\"DestinationX\")", + "GetArgumentAsNumber(\"DestinationY\")", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldGoBack" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPauseDurationBeforeGoingBack" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"WaitBeforeGoingBackDuration\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldLoop\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "=" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldLoop\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + }, + { + "description": "Path name", + "longDescription": "The path can be define with the \"Append curve\" action.", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Number of repetitions", + "name": "RepetitionCount", + "type": "expression" + }, + { + "description": "Duration in seconds", + "name": "Duration", + "type": "expression" + }, + { + "description": "Easing", + "name": "Easing", + "supplementaryInformation": "[\"linear\",\"easeInQuad\",\"easeOutQuad\",\"easeInOutQuad\",\"easeInCubic\",\"easeOutCubic\",\"easeInOutCubic\",\"easeInQuart\",\"easeOutQuart\",\"easeInOutQuart\",\"easeInQuint\",\"easeOutQuint\",\"easeInOutQuint\",\"easeInOutSine\",\"easeInExpo\",\"easeOutExpo\",\"easeInOutExpo\",\"easeInCirc\",\"easeOutCirc\",\"easeInOutCirc\",\"easeOutBounce\",\"easeInBack\",\"easeOutBack\",\"easeInOutBack\",\"elastic\",\"swingFromTo\",\"swingFrom\",\"swingTo\",\"bounce\",\"bouncePast\",\"easeFromTo\",\"easeFrom\",\"easeTo\"]", + "type": "stringWithSelector" + }, + { + "description": "Destination X", + "name": "DestinationX", + "type": "expression" + }, + { + "description": "Destination Y", + "name": "DestinationY", + "type": "expression" + }, + { + "description": "Duration to wait before going back", + "name": "WaitBeforeGoingBackDuration", + "type": "expression" + }, + { + "description": "Loop", + "name": "ShouldLoop", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Move the object by following a path.", + "fullName": "Move on path", + "functionType": "Action", + "name": "Move", + "sentence": "Move _PARAM0_ on the path: _PARAM2_ repeated _PARAM3_ times in _PARAM4_ seconds with _PARAM5_ easing", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"PathName\")" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyDuration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Duration\")" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyEasing" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Easing\")" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyRepetitionCount" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"RepetitionCount\")" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldGoBack" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathOriginX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X()" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathOriginY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y()" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathAngle" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPathScale" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::InitializeMovement" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + }, + { + "description": "Path name", + "longDescription": "The path can be define with the \"Append curve\" action.", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Number of repetitions", + "name": "RepetitionCount", + "type": "expression" + }, + { + "description": "Duration in seconds", + "name": "Duration", + "type": "expression" + }, + { + "description": "Easing", + "name": "Easing", + "supplementaryInformation": "[\"linear\",\"easeInQuad\",\"easeOutQuad\",\"easeInOutQuad\",\"easeInCubic\",\"easeOutCubic\",\"easeInOutCubic\",\"easeInQuart\",\"easeOutQuart\",\"easeInOutQuart\",\"easeInQuint\",\"easeOutQuint\",\"easeInOutQuint\",\"easeInOutSine\",\"easeInExpo\",\"easeOutExpo\",\"easeInOutExpo\",\"easeInCirc\",\"easeOutCirc\",\"easeInOutCirc\",\"easeOutBounce\",\"easeInBack\",\"easeOutBack\",\"easeInOutBack\",\"elastic\",\"swingFromTo\",\"swingFrom\",\"swingTo\",\"bounce\",\"bouncePast\",\"easeFromTo\",\"easeFrom\",\"easeTo\"]", + "type": "stringWithSelector" + } + ], + "objectGroups": [] + }, + { + "description": "Move the object by following a path and go back.", + "fullName": "Move back and forth", + "functionType": "Action", + "name": "MoveAndGoBack", + "sentence": "Move back and forth _PARAM0_ on the path: _PARAM2_ repeated _PARAM3_ times in _PARAM4_ seconds with _PARAM5_ easing, wait _PARAM6_ seconds before going back and loop: _PARAM7_ ", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::Move" + }, + "parameters": [ + "Object", + "Behavior", + "GetArgumentAsString(\"PathName\")", + "GetArgumentAsNumber(\"RepetitionCount\")", + "GetArgumentAsNumber(\"Duration\")", + "GetArgumentAsString(\"Easing\")", + "GetArgumentAsNumber(\"DestinationX\")" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldGoBack" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyPauseDurationBeforeGoingBack" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"WaitBeforeGoingBackDuration\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldLoop\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "=" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldLoop\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + }, + { + "description": "Path name", + "longDescription": "The path can be define with the \"Append curve\" action.", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Number of repetitions", + "name": "RepetitionCount", + "type": "expression" + }, + { + "description": "Duration in seconds", + "name": "Duration", + "type": "expression" + }, + { + "description": "Easing", + "name": "Easing", + "supplementaryInformation": "[\"linear\",\"easeInQuad\",\"easeOutQuad\",\"easeInOutQuad\",\"easeInCubic\",\"easeOutCubic\",\"easeInOutCubic\",\"easeInQuart\",\"easeOutQuart\",\"easeInOutQuart\",\"easeInQuint\",\"easeOutQuint\",\"easeInOutQuint\",\"easeInOutSine\",\"easeInExpo\",\"easeOutExpo\",\"easeInOutExpo\",\"easeInCirc\",\"easeOutCirc\",\"easeInOutCirc\",\"easeOutBounce\",\"easeInBack\",\"easeOutBack\",\"easeInOutBack\",\"elastic\",\"swingFromTo\",\"swingFrom\",\"swingTo\",\"bounce\",\"bouncePast\",\"easeFromTo\",\"easeFrom\",\"easeTo\"]", + "type": "stringWithSelector" + }, + { + "description": "Duration to wait before going back", + "name": "WaitBeforeGoingBackDuration", + "type": "expression" + }, + { + "description": "Loop", + "name": "ShouldLoop", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object has reached one of the 2 ends of the path.", + "fullName": "Reached an end", + "functionType": "Condition", + "name": "HasReachedAnEnd", + "sentence": "_PARAM0_ reached an end of the path", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::Progress()", + "=", + "Object.Behavior::PropertyTarget()" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object has finished to move on the path.", + "fullName": "Finished to move", + "functionType": "Condition", + "name": "HasFinishedToMove", + "sentence": "_PARAM0_ has finished to move", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::And" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::HasReachedAnEnd" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::TweenPathMovement::PropertyShouldGoBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::And" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyShouldGoBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "inverted": true, + "value": "CurvedMovement::TweenPathMovement::PropertyIsGoingBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ] + } + ] + } + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the angle of movement on its path.", + "fullName": "Movement angle", + "functionType": "Expression", + "name": "MovementAngle", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyPathAngle() + CurvedMovement::PathAngle(Object.Behavior::PropertyPathName(), Object.Behavior::RepeatedPathPosition()) + Object.Behavior::PropertyRotationOffset() + Object.Behavior::BackOrForthAngle()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Draw the object trajectory.", + "fullName": "Draw the trajectory", + "functionType": "Action", + "group": "Debug", + "name": "DrawDebug", + "sentence": "Draw trajectory of _PARAM0_ on _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::UseRelativeCoordinates" + }, + "parameters": [ + "ShapePainter", + "no" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::FillOpacity" + }, + "parameters": [ + "ShapePainter", + "=", + "0" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::OutlineSize" + }, + "parameters": [ + "ShapePainter", + "=", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = objects[0].getBehavior(behaviorName);", + "", + "/** @type {gdjs.ShapePainterRuntimeObject} */", + "const shapePainter = eventsFunctionContext.getObjects(\"ShapePainter\")[0];", + "if (!shapePainter) {", + " return ;", + "}", + "", + "/** @type {string} */", + "const pathName = behavior._getPathName();", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "const curvedPath = curvedPaths.get(pathName);", + "if (!curvedPath) {", + " return ;", + "}", + "", + "/** @type {gdjs.AffineTransformation} */", + "const transformation = behavior.curvedMovementTransformation;", + "let point = behavior.curvedMovementWorkingPoint || [0, 0];", + "", + "let originX = behavior._getPathOriginX();", + "let originY = behavior._getPathOriginY();", + "shapePainter.drawPathMoveTo(originX, originY);", + "const repetitionCount = behavior._getRepetitionCount();", + "let previousLastTargetX = 0;", + "let previousLastTargetY = 0;", + "const endX = curvedPath.getEndX();", + "const endY = curvedPath.getEndY();", + "for (let repetitionIndex = 0; repetitionIndex < repetitionCount; repetitionIndex++) {", + " for (let curveIndex = 0; curveIndex < curvedPath.curves.length; curveIndex++) {", + " point[0] = curvedPath.getFirstControlX(curveIndex) + previousLastTargetX;", + " point[1] = curvedPath.getFirstControlY(curveIndex) + previousLastTargetY;", + " if (transformation) {", + " point = curvedPath.transformPosition(point[0], point[1], transformation, point);", + " }", + " const firstControlX = point[0];", + " const firstControlY = point[1];", + "", + " point[0] = curvedPath.getSecondControlX(curveIndex) + previousLastTargetX;", + " point[1] = curvedPath.getSecondControlY(curveIndex) + previousLastTargetY;", + " if (transformation) {", + " point = curvedPath.transformPosition(point[0], point[1], transformation, point);", + " }", + " const secondControlX = point[0];", + " const secondControlY = point[1];", + "", + " point[0] = curvedPath.getTargetX(curveIndex) + previousLastTargetX;", + " point[1] = curvedPath.getTargetY(curveIndex) + previousLastTargetY;", + " if (transformation) {", + " point = curvedPath.transformPosition(point[0], point[1], transformation, point);", + " }", + " const targetX = point[0];", + " const targetY = point[1];", + "", + " shapePainter.drawPathBezierCurveTo(", + " firstControlX + originX,", + " firstControlY + originY,", + " secondControlX + originX,", + " secondControlY + originY,", + " targetX + originX,", + " targetY + originY);", + " }", + " previousLastTargetX += endX;", + " previousLastTargetY += endY;", + "}", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + }, + { + "description": "Shape painter", + "name": "ShapePainter", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Change the transformation to apply to the path.", + "fullName": "Path transformation", + "functionType": "Action", + "name": "SetTransformation", + "private": true, + "sentence": "Change the path trasformation of _PARAM0_ to origin _PARAM2_; _PARAM3_ scale by _PARAM4_ and a rotation of _PARAM5_°", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = objects[0].getBehavior(behaviorName);", + "", + "const scale = eventsFunctionContext.getArgument(\"Scale\");", + "const angle = eventsFunctionContext.getArgument(\"Angle\");", + "", + "/** @type {gdjs.AffineTransformation} */", + "const transformation = behavior.curvedMovementTransformation || new gdjs.AffineTransformation()", + "transformation.setToScale(scale, scale);", + "transformation.rotate(angle / 180 * Math.PI);", + "", + "behavior.curvedMovementTransformation = transformation;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + }, + { + "description": "Origin X", + "name": "OriginX", + "type": "expression" + }, + { + "description": "Origin Y", + "name": "OriginY", + "type": "expression" + }, + { + "description": "Scale", + "name": "Scale", + "type": "expression" + }, + { + "description": "Angle", + "name": "Angle", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Initialize the movement state.", + "fullName": "Initialize the movement", + "functionType": "Action", + "name": "InitializeMovement", + "private": true, + "sentence": "Initialize the movement of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyViewpoint" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Top-down\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SetSpeedScaleY" + }, + "parameters": [ + "", + "Object.Behavior::PropertyPathName()", + "1", + "0.5" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyViewpoint" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Isometry 2:1 (26.565°)\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SetSpeedScaleY" + }, + "parameters": [ + "", + "Object.Behavior::PropertyPathName()", + "0.5", + "0.5" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetTransformation" + }, + "parameters": [ + "Object", + "Behavior", + "Object.X()", + "Object.Y()", + "Object.Behavior::PropertyPathScale()", + "Object.Behavior::PropertyPathAngle()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"__CurvedMovement.Time\"" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyIsGoingBack" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyOrigin" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "CurvedMovement::TweenPathMovement::SetPropertyTarget" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyFlipXToGoBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "FlipX" + }, + "parameters": [ + "Object", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyFlipYToGoBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "FlipY" + }, + "parameters": [ + "Object", + "no" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the number of repetitions between the current position and the origin.", + "fullName": "Repetition done", + "functionType": "Expression", + "name": "RepetitionDone", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "floor(Object.Behavior::Progress() * Object.Behavior::PropertyRepetitionCount())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the position on one repeated path.", + "fullName": "Path position", + "functionType": "Expression", + "name": "RepeatedPathPosition", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PathLength() * mod(Object.Behavior::Progress(), 1 / Object.Behavior::PropertyRepetitionCount()) * Object.Behavior::PropertyRepetitionCount()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the progress on the full path from 0 to 1, where 0 means the origin and 1 the end.", + "fullName": "Progress", + "functionType": "Expression", + "name": "Progress", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Tween::Ease(Object.Behavior::PropertyEasing(), Object.Behavior::PropertyOrigin(), Object.Behavior::PropertyTarget(), min(1, Object.ObjectTimerElapsedTime(\"__CurvedMovement.Time\") / Object.Behavior::PropertyDuration()))" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the length of the path (one repetition only).", + "fullName": "Path length", + "functionType": "Expression", + "name": "PathLength", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "CurvedMovement::PathLength(Object.Behavior::PropertyPathName())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the displacement on X axis of the path end.", + "fullName": "Path end X", + "functionType": "Expression", + "name": "PathEndX", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "CurvedMovement::PathEndX(Object.Behavior::PropertyPathName())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the displacement on Y axis of the path end.", + "fullName": "Path end Y", + "functionType": "Expression", + "name": "PathEndY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "CurvedMovement::PathEndY(Object.Behavior::PropertyPathName())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the speed scale on Y axis of the path.", + "fullName": "Path speed scale Y", + "functionType": "Expression", + "name": "PathSpeedScaleY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "CurvedMovement::SpeedScaleY(Object.Behavior::PropertyPathName())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the angle to use when the object is going back or not.", + "fullName": "Back or forth angle", + "functionType": "Expression", + "name": "BackOrForthAngle", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::TweenPathMovement::PropertyIsGoingBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "180" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Sprite", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::TweenPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "true", + "type": "Boolean", + "label": "Rotate object", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "Rotation" + }, + { + "value": "0", + "type": "Number", + "unit": "DegreeAngle", + "label": "Rotation offset", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "RotationOffset" + }, + { + "value": "", + "type": "Boolean", + "label": "Flip on X to go back", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "FlipXToGoBack" + }, + { + "value": "", + "type": "Boolean", + "label": "Flip on Y to go back", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "FlipYToGoBack" + }, + { + "value": "1", + "type": "Number", + "label": "Speed scale", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "SpeedScale" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathOriginX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathOriginY" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Target" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Origin" + }, + { + "value": "", + "type": "String", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathName" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Duration" + }, + { + "value": "", + "type": "String", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Easing" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DrawingElementIndex" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "X" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Y" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathAngle" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathScale" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "RepetitionCount" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ShouldGoBack" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ShouldLoop" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "RepetitionDoneCount" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "IsGoingBack" + }, + { + "value": "0", + "type": "Number", + "label": "Pause duration before going back", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PauseDurationBeforeGoingBack" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DrawingPathOriginX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DrawingPathOriginY" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DebugLineStrokeWidth" + }, + { + "value": "Top-Down", + "type": "Choice", + "label": "Viewpoint", + "description": "", + "group": "", + "extraInformation": [ + "Top-Down", + "Isometry 2:1 (26.565°)" + ], + "hidden": false, + "name": "Viewpoint" + } + ], + "sharedPropertyDescriptors": [] + }, + { + "description": "Move objects on curved paths at a given speed.", + "fullName": "Movement on a curve (speed-based)", + "name": "SpeedPathMovement", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Move on the path", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::CanMoveFurther" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPreviousSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertySpeed()" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Update speed" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "Object.Behavior::PropertyTargetedSpeed()" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.Behavior::PropertyAcceleration() * TimeDelta()" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "sign(Object.Behavior::PropertyAcceleration())", + "!=", + "sign(Object.Behavior::PropertyTargetedSpeed() - Object.Behavior::PropertySpeed())" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyTargetedSpeed()" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyAcceleration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Update the position on the path (the current length) with a Verlet integration." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPositionOnPath" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "(Object.Behavior::PropertyPreviousSpeed() + Object.Behavior::PropertySpeed()) * TimeDelta() / 2", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "It's useful to know which way to look at when the speed reached 0." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyIsLookingBack" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyIsLookingBack" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the path followed by an object.", + "fullName": "Follow a path", + "functionType": "Action", + "name": "SetPath", + "sentence": "_PARAM0_ follow the path: _PARAM2_ repeated _PARAM3_ times and loop: _PARAM4_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"PathName\")" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyRepetitionCount" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(1, GetArgumentAsNumber(\"RepetitionCount\"))" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldLoop\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldLoop\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathOriginX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X()" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathOriginY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y()" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathAngle" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathScale" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::InitializeMovement" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Path name", + "longDescription": "The path can be define with the \"Append curve\" action.", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Number of repetitions", + "name": "RepetitionCount", + "type": "expression" + }, + { + "description": "Loop", + "name": "ShouldLoop", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Change the path followed by an object to reach a position.", + "fullName": "Follow a path to a position", + "functionType": "Action", + "name": "SetPathTo", + "sentence": "_PARAM0_ follow the path _PARAM2_ repeated _PARAM3_ times to reach _PARAM5_ ; _PARAM6_ and loop: _PARAM4_", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "When the path is close or empty, there is no way to reach a destination" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::IsClosed" + }, + "parameters": [ + "", + "GetArgumentAsString(\"PathName\")", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathName" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"PathName\")" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyRepetitionCount" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(1, GetArgumentAsNumber(\"RepetitionCount\"))" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldLoop\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldLoop\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathOriginX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.X()" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathOriginY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Y()" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathAngle" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "AngleBetweenPositions(Object.X(), Object.Y(), GetArgumentAsNumber(\"DestinationX\"), Object.Y() + (GetArgumentAsNumber(\"DestinationY\") - Object.Y()) / Object.Behavior::PathSpeedScaleY()) - AngleBetweenPositions(0, 0, Object.Behavior::PathEndX(), Object.Behavior::PathEndY() / Object.Behavior::PathSpeedScaleY())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyPathScale" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "DistanceBetweenPositions(Object.X(), Object.Y(), GetArgumentAsNumber(\"DestinationX\"), Object.Y() + (GetArgumentAsNumber(\"DestinationY\") - Object.Y()) / Object.Behavior::PathSpeedScaleY()) / DistanceBetweenPositions(0, 0, Object.Behavior::PathEndX(), Object.Behavior::PathEndY() / Object.Behavior::PathSpeedScaleY()) / GetArgumentAsNumber(\"RepetitionCount\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::InitializeMovement" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Path name", + "longDescription": "The path can be define with the \"Append curve\" action.", + "name": "PathName", + "supplementaryInformation": "sceneBezierCurve", + "type": "identifier" + }, + { + "description": "Number of repetitions", + "name": "RepetitionCount", + "type": "expression" + }, + { + "description": "Loop", + "name": "ShouldLoop", + "type": "yesorno" + }, + { + "description": "Destination X", + "name": "DestinationX", + "type": "expression" + }, + { + "description": "Destination Y", + "name": "DestinationY", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the length between the trajectory origin and the current position.", + "fullName": "Position on the path", + "functionType": "ExpressionAndCondition", + "name": "PositionOnPath", + "sentence": "the length from the trajectory origin", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyCurrentLength()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the position of the object on the path.", + "fullName": "Position on the path", + "functionType": "ActionWithOperator", + "getterName": "PositionOnPath", + "name": "SetPositionOnPath", + "sentence": "Change the position of _PARAM0_ on the path at the length _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::SpeedPathMovement::PropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyCurrentLength" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "clamp(GetArgumentAsNumber(\"Value\"), 0, Object.Behavior::TotalLength())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyCurrentLength" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "mod(GetArgumentAsNumber(\"Value\"), Object.Behavior::TotalLength())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::UpdatePosition" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyRotation" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetAngle" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyPathAngle() + CurvedMovement::PathAngle(Object.Behavior::PropertyPathName(), Object.Behavior::RepeatedPathPosition()) + Object.Behavior::PropertyRotationOffset() + Object.Behavior::BackOrForthAngle()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Length", + "name": "Length", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set the the object on the path according to the current length.", + "fullName": "Update position", + "functionType": "Action", + "name": "UpdatePosition", + "private": true, + "sentence": "Update the position of _PARAM0_ on the path", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "", + "/** @type {string} */", + "const pathName = behavior._getPathName();", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "const curvedPath = curvedPaths.get(pathName);", + "if (!curvedPath) {", + " return;", + "}", + "", + "behavior.workingTransformation = behavior.workingTransformation || new gdjs.AffineTransformation();", + "/** @type {gdjs.AffineTransformation} */", + "const transformation = behavior.workingTransformation;", + "", + "const repetitionDone = behavior.RepetitionDone();", + "transformation.setToTranslation(", + " repetitionDone * behavior.PathEndX(),", + " repetitionDone * behavior.PathEndY() / behavior.PathSpeedScaleY()", + ");", + "transformation.preConcatenate(behavior.curvedMovementTransformation);", + "", + "/** @type {number} */", + "const length = behavior.RepeatedPathPosition();", + "/** @type {[number, number]} */", + "const point = curvedPath.getTransformedPosition(length, transformation);", + "const x = point[0] + behavior._getPathOriginX();", + "const y = point[1] + behavior._getPathOriginY();", + "object.setPosition(x, y);", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the length from the trajectory origin is lesser than a value.", + "fullName": "Current length", + "functionType": "Condition", + "name": "CheckPositionOnPath", + "sentence": "_PARAM0_ is less than _PARAM2_ pixels away from the trajectory origin", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::PositionOnPath()", + "<", + "GetArgumentAsNumber(\"Length\")" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Length from the trajectory origin (in pixels)", + "name": "Length", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object has reached the origin position of the path.", + "fullName": "Reached path origin", + "functionType": "Condition", + "name": "HasReachedOrigin", + "sentence": "_PARAM0_ reached the path beginning", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyCurrentLength" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "<=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object has reached the target position of the path.", + "fullName": "Reached path target", + "functionType": "Condition", + "name": "HasReachedTarget", + "sentence": "_PARAM0_ reached the path target", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyCurrentLength" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::TotalLength()" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object has reached one of the 2 ends of the path.", + "fullName": "Reach an end", + "functionType": "Condition", + "name": "HasReachedAnEnd", + "sentence": "_PARAM0_ reached an end of the path", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedTarget" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedOrigin" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object can still move in the current direction.", + "fullName": "Can move further", + "functionType": "Condition", + "name": "CanMoveFurther", + "sentence": "_PARAM0_ can move further on its path", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyAcceleration" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + } + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyShouldLoop" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::And" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::SpeedPathMovement::HasReachedTarget" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyAcceleration" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ] + } + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::And" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::SpeedPathMovement::HasReachedOrigin" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "0" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyAcceleration" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "0" + ] + } + ] + } + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the angle of movement on its path.", + "fullName": "Movement angle", + "functionType": "Expression", + "name": "MovementAngle", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyPathAngle() + CurvedMovement::PathAngle(Object.Behavior::PropertyPathName(), Object.Behavior::RepeatedPathPosition()) + Object.Behavior::PropertyRotationOffset() + Object.Behavior::BackOrForthAngle()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the speed of the object.", + "fullName": "Speed", + "functionType": "ExpressionAndCondition", + "name": "Speed", + "sentence": "the speed", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertySpeed()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Change the current speed of the object.", + "fullName": "Speed", + "functionType": "ActionWithOperator", + "getterName": "Speed", + "name": "SetSpeed", + "sentence": "Change the speed of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyTargetedSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Speed (in pixels per second)", + "name": "Speed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Make an object accelerate until it reaches a given speed.", + "fullName": "Accelerate", + "functionType": "Action", + "name": "AccelarateAt", + "sentence": "_PARAM0_ accelerate at _PARAM3_ to reach the speed of _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyTargetedSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"TargetedSpeed\")" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyAcceleration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Acceleration\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedAnEnd" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Targeted speed (in pixels per second)", + "name": "TargetedSpeed", + "type": "expression" + }, + { + "description": "Acceleration (in pixels per second per second)", + "name": "Acceleration", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Make an object accelerate to reaches a speed in a given amount of time.", + "fullName": "Accelerate during", + "functionType": "Action", + "name": "AccelarateDuring", + "sentence": "_PARAM0_ accelerate during _PARAM3_ seconds to reach the speed of _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyTargetedSpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"TargetedSpeed\")" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertyAcceleration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "(GetArgumentAsNumber(\"TargetedSpeed\") - Object.Behavior::PropertySpeed()) / GetArgumentAsNumber(\"Duration\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedAnEnd" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Targeted speed (in pixels per second)", + "name": "TargetedSpeed", + "type": "expression" + }, + { + "description": "Duration (in seconds)", + "name": "Duration", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Draw the object trajectory.", + "fullName": "Draw the trajectory", + "functionType": "Action", + "group": "Debug", + "name": "DrawDebug", + "sentence": "Draw trajectory of _PARAM0_ on _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PrimitiveDrawing::UseRelativeCoordinates" + }, + "parameters": [ + "ShapePainter", + "no" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::FillOpacity" + }, + "parameters": [ + "ShapePainter", + "=", + "0" + ] + }, + { + "type": { + "value": "PrimitiveDrawing::OutlineSize" + }, + "parameters": [ + "ShapePainter", + "=", + "ShapePainter.OutlineSize()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = objects[0].getBehavior(behaviorName);", + "", + "/** @type {gdjs.ShapePainterRuntimeObject} */", + "const shapePainter = eventsFunctionContext.getObjects(\"ShapePainter\")[0];", + "if (!shapePainter) {", + " return ;", + "}", + "", + "/** @type {string} */", + "const pathName = behavior._getPathName();", + "/** @type {Map} */", + "const curvedPaths = runtimeScene.__curvedMovementExtension.curvedPaths;", + "const curvedPath = curvedPaths.get(pathName);", + "if (!curvedPath) {", + " return ;", + "}", + "", + "/** @type {gdjs.AffineTransformation} */", + "const transformation = behavior.curvedMovementTransformation;", + "let point = behavior.curvedMovementWorkingPoint || [0, 0];", + "", + "let originX = behavior._getPathOriginX();", + "let originY = behavior._getPathOriginY();", + "shapePainter.drawPathMoveTo(originX, originY);", + "const repetitionCount = behavior._getRepetitionCount();", + "let previousLastTargetX = 0;", + "let previousLastTargetY = 0;", + "const endX = curvedPath.getEndX();", + "const endY = curvedPath.getEndY();", + "for (let repetitionIndex = 0; repetitionIndex < repetitionCount; repetitionIndex++) {", + " for (let curveIndex = 0; curveIndex < curvedPath.curves.length; curveIndex++) {", + " point[0] = curvedPath.getFirstControlX(curveIndex) + previousLastTargetX;", + " point[1] = curvedPath.getFirstControlY(curveIndex) + previousLastTargetY;", + " if (transformation) {", + " point = curvedPath.transformPosition(point[0], point[1], transformation, point);", + " }", + " const firstControlX = point[0];", + " const firstControlY = point[1];", + "", + " point[0] = curvedPath.getSecondControlX(curveIndex) + previousLastTargetX;", + " point[1] = curvedPath.getSecondControlY(curveIndex) + previousLastTargetY;", + " if (transformation) {", + " point = curvedPath.transformPosition(point[0], point[1], transformation, point);", + " }", + " const secondControlX = point[0];", + " const secondControlY = point[1];", + "", + " point[0] = curvedPath.getTargetX(curveIndex) + previousLastTargetX;", + " point[1] = curvedPath.getTargetY(curveIndex) + previousLastTargetY;", + " if (transformation) {", + " point = curvedPath.transformPosition(point[0], point[1], transformation, point);", + " }", + " const targetX = point[0];", + " const targetY = point[1];", + "", + " shapePainter.drawPathBezierCurveTo(", + " firstControlX + originX,", + " firstControlY + originY,", + " secondControlX + originX,", + " secondControlY + originY,", + " targetX + originX,", + " targetY + originY);", + " }", + " previousLastTargetX += endX;", + " previousLastTargetY += endY;", + "}", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Shape painter", + "name": "ShapePainter", + "supplementaryInformation": "PrimitiveDrawing::Drawer", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Change the transformation to apply to the path.", + "fullName": "Path transformation", + "functionType": "Action", + "name": "SetTransformation", + "private": true, + "sentence": "Change the path trasformation of _PARAM0_ to origin _PARAM2_; _PARAM3_ scale by _PARAM4_ and a rotation of _PARAM5_°", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = objects[0].getBehavior(behaviorName);", + "", + "const scale = eventsFunctionContext.getArgument(\"Scale\");", + "const angle = eventsFunctionContext.getArgument(\"Angle\");", + "", + "/** @type {gdjs.AffineTransformation} */", + "const transformation = behavior.curvedMovementTransformation || new gdjs.AffineTransformation()", + "transformation.setToScale(scale, scale);", + "transformation.rotate(angle / 180 * Math.PI);", + "", + "behavior.curvedMovementTransformation = transformation;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + }, + { + "description": "Origin X", + "name": "OriginX", + "type": "expression" + }, + { + "description": "Origin Y", + "name": "OriginY", + "type": "expression" + }, + { + "description": "Scale", + "name": "Scale", + "type": "expression" + }, + { + "description": "Angle", + "name": "Angle", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Initialize the movement state.", + "fullName": "Initialize the movement", + "functionType": "Action", + "name": "InitializeMovement", + "private": true, + "sentence": "Initialize the movement of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyViewpoint" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Top-down\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SetSpeedScaleY" + }, + "parameters": [ + "", + "Object.Behavior::PropertyPathName()", + "1", + "0.5" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyViewpoint" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Isometry 2:1 (26.565°)\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "CurvedMovement::SetSpeedScaleY" + }, + "parameters": [ + "", + "Object.Behavior::PropertyPathName()", + "0.5", + "0.5" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetTransformation" + }, + "parameters": [ + "Object", + "Behavior", + "Object.X()", + "Object.Y()", + "Object.Behavior::PropertyPathScale()", + "Object.Behavior::PropertyPathAngle()", + "" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::SetPositionOnPath" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the position on one repeated path.", + "fullName": "Repeated path position", + "functionType": "Expression", + "name": "RepeatedPathPosition", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::SpeedPathMovement::HasReachedTarget" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "mod(Object.Behavior::PropertyCurrentLength(), Object.Behavior::PathLength())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "When the object reaches the target, it must stay on the last repetition end and not at the start of a new one." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedTarget" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PathLength()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the number of repetitions between the current position and the origin.", + "fullName": "Repetition done", + "functionType": "Expression", + "name": "RepetitionDone", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "CurvedMovement::SpeedPathMovement::HasReachedTarget" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "floor(Object.Behavior::PropertyCurrentLength() / Object.Behavior::PathLength())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "When the object reaches the target, it must stay on the last repetition end and not at the start of a new one." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::HasReachedTarget" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyRepetitionCount() - 1" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the progress on the full path from 0 to 1, where 0 means the origin and 1 the end.", + "fullName": "Progress", + "functionType": "Expression", + "name": "Progress", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "mod(Object.Behavior::PropertyCurrentLength(), Object.Behavior::TotalLength())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the length of the path (one repetition only).", + "fullName": "Path length", + "functionType": "Expression", + "name": "PathLength", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "CurvedMovement::PathLength(Object.Behavior::PropertyPathName())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the length of the complete trajectory (without looping).", + "fullName": "Total length", + "functionType": "Expression", + "name": "TotalLength", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "CurvedMovement::PathLength(Object.Behavior::PropertyPathName()) * Object.Behavior::PropertyRepetitionCount()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the displacement on X axis of the path end.", + "fullName": "Path end X", + "functionType": "Expression", + "name": "PathEndX", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "CurvedMovement::PathEndX(Object.Behavior::PropertyPathName())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the displacement on Y axis of the path end.", + "fullName": "Path end Y", + "functionType": "Expression", + "name": "PathEndY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "CurvedMovement::PathEndY(Object.Behavior::PropertyPathName())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the speed scale on Y axis of the path.", + "fullName": "Path speed scale Y", + "functionType": "Expression", + "name": "PathSpeedScaleY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "CurvedMovement::SpeedScaleY(Object.Behavior::PropertyPathName())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the angle to use when the object is going back or not.", + "fullName": "Back or forth angle", + "functionType": "Expression", + "name": "BackOrForthAngle", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertySpeed" + }, + "parameters": [ + "Object", + "Behavior", + "<", + "0" + ] + }, + { + "type": { + "value": "CurvedMovement::SpeedPathMovement::PropertyIsLookingBack" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "180" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the path origin on X axis of the object.", + "fullName": "Path origin X", + "functionType": "Expression", + "group": "Movement on a curve (speed-based) configuration", + "name": "PathOriginX", + "sentence": "the path origin on X axis", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyPathOriginX()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Return the path origin on Y axis of the object.", + "fullName": "Path origin Y", + "functionType": "Expression", + "group": "Movement on a curve (speed-based) configuration", + "name": "PathOriginY", + "sentence": "the path origin on Y axis", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyPathOriginY()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "CurvedMovement::SpeedPathMovement", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "true", + "type": "Boolean", + "label": "Rotate object", + "description": "", + "group": "Rotation", + "extraInformation": [], + "hidden": false, + "name": "Rotation" + }, + { + "value": "0", + "type": "Number", + "unit": "DegreeAngle", + "label": "Rotation offset", + "description": "", + "group": "Rotation", + "extraInformation": [], + "hidden": false, + "name": "RotationOffset" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Speed" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathOriginX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathOriginY" + }, + { + "value": "", + "type": "String", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathName" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TargetedSpeed" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Acceleration" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DrawingElementIndex" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "X" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Y" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathAngle" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PathScale" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "RepetitionCount" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ShouldLoop" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DrawingPathOriginX" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DrawingPathOriginY" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "DebugLineStrokeWidth" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "PreviousSpeed" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "CurrentLength" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "IsLookingBack" + }, + { + "value": "Top-Down", + "type": "Choice", + "label": "Viewpoint", + "description": "", + "group": "", + "extraInformation": [ + "Top-Down", + "Isometry 2:1 (26.565°)" + ], + "hidden": false, + "name": "Viewpoint" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "@4ian", + "category": "Game mechanic", + "extensionNamespace": "", + "fullName": "Fire bullets", + "helpPath": "/extensions/fire-bullet/details", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWJ1bGxldCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik0xNCwyMkgxMFYyMUgxNFYyMk0xMywxMFY3SDExVjEwTDEwLDExLjVWMjBIMTRWMTEuNUwxMywxME0xMiwyQzEyLDIgMTEsMyAxMSw1VjZIMTNWNUMxMyw1IDEzLDMgMTIsMloiIC8+PC9zdmc+", + "name": "FireBullet", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/bullet.svg", + "shortDescription": "Fire bullets, manage ammo, reloading and overheating.", + "version": "0.6.3", + "description": [ + "This extension allows objects to fire bullets.", + "", + "It handles:", + "- Cooldown between shots", + "- Firing multiple bullets at a time ([open the project online](https://editor.gdevelop.io/?project=example://fire-bullet))", + "- Ammo management", + "- Overheat", + "", + "It can be used for:", + "- Twin-stick shooters ([open the project online](https://editor.gdevelop.io/?project=example://conviction-of-gun-dude-desktop))", + "- Shoot'em up ([open the project online](https://editor.gdevelop.io/?project=example://space-shooter))", + "", + "A simple example shows how to make firing patterns ([open the project online](https://editor.gdevelop.io/?project=example://firing-patterns))." + ], + "origin": { + "identifier": "FireBullet", + "name": "gdevelop-extension-store" + }, + "tags": [ + "fire", + "bullet", + "spawn", + "firerate", + "reload", + "weapon", + "ranged", + "ammo", + "overheat" + ], + "authorIds": [ + "wWP8BSlAW0UP4NeaHa2LcmmDzmH2", + "xpwUwByyImTDcHEqDUqfyg0oRBt1", + "2OwwM8ToR9dx9RJ2sAKTcrLmCB92", + "gqDaZjCfevOOxBYkK6zlhtZnXCg1" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "Fire bullets, manage ammo, reloading, and overheating.", + "fullName": "Fire bullets", + "name": "FireBullet", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"__FireBullet.FiringCooldown\"" + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyAmmoQuantity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyStartingAmmo()" + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyShotsBeforeNextReload" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyShotsPerReload()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "colorB": 224, + "colorG": 16, + "colorR": 189, + "creationTime": 0, + "name": "Take a shot (if triggered)", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Creators can use the \"FireBullet\" action multiple times in a frame and it will be counted as a single \"shot\"." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyHasJustFired" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Reset firing cooldown", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"__FireBullet.FiringCooldown\"" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Update ammo", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Subtract 1 from ammo (if not unlimited ammo)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::PropertyUnlimitedAmmo" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyAmmoQuantity" + }, + "parameters": [ + "Object", + "Behavior", + "-", + "1" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Update reloading counter", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyShotsPerReload" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyShotsBeforeNextReload" + }, + "parameters": [ + "Object", + "Behavior", + "-", + "1" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Automatically reload gun when needed", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyAutomaticReloading" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::IsReloadNeeded" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::IsReloadInProgress" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::ReloadAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Update Overheat", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Increase heat (if needed)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyHeatIncreasePerShot" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyHeatLevel" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "Object.Behavior::PropertyHeatIncreasePerShot()" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Check if this caused overheat" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyOverheatDuration" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::IsOverheated" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"__FireBullet.OverheatDuration\"" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Update statistics", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyTotalShotsFired" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Reset firing detection", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyHasJustFired" + }, + "parameters": [ + "Object", + "Behavior", + "=" + ] + } + ] + } + ], + "parameters": [] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Reload gun when needed", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Detect when reload is completed" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::IsReloadInProgress" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"__FireBullet.ReloadingTimer\"", + ">=", + "Object.Behavior::PropertyReloadDuration()" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyTotalReloadsCompleted" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyReloadInProgress" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::IsUnlimitedAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyShotsBeforeNextReload" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyShotsPerReload()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Only reload the amount of ammo available" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::IsUnlimitedAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyShotsBeforeNextReload" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(Object.Behavior::PropertyShotsPerReload(), Object.Behavior::PropertyAmmoQuantity())" + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Reduce heat level (based on cooling rate)", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::HeatLevel()", + ">", + "0" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyExponentialCoolingRate" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyHeatLevel" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, Object.Behavior::PropertyHeatLevel() - TimeDelta() * Object.Behavior::PropertyExponentialCoolingRate() * Object.Behavior::PropertyHeatLevel())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyLinearCoolingRate" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyHeatLevel" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "max(0, Object.Behavior::PropertyHeatLevel() - TimeDelta() * Object.Behavior::PropertyLinearCoolingRate())" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Fire bullets toward an object.", + "fullName": "Fire bullets toward an object", + "functionType": "Action", + "name": "FireTowardObject", + "sentence": "Fire _PARAM4_ from _PARAM0_, at position _PARAM2_; _PARAM3_, toward _PARAM5_ with speed _PARAM6_ px/s", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Calculate the trajectory angle and use the \"Fire bullets\" action", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::Fire" + }, + "parameters": [ + "Object", + "Behavior", + "GetArgumentAsNumber(\"XPosition\")", + "GetArgumentAsNumber(\"YPosition\")", + "Bullet", + "Object.AngleToObject(TargetObject)", + "GetArgumentAsNumber(\"Speed\")", + "" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "X position, where to create the bullet", + "name": "XPosition", + "type": "expression" + }, + { + "description": "Y position, where to create the bullet", + "name": "YPosition", + "type": "expression" + }, + { + "description": "The bullet object", + "name": "Bullet", + "type": "objectListOrEmptyIfJustDeclared" + }, + { + "description": "Target object", + "name": "TargetObject", + "type": "objectList" + }, + { + "description": "Speed of the bullet, in pixels per second", + "name": "Speed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Fire bullets toward a position.", + "fullName": "Fire bullets toward a position", + "functionType": "Action", + "name": "FireTowardPosition", + "sentence": "Fire _PARAM4_ from _PARAM0_, at position _PARAM2_; _PARAM3_, toward position _PARAM5_;_PARAM6_ with speed _PARAM7_ px/s", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Calculate the trajectory angle and use the \"Fire bullets\" action", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::Fire" + }, + "parameters": [ + "Object", + "Behavior", + "GetArgumentAsNumber(\"XPosition\")", + "GetArgumentAsNumber(\"YPosition\")", + "Bullet", + "Object.AngleToPosition(GetArgumentAsNumber(\"TargetXPosition\"), GetArgumentAsNumber(\"TargetYPosition\"))", + "GetArgumentAsNumber(\"Speed\")", + "" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "X position, where to create the bullet", + "name": "XPosition", + "type": "expression" + }, + { + "description": "Y position, where to create the bullet", + "name": "YPosition", + "type": "expression" + }, + { + "description": "The bullet object", + "name": "Bullet", + "type": "objectListOrEmptyIfJustDeclared" + }, + { + "description": "Target X position", + "name": "TargetXPosition", + "type": "expression" + }, + { + "description": "Target Y position", + "name": "TargetYPosition", + "type": "expression" + }, + { + "description": "Speed of the bullet, in pixels per second", + "name": "Speed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Fire bullets in the direction of a given angle.", + "fullName": "Fire bullets toward an angle", + "functionType": "Action", + "name": "Fire", + "sentence": "Fire _PARAM4_ from _PARAM0_, at position _PARAM2_; _PARAM3_, toward angle _PARAM5_ and speed _PARAM6_ px/s", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Check if ready to shoot", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::IsReadyToShoot" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyHasJustFired" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ], + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Single bullet", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::PropertyBulletQuantity()", + "=", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::FireSingleBullet" + }, + "parameters": [ + "Object", + "Behavior", + "GetArgumentAsNumber(\"XPosition\")", + "GetArgumentAsNumber(\"YPosition\")", + "Bullet", + "GetArgumentAsNumber(\"Angle\")", + "GetArgumentAsNumber(\"Speed\")", + "" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Multiple bullets", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::PropertyBulletQuantity()", + ">", + "1" + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "__FireBullet.CurrentBulletAngle", + "=", + "GetArgumentAsNumber(\"Angle\") - Object.Behavior::PropertyFiringArc()/2" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "__FireBullet.BatchOrderID", + "=", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "Object.Behavior::PropertyBulletQuantity()", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::FireSingleBullet" + }, + "parameters": [ + "Object", + "Behavior", + "GetArgumentAsNumber(\"XPosition\")", + "GetArgumentAsNumber(\"YPosition\")", + "Bullet", + "Object.Variable(__FireBullet.CurrentBulletAngle) + RandomInRange(-Object.Behavior::PropertyAngleVariance(),Object.Behavior::PropertyAngleVariance())", + "GetArgumentAsNumber(\"Speed\")", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Move temp variable to the next angle a bullet will be sent" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "__FireBullet.CurrentBulletAngle", + "+", + "Object.Behavior::PropertyFiringArc() / (Object.Behavior::PropertyBulletQuantity() - 1)" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Object", + "__FireBullet.BatchOrderID", + "+", + "1" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "X position, where to create the bullet", + "name": "XPosition", + "type": "expression" + }, + { + "description": "Y position, where to create the bullet", + "name": "YPosition", + "type": "expression" + }, + { + "description": "The bullet object", + "name": "Bullet", + "type": "objectListOrEmptyIfJustDeclared" + }, + { + "description": "Angle of the bullet, in degrees", + "name": "Angle", + "type": "expression" + }, + { + "description": "Speed of the bullet, in pixels per second", + "name": "Speed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Fire a single bullet. This is only meant to be used inside the \"Fire bullet\" action.", + "fullName": "Fire a single bullet", + "functionType": "Action", + "group": "Firing", + "name": "FireSingleBullet", + "private": true, + "sentence": "Fire a single bullet _PARAM4_ from _PARAM0_, at position _PARAM2_; _PARAM3_, with angle _PARAM5_ and speed _PARAM6_ px/s", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Fire a single bullet", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Create bullet" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Bullet", + "GetArgumentAsNumber(\"XPosition\")", + "GetArgumentAsNumber(\"YPosition\")", + "Object.Behavior::PropertyBulletLayer()" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Move bullet (apply angle and bullet speed variances)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyRandomizedAngle" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Angle\") + RandomInRange(-Object.Behavior::PropertyAngleVariance(), Object.Behavior::PropertyAngleVariance())" + ] + }, + { + "type": { + "value": "AddForceAL" + }, + "parameters": [ + "Bullet", + "Object.Behavior::PropertyRandomizedAngle()", + "GetArgumentAsNumber(\"Speed\") + RandomInRange(-Object.Behavior::PropertyBulletSpeedVariance(), Object.Behavior::PropertyBulletSpeedVariance())", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Add identifier variables (to enable advanced picking by users)" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Bullet", + "__FireBullet.BulletID", + "=", + "Object.Behavior::PropertyTotalBulletsCreated()" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Bullet", + "__FireBullet.BatchID", + "=", + "Object.Behavior::PropertyTotalShotsFired()" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Bullet", + "__FireBullet.BatchOrderID", + "=", + "0" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Rotate newly created bullet, if needed" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyRotateBullet" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetAngle" + }, + "parameters": [ + "Bullet", + "=", + "Object.Behavior::PropertyRandomizedAngle()" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Update statistics" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyTotalBulletsCreated" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "X position, where to create the bullet", + "name": "XPosition", + "type": "expression" + }, + { + "description": "Y position, where to create the bullet", + "name": "YPosition", + "type": "expression" + }, + { + "description": "The bullet object", + "name": "Bullet", + "type": "objectListOrEmptyIfJustDeclared" + }, + { + "description": "Angle of the bullet, in degrees", + "name": "Angle", + "type": "expression" + }, + { + "description": "Speed of the bullet, in pixels per second", + "name": "Speed", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Reload ammo.", + "fullName": "Reload ammo", + "functionType": "Action", + "name": "ReloadAmmo", + "sentence": "Reload ammo on _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::IsOutOfAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyReloadInProgress" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + }, + { + "type": { + "value": "ResetObjectTimer" + }, + "parameters": [ + "Object", + "\"__FireBullet.ReloadingTimer\"" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object has just fired something.", + "fullName": "Has just fired", + "functionType": "Condition", + "group": "Firing", + "name": "HasJustFired", + "sentence": "_PARAM0_ has just fired", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "False" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyHasJustFired" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if bullet rotates to match trajectory.", + "fullName": "Is bullet rotation enabled", + "functionType": "Condition", + "group": "Firing", + "name": "BulletRotationEnabled", + "sentence": "Bullet rotation enabled on _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyRotateBullet" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the firing arc (in degrees) where bullets are shot. Bullets are evenly spaced out inside the firing arc.", + "fullName": "Firing arc", + "functionType": "ExpressionAndCondition", + "group": "Multi-Fire", + "name": "FiringArc", + "sentence": "the firing arc", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyFiringArc()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "FiringArc", + "name": "SetFiringArcOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyFiringArc" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Firing arc (degrees) Range: 0 to 360", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the firing arc (in degrees) where bullets will be shot. Bullets will be evenly spaced out inside the firing arc.", + "fullName": "Set firing arc (deprecated)", + "functionType": "Action", + "group": "Multi-Fire", + "name": "SetFiringArc", + "private": true, + "sentence": "Set firing arc of _PARAM0_ to _PARAM2_ degrees", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetFiringArcOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Firing arc (degrees) Range: 0 to 360", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the angle variance (in degrees) applied to each bullet.", + "fullName": "Angle variance", + "functionType": "ExpressionAndCondition", + "group": "Firing variance", + "name": "AngleVariance", + "sentence": "the angle variance", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyAngleVariance()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "AngleVariance", + "name": "SetAngleVarianceOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyAngleVariance" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Angle variance (degrees) Range: 0 to 180", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the angle variance (in degrees) applied to each bullet.", + "fullName": "Set angle variance (deprecated)", + "functionType": "Action", + "group": "Firing", + "name": "SetAngleVariance", + "private": true, + "sentence": "Set angle variance of _PARAM0_ to _PARAM2_ degrees", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetAngleVarianceOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Angle variance (degrees) Range: 0 to 180", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the bullet speed variance (pixels per second) applied to each bullet.", + "fullName": "Bullet speed variance", + "functionType": "ExpressionAndCondition", + "group": "Firing variance", + "name": "BulletSpeedVariance", + "sentence": "the bullet speed variance", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBulletSpeedVariance()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "BulletSpeedVariance", + "name": "SetBulletSpeedVarianceOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyBulletSpeedVariance" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Angle variance (degrees) Range: 0 to 180", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the speed variance (pixels per second) applied to each bullet.", + "fullName": "Set bullet speed variance (deprecated)", + "functionType": "Action", + "group": "Multi-Fire", + "name": "SetBulletSpeedVariance", + "private": true, + "sentence": "Set bullet speed variance of _PARAM0_ to _PARAM2_ pixels per second", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetBulletSpeedVarianceOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Angle variance (degrees) Range: 0 to 180", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the number of bullets shot every time the \"fire bullet\" action is used.", + "fullName": "Bullets per shot", + "functionType": "ExpressionAndCondition", + "group": "Multi-Fire", + "name": "BulletQuantity", + "sentence": "the number of bullets per shot", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBulletQuantity()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "BulletQuantity", + "name": "SetBulletQuantityOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyBulletQuantity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Bullets", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the number of bullets shot every time the \"fire bullet\" action is used.", + "fullName": "Set number of bullets per shot (deprecated)", + "functionType": "Action", + "group": "Multi-Fire", + "name": "SetBulletQuantity", + "private": true, + "sentence": "Set number of bullets per shot of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetBulletQuantityOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Bullets", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the layer that bullets are created on.", + "fullName": "Set bullet layer", + "functionType": "Action", + "group": "Firing", + "name": "SetBulletLayer", + "sentence": "Set the layer used to create bullets fired by _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyBulletLayer" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsString(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Layer", + "name": "Value", + "type": "layer" + } + ], + "objectGroups": [] + }, + { + "description": "Enable bullet rotation.", + "fullName": "Enable (or disable) bullet rotation", + "functionType": "Action", + "group": "Firing", + "name": "SetRotateBullet", + "sentence": "Enable bullet rotation on _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"RotateBullet\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyRotateBullet" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"RotateBullet\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyRotateBullet" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "defaultValue": "yes", + "description": "Rotate bullet to match trajetory", + "name": "RotateBullet", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Enable unlimited ammo.", + "fullName": "Enable (or disable) unlimited ammo", + "functionType": "Action", + "group": "Ammo", + "name": "SetUnlimitedAmmo", + "sentence": "Enable unlimited ammo on _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"UnlimitedAmmo\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyUnlimitedAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"UnlimitedAmmo\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyUnlimitedAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "defaultValue": "yes", + "description": "Unlimited ammo", + "name": "UnlimitedAmmo", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "the firing cooldown (in seconds) also known as rate of fire.", + "fullName": "Firing cooldown", + "functionType": "ExpressionAndCondition", + "group": "Firing", + "name": "Cooldown", + "sentence": "the firing cooldown", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyFireCooldown()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Cooldown", + "name": "SetCooldownOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyFireCooldown" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Cooldown in seconds", + "name": "NewCooldown", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the firing cooldown, which changes the rate of fire.", + "fullName": "Set firing cooldown (deprecated)", + "functionType": "Action", + "group": "Firing", + "name": "SetCooldown", + "private": true, + "sentence": "Set the fire rate of _PARAM0_ to _PARAM2_ seconds", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetCooldownOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"NewCooldown\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Cooldown in seconds", + "name": "NewCooldown", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the reload duration (in seconds).", + "fullName": "Reload duration", + "functionType": "ExpressionAndCondition", + "group": "Reload", + "name": "ReloadDuration", + "sentence": "the reload duration", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyReloadDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ReloadDuration", + "name": "SetReloadDurationOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyReloadDuration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Reload duration (seconds)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the duration to reload ammo.", + "fullName": "Set reload duration (deprecated)", + "functionType": "Action", + "group": "Reload", + "name": "SetReloadDuration", + "private": true, + "sentence": "Set the reload duration of _PARAM0_ to _PARAM2_ seconds", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetReloadDurationOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Reload duration (seconds)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the overheat duration (in seconds). When an object is overheated, it can't fire for this duration.", + "fullName": "Overheat duration", + "functionType": "ExpressionAndCondition", + "group": "Overheat", + "name": "OverheatDuration", + "sentence": "the overheat duration", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyOverheatDuration()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "OverheatDuration", + "name": "SetOverheatDurationOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyOverheatDuration" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Overheat duration (seconds)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the duration after becoming overheated.", + "fullName": "Set overheat duration (deprecated)", + "functionType": "Action", + "group": "Overheat", + "name": "SetOverheatDuration", + "private": true, + "sentence": "Set the overheat duration of _PARAM0_ to _PARAM2_ seconds", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetOverheatDurationOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Overheat duration (seconds)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the ammo quantity.", + "fullName": "Ammo quantity", + "functionType": "ExpressionAndCondition", + "group": "Ammo", + "name": "AmmoQuantity", + "sentence": "the ammo quantity", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyAmmoQuantity()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "AmmoQuantity", + "name": "SetAmmoQuantityOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyAmmoQuantity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Ammo", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the quantity of ammo.", + "fullName": "Set ammo quantity (deprecated)", + "functionType": "Action", + "group": "Ammo", + "name": "SetAmmoQuantity", + "private": true, + "sentence": "Set the ammo quantity of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetAmmoQuantityOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Ammo", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the heat increase per shot.", + "fullName": "Heat increase per shot", + "functionType": "ExpressionAndCondition", + "group": "Overheat", + "name": "HeatIncreasePerShot", + "sentence": "the heat increase per shot", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyHeatIncreasePerShot()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "HeatIncreasePerShot", + "name": "SetHeatPerShotOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyHeatIncreasePerShot" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Heat increase per shot (Range: 0 to 1)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the heat increase per shot.", + "fullName": "Set heat increase per shot (deprecated)", + "functionType": "Action", + "group": "Overheat", + "name": "SetHeatPerShot", + "private": true, + "sentence": "Set the heat increase of _PARAM0_ to _PARAM2_ per shot", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetHeatPerShotOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Heat increase per shot (Range: 0 to 1)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the max ammo.", + "fullName": "Max ammo", + "functionType": "ExpressionAndCondition", + "group": "Ammo", + "name": "MaxAmmo", + "sentence": "the max ammo", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyMaxAmmo()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "MaxAmmo", + "name": "SetMaxAmmoOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyMaxAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyMaxAmmo" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyAmmoQuantity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(Object.Behavior::MaxAmmo(),Object.Behavior::AmmoQuantity())" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Max ammo", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the max ammo.", + "fullName": "Set max ammo (deprecated)", + "functionType": "Action", + "group": "Ammo", + "name": "SetMaxAmmo", + "private": true, + "sentence": "Set the max ammo of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetMaxAmmoOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Max ammo", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Reset total shots fired.", + "fullName": "Reset total shots fired", + "functionType": "Action", + "group": "Stats", + "name": "ResetTotalShotsFired", + "sentence": "Reset total shots fired by _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyTotalShotsFired" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Reset total bullets created.", + "fullName": "Reset total bullets created", + "functionType": "Action", + "group": "Stats", + "name": "ResetTotalBulletsCreated", + "sentence": "Reset total bullets created by _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyTotalBulletsCreated" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Reset total reloads completed.", + "fullName": "Reset total reloads completed", + "functionType": "Action", + "group": "Stats", + "name": "ResetTotalReloadsCompleted", + "sentence": "Reset total reloads completed by _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyTotalReloadsCompleted" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the number of shots per reload.", + "fullName": "Shots per reload", + "functionType": "ExpressionAndCondition", + "group": "Reload", + "name": "ShotsPerReload", + "sentence": "the shots per reload", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyShotsPerReload()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShotsPerReload", + "name": "SetShotsPerReloadOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyShotsPerReload" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyShotsBeforeNextReload" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "Object.Behavior::PropertyShotsPerReload()" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyShotsBeforeNextReload" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.Behavior::PropertyShotsPerReload()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Shots per reload", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the number of shots per reload.", + "fullName": "Set shots per reload (deprecated)", + "functionType": "Action", + "group": "Reload", + "name": "SetShotsPerReload", + "private": true, + "sentence": "Set the shots per reload of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetShotsPerReloadOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Shots per reload", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Enable (or disable) automatic reloading.", + "fullName": "Enable (or disable) automatic reloading", + "functionType": "Action", + "group": "Reload", + "name": "SetAutomaticReload", + "sentence": "Enable automatic reloading on _PARAM0_: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyAutomaticReloading" + }, + "parameters": [ + "Object", + "Behavior", + "=" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Value\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyAutomaticReloading" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "defaultValue": "yes", + "description": "Enable automatic reloading", + "name": "Value", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "the linear cooling rate (per second).", + "fullName": "Linear cooling rate", + "functionType": "ExpressionAndCondition", + "group": "Overheat", + "name": "LinearCoolingRate", + "sentence": "the linear cooling rate", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyLinearCoolingRate()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "LinearCoolingRate", + "name": "SetLinearCoolingRateOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyLinearCoolingRate" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Heat cooling rate (per second)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the linear rate of cooling.", + "fullName": "Set linear cooling rate (deprecated)", + "functionType": "Action", + "group": "Overheat", + "name": "SetLinearCoolingRate", + "private": true, + "sentence": "Set the linear cooling rate of _PARAM0_ to _PARAM2_ per second", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetLinearCoolingRateOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Heat cooling rate (per second)", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the exponential cooling rate, per second.", + "fullName": "Exponential cooling rate", + "functionType": "ExpressionAndCondition", + "group": "Overheat", + "name": "ExponentialCoolingRate", + "sentence": "the exponential cooling rate", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyExponentialCoolingRate()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ExponentialCoolingRate", + "name": "SetExponentialCoolingRateOp", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyExponentialCoolingRate" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Exponential cooling rate", + "name": "Value", + "supplementaryInformation": "[\"Exponential\",\"Linear\"]", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Change the exponential rate of cooling.", + "fullName": "Set exponential cooling rate (deprecated)", + "functionType": "Action", + "group": "Overheat", + "name": "SetExponentialCoolingRate", + "private": true, + "sentence": "Set the exponential cooling rate of _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetExponentialCoolingRateOp" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Exponential cooling rate", + "name": "Value", + "supplementaryInformation": "[\"Exponential\",\"Linear\"]", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Increase ammo quantity.", + "fullName": "Increase ammo", + "functionType": "Action", + "name": "IncreaseAmmo", + "sentence": "Increase ammo of _PARAM0_ by _PARAM2_ shots", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyAmmoQuantity" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "GetArgumentAsNumber(\"AmmoGained\")" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "If Max Ammo is set, do not exceed the value" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyMaxAmmo" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::SetPropertyAmmoQuantity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "min(Object.Behavior::MaxAmmo(),Object.Behavior::AmmoQuantity())" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::IsReloadNeeded" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::PropertyAutomaticReloading" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "FireBullet::FireBullet::ReloadAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + }, + { + "description": "Ammo gained", + "name": "AmmoGained", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Layer that bullets are created on.", + "fullName": "Bullet layer", + "functionType": "StringExpression", + "group": "Multi-Fire", + "name": "BulletLayer", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "Object.Behavior::PropertyBulletLayer()" + ] + } + ] + } + ], + "expressionType": { + "type": "layer" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the heat level (range: 0 to 1).", + "fullName": "Heat level", + "functionType": "ExpressionAndCondition", + "group": "Overheat", + "name": "HeatLevel", + "sentence": "the heat level", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "min(1,Object.Behavior::PropertyHeatLevel())" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Total shots fired (multi-bullet shots are considered one shot).", + "fullName": "Shots fired", + "functionType": "Expression", + "group": "Stats", + "name": "TotalShotsFired", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTotalShotsFired()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Total bullets created.", + "fullName": "Bullets created", + "functionType": "Expression", + "group": "Stats", + "name": "TotalBulletsCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTotalBulletsCreated()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Reloads completed.", + "fullName": "Reloads completed", + "functionType": "Expression", + "group": "Stats", + "name": "TotalReloadsCompleted", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTotalReloadsCompleted()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the remaining shots before the next reload is required.", + "fullName": "Shots before next reload", + "functionType": "ExpressionAndCondition", + "group": "Reload", + "name": "ShotsBeforeNextReload", + "sentence": "the remaining shots (before the next reload)", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyShotsBeforeNextReload()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the remaining duration before the cooldown will permit a bullet to be fired, in seconds.", + "fullName": "Duration before cooldown end", + "functionType": "ExpressionAndCondition", + "group": "Firing", + "name": "CooldownTimeLeft", + "sentence": "the remaining duration before the cooldown end", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "max(0,Object.Behavior::Cooldown() - Object.ObjectTimerElapsedTime(\"__FireBullet.FiringCooldown\"))" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the remaining duration before the overheat penalty ends, in seconds.", + "fullName": "Duration before overheat end", + "functionType": "ExpressionAndCondition", + "group": "Overheat", + "name": "OverheatTimeLeft", + "sentence": "the remaining duration before the overheat end", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CompareObjectTimer" + }, + "parameters": [ + "Object", + "\"__FireBullet.OverheatDuration\"", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "max(0, Object.Behavior::PropertyOverheatDuration() - Object.ObjectTimerElapsedTime(\"__FireBullet.OverheatDuration\"))" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if object is currently performing an ammo reload.", + "fullName": "Is ammo reloading in progress", + "functionType": "Condition", + "group": "Reload", + "name": "IsReloadInProgress", + "sentence": "_PARAM0_ is reloading ammo", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "False" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyReloadInProgress" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if object is ready to shoot.", + "fullName": "Is ready to shoot", + "functionType": "Condition", + "group": "Firing", + "name": "IsReadyToShoot", + "sentence": "_PARAM0_ is ready to shoot", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "False" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyHasJustFired" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::And" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "BehaviorActivated" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::IsOutOfAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::IsReloadNeeded" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::IsReloadInProgress" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::IsFiringCooldownActive" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::IsOverheated" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if automatic reloading is enabled.", + "fullName": "Is automatic reloading enabled", + "functionType": "Condition", + "group": "Reload", + "name": "IsAutomaticReloadingEnabled", + "sentence": "Automatic reloading is enabled on_PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "False" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyAutomaticReloading" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if ammo is unlimited.", + "fullName": "Is ammo unlimited", + "functionType": "Condition", + "group": "Ammo", + "name": "IsUnlimitedAmmo", + "sentence": "_PARAM0_ has unlimited ammo", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "False" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyUnlimitedAmmo" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if object has no ammo available.", + "fullName": "Is out of ammo", + "functionType": "Condition", + "group": "Ammo", + "name": "IsOutOfAmmo", + "sentence": "_PARAM0_ is out of ammo", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "False" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "FireBullet::FireBullet::IsUnlimitedAmmo" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::PropertyAmmoQuantity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if object needs to reload ammo.", + "fullName": "Is a reload needed", + "functionType": "Condition", + "group": "Reload", + "name": "IsReloadNeeded", + "sentence": "_PARAM0_ needs to reload ammo", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "False" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Shots per reload must not be \"0\"" + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyShotsPerReload" + }, + "parameters": [ + "Object", + "Behavior", + ">", + "0" + ] + }, + { + "type": { + "value": "FireBullet::FireBullet::PropertyShotsBeforeNextReload" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if object is overheated.", + "fullName": "Is overheated", + "functionType": "Condition", + "group": "Overheat", + "name": "IsOverheated", + "sentence": "_PARAM0_ is overheated", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "False" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "FireBullet::FireBullet::PropertyHeatLevel" + }, + "parameters": [ + "Object", + "Behavior", + ">=", + "1" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::OverheatTimeLeft()", + ">", + "0" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if firing cooldown is active.", + "fullName": "Is firing cooldown active", + "functionType": "Condition", + "group": "Firing", + "name": "IsFiringCooldownActive", + "sentence": "Firing cooldown is active on _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "False" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Behavior::CooldownTimeLeft()", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "FireBullet::FireBullet", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "0.1", + "type": "Number", + "unit": "Second", + "label": "Firing cooldown", + "description": "Objects cannot shoot while firing cooldown is active", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "FireCooldown" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "HasJustFired" + }, + { + "value": "45", + "type": "Number", + "unit": "DegreeAngle", + "label": "Firing arc", + "description": "Multi-Fire bullets will be evenly spaced inside the firing arc", + "group": "Multi-Fire", + "extraInformation": [], + "hidden": false, + "name": "FiringArc" + }, + { + "value": "1", + "type": "Number", + "label": "Number of bullets created at once (Multi-Fire)", + "description": "Multi-Fire bullets will be evenly spaced inside the firing arc", + "group": "Multi-Fire", + "extraInformation": [], + "hidden": false, + "name": "BulletQuantity" + }, + { + "value": "0", + "type": "Number", + "unit": "DegreeAngle", + "label": "Angle variance", + "description": "Make imperfect aim (Range: 0 to 180 degrees)", + "group": "Firing variance", + "extraInformation": [], + "hidden": false, + "name": "AngleVariance" + }, + { + "value": "true", + "type": "Boolean", + "label": "Rotate bullets to match their trajectory", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "RotateBullet" + }, + { + "value": "0", + "type": "Number", + "label": "Ammo quantity (current)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "AmmoQuantity" + }, + { + "value": "0", + "type": "Number", + "label": "Shots per reload ", + "description": "Use 0 to disable reloading", + "group": "Reload", + "extraInformation": [], + "hidden": false, + "name": "ShotsPerReload" + }, + { + "value": "1", + "type": "Number", + "unit": "Second", + "label": "Reloading duration", + "description": "Objects cannot shoot while reloading is in progress", + "group": "Reload", + "extraInformation": [], + "hidden": false, + "name": "ReloadDuration" + }, + { + "value": "0", + "type": "Number", + "label": "Max ammo ", + "description": "", + "group": "Ammo", + "extraInformation": [], + "hidden": false, + "name": "MaxAmmo" + }, + { + "value": "0", + "type": "Number", + "label": "Shots before next reload", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ShotsBeforeNextReload" + }, + { + "value": "0", + "type": "Number", + "label": "Total shots fired", + "description": "Regardless of how many bullets are created, only 1 shot will be counted per frame", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TotalShotsFired" + }, + { + "value": "0", + "type": "Number", + "label": "Total bullets created", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TotalBulletsCreated" + }, + { + "value": "0", + "type": "Number", + "label": "Starting ammo", + "description": "", + "group": "Ammo", + "extraInformation": [], + "hidden": false, + "name": "StartingAmmo" + }, + { + "value": "0", + "type": "Number", + "label": "Total reloads completed", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TotalReloadsCompleted" + }, + { + "value": "true", + "type": "Boolean", + "label": "Unlimited ammo", + "description": "", + "group": "Ammo", + "extraInformation": [], + "hidden": false, + "name": "UnlimitedAmmo" + }, + { + "value": "", + "type": "Boolean", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ReloadInProgress" + }, + { + "value": "0", + "type": "Number", + "label": "Heat increase per shot (Range: 0 to 1)", + "description": " Object is overheated when Heat reaches 1", + "group": "Overheat", + "extraInformation": [], + "hidden": false, + "name": "HeatIncreasePerShot" + }, + { + "value": "0", + "type": "Number", + "label": "Heat level (Range: 0 to 1)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "HeatLevel" + }, + { + "value": "true", + "type": "Boolean", + "label": "Reload automatically", + "description": "", + "group": "Reload", + "extraInformation": [], + "hidden": false, + "name": "AutomaticReloading" + }, + { + "value": "0", + "type": "Number", + "unit": "Second", + "label": "Overheat duration", + "description": "Object cannot shoot while overheat duration is active", + "group": "Overheat", + "extraInformation": [], + "hidden": false, + "name": "OverheatDuration" + }, + { + "value": "0.1", + "type": "Number", + "label": "Linear cooling rate (per second)", + "description": "", + "group": "Overheat", + "extraInformation": [], + "hidden": false, + "name": "LinearCoolingRate" + }, + { + "value": "0.3", + "type": "Number", + "label": "Exponential cooling rate (per second)", + "description": "Happens faster when heat is high and slower when heat is low", + "group": "Overheat", + "extraInformation": [ + "Linear", + "Exponential" + ], + "hidden": false, + "name": "ExponentialCoolingRate" + }, + { + "value": "", + "type": "String", + "label": "Layer the bullets are created on", + "description": "Base layer by default", + "group": "Shooting configuration", + "extraInformation": [], + "hidden": true, + "name": "BulletLayer" + }, + { + "value": "0", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "RandomizedAngle" + }, + { + "value": "0", + "type": "Number", + "unit": "PixelSpeed", + "label": "Bullet speed variance", + "description": "Bullet speed will be adjusted by a random value within this range", + "group": "Firing variance", + "extraInformation": [], + "hidden": false, + "name": "BulletSpeedVariance" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "", + "category": "", + "extensionNamespace": "", + "fullName": "", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXRpbWVyLW91dGxpbmUiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTIsMjBBNyw3IDAgMCwxIDUsMTNBNyw3IDAgMCwxIDEyLDZBNyw3IDAgMCwxIDE5LDEzQTcsNyAwIDAsMSAxMiwyME0xOS4wMyw3LjM5TDIwLjQ1LDUuOTdDMjAsNS40NiAxOS41NSw1IDE5LjA0LDQuNTZMMTcuNjIsNkMxNi4wNyw0Ljc0IDE0LjEyLDQgMTIsNEE5LDkgMCAwLDAgMywxM0E5LDkgMCAwLDAgMTIsMjJDMTcsMjIgMjEsMTcuOTcgMjEsMTNDMjEsMTAuODggMjAuMjYsOC45MyAxOS4wMyw3LjM5TTExLDE0SDEzVjhIMTFNMTUsMUg5VjNIMTVWMVoiIC8+PC9zdmc+", + "name": "AdvancedTimer", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/632ad4b4fbdffa09f26d1e73058989bd488b2441c4e85b125c6db16c39c1a1c3_timer-outline.svg", + "shortDescription": "", + "version": "", + "description": "", + "tags": [], + "authorIds": [], + "dependencies": [], + "eventsFunctions": [ + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ObjectTimerElapsedTime", + "name": "SetObjectTimerElapsedTime", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const timerName = eventsFunctionContext.getArgument(\"Timer\");", + "const timerValue = eventsFunctionContext.getArgument(\"Value\");", + "", + "for (const object of objects) {", + " object.unpauseTimer(timerName);", + " object._timers.get(timerName).setTime(timerValue * 1000);", + "}", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "objectList" + }, + { + "description": "Timer's name", + "name": "Timer", + "supplementaryInformation": "objectobjectTimer", + "type": "identifier" + }, + { + "description": "Time in seconds", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the elapsed time of an object timer.", + "fullName": "Object timer value", + "functionType": "ExpressionAndCondition", + "name": "ObjectTimerElapsedTime", + "private": true, + "sentence": "the timer _PARAM1_ of _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.ObjectTimerElapsedTime(GetArgumentAsString(\"Timer\"))" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "objectList" + }, + { + "description": "Timer's name", + "name": "Timer", + "supplementaryInformation": "objectobjectTimer", + "type": "identifier" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [], + "eventsBasedObjects": [] + } + ], + "externalLayouts": [], + "externalSourceFiles": [] +} \ No newline at end of file