gdcore-tools 2.0.0-gd-v5.5.236-autobuild → 2.0.0-gd-v5.5.237-autobuild

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/Runtime/CustomRuntimeObject.js +1 -1
  2. package/dist/Runtime/CustomRuntimeObject.js.map +2 -2
  3. package/dist/Runtime/CustomRuntimeObjectInstanceContainer.js +1 -1
  4. package/dist/Runtime/CustomRuntimeObjectInstanceContainer.js.map +2 -2
  5. package/dist/Runtime/Extensions/3D/A_RuntimeObject3D.js +1 -1
  6. package/dist/Runtime/Extensions/3D/A_RuntimeObject3D.js.map +2 -2
  7. package/dist/Runtime/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.js +1 -1
  8. package/dist/Runtime/Extensions/3D/Cube3DRuntimeObjectPixiRenderer.js.map +2 -2
  9. package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js +1 -1
  10. package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js.map +2 -2
  11. package/dist/Runtime/Extensions/3D/DirectionalLight.js +1 -1
  12. package/dist/Runtime/Extensions/3D/DirectionalLight.js.map +2 -2
  13. package/dist/Runtime/Extensions/3D/HemisphereLight.js +1 -1
  14. package/dist/Runtime/Extensions/3D/HemisphereLight.js.map +2 -2
  15. package/dist/Runtime/Extensions/3D/JsExtension.js +5 -4
  16. package/dist/Runtime/Extensions/Multiplayer/JsExtension.js +67 -0
  17. package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js +1 -1
  18. package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js.map +2 -2
  19. package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js +1 -1
  20. package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js.map +2 -2
  21. package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject.js +1 -1
  22. package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject.js.map +2 -2
  23. package/dist/Runtime/Extensions/Physics3DBehavior/JsExtension.js +48 -0
  24. package/dist/Runtime/Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js +1 -1
  25. package/dist/Runtime/Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js.map +2 -2
  26. package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCar3DRuntimeBehavior.js +1 -1
  27. package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCar3DRuntimeBehavior.js.map +2 -2
  28. package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCharacter3DRuntimeBehavior.js +1 -1
  29. package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCharacter3DRuntimeBehavior.js.map +2 -2
  30. package/dist/Runtime/Extensions/Spine/spineruntimeobject.js +1 -1
  31. package/dist/Runtime/Extensions/Spine/spineruntimeobject.js.map +2 -2
  32. package/dist/Runtime/Extensions/TextInput/JsExtension.js +26 -0
  33. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject-pixi-renderer.js +1 -1
  34. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject-pixi-renderer.js.map +2 -2
  35. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject.js +1 -1
  36. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject.js.map +2 -2
  37. package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js +1 -1
  38. package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js.map +2 -2
  39. package/dist/Runtime/Extensions/TileMap/tilemapcollisionmaskruntimeobject.js +1 -1
  40. package/dist/Runtime/Extensions/TileMap/tilemapcollisionmaskruntimeobject.js.map +2 -2
  41. package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject.js +1 -1
  42. package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject.js.map +2 -2
  43. package/dist/Runtime/Extensions/TiledSpriteObject/tiledspriteruntimeobject.js +1 -1
  44. package/dist/Runtime/Extensions/TiledSpriteObject/tiledspriteruntimeobject.js.map +2 -2
  45. package/dist/Runtime/Extensions/Video/videoruntimeobject.js +1 -1
  46. package/dist/Runtime/Extensions/Video/videoruntimeobject.js.map +2 -2
  47. package/dist/Runtime/events-tools/inputtools.js +1 -1
  48. package/dist/Runtime/events-tools/inputtools.js.map +2 -2
  49. package/dist/Runtime/runtimeobject.js +1 -1
  50. package/dist/Runtime/runtimeobject.js.map +2 -2
  51. package/dist/Runtime/types/project-data.d.ts +4 -0
  52. package/dist/lib/libGD.wasm +0 -0
  53. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../GDevelop/GDJS/Runtime/runtimeobject.ts"],
4
- "sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n /** An axis-aligned bounding box. Used to represents a box around an object for example. */\n export type AABB = {\n /** The [x,y] coordinates of the top left point */\n min: FloatPoint;\n /** The [x,y] coordinates of the bottom right point */\n max: FloatPoint;\n };\n\n export type RendererObjectInterface = {\n visible: boolean;\n };\n\n /**\n * Return the squared bounding radius of an object given its width/height and its center of rotation\n * (relative to the top-left of the object). The radius is relative to the center of rotation.\n */\n const computeSqBoundingRadius = (\n width: float,\n height: float,\n centerX: float,\n centerY: float\n ) => {\n const radiusX = Math.max(centerX, width - centerX);\n const radiusY = Math.max(centerY, height - centerY);\n return Math.pow(radiusX, 2) + Math.pow(radiusY, 2);\n };\n\n /**\n * Arrays and data structure that are (re)used by\n * {@link RuntimeObject.separateFromObjects} to avoid any allocation.\n */\n const separateFromObjectsStatics: {\n moveXArray: Array<float>;\n moveYArray: Array<float>;\n } = {\n moveXArray: [],\n moveYArray: [],\n };\n\n /**\n * Data structure that are (re)used by\n * {@link RuntimeObject.raycastTest} to avoid any allocation.\n */\n const raycastTestStatics: {\n result: RaycastTestResult;\n } = {\n result: gdjs.Polygon.makeNewRaycastTestResult(),\n };\n\n /**\n * Move the object using the results from collisionTest call.\n * This moves the object according to the direction of the longest vector,\n * and projects the others on the orthogonal vector.\n *\n * See {@link RuntimeObject.separateFromObjects}\n *\n * @param object The object to move.\n * @param moveXArray The X coordinates of the vectors to move the object.\n * @param moveYArray The Y coordinates of the vectors to move the object.\n * @return true if the object was moved.\n */\n const moveFollowingSeparatingVectors = (\n object: gdjs.RuntimeObject,\n moveXArray: Array<float>,\n moveYArray: Array<float>\n ): boolean => {\n if (moveXArray.length === 0) {\n moveXArray.length = 0;\n moveYArray.length = 0;\n return false;\n }\n if (moveXArray.length === 1) {\n // Move according to the results returned by the collision algorithm.\n object.setPosition(\n object.getX() + moveXArray[0],\n object.getY() + moveYArray[0]\n );\n moveXArray.length = 0;\n moveYArray.length = 0;\n return true;\n }\n\n // Find the longest vector\n let squaredDistanceMax = 0;\n let distanceMaxIndex = 0;\n for (let index = 0; index < moveXArray.length; index++) {\n const moveX = moveXArray[index];\n const moveY = moveYArray[index];\n\n const squaredDistance = moveX * moveX + moveY * moveY;\n if (squaredDistance > squaredDistanceMax) {\n squaredDistanceMax = squaredDistance;\n distanceMaxIndex = index;\n }\n }\n\n const distanceMax = Math.sqrt(squaredDistanceMax);\n // unit vector of the longest vector\n const uX = moveXArray[distanceMaxIndex] / distanceMax;\n const uY = moveYArray[distanceMaxIndex] / distanceMax;\n\n // normal vector of the longest vector\n const vX = -uY;\n const vY = uX;\n\n // Project other vectors on the normal\n let scalarProductMin = 0;\n let scalarProductMax = 0;\n for (let index = 0; index < moveXArray.length; index++) {\n const moveX = moveXArray[index];\n const moveY = moveYArray[index];\n\n const scalarProduct = moveX * vX + moveY * vY;\n scalarProductMin = Math.min(scalarProductMin, scalarProduct);\n scalarProductMax = Math.max(scalarProductMax, scalarProduct);\n }\n\n // Apply the longest vector\n let deltaX = moveXArray[distanceMaxIndex];\n let deltaY = moveYArray[distanceMaxIndex];\n\n // Apply the longest projected vector if they all are in the same direction\n // Some projections could have rounding errors,\n // they are considered negligible under a 1 for 1,000,000 ratio.\n const scalarProductMinIsNegligible =\n -scalarProductMin < scalarProductMax / 1048576;\n const scalarProductMaxIsNegligible =\n scalarProductMax < -scalarProductMin / 1048576;\n if (scalarProductMinIsNegligible !== scalarProductMaxIsNegligible) {\n if (scalarProductMaxIsNegligible) {\n deltaX += scalarProductMin * vX;\n deltaY += scalarProductMin * vY;\n } else {\n deltaX += scalarProductMax * vX;\n deltaY += scalarProductMax * vY;\n }\n }\n object.setPosition(object.getX() + deltaX, object.getY() + deltaY);\n moveXArray.length = 0;\n moveYArray.length = 0;\n return true;\n };\n\n /**\n * RuntimeObject represents an object being used on a RuntimeScene.\n *\n * A `gdjs.RuntimeObject` should not be instantiated directly, always a child class\n * (because gdjs.RuntimeObject don't call onCreated at the end of its constructor).\n */\n export class RuntimeObject implements EffectsTarget, gdjs.EffectHandler {\n name: string;\n type: string;\n x: float = 0;\n y: float = 0;\n angle: float = 0;\n zOrder: integer = 0;\n hidden: boolean = false;\n layer: string = '';\n protected _nameId: integer;\n protected _livingOnScene: boolean = true;\n\n readonly id: integer;\n private destroyCallbacks = new Set<() => void>();\n _runtimeScene: gdjs.RuntimeInstanceContainer;\n\n /**\n * An optional UUID associated to the object to be used\n * for hot reload. Don't modify or use otherwise.\n */\n persistentUuid: string | null = null;\n\n /**\n * A network ID associated to the object to be used\n * for multiplayer, to identify the object across peers.\n * We don't use persistentUuid as it's only used for hot-reload.\n * We don't use the object ID either as it's not unique across peers.\n */\n networkId: string | null = null;\n\n /**\n * A property to be used by external algorithms to indicate if the\n * object is picked or not in an object selection. By construction, this is\n * not \"thread safe\" or \"re-entrant algorithm\" safe.\n */\n pick: boolean = false;\n\n //Hit boxes:\n protected _defaultHitBoxes: gdjs.Polygon[] = [];\n protected hitBoxes: gdjs.Polygon[];\n protected hitBoxesDirty: boolean = true;\n protected aabb: AABB = { min: [0, 0], max: [0, 0] };\n protected _isIncludedInParentCollisionMask = true;\n\n //Variables:\n protected _variables: gdjs.VariablesContainer;\n\n //Effects:\n protected _rendererEffects: Record<string, gdjs.PixiFiltersTools.Filter> =\n {};\n\n //Forces:\n protected _instantForces: gdjs.Force[] = [];\n _permanentForceX: float = 0;\n _permanentForceY: float = 0;\n _totalForce: gdjs.Force;\n\n /**\n * Contains the behaviors of the object, except those not having lifecycle functions.\n *\n * This means default, hidden, \"capability\" behaviors are not included in this array.\n * This avoids wasting time iterating on them when we know their lifecycle functions\n * are never used.\n */\n protected _behaviors: gdjs.RuntimeBehavior[] = [];\n /**\n * Contains the behaviors of the object by name.\n *\n * This includes the default, hidden, \"capability\" behaviors (those to handle opacity,\n * effects, scale, size...).\n */\n protected _behaviorsTable: Hashtable<gdjs.RuntimeBehavior>;\n protected _timers: Hashtable<gdjs.Timer>;\n\n /**\n * @param instanceContainer The scene or custom object the object belongs to.\n * @param objectData The initial properties of the object.\n */\n constructor(\n instanceContainer: gdjs.RuntimeInstanceContainer,\n objectData: ObjectData & any\n ) {\n this.name = objectData.name || '';\n this.type = objectData.type || '';\n this._nameId = RuntimeObject.getNameIdentifier(this.name);\n this.id = instanceContainer.getScene().createNewUniqueId();\n this._runtimeScene = instanceContainer;\n this._defaultHitBoxes.push(gdjs.Polygon.createRectangle(0, 0));\n this.hitBoxes = this._defaultHitBoxes;\n this._variables = new gdjs.VariablesContainer(\n objectData ? objectData.variables : undefined\n );\n this._totalForce = new gdjs.Force(0, 0, 0);\n this._behaviorsTable = new Hashtable();\n for (let i = 0; i < objectData.effects.length; ++i) {\n this._runtimeScene\n .getGame()\n .getEffectsManager()\n .initializeEffect(objectData.effects[i], this._rendererEffects, this);\n this.updateAllEffectParameters(objectData.effects[i]);\n }\n //Also contains the behaviors: Used when a behavior is accessed by its name ( see getBehavior ).\n for (let i = 0, len = objectData.behaviors.length; i < len; ++i) {\n const autoData = objectData.behaviors[i];\n const Ctor = gdjs.getBehaviorConstructor(autoData.type);\n const behavior = new Ctor(instanceContainer, autoData, this);\n if (behavior.usesLifecycleFunction()) {\n this._behaviors.push(behavior);\n }\n this._behaviorsTable.put(autoData.name, behavior);\n }\n this._timers = new Hashtable();\n }\n\n //Common members functions related to the object and its runtimeScene :\n /**\n * To be called by the child classes in their constructor, at the very end.\n * Notify the behaviors that they have been constructed (this must be done when\n * the object is ready, otherwise behaviors can do operations on the object which\n * could be not initialized yet).\n *\n * If you redefine this function, **make sure to call the original method**\n * (`RuntimeObject.prototype.onCreated.call(this);`).\n */\n onCreated(): void {\n const rendererObject = this.getRendererObject();\n if (rendererObject) {\n for (const effectName in this._rendererEffects) {\n this._rendererEffects[effectName].applyEffect(this);\n }\n }\n\n for (let i = 0; i < this._behaviors.length; ++i) {\n this._behaviors[i].onCreated();\n }\n }\n\n /**\n * Called to reset the object to its default state. This is used for objects that are\n * \"recycled\": they are dismissed (at which point `onDeletedFromScene` is called) but still\n * stored in a cache to be reused next time an object must be created. At this point,\n * `reinitialize` will be called. The object must then work as if it was a newly constructed\n * object.\n *\n * To implement this in your object:\n * * Set `gdjs.YourRuntimeObject.supportsReinitialization = true;` to declare support for recycling.\n * * Implement `reinitialize`. It **must** call the `reinitialize` of `gdjs.RuntimeObject`, and call `this.onCreated();`\n * at the end of `reinitialize`.\n * * It must reset the object as if it was newly constructed (be careful about your renderers and any global state).\n * * The `_runtimeScene`, `_nameId`, `name` and `type` are guaranteed to stay the same and do not\n * need to be set again.\n *\n */\n reinitialize(objectData: ObjectData): void {\n const runtimeScene = this._runtimeScene;\n this.x = 0;\n this.y = 0;\n this.angle = 0;\n this.zOrder = 0;\n this.hidden = false;\n this.layer = '';\n this._livingOnScene = true;\n //@ts-ignore Reinitialize is like a constructor, it can overwrite the readonly property.\n this.id = runtimeScene\n //\n .getScene()\n .createNewUniqueId();\n this.persistentUuid = null;\n this.networkId = null;\n this.pick = false;\n this.hitBoxesDirty = true;\n this._defaultHitBoxes.length = 0;\n this._defaultHitBoxes.push(gdjs.Polygon.createRectangle(0, 0));\n this.aabb.min[0] = 0;\n this.aabb.min[1] = 0;\n this.aabb.max[0] = 0;\n this.aabb.max[1] = 0;\n this._variables = new gdjs.VariablesContainer(objectData.variables);\n this.clearForces();\n\n // Reinitialize behaviors.\n this._behaviorsTable.clear();\n const behaviorsDataCount = objectData.behaviors.length;\n let behaviorsUsingLifecycleFunctionCount = 0;\n for (\n let behaviorDataIndex = 0;\n behaviorDataIndex < behaviorsDataCount;\n ++behaviorDataIndex\n ) {\n const behaviorData = objectData.behaviors[behaviorDataIndex];\n const Ctor = gdjs.getBehaviorConstructor(behaviorData.type);\n // TODO: Add support for behavior recycling with a `reinitialize` method.\n const behavior = new Ctor(runtimeScene, behaviorData, this);\n if (behavior.usesLifecycleFunction()) {\n if (behaviorsUsingLifecycleFunctionCount < this._behaviors.length) {\n this._behaviors[behaviorsUsingLifecycleFunctionCount] = behavior;\n } else {\n this._behaviors.push(behavior);\n }\n behaviorsUsingLifecycleFunctionCount++;\n }\n this._behaviorsTable.put(behaviorData.name, behavior);\n }\n this._behaviors.length = behaviorsUsingLifecycleFunctionCount;\n\n // Reinitialize effects.\n for (let i = 0; i < objectData.effects.length; ++i) {\n this._runtimeScene\n .getGame()\n .getEffectsManager()\n .initializeEffect(objectData.effects[i], this._rendererEffects, this);\n this.updateAllEffectParameters(objectData.effects[i]);\n }\n\n // Make sure to delete existing timers.\n this._timers.clear();\n\n this.destroyCallbacks.clear();\n\n this.invalidateHitboxes();\n }\n\n static supportsReinitialization = false;\n\n /**\n * Return the time elapsed since the last frame,\n * in milliseconds, for the object.\n *\n * Objects can have different elapsed time if they are on layers with different time scales.\n */\n getElapsedTime(): float {\n const theLayer = this._runtimeScene.getLayer(this.layer);\n return theLayer.getElapsedTime();\n }\n\n /**\n * The gdjs.RuntimeScene the object belongs to.\n */\n getParent(): gdjs.RuntimeInstanceContainer {\n return this._runtimeScene;\n }\n\n /**\n * The gdjs.RuntimeScene the object belongs to.\n */\n getRuntimeScene(): gdjs.RuntimeScene {\n return this._runtimeScene.getScene();\n }\n\n /**\n * The container the object belongs to.\n */\n getInstanceContainer(): gdjs.RuntimeInstanceContainer {\n return this._runtimeScene;\n }\n\n /**\n * Called once during the game loop, before events and rendering.\n * @param instanceContainer The container the object belongs to.\n */\n update(instanceContainer: gdjs.RuntimeInstanceContainer): void {}\n\n /**\n * Called once during the game loop, after events and before rendering.\n * @param instanceContainer The container the object belongs to.\n */\n updatePreRender(instanceContainer: gdjs.RuntimeInstanceContainer): void {}\n\n /**\n * Called when the object is created from an initial instance at the startup of the scene.<br>\n * Note that common properties (position, angle, z order...) have already been setup.\n *\n * @param initialInstanceData The data of the initial instance.\n */\n extraInitializationFromInitialInstance(\n initialInstanceData: InstanceData\n ): void {}\n\n /**\n * Called when the object must be updated using the specified objectData. This is the\n * case during hot-reload, and is only called if the object was modified.\n *\n * @param oldObjectData The previous data for the object.\n * @param newObjectData The new data for the object.\n * @returns true if the object was updated, false if it could not (i.e: hot-reload is not supported).\n */\n updateFromObjectData(\n oldObjectData: ObjectData,\n newObjectData: ObjectData\n ): boolean {\n // If not redefined, mark by default the hot-reload as failed.\n return false;\n }\n\n /**\n * Called when trying to send all information about the state of an object to other peers.\n * This can be redefined by objects to send more information.\n * @returns The full network sync data.\n */\n getNetworkSyncData(): ObjectNetworkSyncData {\n const behaviorNetworkSyncData = {};\n this._behaviors.forEach((behavior) => {\n if (!behavior.isSyncedOverNetwork()) {\n return;\n }\n\n const networkSyncData = behavior.getNetworkSyncData();\n if (networkSyncData) {\n behaviorNetworkSyncData[behavior.getName()] = networkSyncData;\n }\n });\n\n const variablesNetworkSyncData = this._variables.getNetworkSyncData({\n // No need to send the player number, as the owner of the object syncs all its variables.\n });\n\n const effectsNetworkSyncData = {};\n for (const effectName in this._rendererEffects) {\n effectsNetworkSyncData[effectName] =\n this._rendererEffects[effectName].getNetworkSyncData();\n }\n\n const timersNetworkSyncData = {};\n for (const timerName in this._timers.items) {\n timersNetworkSyncData[timerName] =\n this._timers.items[timerName].getNetworkSyncData();\n }\n\n return {\n x: this.x,\n y: this.y,\n zo: this.zOrder,\n a: this.angle,\n hid: this.hidden,\n lay: this.layer,\n if: this._instantForces.map((force) => force.getNetworkSyncData()),\n pfx: this._permanentForceX,\n pfy: this._permanentForceY,\n beh: behaviorNetworkSyncData,\n var: variablesNetworkSyncData,\n eff: effectsNetworkSyncData,\n tim: timersNetworkSyncData,\n };\n }\n\n /**\n * Called when the object must be updated using the specified networkSyncData. This is the\n * case during an update of the object from the network.\n *\n * @param networkSyncData The new data for the object.\n * @returns true if the object was updated, false if it could not (i.e: network sync is not supported).\n */\n updateFromNetworkSyncData(networkSyncData: ObjectNetworkSyncData) {\n if (networkSyncData.x !== undefined) {\n this.setX(networkSyncData.x);\n }\n if (networkSyncData.y !== undefined) {\n this.setY(networkSyncData.y);\n }\n if (networkSyncData.zo !== undefined) {\n this.setZOrder(networkSyncData.zo);\n }\n if (networkSyncData.a !== undefined) {\n this.setAngle(networkSyncData.a);\n }\n if (\n networkSyncData.hid !== undefined &&\n this.hidden !== networkSyncData.hid\n ) {\n this.hide(networkSyncData.hid);\n }\n\n if (\n networkSyncData.lay !== undefined &&\n this.layer !== networkSyncData.lay\n ) {\n this.setLayer(networkSyncData.lay);\n }\n\n if (networkSyncData.if) {\n // Force clear all forces and reapply them, using the garbage collector to recycle forces.\n // Is that efficient?\n this.clearForces();\n for (let i = 0, len = networkSyncData.if.length; i < len; ++i) {\n const forceData = networkSyncData.if[i];\n const recycledOrNewForce = this._getRecycledForce(\n forceData.x,\n forceData.y,\n forceData.m\n );\n recycledOrNewForce.updateFromNetworkSyncData(forceData);\n this._instantForces.push(recycledOrNewForce);\n }\n }\n if (networkSyncData.pfx !== undefined) {\n this._permanentForceX = networkSyncData.pfx;\n }\n if (networkSyncData.pfy !== undefined) {\n this._permanentForceY = networkSyncData.pfy;\n }\n\n // Loop through all behaviors and update them.\n for (const behaviorName in networkSyncData.beh) {\n const behaviorNetworkSyncData = networkSyncData.beh[behaviorName];\n const behavior = this.getBehavior(behaviorName);\n if (behavior) {\n behavior.updateFromNetworkSyncData(behaviorNetworkSyncData);\n }\n }\n\n // If variables are synchronized, update them.\n if (networkSyncData.var) {\n this._variables.updateFromNetworkSyncData(networkSyncData.var);\n }\n\n // If effects are synchronized, update them.\n if (networkSyncData.eff) {\n // Loop through all effects and update them.\n for (const effectName in networkSyncData.eff) {\n const effectNetworkSyncData = networkSyncData.eff[effectName];\n const effect = this._rendererEffects[effectName];\n if (effect) {\n effect.updateFromNetworkSyncData(effectNetworkSyncData);\n }\n }\n }\n\n // If timers are synchronized, update them.\n // TODO: If a timer is removed, also remove it from the object?\n if (networkSyncData.tim) {\n for (const timerName in networkSyncData.tim) {\n const timerNetworkSyncData = networkSyncData.tim[timerName];\n const timer = this._timers.get(timerName);\n if (timer) {\n timer.updateFromNetworkSyncData(timerNetworkSyncData);\n }\n }\n }\n }\n\n /**\n * Remove an object from a scene.\n *\n * Do not change/redefine this method. Instead, redefine the onDeletedFromScene method.\n */\n deleteFromScene(): void {\n if (this._livingOnScene) {\n this._runtimeScene.markObjectForDeletion(this);\n this._livingOnScene = false;\n }\n }\n\n registerDestroyCallback(callback: () => void) {\n this.destroyCallbacks.add(callback);\n }\n\n unregisterDestroyCallback(callback: () => void) {\n this.destroyCallbacks.delete(callback);\n }\n\n /**\n * Called when the object is deleted (because it is removed from a scene or\n * the scene is being unloaded). The object is not actually destroyed and\n * can still be used by events.\n *\n * If you redefine this function, **make sure to call the original method**\n * (`super.onDeletedFromScene();`).\n */\n onDeletedFromScene(): void {\n const theLayer = this._runtimeScene.getLayer(this.layer);\n const rendererObject = this.getRendererObject();\n if (rendererObject) {\n theLayer.getRenderer().removeRendererObject(rendererObject);\n }\n const rendererObject3D = this.get3DRendererObject();\n if (rendererObject3D) {\n theLayer.getRenderer().remove3DRendererObject(rendererObject3D);\n }\n for (let j = 0, lenj = this._behaviors.length; j < lenj; ++j) {\n this._behaviors[j].onDestroy();\n }\n this.destroyCallbacks.forEach((c) => c());\n this.clearEffects();\n }\n\n /**\n * Called on deleted objects after all events has been executed for the\n * current frame and the object can be safely destroyed.\n */\n onDestroyed(): void {}\n\n /**\n * Called whenever the scene owning the object is paused.\n * This should *not* impact objects, but some may need to inform their renderer.\n *\n * @param runtimeScene The scene owning the object.\n */\n onScenePaused(runtimeScene: gdjs.RuntimeScene): void {}\n\n /**\n * Called whenever the scene owning the object is resumed after a pause.\n * This should *not* impact objects, but some may need to inform their renderer.\n *\n * @param runtimeScene The scene owning the object.\n */\n onSceneResumed(runtimeScene: gdjs.RuntimeScene): void {}\n\n //Rendering:\n /**\n * @return The internal object for a 2D rendering (PIXI.DisplayObject...)\n */\n getRendererObject(): RendererObjectInterface | null | undefined {\n return undefined;\n }\n\n /**\n * @return The internal object for a 3D rendering (PIXI.DisplayObject...)\n */\n get3DRendererObject(): THREE.Object3D | null | undefined {\n return undefined;\n }\n\n //Common properties:\n /**\n * Get the name of the object.\n * @return The object's name.\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * Get the name identifier of the object.\n * @return The object's name identifier.\n */\n getNameId(): integer {\n return this._nameId;\n }\n\n /**\n * Get the unique identifier of the object.<br>\n * The identifier is set by the runtimeScene owning the object.<br>\n * You can also use the id property (this._object.id) for increased efficiency instead of\n * calling this method.\n *\n * @return The object identifier\n */\n getUniqueId(): integer {\n return this.id;\n }\n\n /**\n * Set the position of the object.\n *\n * @param x The new X position\n * @param y The new Y position\n */\n setPosition(x: float, y: float): void {\n this.setX(x);\n this.setY(y);\n }\n\n /**\n * Set the X position of the object.\n *\n * @param x The new X position\n */\n setX(x: float): void {\n if (x === this.x) {\n return;\n }\n this.x = x;\n this.invalidateHitboxes();\n }\n\n /**\n * Send a signal that the object hitboxes are no longer up to date.\n *\n * The signal is propagated to parents so\n * {@link gdjs.RuntimeObject.hitBoxesDirty} should never be modified\n * directly.\n */\n invalidateHitboxes(): void {\n // TODO EBO Check that no community extension set hitBoxesDirty to true\n // directly.\n this.hitBoxesDirty = true;\n this._runtimeScene.onChildrenLocationChanged();\n }\n\n /**\n * Get the X position of the object.\n *\n * @return The X position of the object\n */\n getX(): float {\n return this.x;\n }\n\n /**\n * Set the Y position of the object.\n *\n * @param y The new Y position\n */\n setY(y: float): void {\n if (y === this.y) {\n return;\n }\n this.y = y;\n this.invalidateHitboxes();\n }\n\n /**\n * Get the Y position of the object.\n *\n * @return The Y position of the object\n */\n getY(): float {\n return this.y;\n }\n\n /**\n * Get the X position of the rendered object.\n *\n * For most objects, this will returns the same value as getX(). But if the object\n * has an origin that is not the same as the point (0,0) of the object displayed,\n * getDrawableX will differ.\n *\n * @return The X position of the rendered object.\n */\n getDrawableX(): float {\n return this.getX();\n }\n\n /**\n * Get the Y position of the rendered object.\n *\n * For most objects, this will returns the same value as getY(). But if the object\n * has an origin that is not the same as the point (0,0) of the object displayed,\n * getDrawableY will differ.\n *\n * @return The Y position of the rendered object.\n */\n getDrawableY(): float {\n return this.getY();\n }\n\n rotateTowardPosition(x: float, y: float, speed: float): void {\n this.rotateTowardAngle(\n gdjs.toDegrees(\n Math.atan2(\n y - (this.getDrawableY() + this.getCenterY()),\n x - (this.getDrawableX() + this.getCenterX())\n )\n ),\n speed\n );\n }\n\n /**\n * @param angle The targeted direction angle.\n * @param speed The rotation speed.\n */\n rotateTowardAngle(angle: float, speed: float): void {\n if (speed === 0) {\n this.setAngle(angle);\n return;\n }\n const angularDiff = gdjs.evtTools.common.angleDifference(\n this.getAngle(),\n angle\n );\n const diffWasPositive = angularDiff >= 0;\n let newAngle =\n this.getAngle() +\n ((diffWasPositive ? -1.0 : 1.0) * speed * this.getElapsedTime()) / 1000;\n\n if (\n // @ts-ignore\n (gdjs.evtTools.common.angleDifference(newAngle, angle) > 0) ^\n diffWasPositive\n ) {\n newAngle = angle;\n }\n this.setAngle(newAngle);\n if (\n //Objects like sprite in 8 directions does not handle small increments...\n this.getAngle() !== newAngle\n ) {\n this.setAngle(\n //...so force them to be in the path angle anyway.\n angle\n );\n }\n }\n\n /**\n * Rotate the object at the given speed\n *\n * @param speed The speed, in degrees per second.\n * @param instanceContainer The container the object belongs to (deprecated - can be omitted).\n */\n rotate(speed: float): void {\n this.setAngle(this.getAngle() + (speed * this.getElapsedTime()) / 1000);\n }\n\n /**\n * Set the angle of the object.\n *\n * @param angle The new angle of the object\n */\n setAngle(angle: float): void {\n if (this.angle === angle) {\n return;\n }\n this.angle = angle;\n this.invalidateHitboxes();\n }\n\n /**\n * Get the rotation of the object.\n *\n * @return The rotation of the object, in degrees.\n */\n getAngle(): float {\n return this.angle;\n }\n\n /**\n * Set the layer of the object.\n *\n * @param layer The new layer of the object\n */\n setLayer(layer: string): void {\n if (layer === this.layer) {\n return;\n }\n const oldLayer = this._runtimeScene.getLayer(this.layer);\n this.layer = layer;\n const newLayer = this._runtimeScene.getLayer(this.layer);\n const rendererObject = this.getRendererObject();\n if (rendererObject) {\n oldLayer.getRenderer().removeRendererObject(rendererObject);\n newLayer.getRenderer().addRendererObject(rendererObject, this.zOrder);\n }\n const rendererObject3D = this.get3DRendererObject();\n if (rendererObject3D) {\n oldLayer.getRenderer().remove3DRendererObject(rendererObject3D);\n newLayer.getRenderer().add3DRendererObject(rendererObject3D);\n }\n }\n\n /**\n * Get the layer of the object.\n *\n * @return The layer of the object\n */\n getLayer(): string {\n return this.layer;\n }\n\n /**\n * Return true if the object is on the specified layer\n *\n * @param layer The layer to be tested.\n * @return true if the object is on the specified layer\n */\n isOnLayer(layer: string): boolean {\n return this.layer === layer;\n }\n\n /**\n * Set the Z order of the object.\n *\n * @param z The new Z order position of the object\n */\n setZOrder(z: integer): void {\n if (z === this.zOrder) {\n return;\n }\n this.zOrder = z;\n const rendererObject = this.getRendererObject();\n if (rendererObject) {\n const theLayer = this._runtimeScene.getLayer(this.layer);\n theLayer.getRenderer().changeRendererObjectZOrder(rendererObject, z);\n }\n }\n\n /**\n * Get the Z order of the object.\n *\n * @return The Z order of the object\n */\n getZOrder(): float {\n return this.zOrder;\n }\n\n /**\n * Get the container of the object variables\n * @return The variables of the object\n */\n getVariables(): gdjs.VariablesContainer {\n return this._variables;\n }\n\n /**\n * Get the value of a variable considered as a number. Equivalent of variable.getAsNumber()\n * @param variable The variable to be accessed\n * @return The value of the specified variable\n * @static\n */\n static getVariableNumber(variable: gdjs.Variable): number {\n return variable.getAsNumber();\n }\n\n /**\n * Return the variable passed as argument without any change.\n * Only for usage by events.\n *\n * @param variable The variable to be accessed\n * @return The specified variable\n * @static\n */\n static returnVariable(variable: gdjs.Variable): gdjs.Variable {\n return variable;\n }\n\n /**\n * Get the value of a variable considered as a string. Equivalent of variable.getAsString()\n * @param variable The variable to be accessed\n * @return The string of the specified variable\n * @static\n */\n static getVariableString(variable: gdjs.Variable): string {\n return variable.getAsString();\n }\n\n /**\n * Shortcut to set the value of a variable considered as a boolean.\n * This shortcut function is needed for events code generation.\n *\n * @private\n * @param {gdjs.Variable} variable\n * @param {boolean} newValue\n */\n static setVariableBoolean = function (\n variable: gdjs.Variable,\n newValue: boolean\n ) {\n variable.setBoolean(newValue);\n };\n\n /**\n * Shortcut to compare the value of a variable considered as a boolean.\n * This shortcut function is needed for events code generation.\n *\n * @private\n * @param {gdjs.Variable} variable\n * @param {boolean} compareWith\n * @returns {boolean}\n */\n static getVariableBoolean = function (\n variable: gdjs.Variable,\n compareWith: boolean\n ): boolean {\n return gdjs.evtTools.common.getVariableBoolean(variable, compareWith);\n };\n\n /**\n * Toggles a variable.\n * This shortcut function is needed for events code generation.\n *\n * @private\n * @param {gdjs.Variable} variable\n * @see {gdjs.evtTools.common.toggleVariableBoolean}\n */\n static toggleVariableBoolean = function (variable: gdjs.Variable) {\n gdjs.evtTools.common.toggleVariableBoolean(variable);\n };\n\n /**\n * Get the number of children from a variable\n * @param variable The variable to be accessed\n * @return The number of children\n * @static\n */\n static getVariableChildCount(variable: gdjs.Variable): integer {\n return variable.getChildrenCount();\n }\n\n /**\n * Shortcut to set the value of a variable considered as a number\n * @param variable The variable to be changed\n * @param newValue The value to be set\n */\n static setVariableNumber(variable: gdjs.Variable, newValue: float): void {\n variable.setNumber(newValue);\n }\n\n /**\n * Shortcut to set the value of a variable considered as a string\n * @param variable The variable to be changed\n * @param newValue {String} The value to be set\n */\n static setVariableString(variable: gdjs.Variable, newValue: string) {\n variable.setString(newValue);\n }\n\n /**\n * @static\n * @param variable The variable to be tested\n * @param childName The name of the child\n */\n private static variableChildExists(\n variable: gdjs.Variable,\n childName: string\n ): boolean {\n return variable.hasChild(childName);\n }\n\n /**\n * @static\n * @param variable The variable to be changed\n * @param childName The name of the child\n */\n private static variableRemoveChild(\n variable: gdjs.Variable,\n childName: string\n ): void {\n variable.removeChild(childName);\n }\n\n /**\n * @static\n * @param variable The variable to be cleared\n */\n private static variableClearChildren(variable: gdjs.Variable): void {\n variable.clearChildren();\n }\n\n /**\n * This shortcut function is needed for events code generation.\n * @private\n */\n static variablePushCopy = function (\n array: gdjs.Variable,\n variable: gdjs.Variable\n ) {\n array.pushVariableCopy(variable);\n };\n\n /**\n * This shortcut function is needed for events code generation.\n * @private\n */\n static valuePush = function (\n array: gdjs.Variable,\n value: string | float | boolean\n ) {\n array.pushValue(value);\n };\n\n /**\n * This shortcut function is needed for events code generation.\n * @private\n */\n static variableRemoveAt = function (array: gdjs.Variable, index: number) {\n array.removeAtIndex(index);\n };\n\n /**\n * Shortcut to get the first value of an array variable as a string.\n */\n static getFirstVariableString = function (array: gdjs.Variable): string {\n if (array.getChildrenCount() === 0) {\n return '';\n }\n return array.getAllChildrenArray()[0].getAsString();\n };\n\n /**\n * Shortcut to get the first value of an array variable as a number.\n */\n static getFirstVariableNumber = function (array: gdjs.Variable): number {\n if (array.getChildrenCount() === 0) {\n return 0;\n }\n return array.getAllChildrenArray()[0].getAsNumber();\n };\n\n /**\n * Shortcut to get the last value of an array variable as a string.\n */\n static getLastVariableString = function (array: gdjs.Variable): string {\n const children = array.getAllChildrenArray();\n return children.length === 0\n ? ''\n : children[children.length - 1].getAsString();\n };\n\n /**\n * Shortcut to get the last value of an array variable as a number.\n */\n static getLastVariableNumber = function (array: gdjs.Variable): number {\n const children = array.getAllChildrenArray();\n return children.length === 0\n ? 0\n : children[children.length - 1].getAsNumber();\n };\n\n /**\n * Shortcut to test if a variable exists for the object.\n * @param name The variable to be tested\n * @return true if the variable exists.\n */\n hasVariable(name: string): boolean {\n return this._variables.has(name);\n }\n\n /**\n * Returns the collection of effects to be rendered by the\n * underlying renderer.\n * @returns The renderer effects.\n */\n getRendererEffects() {\n return this._rendererEffects;\n }\n\n /**\n * Add a new effect, or replace the one with the same name.\n * @param effectData The data describing the effect to add.\n */\n addEffect(effectData: EffectData): boolean {\n const rendererObject = this.getRendererObject();\n if (!rendererObject) {\n return false;\n }\n\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .addEffect(effectData, this._rendererEffects, this);\n }\n\n /**\n * Remove the effect with the specified name\n * @param effectName The name of the effect.\n */\n removeEffect(effectName: string): boolean {\n const rendererObject = this.getRendererObject();\n if (!rendererObject) return false;\n\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .removeEffect(this._rendererEffects, this, effectName);\n }\n\n /**\n * Remove all effects.\n */\n clearEffects(): boolean {\n const rendererObject = this.getRendererObject();\n if (!rendererObject) return false;\n\n this._rendererEffects = {};\n return (\n this._runtimeScene\n .getGame()\n .getEffectsManager()\n // @ts-expect-error - the effects manager is typed with the PIXI object.\n .clearEffects(rendererObject)\n );\n }\n\n /**\n * Change an effect property value (for properties that are numbers).\n * @param name The name of the effect to update.\n * @param parameterName The name of the property to update.\n * @param value The new value (number).\n */\n setEffectDoubleParameter(\n name: string,\n parameterName: string,\n value: float\n ): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .setEffectDoubleParameter(\n this._rendererEffects,\n name,\n parameterName,\n value\n );\n }\n\n /**\n * Change an effect property value (for properties that are strings).\n * @param name The name of the effect to update.\n * @param parameterName The name of the property to update.\n * @param value The new value (string).\n */\n setEffectStringParameter(\n name: string,\n parameterName: string,\n value: string\n ): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .setEffectStringParameter(\n this._rendererEffects,\n name,\n parameterName,\n value\n );\n }\n\n /**\n * Change an effect property value (for properties that are booleans).\n * @param name The name of the effect to update.\n * @param parameterName The name of the property to update.\n * @param value The new value (boolean).\n */\n setEffectBooleanParameter(\n name: string,\n parameterName: string,\n value: boolean\n ): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .setEffectBooleanParameter(\n this._rendererEffects,\n name,\n parameterName,\n value\n );\n }\n\n /**\n * Updates all the parameters of an effect.\n * @param effectData The data describing the effect\n */\n updateAllEffectParameters(effectData: EffectData): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .updateAllEffectParameters(this._rendererEffects, effectData);\n }\n\n /**\n * Enable or disable an effect.\n * @param name The name of the effect to enable or disable.\n * @param enable true to enable, false to disable\n */\n enableEffect(name: string, enable: boolean): void {\n this._runtimeScene\n .getGame()\n .getEffectsManager()\n .enableEffect(this._rendererEffects, this, name, enable);\n }\n\n /**\n * Check if an effect is enabled\n * @param name The name of the effect\n * @return true if the effect is enabled, false otherwise.\n */\n isEffectEnabled(name: string): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .isEffectEnabled(this._rendererEffects, this, name);\n }\n\n /**\n * Check if an effect exists on this object\n * @param name The name of the effect\n * @return true if the effect exists, false otherwise.\n */\n hasEffect(name: string): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .hasEffect(this._rendererEffects, name);\n }\n\n /**\n * Hide (or show) the object.\n * @param enable Set it to true to hide the object, false to show it.\n */\n hide(enable: boolean): void {\n if (enable === undefined) {\n enable = true;\n }\n this.hidden = enable;\n }\n\n /**\n * Return true if the object is not hidden.\n *\n * Note: This is unrelated to the actual visibility of the object on the screen.\n * For this, see `getVisibilityAABB` to get the bounding boxes of the object as displayed\n * on the scene.\n *\n * @return true if the object is not hidden.\n */\n isVisible(): boolean {\n return !this.hidden;\n }\n\n /**\n * Return true if the object is hidden.\n * @return true if the object is hidden.\n */\n isHidden(): boolean {\n return this.hidden;\n }\n\n /**\n * Set the width of the object, if applicable.\n * @param width The new width in pixels.\n */\n setWidth(width: float): void {}\n\n /**\n * Set the height of the object, if applicable.\n * @param height The new height in pixels.\n */\n setHeight(height: float): void {}\n\n /**\n * Return the width of the object.\n * @return The width of the object\n */\n getWidth(): float {\n return 0;\n }\n\n /**\n * Return the height of the object.\n * @return The height of the object\n */\n getHeight(): float {\n return 0;\n }\n\n /**\n * Return the X position of the object center, **relative to the object X position** (`getDrawableX`).\n * Use `getCenterXInScene` to get the position of the center in the scene.\n *\n * @return the X position of the object center, relative to `getDrawableX()`.\n */\n getCenterX(): float {\n return this.getWidth() / 2;\n }\n\n /**\n * Return the Y position of the object center, **relative to the object position** (`getDrawableY`).\n * Use `getCenterYInScene` to get the position of the center in the scene.\n *\n * @return the Y position of the object center, relative to `getDrawableY()`.\n */\n getCenterY(): float {\n return this.getHeight() / 2;\n }\n\n /**\n * Return the X position of the object center, **relative to the scene origin**.\n * @returns the X position of the object center, **relative to the scene origin**.\n */\n getCenterXInScene(): float {\n return this.getDrawableX() + this.getCenterX();\n }\n\n /**\n * Return the Y position of the object center, **relative to the scene origin**.\n * @returns the Y position of the object center, **relative to the scene origin**.\n */\n getCenterYInScene(): float {\n return this.getDrawableY() + this.getCenterY();\n }\n\n /**\n * Change the object center position in the scene.\n * @param x The new X position of the center in the scene.\n * @param y The new Y position of the center in the scene.\n */\n setCenterPositionInScene(x: float, y: float): void {\n this.setX(x + this.x - (this.getDrawableX() + this.getCenterX()));\n this.setY(y + this.y - (this.getDrawableY() + this.getCenterY()));\n }\n\n /**\n * Change the object center X position in the scene.\n * @param x The new X position of the center in the scene.\n */\n setCenterXInScene(x: float): void {\n this.setX(x + this.x - (this.getDrawableX() + this.getCenterX()));\n }\n\n /**\n * Change the object center Y position in the scene.\n * @param y The new Y position of the center in the scene.\n */\n setCenterYInScene(y: float): void {\n this.setY(y + this.y - (this.getDrawableY() + this.getCenterY()));\n }\n\n //Forces :\n /**\n * Get a force from the garbage, or create a new force is garbage is empty.<br>\n * To be used each time a force is created so as to avoid temporaries objects.\n *\n * @param x The x coordinates of the force\n * @param y The y coordinates of the force\n * @param multiplier Set the force multiplier\n */\n private _getRecycledForce(\n x: float,\n y: float,\n multiplier: integer\n ): gdjs.Force {\n if (RuntimeObject.forcesGarbage.length === 0) {\n return new gdjs.Force(x, y, multiplier);\n } else {\n const recycledForce = RuntimeObject.forcesGarbage.pop() as gdjs.Force;\n recycledForce.setX(x);\n recycledForce.setY(y);\n recycledForce.setMultiplier(multiplier);\n return recycledForce;\n }\n }\n\n /**\n * Add a force to the object to move it.\n * @param x The x coordinates of the force\n * @param y The y coordinates of the force\n * @param multiplier Set the force multiplier\n */\n addForce(x: float, y: float, multiplier: integer): void {\n if (multiplier === 1) {\n this._permanentForceX += x;\n this._permanentForceY += y;\n } else if (\n multiplier === 0 &&\n this._instantForces.length > 0 &&\n this._instantForces[0].getMultiplier() === 0\n ) {\n // Avoid to instantiate new a Force for each instance force.\n this._instantForces[0].add(x, y);\n } else {\n // Handle legacy forces with multiplier different from 0 and 1\n // (or the 1st instant force).\n this._instantForces.push(this._getRecycledForce(x, y, multiplier));\n }\n }\n\n /**\n * Add a force using polar coordinates.\n * @param angle The angle of the force, in degrees.\n * @param len The length of the force, in pixels.\n * @param multiplier Set the force multiplier\n */\n addPolarForce(angle: float, len: float, multiplier: integer): void {\n const angleInRadians = gdjs.toRad(angle);\n\n //TODO: Benchmark with Math.PI\n const forceX = Math.cos(angleInRadians) * len;\n const forceY = Math.sin(angleInRadians) * len;\n this.addForce(forceX, forceY, multiplier);\n }\n\n /**\n * Add a force oriented toward a position\n * @param x The target x position\n * @param y The target y position\n * @param len The force length, in pixels.\n * @param multiplier Set the force multiplier\n */\n addForceTowardPosition(\n x: float,\n y: float,\n len: float,\n multiplier: integer\n ): void {\n const angleInRadians = Math.atan2(\n y - (this.getDrawableY() + this.getCenterY()),\n x - (this.getDrawableX() + this.getCenterX())\n );\n const forceX = Math.cos(angleInRadians) * len;\n const forceY = Math.sin(angleInRadians) * len;\n this.addForce(forceX, forceY, multiplier);\n }\n\n /**\n * Add a force oriented toward another object.<br>\n * (Shortcut for addForceTowardPosition)\n * @param object The target object\n * @param len The force length, in pixels.\n * @param multiplier Set the force multiplier\n */\n addForceTowardObject(\n object: gdjs.RuntimeObject | null,\n len: float,\n multiplier: integer\n ): void {\n if (object == null) {\n return;\n }\n this.addForceTowardPosition(\n object.getDrawableX() + object.getCenterX(),\n object.getDrawableY() + object.getCenterY(),\n len,\n multiplier\n );\n }\n\n /**\n * Deletes all forces applied on the object\n */\n clearForces(): void {\n RuntimeObject.forcesGarbage.push.apply(\n RuntimeObject.forcesGarbage,\n this._instantForces\n );\n this._instantForces.length = 0;\n this._permanentForceX = 0;\n this._permanentForceY = 0;\n }\n\n /**\n * Return true if no forces are applied on the object.\n * @return true if no forces are applied on the object.\n */\n hasNoForces(): boolean {\n return (\n this._instantForces.length === 0 &&\n this._permanentForceX === 0 &&\n this._permanentForceY === 0\n );\n }\n\n /**\n * Called once a step by runtimeScene to update forces magnitudes and\n * remove null ones.\n */\n updateForces(elapsedTime: float): void {\n for (let i = 0; i < this._instantForces.length; ) {\n const force = this._instantForces[i];\n const multiplier = force.getMultiplier();\n if (multiplier === 1) {\n // Permanent force\n ++i;\n } else {\n if (\n multiplier === 0 ||\n // Instant or force disappearing\n force.getLength() <= 0.001\n ) {\n RuntimeObject.forcesGarbage.push(force);\n this._instantForces.splice(i, 1);\n } else {\n // Deprecated way of updating forces progressively.\n force.setLength(\n force.getLength() -\n force.getLength() * (1 - multiplier) * elapsedTime\n );\n ++i;\n }\n }\n }\n }\n\n /**\n * Return a force which is the sum of all forces applied on the object.\n *\n * @return A force object.\n */\n getAverageForce(): gdjs.Force {\n this._totalForce.clear();\n this._totalForce.add(this._permanentForceX, this._permanentForceY);\n for (let i = 0, len = this._instantForces.length; i < len; ++i) {\n this._totalForce.addForce(this._instantForces[i]);\n }\n return this._totalForce;\n }\n\n /**\n * Return true if the average angle of the forces applied on the object\n * is in a given range.\n * @deprecated Use isTotalForceAngleAround instead.\n *\n * @param angle The angle to be tested.\n * @param toleranceInDegrees The length of the range :\n * @return true if the difference between the average angle of the forces\n * and the angle parameter is inferior to toleranceInDegrees parameter.\n */\n averageForceAngleIs(angle: float, toleranceInDegrees: float): boolean {\n let averageAngle = this.getAverageForce().getAngle();\n if (averageAngle < 0) {\n averageAngle += 360;\n }\n return Math.abs(angle - averageAngle) < toleranceInDegrees / 2;\n }\n\n /**\n * Return true if the angle of the total force applied on the object\n * is in a given range.\n *\n * @param angle The angle to be tested.\n * @param toleranceInDegrees The maximum distance from the given angle.\n * @return true if the difference between the force angle the given `angle`\n * is less or equals the `toleranceInDegrees`.\n */\n isTotalForceAngleAround(angle: float, toleranceInDegrees: float): boolean {\n return (\n Math.abs(\n gdjs.evtTools.common.angleDifference(\n this.getAverageForce().getAngle(),\n angle\n )\n ) <= toleranceInDegrees\n );\n }\n\n //Hit boxes and collision :\n /**\n * Get all the hit boxes for the object.\n *\n * For collision checks, {@link getHitBoxesAround} should be used instead.\n *\n * The default implementation returns a basic bounding box based the size (getWidth and\n * getHeight) and the center point of the object (getCenterX and getCenterY).\n *\n * You should probably redefine {@link updateHitBoxes} instead of this function.\n *\n * @return An array composed of polygon.\n */\n getHitBoxes(): gdjs.Polygon[] {\n //Avoid a naive implementation requiring to recreate temporaries each time\n //the function is called:\n //(var rectangle = gdjs.Polygon.createRectangle(this.getWidth(), this.getHeight());\n //...)\n if (this.hitBoxesDirty) {\n this.updateHitBoxes();\n this.updateAABB();\n this.hitBoxesDirty = false;\n }\n return this.hitBoxes;\n }\n\n /**\n * Return at least all the hit boxes that overlap a given area.\n *\n * The hit boxes don't need to actually overlap the area,\n * (i.e: it's correct to return more hit boxes than those in the specified area)\n * but the ones that do must be returned.\n *\n * The default implementation returns the same as {@link getHitBoxes}.\n *\n * This method can be overridden by grid based objects (or other objects\n * that can quickly compute which hitboxes are touching a given area)\n * to optimize collision checks.\n *\n * When overriding this method, the following ones should be overridden too:\n * * {@link getHitBoxes}\n * * {@link getAABB}\n * * {@link updateHitBoxes}\n * * {@link updateAABB}\n *\n * @param left bound of the area in scene coordinates\n * @param top bound of the area in scene coordinates\n * @param right bound of the area in scene coordinates\n * @param bottom bound of the area in scene coordinates\n *\n * @return at least all the hit boxes that overlap a given area.\n */\n getHitBoxesAround(\n left: float,\n top: float,\n right: float,\n bottom: float\n ): Iterable<gdjs.Polygon> {\n return this.getHitBoxes();\n }\n\n /**\n * Update the hit boxes for the object.\n *\n * The default implementation set a basic bounding box based on the size (getWidth and\n * getHeight) and the center point of the object (getCenterX and getCenterY).\n * Result is cached until invalidated (by a position change, angle change...).\n *\n * You should not call this function by yourself, it is called when necessary by getHitBoxes method.\n * However, you can redefine it if your object need custom hit boxes.\n */\n updateHitBoxes(): void {\n this.hitBoxes = this._defaultHitBoxes;\n if (this.hitBoxes.length === 0) return;\n const width = this.getWidth();\n const height = this.getHeight();\n const centerX = this.getCenterX();\n const centerY = this.getCenterY();\n if (centerX === width / 2 && centerY === height / 2) {\n this.hitBoxes[0].vertices[0][0] = -centerX;\n this.hitBoxes[0].vertices[0][1] = -centerY;\n this.hitBoxes[0].vertices[1][0] = +centerX;\n this.hitBoxes[0].vertices[1][1] = -centerY;\n this.hitBoxes[0].vertices[2][0] = +centerX;\n this.hitBoxes[0].vertices[2][1] = +centerY;\n this.hitBoxes[0].vertices[3][0] = -centerX;\n this.hitBoxes[0].vertices[3][1] = +centerY;\n } else {\n this.hitBoxes[0].vertices[0][0] = 0 - centerX;\n this.hitBoxes[0].vertices[0][1] = 0 - centerY;\n this.hitBoxes[0].vertices[1][0] = width - centerX;\n this.hitBoxes[0].vertices[1][1] = 0 - centerY;\n this.hitBoxes[0].vertices[2][0] = width - centerX;\n this.hitBoxes[0].vertices[2][1] = height - centerY;\n this.hitBoxes[0].vertices[3][0] = 0 - centerX;\n this.hitBoxes[0].vertices[3][1] = height - centerY;\n }\n this.hitBoxes[0].rotate(gdjs.toRad(this.getAngle()));\n this.hitBoxes[0].move(\n this.getDrawableX() + centerX,\n this.getDrawableY() + centerY\n );\n }\n\n isIncludedInParentCollisionMask(): boolean {\n return this._isIncludedInParentCollisionMask;\n }\n\n setIncludedInParentCollisionMask(isIncluded: boolean): void {\n const wasIncluded = this._isIncludedInParentCollisionMask;\n this._isIncludedInParentCollisionMask = isIncluded;\n if (wasIncluded !== isIncluded) {\n this._runtimeScene.onChildrenLocationChanged();\n }\n }\n\n /**\n * Get the AABB (axis aligned bounding box) for the object.\n *\n * The default implementation uses either the position/size of the object (when angle is 0) or\n * hitboxes (when angle is not 0) to compute the bounding box.\n * Result is cached until invalidated (by a position change, angle change...).\n *\n * You should probably redefine updateAABB instead of this function.\n *\n * @return The bounding box\n */\n getAABB(): AABB {\n if (this.hitBoxesDirty) {\n this.updateHitBoxes();\n this.updateAABB();\n this.hitBoxesDirty = false;\n }\n return this.aabb;\n }\n\n /**\n * Get the AABB (axis aligned bounding box) to be used to determine if the object\n * is visible on screen. The gdjs.RuntimeScene will hide the renderer object if\n * the object is not visible on screen (\"culling\").\n *\n * The default implementation uses the AABB returned by getAABB.\n *\n * If `null` is returned, the object is assumed to be always visible.\n *\n * @return The bounding box or `null`.\n */\n getVisibilityAABB(): AABB | null {\n return this.getAABB();\n }\n\n /**\n * Update the AABB (axis aligned bounding box) for the object.\n *\n * Default implementation uses either the position/size of the object (when angle is 0) or\n * hitboxes (when angle is not 0) to compute the bounding box.\n *\n * You should not call this function by yourself, it is called when necessary by getAABB method.\n * However, you can redefine it if your object can have a faster implementation.\n */\n updateAABB(): void {\n if (this.getAngle() === 0) {\n // Fast/simple computation of AABB for non rotated object\n // (works even for object with non default center/origin\n // because we're using getDrawableX/Y)\n this.aabb.min[0] = this.getDrawableX();\n this.aabb.min[1] = this.getDrawableY();\n this.aabb.max[0] = this.aabb.min[0] + this.getWidth();\n this.aabb.max[1] = this.aabb.min[1] + this.getHeight();\n } else {\n // Use hitboxes if object is rotated to ensure that the AABB\n // is properly bounding the whole object.\n // Slower (10-15% slower).\n let first = true;\n for (let i = 0; i < this.hitBoxes.length; i++) {\n for (let j = 0; j < this.hitBoxes[i].vertices.length; j++) {\n const vertex = this.hitBoxes[i].vertices[j];\n if (first) {\n this.aabb.min[0] = vertex[0];\n this.aabb.max[0] = vertex[0];\n this.aabb.min[1] = vertex[1];\n this.aabb.max[1] = vertex[1];\n first = false;\n } else {\n this.aabb.min[0] = Math.min(this.aabb.min[0], vertex[0]);\n this.aabb.max[0] = Math.max(this.aabb.max[0], vertex[0]);\n this.aabb.min[1] = Math.min(this.aabb.min[1], vertex[1]);\n this.aabb.max[1] = Math.max(this.aabb.max[1], vertex[1]);\n }\n }\n }\n }\n }\n\n /**\n * Shortcut for `getAABB().min[0]`.\n * See {@link getAABB}.\n */\n getAABBLeft(): float {\n return this.getAABB().min[0];\n }\n\n /**\n * Shortcut for `getAABB().min[1]`.\n * See {@link getAABB}.\n */\n getAABBTop(): float {\n return this.getAABB().min[1];\n }\n\n /**\n * Shortcut for `getAABB().max[0]`.\n * See {@link getAABB}.\n */\n getAABBRight(): float {\n return this.getAABB().max[0];\n }\n\n /**\n * Shortcut for `getAABB().max[1]`.\n * See {@link getAABB}.\n */\n getAABBBottom(): float {\n return this.getAABB().max[1];\n }\n\n /**\n * Shortcut for getting the center on the X coordinates of the object AABB.\n * See {@link getAABB}.\n */\n getAABBCenterX(): float {\n return this.getAABB().min[0] / 2 + this.getAABB().max[0] / 2;\n }\n\n /**\n * Shortcut for getting the center on the Y coordinates of the object AABB.\n * See {@link getAABB}.\n */\n getAABBCenterY(): float {\n return this.getAABB().min[1] / 2 + this.getAABB().max[1] / 2;\n }\n\n //Behaviors:\n /**\n * Call each behavior stepPreEvents method.\n */\n stepBehaviorsPreEvents(\n instanceContainer: gdjs.RuntimeInstanceContainer\n ): void {\n for (let i = 0, len = this._behaviors.length; i < len; ++i) {\n this._behaviors[i].stepPreEvents(instanceContainer);\n }\n }\n\n /**\n * Call each behavior stepPostEvents method.\n */\n stepBehaviorsPostEvents(\n instanceContainer: gdjs.RuntimeInstanceContainer\n ): void {\n for (let i = 0, len = this._behaviors.length; i < len; ++i) {\n this._behaviors[i].stepPostEvents(instanceContainer);\n }\n }\n\n /**\n * Called when the object was hot reloaded, to notify behaviors\n * that the object was modified. Useful for behaviors that\n */\n notifyBehaviorsObjectHotReloaded(): void {\n for (let i = 0, len = this._behaviors.length; i < len; ++i) {\n this._behaviors[i].onObjectHotReloaded();\n }\n }\n\n /**\n * Get a behavior from its name.\n * If the behavior does not exists, `undefined` is returned.\n *\n * **Never keep a reference** to a behavior, as they can be hot-reloaded. Instead,\n * always call getBehavior on the object.\n *\n * @param name {String} The behavior name.\n * @return The behavior with the given name, or undefined.\n */\n getBehavior(name: string): gdjs.RuntimeBehavior | null {\n return this._behaviorsTable.get(name);\n }\n\n /**\n * Check if a behavior is used by the object.\n *\n * @param name {String} The behavior name.\n */\n hasBehavior(name: string): boolean {\n return this._behaviorsTable.containsKey(name);\n }\n\n /**\n * De/activate a behavior of the object.\n *\n * @param name {String} The behavior name.\n * @param enable {boolean} true to activate the behavior\n */\n activateBehavior(name: string, enable: boolean): void {\n if (this._behaviorsTable.containsKey(name)) {\n this._behaviorsTable.get(name).activate(enable);\n }\n }\n\n /**\n * Check if a behavior is activated\n *\n * @param name The behavior name.\n * @return true if the behavior is activated.\n */\n behaviorActivated(name: string): boolean {\n if (this._behaviorsTable.containsKey(name)) {\n return this._behaviorsTable.get(name).activated();\n }\n return false;\n }\n\n /**\n * Remove the behavior with the given name. Usually only used by\n * hot-reloading, as performance of this operation is not guaranteed\n * (in the future, this could lead to re-organization of arrays\n * holding behaviors).\n *\n * @param name The name of the behavior to remove.\n * @returns true if the behavior was properly removed, false otherwise.\n */\n removeBehavior(name: string): boolean {\n const behavior = this._behaviorsTable.get(name);\n if (!behavior) {\n return false;\n }\n behavior.onDestroy();\n const behaviorIndex = this._behaviors.indexOf(behavior);\n if (behaviorIndex !== -1) {\n this._behaviors.splice(behaviorIndex, 1);\n }\n this._behaviorsTable.remove(name);\n return true;\n }\n\n /**\n * Create the behavior described by the given BehaviorData\n *\n * @param behaviorData The data to be used to construct the behavior.\n * @returns true if the behavior was properly created, false otherwise.\n */\n addNewBehavior(behaviorData: BehaviorData): boolean {\n const Ctor = gdjs.getBehaviorConstructor(behaviorData.type);\n if (!Ctor) {\n return false;\n }\n const newRuntimeBehavior = new Ctor(\n this._runtimeScene,\n behaviorData,\n this\n );\n if (newRuntimeBehavior.usesLifecycleFunction()) {\n this._behaviors.push(newRuntimeBehavior);\n }\n this._behaviorsTable.put(behaviorData.name, newRuntimeBehavior);\n newRuntimeBehavior.onCreated();\n return true;\n }\n\n //Timers:\n /**\n * Updates the object timers. Called once during the game loop, before events and rendering.\n * @param elapsedTime The elapsed time since the previous frame in milliseconds.\n */\n updateTimers(elapsedTime: float): void {\n for (const name in this._timers.items) {\n if (this._timers.items.hasOwnProperty(name)) {\n this._timers.items[name].updateTime(elapsedTime);\n }\n }\n }\n\n /**\n * Compare a timer elapsed time. If the timer does not exist, it is created.\n *\n * @deprecated prefer using `getTimerElapsedTimeInSecondsOrNaN`.\n *\n * @param timerName The timer name.\n * @param timeInSeconds The time value to check in seconds.\n * @return True if the timer exists and its value is greater than or equal than the given time, false otherwise.\n */\n timerElapsedTime(timerName: string, timeInSeconds: float): boolean {\n if (!this._timers.containsKey(timerName)) {\n this._timers.put(timerName, new gdjs.Timer(timerName));\n return false;\n }\n return this.getTimerElapsedTimeInSeconds(timerName) >= timeInSeconds;\n }\n\n /**\n * Test a if a timer is paused.\n * @param timerName The timer name.\n * @return True if the timer exists and is paused, false otherwise.\n */\n timerPaused(timerName: string): boolean {\n if (!this._timers.containsKey(timerName)) {\n return false;\n }\n return this._timers.get(timerName).isPaused();\n }\n\n /**\n * Reset a timer. If the timer doesn't exist it is created.\n * @param timerName The timer name.\n */\n resetTimer(timerName: string): void {\n if (!this._timers.containsKey(timerName)) {\n this._timers.put(timerName, new gdjs.Timer(timerName));\n }\n this._timers.get(timerName).reset();\n }\n\n /**\n * Pause a timer. If the timer doesn't exist it is created.\n * @param timerName The timer name.\n */\n pauseTimer(timerName: string): void {\n if (!this._timers.containsKey(timerName)) {\n this._timers.put(timerName, new gdjs.Timer(timerName));\n }\n this._timers.get(timerName).setPaused(true);\n }\n\n /**\n * Unpause a timer. If the timer doesn't exist it is created.\n * @param timerName The timer name.\n */\n unpauseTimer(timerName: string): void {\n if (!this._timers.containsKey(timerName)) {\n this._timers.put(timerName, new gdjs.Timer(timerName));\n }\n this._timers.get(timerName).setPaused(false);\n }\n\n /**\n * Remove a timer\n * @param timerName The timer name.\n */\n removeTimer(timerName: string): void {\n if (this._timers.containsKey(timerName)) {\n this._timers.remove(timerName);\n }\n }\n\n /**\n * Get a timer elapsed time.\n *\n * This is used by expressions to return 0 when a timer doesn't exist\n * because numeric expressions must always return a number.\n *\n * @param timerName The timer name.\n * @return The timer elapsed time in seconds, 0 if the timer doesn't exist.\n */\n getTimerElapsedTimeInSeconds(timerName: string): float {\n if (!this._timers.containsKey(timerName)) {\n return 0;\n }\n return this._timers.get(timerName).getTime() / 1000.0;\n }\n\n /**\n * Get a timer elapsed time.\n *\n * This is used by conditions to return false when a timer doesn't exist,\n * no matter the relational operator.\n *\n * @param timerName The timer name.\n * @return The timer elapsed time in seconds, NaN if the timer doesn't exist.\n */\n getTimerElapsedTimeInSecondsOrNaN(timerName: string): float {\n if (!this._timers.containsKey(timerName)) {\n return Number.NaN;\n }\n return this._timers.get(timerName).getTime() / 1000.0;\n }\n\n //Other :\n /**\n * Separate the object from others objects, using their hitboxes.\n * @param objects Objects\n * @param ignoreTouchingEdges If true, then edges that are touching each other, without the hitbox polygons actually overlapping, won't be considered in collision.\n * @return true if the object was moved\n */\n separateFromObjects(\n objects: gdjs.RuntimeObject[],\n ignoreTouchingEdges: boolean\n ): boolean {\n let moveXArray: Array<float> = separateFromObjectsStatics.moveXArray;\n let moveYArray: Array<float> = separateFromObjectsStatics.moveYArray;\n moveXArray.length = 0;\n moveYArray.length = 0;\n\n // We can assume that the moving object is not grid based,\n // so there is no need for optimization:\n // getHitBoxes can be called directly.\n const hitBoxes = this.getHitBoxes();\n let aabb: AABB | null = null;\n\n // Check if there is a collision with each object\n for (const otherObject of objects) {\n if (otherObject.id === this.id) {\n continue;\n }\n let otherHitBoxesArray = otherObject.getHitBoxes();\n let otherHitBoxes: Iterable<gdjs.Polygon> = otherHitBoxesArray;\n if (otherHitBoxesArray.length > 4) {\n // The other object has a lot of hit boxes.\n // Try to reduce the amount of hitboxes to check.\n if (!aabb) {\n aabb = this.getAABB();\n }\n otherHitBoxes = otherObject.getHitBoxesAround(\n aabb.min[0],\n aabb.min[1],\n aabb.max[0],\n aabb.max[1]\n );\n }\n for (const hitBox of hitBoxes) {\n for (const otherHitBox of otherHitBoxes) {\n const result = gdjs.Polygon.collisionTest(\n hitBox,\n otherHitBox,\n ignoreTouchingEdges\n );\n if (result.collision) {\n moveXArray.push(result.move_axis[0]);\n moveYArray.push(result.move_axis[1]);\n }\n }\n }\n }\n return moveFollowingSeparatingVectors(this, moveXArray, moveYArray);\n }\n\n /**\n * Separate the object from others objects, using their hitboxes.\n * @param objectsLists Tables of objects\n * @param ignoreTouchingEdges If true, then edges that are touching each other, without the hitbox polygons actually overlapping, won't be considered in collision.\n * @return true if the object was moved\n */\n separateFromObjectsList(\n objectsLists: ObjectsLists,\n ignoreTouchingEdges: boolean\n ): boolean {\n let moveXArray: Array<float> = separateFromObjectsStatics.moveXArray;\n let moveYArray: Array<float> = separateFromObjectsStatics.moveYArray;\n moveXArray.length = 0;\n moveYArray.length = 0;\n\n // We can assume that the moving object is not grid based\n // So there is no need for optimization\n // getHitBoxes can be called directly.\n const hitBoxes = this.getHitBoxes();\n let aabb: AABB | null = null;\n\n for (const name in objectsLists.items) {\n if (objectsLists.items.hasOwnProperty(name)) {\n const otherObjects = objectsLists.items[name];\n\n // Check if their is a collision with each object\n for (const otherObject of otherObjects) {\n if (otherObject.id === this.id) {\n continue;\n }\n let otherHitBoxesArray = otherObject.getHitBoxes();\n let otherHitBoxes: Iterable<gdjs.Polygon> = otherHitBoxesArray;\n if (otherHitBoxesArray.length > 4) {\n // The other object has a lot of hit boxes.\n // Try to reduce the amount of hitboxes to check.\n if (!aabb) {\n aabb = this.getAABB();\n }\n otherHitBoxes = otherObject.getHitBoxesAround(\n aabb.min[0],\n aabb.min[1],\n aabb.max[0],\n aabb.max[1]\n );\n }\n for (const hitBox of hitBoxes) {\n for (const otherHitBox of otherHitBoxes) {\n const result = gdjs.Polygon.collisionTest(\n hitBox,\n otherHitBox,\n ignoreTouchingEdges\n );\n if (result.collision) {\n moveXArray.push(result.move_axis[0]);\n moveYArray.push(result.move_axis[1]);\n }\n }\n }\n }\n }\n }\n return moveFollowingSeparatingVectors(this, moveXArray, moveYArray);\n }\n\n /**\n * Get the distance, in pixels, between *the center* of this object and another object.\n * @param otherObject The other object\n */\n getDistanceToObject(otherObject: gdjs.RuntimeObject): float {\n return Math.sqrt(this.getSqDistanceToObject(otherObject));\n }\n\n /**\n * Get the squared distance, in pixels, between *the center* of this object and another object.\n * @param otherObject The other object\n */\n getSqDistanceToObject(otherObject: gdjs.RuntimeObject): float {\n if (otherObject === null) {\n return 0;\n }\n const x =\n this.getDrawableX() +\n this.getCenterX() -\n (otherObject.getDrawableX() + otherObject.getCenterX());\n const y =\n this.getDrawableY() +\n this.getCenterY() -\n (otherObject.getDrawableY() + otherObject.getCenterY());\n return x * x + y * y;\n }\n\n /**\n * Get the distance, in pixels, between *the center* of this object and a position.\n * @param targetX Target X position\n * @param targetY Target Y position\n */\n getDistanceToPosition(targetX: float, targetY: float): float {\n return Math.sqrt(this.getSqDistanceToPosition(targetX, targetY));\n }\n\n /**\n * Get the squared distance, in pixels, between *the center* of this object and a position.\n * @param targetX Target X position\n * @param targetY Target Y position\n */\n getSqDistanceToPosition(targetX: float, targetY: float): float {\n const x = this.getDrawableX() + this.getCenterX() - targetX;\n const y = this.getDrawableY() + this.getCenterY() - targetY;\n return x * x + y * y;\n }\n\n /**\n * Get the angle, in degrees, from the *object center* to another object.\n * @param otherObject The other object\n */\n getAngleToObject(otherObject: gdjs.RuntimeObject): float {\n if (otherObject === null) {\n return 0;\n }\n const x =\n this.getDrawableX() +\n this.getCenterX() -\n (otherObject.getDrawableX() + otherObject.getCenterX());\n const y =\n this.getDrawableY() +\n this.getCenterY() -\n (otherObject.getDrawableY() + otherObject.getCenterY());\n return gdjs.toDegrees(Math.atan2(-y, -x));\n }\n\n /**\n * Compute the X position when given an angle and distance relative to the starting object.\n * This is also known as getting the cartesian coordinates of a 2D vector, using its polar coordinates.\n * @param angle The angle, in degrees.\n * @param distance The distance from the object, in pixels\n */\n getXFromAngleAndDistance(angle: float, distance: float): float {\n return (\n this.getDrawableX() +\n this.getCenterX() +\n distance * Math.cos(gdjs.toRad(angle))\n );\n }\n\n /**\n * Compute the Y position when given an angle and distance relative to the starting object.\n * This is also known as getting the cartesian coordinates of a 2D vector, using its polar coordinates.\n * @param angle The angle, in degrees.\n * @param distance The distance from the object, in pixels\n */\n getYFromAngleAndDistance(angle: float, distance: float): float {\n return (\n this.getDrawableY() +\n this.getCenterY() +\n distance * Math.sin(gdjs.toRad(angle))\n );\n }\n\n /**\n * Get the angle, in degrees, from the *object center* to a position.\n * @param targetX Target X position\n * @param targetY Target Y position\n */\n getAngleToPosition(targetX: float, targetY: float): float {\n const x = this.getDrawableX() + this.getCenterX() - targetX;\n const y = this.getDrawableY() + this.getCenterY() - targetY;\n return gdjs.toDegrees(Math.atan2(-y, -x));\n }\n\n /**\n * Put the object around a position, with a specific distance and angle.\n * The distance and angle are computed between the position and *the center of the object*.\n *\n * @param x The x position of the target\n * @param y The y position of the target\n * @param distance The distance between the object and the target, in pixels.\n * @param angleInDegrees The angle between the object and the target, in degrees.\n */\n putAround(\n x: float,\n y: float,\n distance: float,\n angleInDegrees: float\n ): void {\n const angleInRadians = gdjs.toRad(angleInDegrees);\n\n this.setCenterXInScene(x + Math.cos(angleInRadians) * distance);\n this.setCenterYInScene(y + Math.sin(angleInRadians) * distance);\n }\n\n /**\n * Put the object around another object, with a specific distance and angle.\n * The distance and angle are computed between *the centers of the objects*.\n *\n * @param obj The target object\n * @param distance The distance between the object and the target\n * @param angleInDegrees The angle between the object and the target, in degrees.\n */\n putAroundObject(\n obj: gdjs.RuntimeObject | null,\n distance: float,\n angleInDegrees: float\n ): void {\n if (!obj) return;\n\n this.putAround(\n obj.getDrawableX() + obj.getCenterX(),\n obj.getDrawableY() + obj.getCenterY(),\n distance,\n angleInDegrees\n );\n }\n\n /**\n * @deprecated\n * @param objectsLists Tables of objects\n */\n separateObjectsWithoutForces(objectsLists: ObjectsLists): void {\n //Prepare the list of objects to iterate over.\n const objects = gdjs.staticArray(\n RuntimeObject.prototype.separateObjectsWithoutForces\n );\n objects.length = 0;\n const lists = gdjs.staticArray2(\n RuntimeObject.prototype.separateObjectsWithoutForces\n );\n objectsLists.values(lists);\n for (let i = 0, len = lists.length; i < len; ++i) {\n objects.push.apply(objects, lists[i]);\n }\n for (let i = 0, len = objects.length; i < len; ++i) {\n if (objects[i].id != this.id) {\n if (this.getDrawableX() < objects[i].getDrawableX()) {\n this.setX(objects[i].getDrawableX() - this.getWidth());\n } else {\n if (\n this.getDrawableX() + this.getWidth() >\n objects[i].getDrawableX() + objects[i].getWidth()\n ) {\n this.setX(objects[i].getDrawableX() + objects[i].getWidth());\n }\n }\n if (this.getDrawableY() < objects[i].getDrawableY()) {\n this.setY(objects[i].getDrawableY() - this.getHeight());\n } else {\n if (\n this.getDrawableY() + this.getHeight() >\n objects[i].getDrawableY() + objects[i].getHeight()\n ) {\n this.setY(objects[i].getDrawableY() + objects[i].getHeight());\n }\n }\n }\n }\n }\n\n /**\n * @deprecated\n * @param objectsLists Tables of objects\n */\n separateObjectsWithForces(objectsLists: ObjectsLists): void {\n //Prepare the list of objects to iterate over.\n const objects = gdjs.staticArray(\n RuntimeObject.prototype.separateObjectsWithForces\n );\n objects.length = 0;\n const lists = gdjs.staticArray2(\n RuntimeObject.prototype.separateObjectsWithForces\n );\n objectsLists.values(lists);\n for (let i = 0, len = lists.length; i < len; ++i) {\n objects.push.apply(objects, lists[i]);\n }\n for (let i = 0, len = objects.length; i < len; ++i) {\n if (objects[i].id != this.id) {\n if (\n this.getDrawableX() + this.getCenterX() <\n objects[i].getDrawableX() + objects[i].getCenterX()\n ) {\n let av = this.hasNoForces() ? 0 : this.getAverageForce().getX();\n this.addForce(-av - 10, 0, 0);\n } else {\n let av = this.hasNoForces() ? 0 : this.getAverageForce().getX();\n this.addForce(-av + 10, 0, 0);\n }\n if (\n this.getDrawableY() + this.getCenterY() <\n objects[i].getDrawableY() + objects[i].getCenterY()\n ) {\n let av = this.hasNoForces() ? 0 : this.getAverageForce().getY();\n this.addForce(0, -av - 10, 0);\n } else {\n let av = this.hasNoForces() ? 0 : this.getAverageForce().getY();\n this.addForce(0, -av + 10, 0);\n }\n }\n }\n }\n\n /**\n * Return true if the hitboxes of two objects are overlapping\n * @static\n * @param obj1 The first runtimeObject\n * @param obj2 The second runtimeObject\n * @param ignoreTouchingEdges If true, then edges that are touching each other, without the hitbox polygons actually overlapping, won't be considered in collision.\n * @param ignoredObject1Polygon A polygon from the `obj1` collision mask to ignore\n * @return true if obj1 and obj2 are in collision\n */\n static collisionTest(\n obj1: gdjs.RuntimeObject,\n obj2: gdjs.RuntimeObject,\n ignoreTouchingEdges: boolean,\n ignoredObject1Polygon: gdjs.Polygon | null = null\n ): boolean {\n //First check if bounding circle are too far.\n const o1centerX = obj1.getCenterX();\n const o1centerY = obj1.getCenterY();\n const obj1BoundingRadius = Math.sqrt(\n computeSqBoundingRadius(\n obj1.getWidth(),\n obj1.getHeight(),\n o1centerX,\n o1centerY\n )\n );\n\n const o2centerX = obj2.getCenterX();\n const o2centerY = obj2.getCenterY();\n const obj2BoundingRadius = Math.sqrt(\n computeSqBoundingRadius(\n obj2.getWidth(),\n obj2.getHeight(),\n o2centerX,\n o2centerY\n )\n );\n\n const o1AbsoluteCenterX = obj1.getDrawableX() + o1centerX;\n const o1AbsoluteCenterY = obj1.getDrawableY() + o1centerY;\n const o2AbsoluteCenterX = obj2.getDrawableX() + o2centerX;\n const o2AbsoluteCenterY = obj2.getDrawableY() + o2centerY;\n\n const diffX = o1AbsoluteCenterX - o2AbsoluteCenterX;\n const diffY = o1AbsoluteCenterY - o2AbsoluteCenterY;\n if (\n Math.sqrt(diffX * diffX + diffY * diffY) >\n obj1BoundingRadius + obj2BoundingRadius\n ) {\n return false;\n }\n\n // Do a real check if necessary.\n const hitBoxes1 = obj1.getHitBoxesAround(\n o2AbsoluteCenterX - obj2BoundingRadius,\n o2AbsoluteCenterY - obj2BoundingRadius,\n o2AbsoluteCenterX + obj2BoundingRadius,\n o2AbsoluteCenterY + obj2BoundingRadius\n );\n const hitBoxes2 = obj2.getHitBoxesAround(\n o1AbsoluteCenterX - obj1BoundingRadius,\n o1AbsoluteCenterY - obj1BoundingRadius,\n o1AbsoluteCenterX + obj1BoundingRadius,\n o1AbsoluteCenterY + obj1BoundingRadius\n );\n\n for (const hitBox1 of hitBoxes1) {\n if (hitBox1 === ignoredObject1Polygon) {\n continue;\n }\n for (const hitBox2 of hitBoxes2) {\n if (\n gdjs.Polygon.collisionTest(hitBox1, hitBox2, ignoreTouchingEdges)\n .collision\n ) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * @param x The raycast source X\n * @param y The raycast source Y\n * @param endX The raycast end position X\n * @param endY The raycast end position Y\n * @param closest Get the closest or farthest collision mask result?\n * @return A raycast result with the contact points and distances\n */\n raycastTest(\n x: float,\n y: float,\n endX: float,\n endY: float,\n closest: boolean\n ): RaycastTestResult {\n // First check if bounding circles are too far\n const objCenterX = this.getCenterX();\n const objCenterY = this.getCenterY();\n const objSqBoundingRadius = computeSqBoundingRadius(\n this.getWidth(),\n this.getHeight(),\n objCenterX,\n objCenterY\n );\n\n const rayCenterWorldX = (x + endX) / 2;\n const rayCenterWorldY = (y + endY) / 2;\n const raySqBoundingRadius =\n (endX - x) * (endX - x) + (endY - y) * (endY - y);\n\n const diffX = this.getDrawableX() + objCenterX - rayCenterWorldX;\n const diffY = this.getDrawableY() + objCenterY - rayCenterWorldY;\n\n let result = raycastTestStatics.result;\n result.collision = false;\n if (\n // As an optimization, avoid computing the square root of the two boundings radius\n // and the distance by comparing the squared values instead.\n diffX * diffX + diffY * diffY >\n objSqBoundingRadius +\n raySqBoundingRadius +\n 2 * Math.sqrt(raySqBoundingRadius * objSqBoundingRadius)\n ) {\n return result;\n }\n\n // Do a real check if necessary.\n if (closest) {\n let sqDistMin = Number.MAX_VALUE;\n const hitBoxes = this.getHitBoxesAround(x, y, endX, endY);\n for (const hitBox of hitBoxes) {\n const res = gdjs.Polygon.raycastTest(hitBox, x, y, endX, endY);\n if (res.collision && res.closeSqDist < sqDistMin) {\n sqDistMin = res.closeSqDist;\n gdjs.Polygon.copyRaycastTestResult(res, result);\n }\n }\n } else {\n let sqDistMax = -Number.MAX_VALUE;\n const hitBoxes = this.getHitBoxesAround(x, y, endX, endY);\n for (const hitBox of hitBoxes) {\n const res = gdjs.Polygon.raycastTest(hitBox, x, y, endX, endY);\n if (\n res.collision &&\n res.farSqDist > sqDistMax &&\n res.farSqDist <= raySqBoundingRadius\n ) {\n sqDistMax = res.farSqDist;\n gdjs.Polygon.copyRaycastTestResult(res, result);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Return true if the specified position is inside object bounding box.\n *\n * The position should be in \"world\" coordinates, i.e use gdjs.Layer.convertCoords\n * if you need to pass the mouse or a touch position that you get from gdjs.InputManager.\n * To check if a point is inside the object collision mask, you can use `isCollidingWithPoint` instead.\n *\n */\n insideObject(x: float, y: float): boolean {\n if (this.hitBoxesDirty) {\n this.updateHitBoxes();\n this.updateAABB();\n this.hitBoxesDirty = false;\n }\n return (\n this.aabb.min[0] <= x &&\n this.aabb.max[0] >= x &&\n this.aabb.min[1] <= y &&\n this.aabb.max[1] >= y\n );\n }\n\n /**\n * Check the distance between two objects.\n * @static\n */\n static distanceTest(\n obj1: RuntimeObject,\n obj2: RuntimeObject,\n distance: float\n ): boolean {\n return obj1.getSqDistanceToObject(obj2) <= distance;\n }\n\n /**\n * Return true if the cursor, or any touch, is on the object.\n *\n * @return true if the cursor, or any touch, is on the object.\n */\n cursorOnObject(instanceContainer: gdjs.RuntimeInstanceContainer): boolean {\n const workingPoint: FloatPoint = gdjs.staticArray(\n RuntimeObject.prototype.cursorOnObject\n ) as FloatPoint;\n workingPoint.length = 2;\n const inputManager = instanceContainer.getGame().getInputManager();\n const layer = instanceContainer.getLayer(this.layer);\n const mousePos = layer.convertCoords(\n inputManager.getCursorX(),\n inputManager.getCursorY(),\n 0,\n workingPoint\n );\n if (this.insideObject(mousePos[0], mousePos[1])) {\n return true;\n }\n const touchIds = inputManager.getAllTouchIdentifiers();\n for (let i = 0; i < touchIds.length; ++i) {\n const touchPos = layer.convertCoords(\n inputManager.getTouchX(touchIds[i]),\n inputManager.getTouchY(touchIds[i]),\n 0,\n workingPoint\n );\n if (this.insideObject(touchPos[0], touchPos[1])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if a point is inside the object collision hitboxes.\n * @param pointX The point x coordinate.\n * @param pointY The point y coordinate.\n * @return true if the point is inside the object collision hitboxes.\n */\n isCollidingWithPoint(pointX: float, pointY: float): boolean {\n const hitBoxes = this.getHitBoxesAround(pointX, pointY, pointX, pointY);\n for (const hitBox of hitBoxes) {\n if (gdjs.Polygon.isPointInside(hitBox, pointX, pointY)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get the identifier associated to an object name.\n * Some features may want to compare objects name a large number of time. In this case,\n * it may be more efficient to compare objects name identifiers.\n *\n * @static\n */\n static getNameIdentifier(name: string): integer {\n if (RuntimeObject._identifiers.containsKey(name)) {\n return RuntimeObject._identifiers.get(name);\n }\n RuntimeObject._newId = (RuntimeObject._newId || 0) + 1;\n const newIdentifier = RuntimeObject._newId;\n RuntimeObject._identifiers.put(name, newIdentifier);\n return newIdentifier;\n }\n\n /**\n * Table containing the id corresponding to an object name. Do not use directly or modify.\n * @static\n */\n static _identifiers = new Hashtable<integer>();\n\n /**\n * The next available unique identifier for an object. Do not use directly or modify.\n * @static\n */\n static _newId = 0;\n\n /**\n * Global container for unused forces, avoiding recreating forces each tick.\n * @static\n */\n static forcesGarbage: Array<gdjs.Force> = [];\n\n getVariableNumber = RuntimeObject.getVariableNumber;\n returnVariable = RuntimeObject.returnVariable;\n getVariableString = RuntimeObject.getVariableString;\n setVariableNumber = RuntimeObject.setVariableNumber;\n setVariableString = RuntimeObject.setVariableString;\n getVariableBoolean = RuntimeObject.getVariableBoolean;\n setVariableBoolean = RuntimeObject.setVariableBoolean;\n getVariableChildCount = RuntimeObject.getVariableChildCount;\n getFirstVariableNumber = RuntimeObject.getFirstVariableNumber;\n getFirstVariableString = RuntimeObject.getFirstVariableString;\n getLastVariableNumber = RuntimeObject.getLastVariableNumber;\n getLastVariableString = RuntimeObject.getLastVariableString;\n toggleVariableBoolean = RuntimeObject.toggleVariableBoolean;\n variableChildExists = RuntimeObject.variableChildExists;\n variableRemoveChild = RuntimeObject.variableRemoveChild;\n variableClearChildren = RuntimeObject.variableClearChildren;\n variablePushCopy = RuntimeObject.variablePushCopy;\n valuePush = RuntimeObject.valuePush;\n variableRemoveAt = RuntimeObject.variableRemoveAt;\n\n /**\n * Get the squared distance, in pixels, from the *object center* to a position.\n * @param pointX X position\n * @param pointY Y position\n * @deprecated Use `getSqDistanceToPosition` instead.\n */\n getSqDistanceTo = RuntimeObject.prototype.getSqDistanceToPosition;\n }\n gdjs.registerObject('', gdjs.RuntimeObject);\n}\n"],
5
- "mappings": "AAKA,GAAU,MAAV,UAAU,EAAV,CAiBE,KAAM,GAA0B,CAC9B,EACA,EACA,EACA,IACG,CACH,KAAM,GAAU,KAAK,IAAI,EAAS,EAAQ,GACpC,EAAU,KAAK,IAAI,EAAS,EAAS,GAC3C,MAAO,MAAK,IAAI,EAAS,GAAK,KAAK,IAAI,EAAS,IAO5C,EAGF,CACF,WAAY,GACZ,WAAY,IAOR,EAEF,CACF,OAAQ,EAAK,QAAQ,4BAejB,EAAiC,CACrC,EACA,EACA,IACY,CACZ,GAAI,EAAW,SAAW,EACxB,SAAW,OAAS,EACpB,EAAW,OAAS,EACb,GAET,GAAI,EAAW,SAAW,EAExB,SAAO,YACL,EAAO,OAAS,EAAW,GAC3B,EAAO,OAAS,EAAW,IAE7B,EAAW,OAAS,EACpB,EAAW,OAAS,EACb,GAIT,GAAI,GAAqB,EACrB,EAAmB,EACvB,OAAS,GAAQ,EAAG,EAAQ,EAAW,OAAQ,IAAS,CACtD,KAAM,GAAQ,EAAW,GACnB,EAAQ,EAAW,GAEnB,EAAkB,EAAQ,EAAQ,EAAQ,EAChD,AAAI,EAAkB,GACpB,GAAqB,EACrB,EAAmB,GAIvB,KAAM,GAAc,KAAK,KAAK,GAExB,EAAK,EAAW,GAAoB,EAIpC,EAAK,CAHA,GAAW,GAAoB,GAIpC,EAAK,EAGX,GAAI,GAAmB,EACnB,EAAmB,EACvB,OAAS,GAAQ,EAAG,EAAQ,EAAW,OAAQ,IAAS,CACtD,KAAM,GAAQ,EAAW,GACnB,EAAQ,EAAW,GAEnB,EAAgB,EAAQ,EAAK,EAAQ,EAC3C,EAAmB,KAAK,IAAI,EAAkB,GAC9C,EAAmB,KAAK,IAAI,EAAkB,GAIhD,GAAI,GAAS,EAAW,GACpB,EAAS,EAAW,GAKxB,KAAM,GACJ,CAAC,EAAmB,EAAmB,QACnC,EACJ,EAAmB,CAAC,EAAmB,QACzC,MAAI,KAAiC,GACnC,CAAI,EACF,IAAU,EAAmB,EAC7B,GAAU,EAAmB,GAE7B,IAAU,EAAmB,EAC7B,GAAU,EAAmB,IAGjC,EAAO,YAAY,EAAO,OAAS,EAAQ,EAAO,OAAS,GAC3D,EAAW,OAAS,EACpB,EAAW,OAAS,EACb,IASF,OAAiE,CA8EtE,YACE,EACA,EACA,CA9EF,OAAW,EACX,OAAW,EACX,WAAe,EACf,YAAkB,EAClB,YAAkB,GAClB,WAAgB,GAEN,oBAA0B,GAG5B,sBAAmB,GAAI,KAO/B,oBAAgC,KAQhC,eAA2B,KAO3B,UAAgB,GAGN,sBAAmC,GAEnC,mBAAyB,GACzB,UAAa,CAAE,IAAK,CAAC,EAAG,GAAI,IAAK,CAAC,EAAG,IACrC,sCAAmC,GAMnC,sBACR,GAGQ,oBAA+B,GACzC,sBAA0B,EAC1B,sBAA0B,EAUhB,gBAAqC,GA0hF/C,uBAAoB,EAAc,kBAClC,oBAAiB,EAAc,eAC/B,uBAAoB,EAAc,kBAClC,uBAAoB,EAAc,kBAClC,uBAAoB,EAAc,kBAClC,wBAAqB,EAAc,mBACnC,wBAAqB,EAAc,mBACnC,2BAAwB,EAAc,sBACtC,4BAAyB,EAAc,uBACvC,4BAAyB,EAAc,uBACvC,2BAAwB,EAAc,sBACtC,2BAAwB,EAAc,sBACtC,2BAAwB,EAAc,sBACtC,yBAAsB,EAAc,oBACpC,yBAAsB,EAAc,oBACpC,2BAAwB,EAAc,sBACtC,sBAAmB,EAAc,iBACjC,eAAY,EAAc,UAC1B,sBAAmB,EAAc,iBAQjC,qBAAkB,EAAc,UAAU,wBAliFxC,KAAK,KAAO,EAAW,MAAQ,GAC/B,KAAK,KAAO,EAAW,MAAQ,GAC/B,KAAK,QAAU,EAAc,kBAAkB,KAAK,MACpD,KAAK,GAAK,EAAkB,WAAW,oBACvC,KAAK,cAAgB,EACrB,KAAK,iBAAiB,KAAK,EAAK,QAAQ,gBAAgB,EAAG,IAC3D,KAAK,SAAW,KAAK,iBACrB,KAAK,WAAa,GAAI,GAAK,mBACzB,EAAa,EAAW,UAAY,QAEtC,KAAK,YAAc,GAAI,GAAK,MAAM,EAAG,EAAG,GACxC,KAAK,gBAAkB,GAAI,WAC3B,OAAS,GAAI,EAAG,EAAI,EAAW,QAAQ,OAAQ,EAAE,EAC/C,KAAK,cACF,UACA,oBACA,iBAAiB,EAAW,QAAQ,GAAI,KAAK,iBAAkB,MAClE,KAAK,0BAA0B,EAAW,QAAQ,IAGpD,OAAS,GAAI,EAAG,EAAM,EAAW,UAAU,OAAQ,EAAI,EAAK,EAAE,EAAG,CAC/D,KAAM,GAAW,EAAW,UAAU,GAChC,EAAO,EAAK,uBAAuB,EAAS,MAC5C,EAAW,GAAI,GAAK,EAAmB,EAAU,MACvD,AAAI,EAAS,yBACX,KAAK,WAAW,KAAK,GAEvB,KAAK,gBAAgB,IAAI,EAAS,KAAM,GAE1C,KAAK,QAAU,GAAI,WAarB,WAAkB,CAEhB,GADuB,KAAK,oBAE1B,SAAW,KAAc,MAAK,iBAC5B,KAAK,iBAAiB,GAAY,YAAY,MAIlD,OAAS,GAAI,EAAG,EAAI,KAAK,WAAW,OAAQ,EAAE,EAC5C,KAAK,WAAW,GAAG,YAoBvB,aAAa,EAA8B,CACzC,KAAM,GAAe,KAAK,cAC1B,KAAK,EAAI,EACT,KAAK,EAAI,EACT,KAAK,MAAQ,EACb,KAAK,OAAS,EACd,KAAK,OAAS,GACd,KAAK,MAAQ,GACb,KAAK,eAAiB,GAEtB,KAAK,GAAK,EAEP,WACA,oBACH,KAAK,eAAiB,KACtB,KAAK,UAAY,KACjB,KAAK,KAAO,GACZ,KAAK,cAAgB,GACrB,KAAK,iBAAiB,OAAS,EAC/B,KAAK,iBAAiB,KAAK,EAAK,QAAQ,gBAAgB,EAAG,IAC3D,KAAK,KAAK,IAAI,GAAK,EACnB,KAAK,KAAK,IAAI,GAAK,EACnB,KAAK,KAAK,IAAI,GAAK,EACnB,KAAK,KAAK,IAAI,GAAK,EACnB,KAAK,WAAa,GAAI,GAAK,mBAAmB,EAAW,WACzD,KAAK,cAGL,KAAK,gBAAgB,QACrB,KAAM,GAAqB,EAAW,UAAU,OAChD,GAAI,GAAuC,EAC3C,OACM,GAAoB,EACxB,EAAoB,EACpB,EAAE,EACF,CACA,KAAM,GAAe,EAAW,UAAU,GACpC,EAAO,EAAK,uBAAuB,EAAa,MAEhD,EAAW,GAAI,GAAK,EAAc,EAAc,MACtD,AAAI,EAAS,yBACX,CAAI,EAAuC,KAAK,WAAW,OACzD,KAAK,WAAW,GAAwC,EAExD,KAAK,WAAW,KAAK,GAEvB,KAEF,KAAK,gBAAgB,IAAI,EAAa,KAAM,GAE9C,KAAK,WAAW,OAAS,EAGzB,OAAS,GAAI,EAAG,EAAI,EAAW,QAAQ,OAAQ,EAAE,EAC/C,KAAK,cACF,UACA,oBACA,iBAAiB,EAAW,QAAQ,GAAI,KAAK,iBAAkB,MAClE,KAAK,0BAA0B,EAAW,QAAQ,IAIpD,KAAK,QAAQ,QAEb,KAAK,iBAAiB,QAEtB,KAAK,qBAWP,gBAAwB,CAEtB,MAAO,AADU,MAAK,cAAc,SAAS,KAAK,OAClC,iBAMlB,WAA2C,CACzC,MAAO,MAAK,cAMd,iBAAqC,CACnC,MAAO,MAAK,cAAc,WAM5B,sBAAsD,CACpD,MAAO,MAAK,cAOd,OAAO,EAAwD,EAM/D,gBAAgB,EAAwD,EAQxE,uCACE,EACM,EAUR,qBACE,EACA,EACS,CAET,MAAO,GAQT,oBAA4C,CAC1C,KAAM,GAA0B,GAChC,KAAK,WAAW,QAAQ,AAAC,GAAa,CACpC,GAAI,CAAC,EAAS,sBACZ,OAGF,KAAM,GAAkB,EAAS,qBACjC,AAAI,GACF,GAAwB,EAAS,WAAa,KAIlD,KAAM,GAA2B,KAAK,WAAW,mBAAmB,IAI9D,EAAyB,GAC/B,SAAW,KAAc,MAAK,iBAC5B,EAAuB,GACrB,KAAK,iBAAiB,GAAY,qBAGtC,KAAM,GAAwB,GAC9B,SAAW,KAAa,MAAK,QAAQ,MACnC,EAAsB,GACpB,KAAK,QAAQ,MAAM,GAAW,qBAGlC,MAAO,CACL,EAAG,KAAK,EACR,EAAG,KAAK,EACR,GAAI,KAAK,OACT,EAAG,KAAK,MACR,IAAK,KAAK,OACV,IAAK,KAAK,MACV,GAAI,KAAK,eAAe,IAAI,AAAC,GAAU,EAAM,sBAC7C,IAAK,KAAK,iBACV,IAAK,KAAK,iBACV,IAAK,EACL,IAAK,EACL,IAAK,EACL,IAAK,GAWT,0BAA0B,EAAwC,CA2BhE,GA1BI,EAAgB,IAAM,QACxB,KAAK,KAAK,EAAgB,GAExB,EAAgB,IAAM,QACxB,KAAK,KAAK,EAAgB,GAExB,EAAgB,KAAO,QACzB,KAAK,UAAU,EAAgB,IAE7B,EAAgB,IAAM,QACxB,KAAK,SAAS,EAAgB,GAG9B,EAAgB,MAAQ,QACxB,KAAK,SAAW,EAAgB,KAEhC,KAAK,KAAK,EAAgB,KAI1B,EAAgB,MAAQ,QACxB,KAAK,QAAU,EAAgB,KAE/B,KAAK,SAAS,EAAgB,KAG5B,EAAgB,GAAI,CAGtB,KAAK,cACL,OAAS,GAAI,EAAG,EAAM,EAAgB,GAAG,OAAQ,EAAI,EAAK,EAAE,EAAG,CAC7D,KAAM,GAAY,EAAgB,GAAG,GAC/B,EAAqB,KAAK,kBAC9B,EAAU,EACV,EAAU,EACV,EAAU,GAEZ,EAAmB,0BAA0B,GAC7C,KAAK,eAAe,KAAK,IAG7B,AAAI,EAAgB,MAAQ,QAC1B,MAAK,iBAAmB,EAAgB,KAEtC,EAAgB,MAAQ,QAC1B,MAAK,iBAAmB,EAAgB,KAI1C,SAAW,KAAgB,GAAgB,IAAK,CAC9C,KAAM,GAA0B,EAAgB,IAAI,GAC9C,EAAW,KAAK,YAAY,GAClC,AAAI,GACF,EAAS,0BAA0B,GAUvC,GALI,EAAgB,KAClB,KAAK,WAAW,0BAA0B,EAAgB,KAIxD,EAAgB,IAElB,SAAW,KAAc,GAAgB,IAAK,CAC5C,KAAM,GAAwB,EAAgB,IAAI,GAC5C,EAAS,KAAK,iBAAiB,GACrC,AAAI,GACF,EAAO,0BAA0B,GAOvC,GAAI,EAAgB,IAClB,SAAW,KAAa,GAAgB,IAAK,CAC3C,KAAM,GAAuB,EAAgB,IAAI,GAC3C,EAAQ,KAAK,QAAQ,IAAI,GAC/B,AAAI,GACF,EAAM,0BAA0B,IAWxC,iBAAwB,CACtB,AAAI,KAAK,gBACP,MAAK,cAAc,sBAAsB,MACzC,KAAK,eAAiB,IAI1B,wBAAwB,EAAsB,CAC5C,KAAK,iBAAiB,IAAI,GAG5B,0BAA0B,EAAsB,CAC9C,KAAK,iBAAiB,OAAO,GAW/B,oBAA2B,CACzB,KAAM,GAAW,KAAK,cAAc,SAAS,KAAK,OAC5C,EAAiB,KAAK,oBAC5B,AAAI,GACF,EAAS,cAAc,qBAAqB,GAE9C,KAAM,GAAmB,KAAK,sBAC9B,AAAI,GACF,EAAS,cAAc,uBAAuB,GAEhD,OAAS,GAAI,EAAG,EAAO,KAAK,WAAW,OAAQ,EAAI,EAAM,EAAE,EACzD,KAAK,WAAW,GAAG,YAErB,KAAK,iBAAiB,QAAQ,AAAC,GAAM,KACrC,KAAK,eAOP,aAAoB,EAQpB,cAAc,EAAuC,EAQrD,eAAe,EAAuC,EAMtD,mBAAgE,EAOhE,qBAAyD,EASzD,SAAkB,CAChB,MAAO,MAAK,KAOd,WAAqB,CACnB,MAAO,MAAK,QAWd,aAAuB,CACrB,MAAO,MAAK,GASd,YAAY,EAAU,EAAgB,CACpC,KAAK,KAAK,GACV,KAAK,KAAK,GAQZ,KAAK,EAAgB,CACnB,AAAI,IAAM,KAAK,GAGf,MAAK,EAAI,EACT,KAAK,sBAUP,oBAA2B,CAGzB,KAAK,cAAgB,GACrB,KAAK,cAAc,4BAQrB,MAAc,CACZ,MAAO,MAAK,EAQd,KAAK,EAAgB,CACnB,AAAI,IAAM,KAAK,GAGf,MAAK,EAAI,EACT,KAAK,sBAQP,MAAc,CACZ,MAAO,MAAK,EAYd,cAAsB,CACpB,MAAO,MAAK,OAYd,cAAsB,CACpB,MAAO,MAAK,OAGd,qBAAqB,EAAU,EAAU,EAAoB,CAC3D,KAAK,kBACH,EAAK,UACH,KAAK,MACH,EAAK,MAAK,eAAiB,KAAK,cAChC,EAAK,MAAK,eAAiB,KAAK,gBAGpC,GAQJ,kBAAkB,EAAc,EAAoB,CAClD,GAAI,IAAU,EAAG,CACf,KAAK,SAAS,GACd,OAMF,KAAM,GAAkB,AAJJ,EAAK,SAAS,OAAO,gBACvC,KAAK,WACL,IAEqC,EACvC,GAAI,GACF,KAAK,WACH,GAAkB,GAAO,GAAO,EAAQ,KAAK,iBAAoB,IAErE,AAEG,EAAK,SAAS,OAAO,gBAAgB,EAAU,GAAS,EACzD,GAEA,GAAW,GAEb,KAAK,SAAS,GAGZ,KAAK,aAAe,GAEpB,KAAK,SAEH,GAWN,OAAO,EAAoB,CACzB,KAAK,SAAS,KAAK,WAAc,EAAQ,KAAK,iBAAoB,KAQpE,SAAS,EAAoB,CAC3B,AAAI,KAAK,QAAU,GAGnB,MAAK,MAAQ,EACb,KAAK,sBAQP,UAAkB,CAChB,MAAO,MAAK,MAQd,SAAS,EAAqB,CAC5B,GAAI,IAAU,KAAK,MACjB,OAEF,KAAM,GAAW,KAAK,cAAc,SAAS,KAAK,OAClD,KAAK,MAAQ,EACb,KAAM,GAAW,KAAK,cAAc,SAAS,KAAK,OAC5C,EAAiB,KAAK,oBAC5B,AAAI,GACF,GAAS,cAAc,qBAAqB,GAC5C,EAAS,cAAc,kBAAkB,EAAgB,KAAK,SAEhE,KAAM,GAAmB,KAAK,sBAC9B,AAAI,GACF,GAAS,cAAc,uBAAuB,GAC9C,EAAS,cAAc,oBAAoB,IAS/C,UAAmB,CACjB,MAAO,MAAK,MASd,UAAU,EAAwB,CAChC,MAAO,MAAK,QAAU,EAQxB,UAAU,EAAkB,CAC1B,GAAI,IAAM,KAAK,OACb,OAEF,KAAK,OAAS,EACd,KAAM,GAAiB,KAAK,oBAC5B,AAAI,GAEF,AADiB,KAAK,cAAc,SAAS,KAAK,OACzC,cAAc,2BAA2B,EAAgB,GAStE,WAAmB,CACjB,MAAO,MAAK,OAOd,cAAwC,CACtC,MAAO,MAAK,iBASP,mBAAkB,EAAiC,CACxD,MAAO,GAAS,oBAWX,gBAAe,EAAwC,CAC5D,MAAO,SASF,mBAAkB,EAAiC,CACxD,MAAO,GAAS,oBAoDX,uBAAsB,EAAkC,CAC7D,MAAO,GAAS,yBAQX,mBAAkB,EAAyB,EAAuB,CACvE,EAAS,UAAU,SAQd,mBAAkB,EAAyB,EAAkB,CAClE,EAAS,UAAU,SAQN,qBACb,EACA,EACS,CACT,MAAO,GAAS,SAAS,SAQZ,qBACb,EACA,EACM,CACN,EAAS,YAAY,SAOR,uBAAsB,EAA+B,CAClE,EAAS,gBA8EX,YAAY,EAAuB,CACjC,MAAO,MAAK,WAAW,IAAI,GAQ7B,oBAAqB,CACnB,MAAO,MAAK,iBAOd,UAAU,EAAiC,CAEzC,MADuB,MAAK,oBAKrB,KAAK,cACT,UACA,oBACA,UAAU,EAAY,KAAK,iBAAkB,MANvC,GAaX,aAAa,EAA6B,CAExC,MADuB,MAAK,oBAGrB,KAAK,cACT,UACA,oBACA,aAAa,KAAK,iBAAkB,KAAM,GALjB,GAW9B,cAAwB,CACtB,KAAM,GAAiB,KAAK,oBAC5B,MAAK,GAEL,MAAK,iBAAmB,GAEtB,KAAK,cACF,UACA,oBAEA,aAAa,IARU,GAkB9B,yBACE,EACA,EACA,EACS,CACT,MAAO,MAAK,cACT,UACA,oBACA,yBACC,KAAK,iBACL,EACA,EACA,GAUN,yBACE,EACA,EACA,EACS,CACT,MAAO,MAAK,cACT,UACA,oBACA,yBACC,KAAK,iBACL,EACA,EACA,GAUN,0BACE,EACA,EACA,EACS,CACT,MAAO,MAAK,cACT,UACA,oBACA,0BACC,KAAK,iBACL,EACA,EACA,GAQN,0BAA0B,EAAiC,CACzD,MAAO,MAAK,cACT,UACA,oBACA,0BAA0B,KAAK,iBAAkB,GAQtD,aAAa,EAAc,EAAuB,CAChD,KAAK,cACF,UACA,oBACA,aAAa,KAAK,iBAAkB,KAAM,EAAM,GAQrD,gBAAgB,EAAuB,CACrC,MAAO,MAAK,cACT,UACA,oBACA,gBAAgB,KAAK,iBAAkB,KAAM,GAQlD,UAAU,EAAuB,CAC/B,MAAO,MAAK,cACT,UACA,oBACA,UAAU,KAAK,iBAAkB,GAOtC,KAAK,EAAuB,CAC1B,AAAI,IAAW,QACb,GAAS,IAEX,KAAK,OAAS,EAYhB,WAAqB,CACnB,MAAO,CAAC,KAAK,OAOf,UAAoB,CAClB,MAAO,MAAK,OAOd,SAAS,EAAoB,EAM7B,UAAU,EAAqB,EAM/B,UAAkB,CAChB,MAAO,GAOT,WAAmB,CACjB,MAAO,GAST,YAAoB,CAClB,MAAO,MAAK,WAAa,EAS3B,YAAoB,CAClB,MAAO,MAAK,YAAc,EAO5B,mBAA2B,CACzB,MAAO,MAAK,eAAiB,KAAK,aAOpC,mBAA2B,CACzB,MAAO,MAAK,eAAiB,KAAK,aAQpC,yBAAyB,EAAU,EAAgB,CACjD,KAAK,KAAK,EAAI,KAAK,EAAK,MAAK,eAAiB,KAAK,eACnD,KAAK,KAAK,EAAI,KAAK,EAAK,MAAK,eAAiB,KAAK,eAOrD,kBAAkB,EAAgB,CAChC,KAAK,KAAK,EAAI,KAAK,EAAK,MAAK,eAAiB,KAAK,eAOrD,kBAAkB,EAAgB,CAChC,KAAK,KAAK,EAAI,KAAK,EAAK,MAAK,eAAiB,KAAK,eAY7C,kBACN,EACA,EACA,EACY,CACZ,GAAI,EAAc,cAAc,SAAW,EACzC,MAAO,IAAI,GAAK,MAAM,EAAG,EAAG,GACvB,CACL,KAAM,GAAgB,EAAc,cAAc,MAClD,SAAc,KAAK,GACnB,EAAc,KAAK,GACnB,EAAc,cAAc,GACrB,GAUX,SAAS,EAAU,EAAU,EAA2B,CACtD,AAAI,IAAe,EACjB,MAAK,kBAAoB,EACzB,KAAK,kBAAoB,GACpB,AACL,IAAe,GACf,KAAK,eAAe,OAAS,GAC7B,KAAK,eAAe,GAAG,kBAAoB,EAG3C,KAAK,eAAe,GAAG,IAAI,EAAG,GAI9B,KAAK,eAAe,KAAK,KAAK,kBAAkB,EAAG,EAAG,IAU1D,cAAc,EAAc,EAAY,EAA2B,CACjE,KAAM,GAAiB,EAAK,MAAM,GAG5B,EAAS,KAAK,IAAI,GAAkB,EACpC,EAAS,KAAK,IAAI,GAAkB,EAC1C,KAAK,SAAS,EAAQ,EAAQ,GAUhC,uBACE,EACA,EACA,EACA,EACM,CACN,KAAM,GAAiB,KAAK,MAC1B,EAAK,MAAK,eAAiB,KAAK,cAChC,EAAK,MAAK,eAAiB,KAAK,eAE5B,EAAS,KAAK,IAAI,GAAkB,EACpC,EAAS,KAAK,IAAI,GAAkB,EAC1C,KAAK,SAAS,EAAQ,EAAQ,GAUhC,qBACE,EACA,EACA,EACM,CACN,AAAI,GAAU,MAGd,KAAK,uBACH,EAAO,eAAiB,EAAO,aAC/B,EAAO,eAAiB,EAAO,aAC/B,EACA,GAOJ,aAAoB,CAClB,EAAc,cAAc,KAAK,MAC/B,EAAc,cACd,KAAK,gBAEP,KAAK,eAAe,OAAS,EAC7B,KAAK,iBAAmB,EACxB,KAAK,iBAAmB,EAO1B,aAAuB,CACrB,MACE,MAAK,eAAe,SAAW,GAC/B,KAAK,mBAAqB,GAC1B,KAAK,mBAAqB,EAQ9B,aAAa,EAA0B,CACrC,OAAS,GAAI,EAAG,EAAI,KAAK,eAAe,QAAU,CAChD,KAAM,GAAQ,KAAK,eAAe,GAC5B,EAAa,EAAM,gBACzB,AAAI,IAAe,EAEjB,EAAE,EAEF,AACE,IAAe,GAEf,EAAM,aAAe,KAErB,GAAc,cAAc,KAAK,GACjC,KAAK,eAAe,OAAO,EAAG,IAG9B,GAAM,UACJ,EAAM,YACJ,EAAM,YAAe,GAAI,GAAc,GAE3C,EAAE,IAWV,iBAA8B,CAC5B,KAAK,YAAY,QACjB,KAAK,YAAY,IAAI,KAAK,iBAAkB,KAAK,kBACjD,OAAS,GAAI,EAAG,EAAM,KAAK,eAAe,OAAQ,EAAI,EAAK,EAAE,EAC3D,KAAK,YAAY,SAAS,KAAK,eAAe,IAEhD,MAAO,MAAK,YAad,oBAAoB,EAAc,EAAoC,CACpE,GAAI,GAAe,KAAK,kBAAkB,WAC1C,MAAI,GAAe,GACjB,IAAgB,KAEX,KAAK,IAAI,EAAQ,GAAgB,EAAqB,EAY/D,wBAAwB,EAAc,EAAoC,CACxE,MACE,MAAK,IACH,EAAK,SAAS,OAAO,gBACnB,KAAK,kBAAkB,WACvB,KAEC,EAiBT,aAA8B,CAK5B,MAAI,MAAK,eACP,MAAK,iBACL,KAAK,aACL,KAAK,cAAgB,IAEhB,KAAK,SA6Bd,kBACE,EACA,EACA,EACA,EACwB,CACxB,MAAO,MAAK,cAad,gBAAuB,CAErB,GADA,KAAK,SAAW,KAAK,iBACjB,KAAK,SAAS,SAAW,EAAG,OAChC,KAAM,GAAQ,KAAK,WACb,EAAS,KAAK,YACd,EAAU,KAAK,aACf,EAAU,KAAK,aACrB,AAAI,IAAY,EAAQ,GAAK,IAAY,EAAS,EAChD,MAAK,SAAS,GAAG,SAAS,GAAG,GAAK,CAAC,EACnC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,CAAC,EACnC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,CAAC,EACnC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,CAAC,EACnC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,CAAC,EACnC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,CAAC,EACnC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,CAAC,EACnC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,CAAC,GAEnC,MAAK,SAAS,GAAG,SAAS,GAAG,GAAK,EAAI,EACtC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,EAAI,EACtC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,EAAQ,EAC1C,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,EAAI,EACtC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,EAAQ,EAC1C,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,EAAS,EAC3C,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,EAAI,EACtC,KAAK,SAAS,GAAG,SAAS,GAAG,GAAK,EAAS,GAE7C,KAAK,SAAS,GAAG,OAAO,EAAK,MAAM,KAAK,aACxC,KAAK,SAAS,GAAG,KACf,KAAK,eAAiB,EACtB,KAAK,eAAiB,GAI1B,iCAA2C,CACzC,MAAO,MAAK,iCAGd,iCAAiC,EAA2B,CAC1D,KAAM,GAAc,KAAK,iCACzB,KAAK,iCAAmC,EACpC,IAAgB,GAClB,KAAK,cAAc,4BAevB,SAAgB,CACd,MAAI,MAAK,eACP,MAAK,iBACL,KAAK,aACL,KAAK,cAAgB,IAEhB,KAAK,KAcd,mBAAiC,CAC/B,MAAO,MAAK,UAYd,YAAmB,CACjB,GAAI,KAAK,aAAe,EAItB,KAAK,KAAK,IAAI,GAAK,KAAK,eACxB,KAAK,KAAK,IAAI,GAAK,KAAK,eACxB,KAAK,KAAK,IAAI,GAAK,KAAK,KAAK,IAAI,GAAK,KAAK,WAC3C,KAAK,KAAK,IAAI,GAAK,KAAK,KAAK,IAAI,GAAK,KAAK,gBACtC,CAIL,GAAI,GAAQ,GACZ,OAAS,GAAI,EAAG,EAAI,KAAK,SAAS,OAAQ,IACxC,OAAS,GAAI,EAAG,EAAI,KAAK,SAAS,GAAG,SAAS,OAAQ,IAAK,CACzD,KAAM,GAAS,KAAK,SAAS,GAAG,SAAS,GACzC,AAAI,EACF,MAAK,KAAK,IAAI,GAAK,EAAO,GAC1B,KAAK,KAAK,IAAI,GAAK,EAAO,GAC1B,KAAK,KAAK,IAAI,GAAK,EAAO,GAC1B,KAAK,KAAK,IAAI,GAAK,EAAO,GAC1B,EAAQ,IAER,MAAK,KAAK,IAAI,GAAK,KAAK,IAAI,KAAK,KAAK,IAAI,GAAI,EAAO,IACrD,KAAK,KAAK,IAAI,GAAK,KAAK,IAAI,KAAK,KAAK,IAAI,GAAI,EAAO,IACrD,KAAK,KAAK,IAAI,GAAK,KAAK,IAAI,KAAK,KAAK,IAAI,GAAI,EAAO,IACrD,KAAK,KAAK,IAAI,GAAK,KAAK,IAAI,KAAK,KAAK,IAAI,GAAI,EAAO,OAW/D,aAAqB,CACnB,MAAO,MAAK,UAAU,IAAI,GAO5B,YAAoB,CAClB,MAAO,MAAK,UAAU,IAAI,GAO5B,cAAsB,CACpB,MAAO,MAAK,UAAU,IAAI,GAO5B,eAAuB,CACrB,MAAO,MAAK,UAAU,IAAI,GAO5B,gBAAwB,CACtB,MAAO,MAAK,UAAU,IAAI,GAAK,EAAI,KAAK,UAAU,IAAI,GAAK,EAO7D,gBAAwB,CACtB,MAAO,MAAK,UAAU,IAAI,GAAK,EAAI,KAAK,UAAU,IAAI,GAAK,EAO7D,uBACE,EACM,CACN,OAAS,GAAI,EAAG,EAAM,KAAK,WAAW,OAAQ,EAAI,EAAK,EAAE,EACvD,KAAK,WAAW,GAAG,cAAc,GAOrC,wBACE,EACM,CACN,OAAS,GAAI,EAAG,EAAM,KAAK,WAAW,OAAQ,EAAI,EAAK,EAAE,EACvD,KAAK,WAAW,GAAG,eAAe,GAQtC,kCAAyC,CACvC,OAAS,GAAI,EAAG,EAAM,KAAK,WAAW,OAAQ,EAAI,EAAK,EAAE,EACvD,KAAK,WAAW,GAAG,sBAcvB,YAAY,EAA2C,CACrD,MAAO,MAAK,gBAAgB,IAAI,GAQlC,YAAY,EAAuB,CACjC,MAAO,MAAK,gBAAgB,YAAY,GAS1C,iBAAiB,EAAc,EAAuB,CACpD,AAAI,KAAK,gBAAgB,YAAY,IACnC,KAAK,gBAAgB,IAAI,GAAM,SAAS,GAU5C,kBAAkB,EAAuB,CACvC,MAAI,MAAK,gBAAgB,YAAY,GAC5B,KAAK,gBAAgB,IAAI,GAAM,YAEjC,GAYT,eAAe,EAAuB,CACpC,KAAM,GAAW,KAAK,gBAAgB,IAAI,GAC1C,GAAI,CAAC,EACH,MAAO,GAET,EAAS,YACT,KAAM,GAAgB,KAAK,WAAW,QAAQ,GAC9C,MAAI,KAAkB,IACpB,KAAK,WAAW,OAAO,EAAe,GAExC,KAAK,gBAAgB,OAAO,GACrB,GAST,eAAe,EAAqC,CAClD,KAAM,GAAO,EAAK,uBAAuB,EAAa,MACtD,GAAI,CAAC,EACH,MAAO,GAET,KAAM,GAAqB,GAAI,GAC7B,KAAK,cACL,EACA,MAEF,MAAI,GAAmB,yBACrB,KAAK,WAAW,KAAK,GAEvB,KAAK,gBAAgB,IAAI,EAAa,KAAM,GAC5C,EAAmB,YACZ,GAQT,aAAa,EAA0B,CACrC,SAAW,KAAQ,MAAK,QAAQ,MAC9B,AAAI,KAAK,QAAQ,MAAM,eAAe,IACpC,KAAK,QAAQ,MAAM,GAAM,WAAW,GAc1C,iBAAiB,EAAmB,EAA+B,CACjE,MAAK,MAAK,QAAQ,YAAY,GAIvB,KAAK,6BAA6B,IAAc,EAHrD,MAAK,QAAQ,IAAI,EAAW,GAAI,GAAK,MAAM,IACpC,IAUX,YAAY,EAA4B,CACtC,MAAK,MAAK,QAAQ,YAAY,GAGvB,KAAK,QAAQ,IAAI,GAAW,WAF1B,GASX,WAAW,EAAyB,CAClC,AAAK,KAAK,QAAQ,YAAY,IAC5B,KAAK,QAAQ,IAAI,EAAW,GAAI,GAAK,MAAM,IAE7C,KAAK,QAAQ,IAAI,GAAW,QAO9B,WAAW,EAAyB,CAClC,AAAK,KAAK,QAAQ,YAAY,IAC5B,KAAK,QAAQ,IAAI,EAAW,GAAI,GAAK,MAAM,IAE7C,KAAK,QAAQ,IAAI,GAAW,UAAU,IAOxC,aAAa,EAAyB,CACpC,AAAK,KAAK,QAAQ,YAAY,IAC5B,KAAK,QAAQ,IAAI,EAAW,GAAI,GAAK,MAAM,IAE7C,KAAK,QAAQ,IAAI,GAAW,UAAU,IAOxC,YAAY,EAAyB,CACnC,AAAI,KAAK,QAAQ,YAAY,IAC3B,KAAK,QAAQ,OAAO,GAaxB,6BAA6B,EAA0B,CACrD,MAAK,MAAK,QAAQ,YAAY,GAGvB,KAAK,QAAQ,IAAI,GAAW,UAAY,IAFtC,EAcX,kCAAkC,EAA0B,CAC1D,MAAK,MAAK,QAAQ,YAAY,GAGvB,KAAK,QAAQ,IAAI,GAAW,UAAY,IAFtC,OAAO,IAYlB,oBACE,EACA,EACS,CACT,GAAI,GAA2B,EAA2B,WACtD,EAA2B,EAA2B,WAC1D,EAAW,OAAS,EACpB,EAAW,OAAS,EAKpB,KAAM,GAAW,KAAK,cACtB,GAAI,GAAoB,KAGxB,SAAW,KAAe,GAAS,CACjC,GAAI,EAAY,KAAO,KAAK,GAC1B,SAEF,GAAI,GAAqB,EAAY,cACjC,EAAwC,EAC5C,AAAI,EAAmB,OAAS,GAGzB,IACH,GAAO,KAAK,WAEd,EAAgB,EAAY,kBAC1B,EAAK,IAAI,GACT,EAAK,IAAI,GACT,EAAK,IAAI,GACT,EAAK,IAAI,KAGb,SAAW,KAAU,GACnB,SAAW,KAAe,GAAe,CACvC,KAAM,GAAS,EAAK,QAAQ,cAC1B,EACA,EACA,GAEF,AAAI,EAAO,WACT,GAAW,KAAK,EAAO,UAAU,IACjC,EAAW,KAAK,EAAO,UAAU,MAKzC,MAAO,GAA+B,KAAM,EAAY,GAS1D,wBACE,EACA,EACS,CACT,GAAI,GAA2B,EAA2B,WACtD,EAA2B,EAA2B,WAC1D,EAAW,OAAS,EACpB,EAAW,OAAS,EAKpB,KAAM,GAAW,KAAK,cACtB,GAAI,GAAoB,KAExB,SAAW,KAAQ,GAAa,MAC9B,GAAI,EAAa,MAAM,eAAe,GAAO,CAC3C,KAAM,GAAe,EAAa,MAAM,GAGxC,SAAW,KAAe,GAAc,CACtC,GAAI,EAAY,KAAO,KAAK,GAC1B,SAEF,GAAI,GAAqB,EAAY,cACjC,EAAwC,EAC5C,AAAI,EAAmB,OAAS,GAGzB,IACH,GAAO,KAAK,WAEd,EAAgB,EAAY,kBAC1B,EAAK,IAAI,GACT,EAAK,IAAI,GACT,EAAK,IAAI,GACT,EAAK,IAAI,KAGb,SAAW,KAAU,GACnB,SAAW,KAAe,GAAe,CACvC,KAAM,GAAS,EAAK,QAAQ,cAC1B,EACA,EACA,GAEF,AAAI,EAAO,WACT,GAAW,KAAK,EAAO,UAAU,IACjC,EAAW,KAAK,EAAO,UAAU,OAO7C,MAAO,GAA+B,KAAM,EAAY,GAO1D,oBAAoB,EAAwC,CAC1D,MAAO,MAAK,KAAK,KAAK,sBAAsB,IAO9C,sBAAsB,EAAwC,CAC5D,GAAI,IAAgB,KAClB,MAAO,GAET,KAAM,GACJ,KAAK,eACL,KAAK,aACJ,GAAY,eAAiB,EAAY,cACtC,EACJ,KAAK,eACL,KAAK,aACJ,GAAY,eAAiB,EAAY,cAC5C,MAAO,GAAI,EAAI,EAAI,EAQrB,sBAAsB,EAAgB,EAAuB,CAC3D,MAAO,MAAK,KAAK,KAAK,wBAAwB,EAAS,IAQzD,wBAAwB,EAAgB,EAAuB,CAC7D,KAAM,GAAI,KAAK,eAAiB,KAAK,aAAe,EAC9C,EAAI,KAAK,eAAiB,KAAK,aAAe,EACpD,MAAO,GAAI,EAAI,EAAI,EAOrB,iBAAiB,EAAwC,CACvD,GAAI,IAAgB,KAClB,MAAO,GAET,KAAM,GACJ,KAAK,eACL,KAAK,aACJ,GAAY,eAAiB,EAAY,cACtC,EACJ,KAAK,eACL,KAAK,aACJ,GAAY,eAAiB,EAAY,cAC5C,MAAO,GAAK,UAAU,KAAK,MAAM,CAAC,EAAG,CAAC,IASxC,yBAAyB,EAAc,EAAwB,CAC7D,MACE,MAAK,eACL,KAAK,aACL,EAAW,KAAK,IAAI,EAAK,MAAM,IAUnC,yBAAyB,EAAc,EAAwB,CAC7D,MACE,MAAK,eACL,KAAK,aACL,EAAW,KAAK,IAAI,EAAK,MAAM,IASnC,mBAAmB,EAAgB,EAAuB,CACxD,KAAM,GAAI,KAAK,eAAiB,KAAK,aAAe,EAC9C,EAAI,KAAK,eAAiB,KAAK,aAAe,EACpD,MAAO,GAAK,UAAU,KAAK,MAAM,CAAC,EAAG,CAAC,IAYxC,UACE,EACA,EACA,EACA,EACM,CACN,KAAM,GAAiB,EAAK,MAAM,GAElC,KAAK,kBAAkB,EAAI,KAAK,IAAI,GAAkB,GACtD,KAAK,kBAAkB,EAAI,KAAK,IAAI,GAAkB,GAWxD,gBACE,EACA,EACA,EACM,CACN,AAAI,CAAC,GAEL,KAAK,UACH,EAAI,eAAiB,EAAI,aACzB,EAAI,eAAiB,EAAI,aACzB,EACA,GAQJ,6BAA6B,EAAkC,CAE7D,KAAM,GAAU,EAAK,YACnB,EAAc,UAAU,8BAE1B,EAAQ,OAAS,EACjB,KAAM,GAAQ,EAAK,aACjB,EAAc,UAAU,8BAE1B,EAAa,OAAO,GACpB,OAAS,GAAI,EAAG,EAAM,EAAM,OAAQ,EAAI,EAAK,EAAE,EAC7C,EAAQ,KAAK,MAAM,EAAS,EAAM,IAEpC,OAAS,GAAI,EAAG,EAAM,EAAQ,OAAQ,EAAI,EAAK,EAAE,EAC/C,AAAI,EAAQ,GAAG,IAAM,KAAK,IACxB,CAAI,KAAK,eAAiB,EAAQ,GAAG,eACnC,KAAK,KAAK,EAAQ,GAAG,eAAiB,KAAK,YAGzC,KAAK,eAAiB,KAAK,WAC3B,EAAQ,GAAG,eAAiB,EAAQ,GAAG,YAEvC,KAAK,KAAK,EAAQ,GAAG,eAAiB,EAAQ,GAAG,YAGrD,AAAI,KAAK,eAAiB,EAAQ,GAAG,eACnC,KAAK,KAAK,EAAQ,GAAG,eAAiB,KAAK,aAGzC,KAAK,eAAiB,KAAK,YAC3B,EAAQ,GAAG,eAAiB,EAAQ,GAAG,aAEvC,KAAK,KAAK,EAAQ,GAAG,eAAiB,EAAQ,GAAG,cAW3D,0BAA0B,EAAkC,CAE1D,KAAM,GAAU,EAAK,YACnB,EAAc,UAAU,2BAE1B,EAAQ,OAAS,EACjB,KAAM,GAAQ,EAAK,aACjB,EAAc,UAAU,2BAE1B,EAAa,OAAO,GACpB,OAAS,GAAI,EAAG,EAAM,EAAM,OAAQ,EAAI,EAAK,EAAE,EAC7C,EAAQ,KAAK,MAAM,EAAS,EAAM,IAEpC,OAAS,GAAI,EAAG,EAAM,EAAQ,OAAQ,EAAI,EAAK,EAAE,EAC/C,GAAI,EAAQ,GAAG,IAAM,KAAK,GAAI,CAC5B,GACE,KAAK,eAAiB,KAAK,aAC3B,EAAQ,GAAG,eAAiB,EAAQ,GAAG,aACvC,CACA,GAAI,GAAK,KAAK,cAAgB,EAAI,KAAK,kBAAkB,OACzD,KAAK,SAAS,CAAC,EAAK,GAAI,EAAG,OACtB,CACL,GAAI,GAAK,KAAK,cAAgB,EAAI,KAAK,kBAAkB,OACzD,KAAK,SAAS,CAAC,EAAK,GAAI,EAAG,GAE7B,GACE,KAAK,eAAiB,KAAK,aAC3B,EAAQ,GAAG,eAAiB,EAAQ,GAAG,aACvC,CACA,GAAI,GAAK,KAAK,cAAgB,EAAI,KAAK,kBAAkB,OACzD,KAAK,SAAS,EAAG,CAAC,EAAK,GAAI,OACtB,CACL,GAAI,GAAK,KAAK,cAAgB,EAAI,KAAK,kBAAkB,OACzD,KAAK,SAAS,EAAG,CAAC,EAAK,GAAI,WAe5B,eACL,EACA,EACA,EACA,EAA6C,KACpC,CAET,KAAM,GAAY,EAAK,aACjB,EAAY,EAAK,aACjB,EAAqB,KAAK,KAC9B,EACE,EAAK,WACL,EAAK,YACL,EACA,IAIE,EAAY,EAAK,aACjB,EAAY,EAAK,aACjB,EAAqB,KAAK,KAC9B,EACE,EAAK,WACL,EAAK,YACL,EACA,IAIE,EAAoB,EAAK,eAAiB,EAC1C,EAAoB,EAAK,eAAiB,EAC1C,EAAoB,EAAK,eAAiB,EAC1C,EAAoB,EAAK,eAAiB,EAE1C,EAAQ,EAAoB,EAC5B,EAAQ,EAAoB,EAClC,GACE,KAAK,KAAK,EAAQ,EAAQ,EAAQ,GAClC,EAAqB,EAErB,MAAO,GAIT,KAAM,GAAY,EAAK,kBACrB,EAAoB,EACpB,EAAoB,EACpB,EAAoB,EACpB,EAAoB,GAEhB,EAAY,EAAK,kBACrB,EAAoB,EACpB,EAAoB,EACpB,EAAoB,EACpB,EAAoB,GAGtB,SAAW,KAAW,GACpB,GAAI,IAAY,GAGhB,SAAW,KAAW,GACpB,GACE,EAAK,QAAQ,cAAc,EAAS,EAAS,GAC1C,UAEH,MAAO,GAIb,MAAO,GAWT,YACE,EACA,EACA,EACA,EACA,EACmB,CAEnB,KAAM,GAAa,KAAK,aAClB,EAAa,KAAK,aAClB,EAAsB,EAC1B,KAAK,WACL,KAAK,YACL,EACA,GAGI,EAAmB,GAAI,GAAQ,EAC/B,EAAmB,GAAI,GAAQ,EAC/B,EACH,GAAO,GAAM,GAAO,GAAM,GAAO,GAAM,GAAO,GAE3C,EAAQ,KAAK,eAAiB,EAAa,EAC3C,EAAQ,KAAK,eAAiB,EAAa,EAEjD,GAAI,GAAS,EAAmB,OAEhC,GADA,EAAO,UAAY,GAIjB,EAAQ,EAAQ,EAAQ,EACxB,EACE,EACA,EAAI,KAAK,KAAK,EAAsB,GAEtC,MAAO,GAIT,GAAI,EAAS,CACX,GAAI,GAAY,OAAO,UACvB,KAAM,GAAW,KAAK,kBAAkB,EAAG,EAAG,EAAM,GACpD,SAAW,KAAU,GAAU,CAC7B,KAAM,GAAM,EAAK,QAAQ,YAAY,EAAQ,EAAG,EAAG,EAAM,GACzD,AAAI,EAAI,WAAa,EAAI,YAAc,GACrC,GAAY,EAAI,YAChB,EAAK,QAAQ,sBAAsB,EAAK,SAGvC,CACL,GAAI,GAAY,CAAC,OAAO,UACxB,KAAM,GAAW,KAAK,kBAAkB,EAAG,EAAG,EAAM,GACpD,SAAW,KAAU,GAAU,CAC7B,KAAM,GAAM,EAAK,QAAQ,YAAY,EAAQ,EAAG,EAAG,EAAM,GACzD,AACE,EAAI,WACJ,EAAI,UAAY,GAChB,EAAI,WAAa,GAEjB,GAAY,EAAI,UAChB,EAAK,QAAQ,sBAAsB,EAAK,KAK9C,MAAO,GAWT,aAAa,EAAU,EAAmB,CACxC,MAAI,MAAK,eACP,MAAK,iBACL,KAAK,aACL,KAAK,cAAgB,IAGrB,KAAK,KAAK,IAAI,IAAM,GACpB,KAAK,KAAK,IAAI,IAAM,GACpB,KAAK,KAAK,IAAI,IAAM,GACpB,KAAK,KAAK,IAAI,IAAM,QAQjB,cACL,EACA,EACA,EACS,CACT,MAAO,GAAK,sBAAsB,IAAS,EAQ7C,eAAe,EAA2D,CACxE,KAAM,GAA2B,EAAK,YACpC,EAAc,UAAU,gBAE1B,EAAa,OAAS,EACtB,KAAM,GAAe,EAAkB,UAAU,kBAC3C,EAAQ,EAAkB,SAAS,KAAK,OACxC,EAAW,EAAM,cACrB,EAAa,aACb,EAAa,aACb,EACA,GAEF,GAAI,KAAK,aAAa,EAAS,GAAI,EAAS,IAC1C,MAAO,GAET,KAAM,GAAW,EAAa,yBAC9B,OAAS,GAAI,EAAG,EAAI,EAAS,OAAQ,EAAE,EAAG,CACxC,KAAM,GAAW,EAAM,cACrB,EAAa,UAAU,EAAS,IAChC,EAAa,UAAU,EAAS,IAChC,EACA,GAEF,GAAI,KAAK,aAAa,EAAS,GAAI,EAAS,IAC1C,MAAO,GAGX,MAAO,GAST,qBAAqB,EAAe,EAAwB,CAC1D,KAAM,GAAW,KAAK,kBAAkB,EAAQ,EAAQ,EAAQ,GAChE,SAAW,KAAU,GACnB,GAAI,EAAK,QAAQ,cAAc,EAAQ,EAAQ,GAC7C,MAAO,GAGX,MAAO,SAUF,mBAAkB,EAAuB,CAC9C,GAAI,EAAc,aAAa,YAAY,GACzC,MAAO,GAAc,aAAa,IAAI,GAExC,EAAc,OAAU,GAAc,QAAU,GAAK,EACrD,KAAM,GAAgB,EAAc,OACpC,SAAc,aAAa,IAAI,EAAM,GAC9B,IArkFJ,QA8NE,AA9NF,EA8NE,yBAA2B,GA8mB3B,AA50BF,EA40BE,mBAAqB,SAC1B,EACA,EACA,CACA,EAAS,WAAW,IAYf,AA51BF,EA41BE,mBAAqB,SAC1B,EACA,EACS,CACT,MAAO,GAAK,SAAS,OAAO,mBAAmB,EAAU,IAWpD,AA32BF,EA22BE,sBAAwB,SAAU,EAAyB,CAChE,EAAK,SAAS,OAAO,sBAAsB,IAmEtC,AA/6BF,EA+6BE,iBAAmB,SACxB,EACA,EACA,CACA,EAAM,iBAAiB,IAOlB,AA17BF,EA07BE,UAAY,SACjB,EACA,EACA,CACA,EAAM,UAAU,IAOX,AAr8BF,EAq8BE,iBAAmB,SAAU,EAAsB,EAAe,CACvE,EAAM,cAAc,IAMf,AA58BF,EA48BE,uBAAyB,SAAU,EAA8B,CACtE,MAAI,GAAM,qBAAuB,EACxB,GAEF,EAAM,sBAAsB,GAAG,eAMjC,AAt9BF,EAs9BE,uBAAyB,SAAU,EAA8B,CACtE,MAAI,GAAM,qBAAuB,EACxB,EAEF,EAAM,sBAAsB,GAAG,eAMjC,AAh+BF,EAg+BE,sBAAwB,SAAU,EAA8B,CACrE,KAAM,GAAW,EAAM,sBACvB,MAAO,GAAS,SAAW,EACvB,GACA,EAAS,EAAS,OAAS,GAAG,eAM7B,AA1+BF,EA0+BE,sBAAwB,SAAU,EAA8B,CACrE,KAAM,GAAW,EAAM,sBACvB,MAAO,GAAS,SAAW,EACvB,EACA,EAAS,EAAS,OAAS,GAAG,eA8lD7B,AA5kFF,EA4kFE,aAAe,GAAI,WAMnB,AAllFF,EAklFE,OAAS,EAMT,AAxlFF,EAwlFE,cAAmC,GAxlFrC,EAAM,gBAsnFb,EAAK,eAAe,GAAI,EAAK,iBA5wFrB",
4
+ "sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n /** An axis-aligned bounding box. Used to represents a box around an object for example. */\n export type AABB = {\n /** The [x,y] coordinates of the top left point */\n min: FloatPoint;\n /** The [x,y] coordinates of the bottom right point */\n max: FloatPoint;\n };\n\n export type RendererObjectInterface = {\n visible: boolean;\n };\n\n /**\n * Return the squared bounding radius of an object given its width/height and its center of rotation\n * (relative to the top-left of the object). The radius is relative to the center of rotation.\n */\n const computeSqBoundingRadius = (\n width: float,\n height: float,\n centerX: float,\n centerY: float\n ) => {\n const radiusX = Math.max(centerX, width - centerX);\n const radiusY = Math.max(centerY, height - centerY);\n return Math.pow(radiusX, 2) + Math.pow(radiusY, 2);\n };\n\n /**\n * Arrays and data structure that are (re)used by\n * {@link RuntimeObject.separateFromObjects} to avoid any allocation.\n */\n const separateFromObjectsStatics: {\n moveXArray: Array<float>;\n moveYArray: Array<float>;\n } = {\n moveXArray: [],\n moveYArray: [],\n };\n\n /**\n * Data structure that are (re)used by\n * {@link RuntimeObject.raycastTest} to avoid any allocation.\n */\n const raycastTestStatics: {\n result: RaycastTestResult;\n } = {\n result: gdjs.Polygon.makeNewRaycastTestResult(),\n };\n\n /**\n * Move the object using the results from collisionTest call.\n * This moves the object according to the direction of the longest vector,\n * and projects the others on the orthogonal vector.\n *\n * See {@link RuntimeObject.separateFromObjects}\n *\n * @param object The object to move.\n * @param moveXArray The X coordinates of the vectors to move the object.\n * @param moveYArray The Y coordinates of the vectors to move the object.\n * @return true if the object was moved.\n */\n const moveFollowingSeparatingVectors = (\n object: gdjs.RuntimeObject,\n moveXArray: Array<float>,\n moveYArray: Array<float>\n ): boolean => {\n if (moveXArray.length === 0) {\n moveXArray.length = 0;\n moveYArray.length = 0;\n return false;\n }\n if (moveXArray.length === 1) {\n // Move according to the results returned by the collision algorithm.\n object.setPosition(\n object.getX() + moveXArray[0],\n object.getY() + moveYArray[0]\n );\n moveXArray.length = 0;\n moveYArray.length = 0;\n return true;\n }\n\n // Find the longest vector\n let squaredDistanceMax = 0;\n let distanceMaxIndex = 0;\n for (let index = 0; index < moveXArray.length; index++) {\n const moveX = moveXArray[index];\n const moveY = moveYArray[index];\n\n const squaredDistance = moveX * moveX + moveY * moveY;\n if (squaredDistance > squaredDistanceMax) {\n squaredDistanceMax = squaredDistance;\n distanceMaxIndex = index;\n }\n }\n\n const distanceMax = Math.sqrt(squaredDistanceMax);\n // unit vector of the longest vector\n const uX = moveXArray[distanceMaxIndex] / distanceMax;\n const uY = moveYArray[distanceMaxIndex] / distanceMax;\n\n // normal vector of the longest vector\n const vX = -uY;\n const vY = uX;\n\n // Project other vectors on the normal\n let scalarProductMin = 0;\n let scalarProductMax = 0;\n for (let index = 0; index < moveXArray.length; index++) {\n const moveX = moveXArray[index];\n const moveY = moveYArray[index];\n\n const scalarProduct = moveX * vX + moveY * vY;\n scalarProductMin = Math.min(scalarProductMin, scalarProduct);\n scalarProductMax = Math.max(scalarProductMax, scalarProduct);\n }\n\n // Apply the longest vector\n let deltaX = moveXArray[distanceMaxIndex];\n let deltaY = moveYArray[distanceMaxIndex];\n\n // Apply the longest projected vector if they all are in the same direction\n // Some projections could have rounding errors,\n // they are considered negligible under a 1 for 1,000,000 ratio.\n const scalarProductMinIsNegligible =\n -scalarProductMin < scalarProductMax / 1048576;\n const scalarProductMaxIsNegligible =\n scalarProductMax < -scalarProductMin / 1048576;\n if (scalarProductMinIsNegligible !== scalarProductMaxIsNegligible) {\n if (scalarProductMaxIsNegligible) {\n deltaX += scalarProductMin * vX;\n deltaY += scalarProductMin * vY;\n } else {\n deltaX += scalarProductMax * vX;\n deltaY += scalarProductMax * vY;\n }\n }\n object.setPosition(object.getX() + deltaX, object.getY() + deltaY);\n moveXArray.length = 0;\n moveYArray.length = 0;\n return true;\n };\n\n /**\n * RuntimeObject represents an object being used on a RuntimeScene.\n *\n * A `gdjs.RuntimeObject` should not be instantiated directly, always a child class\n * (because gdjs.RuntimeObject don't call onCreated at the end of its constructor).\n */\n export class RuntimeObject implements EffectsTarget, gdjs.EffectHandler {\n name: string;\n type: string;\n x: float = 0;\n y: float = 0;\n angle: float = 0;\n zOrder: integer = 0;\n hidden: boolean = false;\n layer: string = '';\n protected _nameId: integer;\n protected _livingOnScene: boolean = true;\n\n readonly id: integer;\n private destroyCallbacks = new Set<() => void>();\n _runtimeScene: gdjs.RuntimeInstanceContainer;\n\n /**\n * An optional UUID associated to the object to be used\n * for hot reload. Don't modify or use otherwise.\n */\n persistentUuid: string | null = null;\n\n /**\n * A network ID associated to the object to be used\n * for multiplayer, to identify the object across peers.\n * We don't use persistentUuid as it's only used for hot-reload.\n * We don't use the object ID either as it's not unique across peers.\n */\n networkId: string | null = null;\n\n /**\n * A property to be used by external algorithms to indicate if the\n * object is picked or not in an object selection. By construction, this is\n * not \"thread safe\" or \"re-entrant algorithm\" safe.\n */\n pick: boolean = false;\n\n //Hit boxes:\n protected _defaultHitBoxes: gdjs.Polygon[] = [];\n protected hitBoxes: gdjs.Polygon[];\n protected hitBoxesDirty: boolean = true;\n protected aabb: AABB = { min: [0, 0], max: [0, 0] };\n protected _isIncludedInParentCollisionMask = true;\n\n //Variables:\n protected _variables: gdjs.VariablesContainer;\n\n //Effects:\n protected _rendererEffects: Record<string, gdjs.PixiFiltersTools.Filter> =\n {};\n\n //Forces:\n protected _instantForces: gdjs.Force[] = [];\n _permanentForceX: float = 0;\n _permanentForceY: float = 0;\n _totalForce: gdjs.Force;\n\n /**\n * Contains the behaviors of the object, except those not having lifecycle functions.\n *\n * This means default, hidden, \"capability\" behaviors are not included in this array.\n * This avoids wasting time iterating on them when we know their lifecycle functions\n * are never used.\n */\n protected _behaviors: gdjs.RuntimeBehavior[] = [];\n /**\n * Contains the behaviors of the object by name.\n *\n * This includes the default, hidden, \"capability\" behaviors (those to handle opacity,\n * effects, scale, size...).\n */\n protected _behaviorsTable: Hashtable<gdjs.RuntimeBehavior>;\n protected _timers: Hashtable<gdjs.Timer>;\n\n /**\n * @param instanceContainer The scene or custom object the object belongs to.\n * @param objectData The initial properties of the object.\n */\n constructor(\n instanceContainer: gdjs.RuntimeInstanceContainer,\n objectData: ObjectData & any\n ) {\n this.name = objectData.name || '';\n this.type = objectData.type || '';\n this._nameId = RuntimeObject.getNameIdentifier(this.name);\n this.id = instanceContainer.getScene().createNewUniqueId();\n this._runtimeScene = instanceContainer;\n this._defaultHitBoxes.push(gdjs.Polygon.createRectangle(0, 0));\n this.hitBoxes = this._defaultHitBoxes;\n this._variables = new gdjs.VariablesContainer(\n objectData ? objectData.variables : undefined\n );\n this._totalForce = new gdjs.Force(0, 0, 0);\n this._behaviorsTable = new Hashtable();\n for (let i = 0; i < objectData.effects.length; ++i) {\n this._runtimeScene\n .getGame()\n .getEffectsManager()\n .initializeEffect(objectData.effects[i], this._rendererEffects, this);\n this.updateAllEffectParameters(objectData.effects[i]);\n }\n //Also contains the behaviors: Used when a behavior is accessed by its name ( see getBehavior ).\n for (let i = 0, len = objectData.behaviors.length; i < len; ++i) {\n const autoData = objectData.behaviors[i];\n const Ctor = gdjs.getBehaviorConstructor(autoData.type);\n const behavior = new Ctor(instanceContainer, autoData, this);\n if (behavior.usesLifecycleFunction()) {\n this._behaviors.push(behavior);\n }\n this._behaviorsTable.put(autoData.name, behavior);\n }\n this._timers = new Hashtable();\n }\n\n //Common members functions related to the object and its runtimeScene :\n /**\n * To be called by the child classes in their constructor, at the very end.\n * Notify the behaviors that they have been constructed (this must be done when\n * the object is ready, otherwise behaviors can do operations on the object which\n * could be not initialized yet).\n *\n * If you redefine this function, **make sure to call the original method**\n * (`RuntimeObject.prototype.onCreated.call(this);`).\n */\n onCreated(): void {\n const rendererObject = this.getRendererObject();\n if (rendererObject) {\n for (const effectName in this._rendererEffects) {\n this._rendererEffects[effectName].applyEffect(this);\n }\n }\n\n for (let i = 0; i < this._behaviors.length; ++i) {\n this._behaviors[i].onCreated();\n }\n }\n\n /**\n * Called to reset the object to its default state. This is used for objects that are\n * \"recycled\": they are dismissed (at which point `onDeletedFromScene` is called) but still\n * stored in a cache to be reused next time an object must be created. At this point,\n * `reinitialize` will be called. The object must then work as if it was a newly constructed\n * object.\n *\n * To implement this in your object:\n * * Set `gdjs.YourRuntimeObject.supportsReinitialization = true;` to declare support for recycling.\n * * Implement `reinitialize`. It **must** call the `reinitialize` of `gdjs.RuntimeObject`, and call `this.onCreated();`\n * at the end of `reinitialize`.\n * * It must reset the object as if it was newly constructed (be careful about your renderers and any global state).\n * * The `_runtimeScene`, `_nameId`, `name` and `type` are guaranteed to stay the same and do not\n * need to be set again.\n *\n */\n reinitialize(objectData: ObjectData): void {\n const runtimeScene = this._runtimeScene;\n this.x = 0;\n this.y = 0;\n this.angle = 0;\n this.zOrder = 0;\n this.hidden = false;\n this.layer = '';\n this._livingOnScene = true;\n //@ts-ignore Reinitialize is like a constructor, it can overwrite the readonly property.\n this.id = runtimeScene\n //\n .getScene()\n .createNewUniqueId();\n this.persistentUuid = null;\n this.networkId = null;\n this.pick = false;\n this.hitBoxesDirty = true;\n this._defaultHitBoxes.length = 0;\n this._defaultHitBoxes.push(gdjs.Polygon.createRectangle(0, 0));\n this.aabb.min[0] = 0;\n this.aabb.min[1] = 0;\n this.aabb.max[0] = 0;\n this.aabb.max[1] = 0;\n this._variables = new gdjs.VariablesContainer(objectData.variables);\n this.clearForces();\n\n // Reinitialize behaviors.\n this._behaviorsTable.clear();\n const behaviorsDataCount = objectData.behaviors.length;\n let behaviorsUsingLifecycleFunctionCount = 0;\n for (\n let behaviorDataIndex = 0;\n behaviorDataIndex < behaviorsDataCount;\n ++behaviorDataIndex\n ) {\n const behaviorData = objectData.behaviors[behaviorDataIndex];\n const Ctor = gdjs.getBehaviorConstructor(behaviorData.type);\n // TODO: Add support for behavior recycling with a `reinitialize` method.\n const behavior = new Ctor(runtimeScene, behaviorData, this);\n if (behavior.usesLifecycleFunction()) {\n if (behaviorsUsingLifecycleFunctionCount < this._behaviors.length) {\n this._behaviors[behaviorsUsingLifecycleFunctionCount] = behavior;\n } else {\n this._behaviors.push(behavior);\n }\n behaviorsUsingLifecycleFunctionCount++;\n }\n this._behaviorsTable.put(behaviorData.name, behavior);\n }\n this._behaviors.length = behaviorsUsingLifecycleFunctionCount;\n\n // Reinitialize effects.\n for (let i = 0; i < objectData.effects.length; ++i) {\n this._runtimeScene\n .getGame()\n .getEffectsManager()\n .initializeEffect(objectData.effects[i], this._rendererEffects, this);\n this.updateAllEffectParameters(objectData.effects[i]);\n }\n\n // Make sure to delete existing timers.\n this._timers.clear();\n\n this.destroyCallbacks.clear();\n\n this.invalidateHitboxes();\n }\n\n static supportsReinitialization = false;\n\n /**\n * Return the time elapsed since the last frame,\n * in milliseconds, for the object.\n *\n * Objects can have different elapsed time if they are on layers with different time scales.\n */\n getElapsedTime(): float {\n const theLayer = this._runtimeScene.getLayer(this.layer);\n return theLayer.getElapsedTime();\n }\n\n /**\n * The gdjs.RuntimeScene the object belongs to.\n */\n getParent(): gdjs.RuntimeInstanceContainer {\n return this._runtimeScene;\n }\n\n /**\n * The gdjs.RuntimeScene the object belongs to.\n */\n getRuntimeScene(): gdjs.RuntimeScene {\n return this._runtimeScene.getScene();\n }\n\n /**\n * The container the object belongs to.\n */\n getInstanceContainer(): gdjs.RuntimeInstanceContainer {\n return this._runtimeScene;\n }\n\n /**\n * Called once during the game loop, before events and rendering.\n * @param instanceContainer The container the object belongs to.\n */\n update(instanceContainer: gdjs.RuntimeInstanceContainer): void {}\n\n /**\n * Called once during the game loop, after events and before rendering.\n * @param instanceContainer The container the object belongs to.\n */\n updatePreRender(instanceContainer: gdjs.RuntimeInstanceContainer): void {}\n\n /**\n * Called when the object is created from an initial instance at the startup of the scene.<br>\n * Note that common properties (position, angle, z order...) have already been setup.\n *\n * @param initialInstanceData The data of the initial instance.\n */\n extraInitializationFromInitialInstance(\n initialInstanceData: InstanceData\n ): void {}\n\n /**\n * Called when the object must be updated using the specified objectData. This is the\n * case during hot-reload, and is only called if the object was modified.\n *\n * @param oldObjectData The previous data for the object.\n * @param newObjectData The new data for the object.\n * @returns true if the object was updated, false if it could not (i.e: hot-reload is not supported).\n */\n updateFromObjectData(\n oldObjectData: ObjectData,\n newObjectData: ObjectData\n ): boolean {\n // If not redefined, mark by default the hot-reload as failed.\n return false;\n }\n\n /**\n * Called when trying to send all information about the state of an object to other peers.\n * This can be redefined by objects to send more information.\n * @returns The full network sync data.\n */\n getNetworkSyncData(): ObjectNetworkSyncData {\n const behaviorNetworkSyncData = {};\n this._behaviors.forEach((behavior) => {\n if (!behavior.isSyncedOverNetwork()) {\n return;\n }\n\n const networkSyncData = behavior.getNetworkSyncData();\n if (networkSyncData) {\n behaviorNetworkSyncData[behavior.getName()] = networkSyncData;\n }\n });\n\n const variablesNetworkSyncData = this._variables.getNetworkSyncData({\n // No need to send the player number, as the owner of the object syncs all its variables.\n });\n\n const effectsNetworkSyncData = {};\n for (const effectName in this._rendererEffects) {\n effectsNetworkSyncData[effectName] =\n this._rendererEffects[effectName].getNetworkSyncData();\n }\n\n const timersNetworkSyncData = {};\n for (const timerName in this._timers.items) {\n timersNetworkSyncData[timerName] =\n this._timers.items[timerName].getNetworkSyncData();\n }\n\n return {\n x: this.x,\n y: this.y,\n w: this.getWidth(),\n h: this.getHeight(),\n zo: this.zOrder,\n a: this.angle,\n hid: this.hidden,\n lay: this.layer,\n if: this._instantForces.map((force) => force.getNetworkSyncData()),\n pfx: this._permanentForceX,\n pfy: this._permanentForceY,\n beh: behaviorNetworkSyncData,\n var: variablesNetworkSyncData,\n eff: effectsNetworkSyncData,\n tim: timersNetworkSyncData,\n };\n }\n\n /**\n * Called when the object must be updated using the specified networkSyncData. This is the\n * case during an update of the object from the network.\n *\n * @param networkSyncData The new data for the object.\n * @returns true if the object was updated, false if it could not (i.e: network sync is not supported).\n */\n updateFromNetworkSyncData(networkSyncData: ObjectNetworkSyncData) {\n if (networkSyncData.x !== undefined) {\n this.setX(networkSyncData.x);\n }\n if (networkSyncData.y !== undefined) {\n this.setY(networkSyncData.y);\n }\n if (networkSyncData.w !== undefined) {\n this.setWidth(networkSyncData.w);\n }\n if (networkSyncData.h !== undefined) {\n this.setHeight(networkSyncData.h);\n }\n if (networkSyncData.zo !== undefined) {\n this.setZOrder(networkSyncData.zo);\n }\n if (networkSyncData.a !== undefined) {\n this.setAngle(networkSyncData.a);\n }\n if (\n networkSyncData.hid !== undefined &&\n this.hidden !== networkSyncData.hid\n ) {\n this.hide(networkSyncData.hid);\n }\n\n if (\n networkSyncData.lay !== undefined &&\n this.layer !== networkSyncData.lay\n ) {\n this.setLayer(networkSyncData.lay);\n }\n\n if (networkSyncData.if) {\n // Force clear all forces and reapply them, using the garbage collector to recycle forces.\n // Is that efficient?\n this.clearForces();\n for (let i = 0, len = networkSyncData.if.length; i < len; ++i) {\n const forceData = networkSyncData.if[i];\n const recycledOrNewForce = this._getRecycledForce(\n forceData.x,\n forceData.y,\n forceData.m\n );\n recycledOrNewForce.updateFromNetworkSyncData(forceData);\n this._instantForces.push(recycledOrNewForce);\n }\n }\n if (networkSyncData.pfx !== undefined) {\n this._permanentForceX = networkSyncData.pfx;\n }\n if (networkSyncData.pfy !== undefined) {\n this._permanentForceY = networkSyncData.pfy;\n }\n\n // Loop through all behaviors and update them.\n for (const behaviorName in networkSyncData.beh) {\n const behaviorNetworkSyncData = networkSyncData.beh[behaviorName];\n const behavior = this.getBehavior(behaviorName);\n if (behavior) {\n behavior.updateFromNetworkSyncData(behaviorNetworkSyncData);\n }\n }\n\n // If variables are synchronized, update them.\n if (networkSyncData.var) {\n this._variables.updateFromNetworkSyncData(networkSyncData.var);\n }\n\n // If effects are synchronized, update them.\n if (networkSyncData.eff) {\n // Loop through all effects and update them.\n for (const effectName in networkSyncData.eff) {\n const effectNetworkSyncData = networkSyncData.eff[effectName];\n const effect = this._rendererEffects[effectName];\n if (effect) {\n effect.updateFromNetworkSyncData(effectNetworkSyncData);\n }\n }\n }\n\n // If timers are synchronized, update them.\n // TODO: If a timer is removed, also remove it from the object?\n if (networkSyncData.tim) {\n for (const timerName in networkSyncData.tim) {\n const timerNetworkSyncData = networkSyncData.tim[timerName];\n const timer = this._timers.get(timerName);\n if (timer) {\n timer.updateFromNetworkSyncData(timerNetworkSyncData);\n }\n }\n }\n }\n\n /**\n * Remove an object from a scene.\n *\n * Do not change/redefine this method. Instead, redefine the onDeletedFromScene method.\n */\n deleteFromScene(): void {\n if (this._livingOnScene) {\n this._runtimeScene.markObjectForDeletion(this);\n this._livingOnScene = false;\n }\n }\n\n registerDestroyCallback(callback: () => void) {\n this.destroyCallbacks.add(callback);\n }\n\n unregisterDestroyCallback(callback: () => void) {\n this.destroyCallbacks.delete(callback);\n }\n\n /**\n * Called when the object is deleted (because it is removed from a scene or\n * the scene is being unloaded). The object is not actually destroyed and\n * can still be used by events.\n *\n * If you redefine this function, **make sure to call the original method**\n * (`super.onDeletedFromScene();`).\n */\n onDeletedFromScene(): void {\n const theLayer = this._runtimeScene.getLayer(this.layer);\n const rendererObject = this.getRendererObject();\n if (rendererObject) {\n theLayer.getRenderer().removeRendererObject(rendererObject);\n }\n const rendererObject3D = this.get3DRendererObject();\n if (rendererObject3D) {\n theLayer.getRenderer().remove3DRendererObject(rendererObject3D);\n }\n for (let j = 0, lenj = this._behaviors.length; j < lenj; ++j) {\n this._behaviors[j].onDestroy();\n }\n this.destroyCallbacks.forEach((c) => c());\n this.clearEffects();\n }\n\n /**\n * Called on deleted objects after all events has been executed for the\n * current frame and the object can be safely destroyed.\n */\n onDestroyed(): void {}\n\n /**\n * Called whenever the scene owning the object is paused.\n * This should *not* impact objects, but some may need to inform their renderer.\n *\n * @param runtimeScene The scene owning the object.\n */\n onScenePaused(runtimeScene: gdjs.RuntimeScene): void {}\n\n /**\n * Called whenever the scene owning the object is resumed after a pause.\n * This should *not* impact objects, but some may need to inform their renderer.\n *\n * @param runtimeScene The scene owning the object.\n */\n onSceneResumed(runtimeScene: gdjs.RuntimeScene): void {}\n\n //Rendering:\n /**\n * @return The internal object for a 2D rendering (PIXI.DisplayObject...)\n */\n getRendererObject(): RendererObjectInterface | null | undefined {\n return undefined;\n }\n\n /**\n * @return The internal object for a 3D rendering (PIXI.DisplayObject...)\n */\n get3DRendererObject(): THREE.Object3D | null | undefined {\n return undefined;\n }\n\n //Common properties:\n /**\n * Get the name of the object.\n * @return The object's name.\n */\n getName(): string {\n return this.name;\n }\n\n /**\n * Get the name identifier of the object.\n * @return The object's name identifier.\n */\n getNameId(): integer {\n return this._nameId;\n }\n\n /**\n * Get the unique identifier of the object.<br>\n * The identifier is set by the runtimeScene owning the object.<br>\n * You can also use the id property (this._object.id) for increased efficiency instead of\n * calling this method.\n *\n * @return The object identifier\n */\n getUniqueId(): integer {\n return this.id;\n }\n\n /**\n * Set the position of the object.\n *\n * @param x The new X position\n * @param y The new Y position\n */\n setPosition(x: float, y: float): void {\n this.setX(x);\n this.setY(y);\n }\n\n /**\n * Set the X position of the object.\n *\n * @param x The new X position\n */\n setX(x: float): void {\n if (x === this.x) {\n return;\n }\n this.x = x;\n this.invalidateHitboxes();\n }\n\n /**\n * Send a signal that the object hitboxes are no longer up to date.\n *\n * The signal is propagated to parents so\n * {@link gdjs.RuntimeObject.hitBoxesDirty} should never be modified\n * directly.\n */\n invalidateHitboxes(): void {\n // TODO EBO Check that no community extension set hitBoxesDirty to true\n // directly.\n this.hitBoxesDirty = true;\n this._runtimeScene.onChildrenLocationChanged();\n }\n\n /**\n * Get the X position of the object.\n *\n * @return The X position of the object\n */\n getX(): float {\n return this.x;\n }\n\n /**\n * Set the Y position of the object.\n *\n * @param y The new Y position\n */\n setY(y: float): void {\n if (y === this.y) {\n return;\n }\n this.y = y;\n this.invalidateHitboxes();\n }\n\n /**\n * Get the Y position of the object.\n *\n * @return The Y position of the object\n */\n getY(): float {\n return this.y;\n }\n\n /**\n * Get the X position of the rendered object.\n *\n * For most objects, this will returns the same value as getX(). But if the object\n * has an origin that is not the same as the point (0,0) of the object displayed,\n * getDrawableX will differ.\n *\n * @return The X position of the rendered object.\n */\n getDrawableX(): float {\n return this.getX();\n }\n\n /**\n * Get the Y position of the rendered object.\n *\n * For most objects, this will returns the same value as getY(). But if the object\n * has an origin that is not the same as the point (0,0) of the object displayed,\n * getDrawableY will differ.\n *\n * @return The Y position of the rendered object.\n */\n getDrawableY(): float {\n return this.getY();\n }\n\n rotateTowardPosition(x: float, y: float, speed: float): void {\n this.rotateTowardAngle(\n gdjs.toDegrees(\n Math.atan2(\n y - (this.getDrawableY() + this.getCenterY()),\n x - (this.getDrawableX() + this.getCenterX())\n )\n ),\n speed\n );\n }\n\n /**\n * @param angle The targeted direction angle.\n * @param speed The rotation speed.\n */\n rotateTowardAngle(angle: float, speed: float): void {\n if (speed === 0) {\n this.setAngle(angle);\n return;\n }\n const angularDiff = gdjs.evtTools.common.angleDifference(\n this.getAngle(),\n angle\n );\n const diffWasPositive = angularDiff >= 0;\n let newAngle =\n this.getAngle() +\n ((diffWasPositive ? -1.0 : 1.0) * speed * this.getElapsedTime()) / 1000;\n\n if (\n // @ts-ignore\n (gdjs.evtTools.common.angleDifference(newAngle, angle) > 0) ^\n diffWasPositive\n ) {\n newAngle = angle;\n }\n this.setAngle(newAngle);\n if (\n //Objects like sprite in 8 directions does not handle small increments...\n this.getAngle() !== newAngle\n ) {\n this.setAngle(\n //...so force them to be in the path angle anyway.\n angle\n );\n }\n }\n\n /**\n * Rotate the object at the given speed\n *\n * @param speed The speed, in degrees per second.\n * @param instanceContainer The container the object belongs to (deprecated - can be omitted).\n */\n rotate(speed: float): void {\n this.setAngle(this.getAngle() + (speed * this.getElapsedTime()) / 1000);\n }\n\n /**\n * Set the angle of the object.\n *\n * @param angle The new angle of the object\n */\n setAngle(angle: float): void {\n if (this.angle === angle) {\n return;\n }\n this.angle = angle;\n this.invalidateHitboxes();\n }\n\n /**\n * Get the rotation of the object.\n *\n * @return The rotation of the object, in degrees.\n */\n getAngle(): float {\n return this.angle;\n }\n\n /**\n * Set the layer of the object.\n *\n * @param layer The new layer of the object\n */\n setLayer(layer: string): void {\n if (layer === this.layer) {\n return;\n }\n const oldLayer = this._runtimeScene.getLayer(this.layer);\n this.layer = layer;\n const newLayer = this._runtimeScene.getLayer(this.layer);\n const rendererObject = this.getRendererObject();\n if (rendererObject) {\n oldLayer.getRenderer().removeRendererObject(rendererObject);\n newLayer.getRenderer().addRendererObject(rendererObject, this.zOrder);\n }\n const rendererObject3D = this.get3DRendererObject();\n if (rendererObject3D) {\n oldLayer.getRenderer().remove3DRendererObject(rendererObject3D);\n newLayer.getRenderer().add3DRendererObject(rendererObject3D);\n }\n }\n\n /**\n * Get the layer of the object.\n *\n * @return The layer of the object\n */\n getLayer(): string {\n return this.layer;\n }\n\n /**\n * Return true if the object is on the specified layer\n *\n * @param layer The layer to be tested.\n * @return true if the object is on the specified layer\n */\n isOnLayer(layer: string): boolean {\n return this.layer === layer;\n }\n\n /**\n * Set the Z order of the object.\n *\n * @param z The new Z order position of the object\n */\n setZOrder(z: integer): void {\n if (z === this.zOrder) {\n return;\n }\n this.zOrder = z;\n const rendererObject = this.getRendererObject();\n if (rendererObject) {\n const theLayer = this._runtimeScene.getLayer(this.layer);\n theLayer.getRenderer().changeRendererObjectZOrder(rendererObject, z);\n }\n }\n\n /**\n * Get the Z order of the object.\n *\n * @return The Z order of the object\n */\n getZOrder(): float {\n return this.zOrder;\n }\n\n /**\n * Get the container of the object variables\n * @return The variables of the object\n */\n getVariables(): gdjs.VariablesContainer {\n return this._variables;\n }\n\n /**\n * Get the value of a variable considered as a number. Equivalent of variable.getAsNumber()\n * @param variable The variable to be accessed\n * @return The value of the specified variable\n * @static\n */\n static getVariableNumber(variable: gdjs.Variable): number {\n return variable.getAsNumber();\n }\n\n /**\n * Return the variable passed as argument without any change.\n * Only for usage by events.\n *\n * @param variable The variable to be accessed\n * @return The specified variable\n * @static\n */\n static returnVariable(variable: gdjs.Variable): gdjs.Variable {\n return variable;\n }\n\n /**\n * Get the value of a variable considered as a string. Equivalent of variable.getAsString()\n * @param variable The variable to be accessed\n * @return The string of the specified variable\n * @static\n */\n static getVariableString(variable: gdjs.Variable): string {\n return variable.getAsString();\n }\n\n /**\n * Shortcut to set the value of a variable considered as a boolean.\n * This shortcut function is needed for events code generation.\n *\n * @private\n * @param {gdjs.Variable} variable\n * @param {boolean} newValue\n */\n static setVariableBoolean = function (\n variable: gdjs.Variable,\n newValue: boolean\n ) {\n variable.setBoolean(newValue);\n };\n\n /**\n * Shortcut to compare the value of a variable considered as a boolean.\n * This shortcut function is needed for events code generation.\n *\n * @private\n * @param {gdjs.Variable} variable\n * @param {boolean} compareWith\n * @returns {boolean}\n */\n static getVariableBoolean = function (\n variable: gdjs.Variable,\n compareWith: boolean\n ): boolean {\n return gdjs.evtTools.common.getVariableBoolean(variable, compareWith);\n };\n\n /**\n * Toggles a variable.\n * This shortcut function is needed for events code generation.\n *\n * @private\n * @param {gdjs.Variable} variable\n * @see {gdjs.evtTools.common.toggleVariableBoolean}\n */\n static toggleVariableBoolean = function (variable: gdjs.Variable) {\n gdjs.evtTools.common.toggleVariableBoolean(variable);\n };\n\n /**\n * Get the number of children from a variable\n * @param variable The variable to be accessed\n * @return The number of children\n * @static\n */\n static getVariableChildCount(variable: gdjs.Variable): integer {\n return variable.getChildrenCount();\n }\n\n /**\n * Shortcut to set the value of a variable considered as a number\n * @param variable The variable to be changed\n * @param newValue The value to be set\n */\n static setVariableNumber(variable: gdjs.Variable, newValue: float): void {\n variable.setNumber(newValue);\n }\n\n /**\n * Shortcut to set the value of a variable considered as a string\n * @param variable The variable to be changed\n * @param newValue {String} The value to be set\n */\n static setVariableString(variable: gdjs.Variable, newValue: string) {\n variable.setString(newValue);\n }\n\n /**\n * @static\n * @param variable The variable to be tested\n * @param childName The name of the child\n */\n private static variableChildExists(\n variable: gdjs.Variable,\n childName: string\n ): boolean {\n return variable.hasChild(childName);\n }\n\n /**\n * @static\n * @param variable The variable to be changed\n * @param childName The name of the child\n */\n private static variableRemoveChild(\n variable: gdjs.Variable,\n childName: string\n ): void {\n variable.removeChild(childName);\n }\n\n /**\n * @static\n * @param variable The variable to be cleared\n */\n private static variableClearChildren(variable: gdjs.Variable): void {\n variable.clearChildren();\n }\n\n /**\n * This shortcut function is needed for events code generation.\n * @private\n */\n static variablePushCopy = function (\n array: gdjs.Variable,\n variable: gdjs.Variable\n ) {\n array.pushVariableCopy(variable);\n };\n\n /**\n * This shortcut function is needed for events code generation.\n * @private\n */\n static valuePush = function (\n array: gdjs.Variable,\n value: string | float | boolean\n ) {\n array.pushValue(value);\n };\n\n /**\n * This shortcut function is needed for events code generation.\n * @private\n */\n static variableRemoveAt = function (array: gdjs.Variable, index: number) {\n array.removeAtIndex(index);\n };\n\n /**\n * Shortcut to get the first value of an array variable as a string.\n */\n static getFirstVariableString = function (array: gdjs.Variable): string {\n if (array.getChildrenCount() === 0) {\n return '';\n }\n return array.getAllChildrenArray()[0].getAsString();\n };\n\n /**\n * Shortcut to get the first value of an array variable as a number.\n */\n static getFirstVariableNumber = function (array: gdjs.Variable): number {\n if (array.getChildrenCount() === 0) {\n return 0;\n }\n return array.getAllChildrenArray()[0].getAsNumber();\n };\n\n /**\n * Shortcut to get the last value of an array variable as a string.\n */\n static getLastVariableString = function (array: gdjs.Variable): string {\n const children = array.getAllChildrenArray();\n return children.length === 0\n ? ''\n : children[children.length - 1].getAsString();\n };\n\n /**\n * Shortcut to get the last value of an array variable as a number.\n */\n static getLastVariableNumber = function (array: gdjs.Variable): number {\n const children = array.getAllChildrenArray();\n return children.length === 0\n ? 0\n : children[children.length - 1].getAsNumber();\n };\n\n /**\n * Shortcut to test if a variable exists for the object.\n * @param name The variable to be tested\n * @return true if the variable exists.\n */\n hasVariable(name: string): boolean {\n return this._variables.has(name);\n }\n\n /**\n * Returns the collection of effects to be rendered by the\n * underlying renderer.\n * @returns The renderer effects.\n */\n getRendererEffects() {\n return this._rendererEffects;\n }\n\n /**\n * Add a new effect, or replace the one with the same name.\n * @param effectData The data describing the effect to add.\n */\n addEffect(effectData: EffectData): boolean {\n const rendererObject = this.getRendererObject();\n if (!rendererObject) {\n return false;\n }\n\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .addEffect(effectData, this._rendererEffects, this);\n }\n\n /**\n * Remove the effect with the specified name\n * @param effectName The name of the effect.\n */\n removeEffect(effectName: string): boolean {\n const rendererObject = this.getRendererObject();\n if (!rendererObject) return false;\n\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .removeEffect(this._rendererEffects, this, effectName);\n }\n\n /**\n * Remove all effects.\n */\n clearEffects(): boolean {\n const rendererObject = this.getRendererObject();\n if (!rendererObject) return false;\n\n this._rendererEffects = {};\n return (\n this._runtimeScene\n .getGame()\n .getEffectsManager()\n // @ts-expect-error - the effects manager is typed with the PIXI object.\n .clearEffects(rendererObject)\n );\n }\n\n /**\n * Change an effect property value (for properties that are numbers).\n * @param name The name of the effect to update.\n * @param parameterName The name of the property to update.\n * @param value The new value (number).\n */\n setEffectDoubleParameter(\n name: string,\n parameterName: string,\n value: float\n ): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .setEffectDoubleParameter(\n this._rendererEffects,\n name,\n parameterName,\n value\n );\n }\n\n /**\n * Change an effect property value (for properties that are strings).\n * @param name The name of the effect to update.\n * @param parameterName The name of the property to update.\n * @param value The new value (string).\n */\n setEffectStringParameter(\n name: string,\n parameterName: string,\n value: string\n ): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .setEffectStringParameter(\n this._rendererEffects,\n name,\n parameterName,\n value\n );\n }\n\n /**\n * Change an effect property value (for properties that are booleans).\n * @param name The name of the effect to update.\n * @param parameterName The name of the property to update.\n * @param value The new value (boolean).\n */\n setEffectBooleanParameter(\n name: string,\n parameterName: string,\n value: boolean\n ): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .setEffectBooleanParameter(\n this._rendererEffects,\n name,\n parameterName,\n value\n );\n }\n\n /**\n * Updates all the parameters of an effect.\n * @param effectData The data describing the effect\n */\n updateAllEffectParameters(effectData: EffectData): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .updateAllEffectParameters(this._rendererEffects, effectData);\n }\n\n /**\n * Enable or disable an effect.\n * @param name The name of the effect to enable or disable.\n * @param enable true to enable, false to disable\n */\n enableEffect(name: string, enable: boolean): void {\n this._runtimeScene\n .getGame()\n .getEffectsManager()\n .enableEffect(this._rendererEffects, this, name, enable);\n }\n\n /**\n * Check if an effect is enabled\n * @param name The name of the effect\n * @return true if the effect is enabled, false otherwise.\n */\n isEffectEnabled(name: string): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .isEffectEnabled(this._rendererEffects, this, name);\n }\n\n /**\n * Check if an effect exists on this object\n * @param name The name of the effect\n * @return true if the effect exists, false otherwise.\n */\n hasEffect(name: string): boolean {\n return this._runtimeScene\n .getGame()\n .getEffectsManager()\n .hasEffect(this._rendererEffects, name);\n }\n\n /**\n * Hide (or show) the object.\n * @param enable Set it to true to hide the object, false to show it.\n */\n hide(enable: boolean): void {\n if (enable === undefined) {\n enable = true;\n }\n this.hidden = enable;\n }\n\n /**\n * Return true if the object is not hidden.\n *\n * Note: This is unrelated to the actual visibility of the object on the screen.\n * For this, see `getVisibilityAABB` to get the bounding boxes of the object as displayed\n * on the scene.\n *\n * @return true if the object is not hidden.\n */\n isVisible(): boolean {\n return !this.hidden;\n }\n\n /**\n * Return true if the object is hidden.\n * @return true if the object is hidden.\n */\n isHidden(): boolean {\n return this.hidden;\n }\n\n /**\n * Set the width of the object, if applicable.\n * @param width The new width in pixels.\n */\n setWidth(width: float): void {}\n\n /**\n * Set the height of the object, if applicable.\n * @param height The new height in pixels.\n */\n setHeight(height: float): void {}\n\n /**\n * Return the width of the object.\n * @return The width of the object\n */\n getWidth(): float {\n return 0;\n }\n\n /**\n * Return the height of the object.\n * @return The height of the object\n */\n getHeight(): float {\n return 0;\n }\n\n /**\n * Return the X position of the object center, **relative to the object X position** (`getDrawableX`).\n * Use `getCenterXInScene` to get the position of the center in the scene.\n *\n * @return the X position of the object center, relative to `getDrawableX()`.\n */\n getCenterX(): float {\n return this.getWidth() / 2;\n }\n\n /**\n * Return the Y position of the object center, **relative to the object position** (`getDrawableY`).\n * Use `getCenterYInScene` to get the position of the center in the scene.\n *\n * @return the Y position of the object center, relative to `getDrawableY()`.\n */\n getCenterY(): float {\n return this.getHeight() / 2;\n }\n\n /**\n * Return the X position of the object center, **relative to the scene origin**.\n * @returns the X position of the object center, **relative to the scene origin**.\n */\n getCenterXInScene(): float {\n return this.getDrawableX() + this.getCenterX();\n }\n\n /**\n * Return the Y position of the object center, **relative to the scene origin**.\n * @returns the Y position of the object center, **relative to the scene origin**.\n */\n getCenterYInScene(): float {\n return this.getDrawableY() + this.getCenterY();\n }\n\n /**\n * Change the object center position in the scene.\n * @param x The new X position of the center in the scene.\n * @param y The new Y position of the center in the scene.\n */\n setCenterPositionInScene(x: float, y: float): void {\n this.setX(x + this.x - (this.getDrawableX() + this.getCenterX()));\n this.setY(y + this.y - (this.getDrawableY() + this.getCenterY()));\n }\n\n /**\n * Change the object center X position in the scene.\n * @param x The new X position of the center in the scene.\n */\n setCenterXInScene(x: float): void {\n this.setX(x + this.x - (this.getDrawableX() + this.getCenterX()));\n }\n\n /**\n * Change the object center Y position in the scene.\n * @param y The new Y position of the center in the scene.\n */\n setCenterYInScene(y: float): void {\n this.setY(y + this.y - (this.getDrawableY() + this.getCenterY()));\n }\n\n //Forces :\n /**\n * Get a force from the garbage, or create a new force is garbage is empty.<br>\n * To be used each time a force is created so as to avoid temporaries objects.\n *\n * @param x The x coordinates of the force\n * @param y The y coordinates of the force\n * @param multiplier Set the force multiplier\n */\n private _getRecycledForce(\n x: float,\n y: float,\n multiplier: integer\n ): gdjs.Force {\n if (RuntimeObject.forcesGarbage.length === 0) {\n return new gdjs.Force(x, y, multiplier);\n } else {\n const recycledForce = RuntimeObject.forcesGarbage.pop() as gdjs.Force;\n recycledForce.setX(x);\n recycledForce.setY(y);\n recycledForce.setMultiplier(multiplier);\n return recycledForce;\n }\n }\n\n /**\n * Add a force to the object to move it.\n * @param x The x coordinates of the force\n * @param y The y coordinates of the force\n * @param multiplier Set the force multiplier\n */\n addForce(x: float, y: float, multiplier: integer): void {\n if (multiplier === 1) {\n this._permanentForceX += x;\n this._permanentForceY += y;\n } else if (\n multiplier === 0 &&\n this._instantForces.length > 0 &&\n this._instantForces[0].getMultiplier() === 0\n ) {\n // Avoid to instantiate new a Force for each instance force.\n this._instantForces[0].add(x, y);\n } else {\n // Handle legacy forces with multiplier different from 0 and 1\n // (or the 1st instant force).\n this._instantForces.push(this._getRecycledForce(x, y, multiplier));\n }\n }\n\n /**\n * Add a force using polar coordinates.\n * @param angle The angle of the force, in degrees.\n * @param len The length of the force, in pixels.\n * @param multiplier Set the force multiplier\n */\n addPolarForce(angle: float, len: float, multiplier: integer): void {\n const angleInRadians = gdjs.toRad(angle);\n\n //TODO: Benchmark with Math.PI\n const forceX = Math.cos(angleInRadians) * len;\n const forceY = Math.sin(angleInRadians) * len;\n this.addForce(forceX, forceY, multiplier);\n }\n\n /**\n * Add a force oriented toward a position\n * @param x The target x position\n * @param y The target y position\n * @param len The force length, in pixels.\n * @param multiplier Set the force multiplier\n */\n addForceTowardPosition(\n x: float,\n y: float,\n len: float,\n multiplier: integer\n ): void {\n const angleInRadians = Math.atan2(\n y - (this.getDrawableY() + this.getCenterY()),\n x - (this.getDrawableX() + this.getCenterX())\n );\n const forceX = Math.cos(angleInRadians) * len;\n const forceY = Math.sin(angleInRadians) * len;\n this.addForce(forceX, forceY, multiplier);\n }\n\n /**\n * Add a force oriented toward another object.<br>\n * (Shortcut for addForceTowardPosition)\n * @param object The target object\n * @param len The force length, in pixels.\n * @param multiplier Set the force multiplier\n */\n addForceTowardObject(\n object: gdjs.RuntimeObject | null,\n len: float,\n multiplier: integer\n ): void {\n if (object == null) {\n return;\n }\n this.addForceTowardPosition(\n object.getDrawableX() + object.getCenterX(),\n object.getDrawableY() + object.getCenterY(),\n len,\n multiplier\n );\n }\n\n /**\n * Deletes all forces applied on the object\n */\n clearForces(): void {\n RuntimeObject.forcesGarbage.push.apply(\n RuntimeObject.forcesGarbage,\n this._instantForces\n );\n this._instantForces.length = 0;\n this._permanentForceX = 0;\n this._permanentForceY = 0;\n }\n\n /**\n * Return true if no forces are applied on the object.\n * @return true if no forces are applied on the object.\n */\n hasNoForces(): boolean {\n return (\n this._instantForces.length === 0 &&\n this._permanentForceX === 0 &&\n this._permanentForceY === 0\n );\n }\n\n /**\n * Called once a step by runtimeScene to update forces magnitudes and\n * remove null ones.\n */\n updateForces(elapsedTime: float): void {\n for (let i = 0; i < this._instantForces.length; ) {\n const force = this._instantForces[i];\n const multiplier = force.getMultiplier();\n if (multiplier === 1) {\n // Permanent force\n ++i;\n } else {\n if (\n multiplier === 0 ||\n // Instant or force disappearing\n force.getLength() <= 0.001\n ) {\n RuntimeObject.forcesGarbage.push(force);\n this._instantForces.splice(i, 1);\n } else {\n // Deprecated way of updating forces progressively.\n force.setLength(\n force.getLength() -\n force.getLength() * (1 - multiplier) * elapsedTime\n );\n ++i;\n }\n }\n }\n }\n\n /**\n * Return a force which is the sum of all forces applied on the object.\n *\n * @return A force object.\n */\n getAverageForce(): gdjs.Force {\n this._totalForce.clear();\n this._totalForce.add(this._permanentForceX, this._permanentForceY);\n for (let i = 0, len = this._instantForces.length; i < len; ++i) {\n this._totalForce.addForce(this._instantForces[i]);\n }\n return this._totalForce;\n }\n\n /**\n * Return true if the average angle of the forces applied on the object\n * is in a given range.\n * @deprecated Use isTotalForceAngleAround instead.\n *\n * @param angle The angle to be tested.\n * @param toleranceInDegrees The length of the range :\n * @return true if the difference between the average angle of the forces\n * and the angle parameter is inferior to toleranceInDegrees parameter.\n */\n averageForceAngleIs(angle: float, toleranceInDegrees: float): boolean {\n let averageAngle = this.getAverageForce().getAngle();\n if (averageAngle < 0) {\n averageAngle += 360;\n }\n return Math.abs(angle - averageAngle) < toleranceInDegrees / 2;\n }\n\n /**\n * Return true if the angle of the total force applied on the object\n * is in a given range.\n *\n * @param angle The angle to be tested.\n * @param toleranceInDegrees The maximum distance from the given angle.\n * @return true if the difference between the force angle the given `angle`\n * is less or equals the `toleranceInDegrees`.\n */\n isTotalForceAngleAround(angle: float, toleranceInDegrees: float): boolean {\n return (\n Math.abs(\n gdjs.evtTools.common.angleDifference(\n this.getAverageForce().getAngle(),\n angle\n )\n ) <= toleranceInDegrees\n );\n }\n\n //Hit boxes and collision :\n /**\n * Get all the hit boxes for the object.\n *\n * For collision checks, {@link getHitBoxesAround} should be used instead.\n *\n * The default implementation returns a basic bounding box based the size (getWidth and\n * getHeight) and the center point of the object (getCenterX and getCenterY).\n *\n * You should probably redefine {@link updateHitBoxes} instead of this function.\n *\n * @return An array composed of polygon.\n */\n getHitBoxes(): gdjs.Polygon[] {\n //Avoid a naive implementation requiring to recreate temporaries each time\n //the function is called:\n //(var rectangle = gdjs.Polygon.createRectangle(this.getWidth(), this.getHeight());\n //...)\n if (this.hitBoxesDirty) {\n this.updateHitBoxes();\n this.updateAABB();\n this.hitBoxesDirty = false;\n }\n return this.hitBoxes;\n }\n\n /**\n * Return at least all the hit boxes that overlap a given area.\n *\n * The hit boxes don't need to actually overlap the area,\n * (i.e: it's correct to return more hit boxes than those in the specified area)\n * but the ones that do must be returned.\n *\n * The default implementation returns the same as {@link getHitBoxes}.\n *\n * This method can be overridden by grid based objects (or other objects\n * that can quickly compute which hitboxes are touching a given area)\n * to optimize collision checks.\n *\n * When overriding this method, the following ones should be overridden too:\n * * {@link getHitBoxes}\n * * {@link getAABB}\n * * {@link updateHitBoxes}\n * * {@link updateAABB}\n *\n * @param left bound of the area in scene coordinates\n * @param top bound of the area in scene coordinates\n * @param right bound of the area in scene coordinates\n * @param bottom bound of the area in scene coordinates\n *\n * @return at least all the hit boxes that overlap a given area.\n */\n getHitBoxesAround(\n left: float,\n top: float,\n right: float,\n bottom: float\n ): Iterable<gdjs.Polygon> {\n return this.getHitBoxes();\n }\n\n /**\n * Update the hit boxes for the object.\n *\n * The default implementation set a basic bounding box based on the size (getWidth and\n * getHeight) and the center point of the object (getCenterX and getCenterY).\n * Result is cached until invalidated (by a position change, angle change...).\n *\n * You should not call this function by yourself, it is called when necessary by getHitBoxes method.\n * However, you can redefine it if your object need custom hit boxes.\n */\n updateHitBoxes(): void {\n this.hitBoxes = this._defaultHitBoxes;\n if (this.hitBoxes.length === 0) return;\n const width = this.getWidth();\n const height = this.getHeight();\n const centerX = this.getCenterX();\n const centerY = this.getCenterY();\n if (centerX === width / 2 && centerY === height / 2) {\n this.hitBoxes[0].vertices[0][0] = -centerX;\n this.hitBoxes[0].vertices[0][1] = -centerY;\n this.hitBoxes[0].vertices[1][0] = +centerX;\n this.hitBoxes[0].vertices[1][1] = -centerY;\n this.hitBoxes[0].vertices[2][0] = +centerX;\n this.hitBoxes[0].vertices[2][1] = +centerY;\n this.hitBoxes[0].vertices[3][0] = -centerX;\n this.hitBoxes[0].vertices[3][1] = +centerY;\n } else {\n this.hitBoxes[0].vertices[0][0] = 0 - centerX;\n this.hitBoxes[0].vertices[0][1] = 0 - centerY;\n this.hitBoxes[0].vertices[1][0] = width - centerX;\n this.hitBoxes[0].vertices[1][1] = 0 - centerY;\n this.hitBoxes[0].vertices[2][0] = width - centerX;\n this.hitBoxes[0].vertices[2][1] = height - centerY;\n this.hitBoxes[0].vertices[3][0] = 0 - centerX;\n this.hitBoxes[0].vertices[3][1] = height - centerY;\n }\n this.hitBoxes[0].rotate(gdjs.toRad(this.getAngle()));\n this.hitBoxes[0].move(\n this.getDrawableX() + centerX,\n this.getDrawableY() + centerY\n );\n }\n\n isIncludedInParentCollisionMask(): boolean {\n return this._isIncludedInParentCollisionMask;\n }\n\n setIncludedInParentCollisionMask(isIncluded: boolean): void {\n const wasIncluded = this._isIncludedInParentCollisionMask;\n this._isIncludedInParentCollisionMask = isIncluded;\n if (wasIncluded !== isIncluded) {\n this._runtimeScene.onChildrenLocationChanged();\n }\n }\n\n /**\n * Get the AABB (axis aligned bounding box) for the object.\n *\n * The default implementation uses either the position/size of the object (when angle is 0) or\n * hitboxes (when angle is not 0) to compute the bounding box.\n * Result is cached until invalidated (by a position change, angle change...).\n *\n * You should probably redefine updateAABB instead of this function.\n *\n * @return The bounding box\n */\n getAABB(): AABB {\n if (this.hitBoxesDirty) {\n this.updateHitBoxes();\n this.updateAABB();\n this.hitBoxesDirty = false;\n }\n return this.aabb;\n }\n\n /**\n * Get the AABB (axis aligned bounding box) to be used to determine if the object\n * is visible on screen. The gdjs.RuntimeScene will hide the renderer object if\n * the object is not visible on screen (\"culling\").\n *\n * The default implementation uses the AABB returned by getAABB.\n *\n * If `null` is returned, the object is assumed to be always visible.\n *\n * @return The bounding box or `null`.\n */\n getVisibilityAABB(): AABB | null {\n return this.getAABB();\n }\n\n /**\n * Update the AABB (axis aligned bounding box) for the object.\n *\n * Default implementation uses either the position/size of the object (when angle is 0) or\n * hitboxes (when angle is not 0) to compute the bounding box.\n *\n * You should not call this function by yourself, it is called when necessary by getAABB method.\n * However, you can redefine it if your object can have a faster implementation.\n */\n updateAABB(): void {\n if (this.getAngle() === 0) {\n // Fast/simple computation of AABB for non rotated object\n // (works even for object with non default center/origin\n // because we're using getDrawableX/Y)\n this.aabb.min[0] = this.getDrawableX();\n this.aabb.min[1] = this.getDrawableY();\n this.aabb.max[0] = this.aabb.min[0] + this.getWidth();\n this.aabb.max[1] = this.aabb.min[1] + this.getHeight();\n } else {\n // Use hitboxes if object is rotated to ensure that the AABB\n // is properly bounding the whole object.\n // Slower (10-15% slower).\n let first = true;\n for (let i = 0; i < this.hitBoxes.length; i++) {\n for (let j = 0; j < this.hitBoxes[i].vertices.length; j++) {\n const vertex = this.hitBoxes[i].vertices[j];\n if (first) {\n this.aabb.min[0] = vertex[0];\n this.aabb.max[0] = vertex[0];\n this.aabb.min[1] = vertex[1];\n this.aabb.max[1] = vertex[1];\n first = false;\n } else {\n this.aabb.min[0] = Math.min(this.aabb.min[0], vertex[0]);\n this.aabb.max[0] = Math.max(this.aabb.max[0], vertex[0]);\n this.aabb.min[1] = Math.min(this.aabb.min[1], vertex[1]);\n this.aabb.max[1] = Math.max(this.aabb.max[1], vertex[1]);\n }\n }\n }\n }\n }\n\n /**\n * Shortcut for `getAABB().min[0]`.\n * See {@link getAABB}.\n */\n getAABBLeft(): float {\n return this.getAABB().min[0];\n }\n\n /**\n * Shortcut for `getAABB().min[1]`.\n * See {@link getAABB}.\n */\n getAABBTop(): float {\n return this.getAABB().min[1];\n }\n\n /**\n * Shortcut for `getAABB().max[0]`.\n * See {@link getAABB}.\n */\n getAABBRight(): float {\n return this.getAABB().max[0];\n }\n\n /**\n * Shortcut for `getAABB().max[1]`.\n * See {@link getAABB}.\n */\n getAABBBottom(): float {\n return this.getAABB().max[1];\n }\n\n /**\n * Shortcut for getting the center on the X coordinates of the object AABB.\n * See {@link getAABB}.\n */\n getAABBCenterX(): float {\n return this.getAABB().min[0] / 2 + this.getAABB().max[0] / 2;\n }\n\n /**\n * Shortcut for getting the center on the Y coordinates of the object AABB.\n * See {@link getAABB}.\n */\n getAABBCenterY(): float {\n return this.getAABB().min[1] / 2 + this.getAABB().max[1] / 2;\n }\n\n //Behaviors:\n /**\n * Call each behavior stepPreEvents method.\n */\n stepBehaviorsPreEvents(\n instanceContainer: gdjs.RuntimeInstanceContainer\n ): void {\n for (let i = 0, len = this._behaviors.length; i < len; ++i) {\n this._behaviors[i].stepPreEvents(instanceContainer);\n }\n }\n\n /**\n * Call each behavior stepPostEvents method.\n */\n stepBehaviorsPostEvents(\n instanceContainer: gdjs.RuntimeInstanceContainer\n ): void {\n for (let i = 0, len = this._behaviors.length; i < len; ++i) {\n this._behaviors[i].stepPostEvents(instanceContainer);\n }\n }\n\n /**\n * Called when the object was hot reloaded, to notify behaviors\n * that the object was modified. Useful for behaviors that\n */\n notifyBehaviorsObjectHotReloaded(): void {\n for (let i = 0, len = this._behaviors.length; i < len; ++i) {\n this._behaviors[i].onObjectHotReloaded();\n }\n }\n\n /**\n * Get a behavior from its name.\n * If the behavior does not exists, `undefined` is returned.\n *\n * **Never keep a reference** to a behavior, as they can be hot-reloaded. Instead,\n * always call getBehavior on the object.\n *\n * @param name {String} The behavior name.\n * @return The behavior with the given name, or undefined.\n */\n getBehavior(name: string): gdjs.RuntimeBehavior | null {\n return this._behaviorsTable.get(name);\n }\n\n /**\n * Check if a behavior is used by the object.\n *\n * @param name {String} The behavior name.\n */\n hasBehavior(name: string): boolean {\n return this._behaviorsTable.containsKey(name);\n }\n\n /**\n * De/activate a behavior of the object.\n *\n * @param name {String} The behavior name.\n * @param enable {boolean} true to activate the behavior\n */\n activateBehavior(name: string, enable: boolean): void {\n if (this._behaviorsTable.containsKey(name)) {\n this._behaviorsTable.get(name).activate(enable);\n }\n }\n\n /**\n * Check if a behavior is activated\n *\n * @param name The behavior name.\n * @return true if the behavior is activated.\n */\n behaviorActivated(name: string): boolean {\n if (this._behaviorsTable.containsKey(name)) {\n return this._behaviorsTable.get(name).activated();\n }\n return false;\n }\n\n /**\n * Remove the behavior with the given name. Usually only used by\n * hot-reloading, as performance of this operation is not guaranteed\n * (in the future, this could lead to re-organization of arrays\n * holding behaviors).\n *\n * @param name The name of the behavior to remove.\n * @returns true if the behavior was properly removed, false otherwise.\n */\n removeBehavior(name: string): boolean {\n const behavior = this._behaviorsTable.get(name);\n if (!behavior) {\n return false;\n }\n behavior.onDestroy();\n const behaviorIndex = this._behaviors.indexOf(behavior);\n if (behaviorIndex !== -1) {\n this._behaviors.splice(behaviorIndex, 1);\n }\n this._behaviorsTable.remove(name);\n return true;\n }\n\n /**\n * Create the behavior described by the given BehaviorData\n *\n * @param behaviorData The data to be used to construct the behavior.\n * @returns true if the behavior was properly created, false otherwise.\n */\n addNewBehavior(behaviorData: BehaviorData): boolean {\n const Ctor = gdjs.getBehaviorConstructor(behaviorData.type);\n if (!Ctor) {\n return false;\n }\n const newRuntimeBehavior = new Ctor(\n this._runtimeScene,\n behaviorData,\n this\n );\n if (newRuntimeBehavior.usesLifecycleFunction()) {\n this._behaviors.push(newRuntimeBehavior);\n }\n this._behaviorsTable.put(behaviorData.name, newRuntimeBehavior);\n newRuntimeBehavior.onCreated();\n return true;\n }\n\n //Timers:\n /**\n * Updates the object timers. Called once during the game loop, before events and rendering.\n * @param elapsedTime The elapsed time since the previous frame in milliseconds.\n */\n updateTimers(elapsedTime: float): void {\n for (const name in this._timers.items) {\n if (this._timers.items.hasOwnProperty(name)) {\n this._timers.items[name].updateTime(elapsedTime);\n }\n }\n }\n\n /**\n * Compare a timer elapsed time. If the timer does not exist, it is created.\n *\n * @deprecated prefer using `getTimerElapsedTimeInSecondsOrNaN`.\n *\n * @param timerName The timer name.\n * @param timeInSeconds The time value to check in seconds.\n * @return True if the timer exists and its value is greater than or equal than the given time, false otherwise.\n */\n timerElapsedTime(timerName: string, timeInSeconds: float): boolean {\n if (!this._timers.containsKey(timerName)) {\n this._timers.put(timerName, new gdjs.Timer(timerName));\n return false;\n }\n return this.getTimerElapsedTimeInSeconds(timerName) >= timeInSeconds;\n }\n\n /**\n * Test a if a timer is paused.\n * @param timerName The timer name.\n * @return True if the timer exists and is paused, false otherwise.\n */\n timerPaused(timerName: string): boolean {\n if (!this._timers.containsKey(timerName)) {\n return false;\n }\n return this._timers.get(timerName).isPaused();\n }\n\n /**\n * Reset a timer. If the timer doesn't exist it is created.\n * @param timerName The timer name.\n */\n resetTimer(timerName: string): void {\n if (!this._timers.containsKey(timerName)) {\n this._timers.put(timerName, new gdjs.Timer(timerName));\n }\n this._timers.get(timerName).reset();\n }\n\n /**\n * Pause a timer. If the timer doesn't exist it is created.\n * @param timerName The timer name.\n */\n pauseTimer(timerName: string): void {\n if (!this._timers.containsKey(timerName)) {\n this._timers.put(timerName, new gdjs.Timer(timerName));\n }\n this._timers.get(timerName).setPaused(true);\n }\n\n /**\n * Unpause a timer. If the timer doesn't exist it is created.\n * @param timerName The timer name.\n */\n unpauseTimer(timerName: string): void {\n if (!this._timers.containsKey(timerName)) {\n this._timers.put(timerName, new gdjs.Timer(timerName));\n }\n this._timers.get(timerName).setPaused(false);\n }\n\n /**\n * Remove a timer\n * @param timerName The timer name.\n */\n removeTimer(timerName: string): void {\n if (this._timers.containsKey(timerName)) {\n this._timers.remove(timerName);\n }\n }\n\n /**\n * Get a timer elapsed time.\n *\n * This is used by expressions to return 0 when a timer doesn't exist\n * because numeric expressions must always return a number.\n *\n * @param timerName The timer name.\n * @return The timer elapsed time in seconds, 0 if the timer doesn't exist.\n */\n getTimerElapsedTimeInSeconds(timerName: string): float {\n if (!this._timers.containsKey(timerName)) {\n return 0;\n }\n return this._timers.get(timerName).getTime() / 1000.0;\n }\n\n /**\n * Get a timer elapsed time.\n *\n * This is used by conditions to return false when a timer doesn't exist,\n * no matter the relational operator.\n *\n * @param timerName The timer name.\n * @return The timer elapsed time in seconds, NaN if the timer doesn't exist.\n */\n getTimerElapsedTimeInSecondsOrNaN(timerName: string): float {\n if (!this._timers.containsKey(timerName)) {\n return Number.NaN;\n }\n return this._timers.get(timerName).getTime() / 1000.0;\n }\n\n //Other :\n /**\n * Separate the object from others objects, using their hitboxes.\n * @param objects Objects\n * @param ignoreTouchingEdges If true, then edges that are touching each other, without the hitbox polygons actually overlapping, won't be considered in collision.\n * @return true if the object was moved\n */\n separateFromObjects(\n objects: gdjs.RuntimeObject[],\n ignoreTouchingEdges: boolean\n ): boolean {\n let moveXArray: Array<float> = separateFromObjectsStatics.moveXArray;\n let moveYArray: Array<float> = separateFromObjectsStatics.moveYArray;\n moveXArray.length = 0;\n moveYArray.length = 0;\n\n // We can assume that the moving object is not grid based,\n // so there is no need for optimization:\n // getHitBoxes can be called directly.\n const hitBoxes = this.getHitBoxes();\n let aabb: AABB | null = null;\n\n // Check if there is a collision with each object\n for (const otherObject of objects) {\n if (otherObject.id === this.id) {\n continue;\n }\n let otherHitBoxesArray = otherObject.getHitBoxes();\n let otherHitBoxes: Iterable<gdjs.Polygon> = otherHitBoxesArray;\n if (otherHitBoxesArray.length > 4) {\n // The other object has a lot of hit boxes.\n // Try to reduce the amount of hitboxes to check.\n if (!aabb) {\n aabb = this.getAABB();\n }\n otherHitBoxes = otherObject.getHitBoxesAround(\n aabb.min[0],\n aabb.min[1],\n aabb.max[0],\n aabb.max[1]\n );\n }\n for (const hitBox of hitBoxes) {\n for (const otherHitBox of otherHitBoxes) {\n const result = gdjs.Polygon.collisionTest(\n hitBox,\n otherHitBox,\n ignoreTouchingEdges\n );\n if (result.collision) {\n moveXArray.push(result.move_axis[0]);\n moveYArray.push(result.move_axis[1]);\n }\n }\n }\n }\n return moveFollowingSeparatingVectors(this, moveXArray, moveYArray);\n }\n\n /**\n * Separate the object from others objects, using their hitboxes.\n * @param objectsLists Tables of objects\n * @param ignoreTouchingEdges If true, then edges that are touching each other, without the hitbox polygons actually overlapping, won't be considered in collision.\n * @return true if the object was moved\n */\n separateFromObjectsList(\n objectsLists: ObjectsLists,\n ignoreTouchingEdges: boolean\n ): boolean {\n let moveXArray: Array<float> = separateFromObjectsStatics.moveXArray;\n let moveYArray: Array<float> = separateFromObjectsStatics.moveYArray;\n moveXArray.length = 0;\n moveYArray.length = 0;\n\n // We can assume that the moving object is not grid based\n // So there is no need for optimization\n // getHitBoxes can be called directly.\n const hitBoxes = this.getHitBoxes();\n let aabb: AABB | null = null;\n\n for (const name in objectsLists.items) {\n if (objectsLists.items.hasOwnProperty(name)) {\n const otherObjects = objectsLists.items[name];\n\n // Check if their is a collision with each object\n for (const otherObject of otherObjects) {\n if (otherObject.id === this.id) {\n continue;\n }\n let otherHitBoxesArray = otherObject.getHitBoxes();\n let otherHitBoxes: Iterable<gdjs.Polygon> = otherHitBoxesArray;\n if (otherHitBoxesArray.length > 4) {\n // The other object has a lot of hit boxes.\n // Try to reduce the amount of hitboxes to check.\n if (!aabb) {\n aabb = this.getAABB();\n }\n otherHitBoxes = otherObject.getHitBoxesAround(\n aabb.min[0],\n aabb.min[1],\n aabb.max[0],\n aabb.max[1]\n );\n }\n for (const hitBox of hitBoxes) {\n for (const otherHitBox of otherHitBoxes) {\n const result = gdjs.Polygon.collisionTest(\n hitBox,\n otherHitBox,\n ignoreTouchingEdges\n );\n if (result.collision) {\n moveXArray.push(result.move_axis[0]);\n moveYArray.push(result.move_axis[1]);\n }\n }\n }\n }\n }\n }\n return moveFollowingSeparatingVectors(this, moveXArray, moveYArray);\n }\n\n /**\n * Get the distance, in pixels, between *the center* of this object and another object.\n * @param otherObject The other object\n */\n getDistanceToObject(otherObject: gdjs.RuntimeObject): float {\n return Math.sqrt(this.getSqDistanceToObject(otherObject));\n }\n\n /**\n * Get the squared distance, in pixels, between *the center* of this object and another object.\n * @param otherObject The other object\n */\n getSqDistanceToObject(otherObject: gdjs.RuntimeObject): float {\n if (otherObject === null) {\n return 0;\n }\n const x =\n this.getDrawableX() +\n this.getCenterX() -\n (otherObject.getDrawableX() + otherObject.getCenterX());\n const y =\n this.getDrawableY() +\n this.getCenterY() -\n (otherObject.getDrawableY() + otherObject.getCenterY());\n return x * x + y * y;\n }\n\n /**\n * Get the distance, in pixels, between *the center* of this object and a position.\n * @param targetX Target X position\n * @param targetY Target Y position\n */\n getDistanceToPosition(targetX: float, targetY: float): float {\n return Math.sqrt(this.getSqDistanceToPosition(targetX, targetY));\n }\n\n /**\n * Get the squared distance, in pixels, between *the center* of this object and a position.\n * @param targetX Target X position\n * @param targetY Target Y position\n */\n getSqDistanceToPosition(targetX: float, targetY: float): float {\n const x = this.getDrawableX() + this.getCenterX() - targetX;\n const y = this.getDrawableY() + this.getCenterY() - targetY;\n return x * x + y * y;\n }\n\n /**\n * Get the angle, in degrees, from the *object center* to another object.\n * @param otherObject The other object\n */\n getAngleToObject(otherObject: gdjs.RuntimeObject): float {\n if (otherObject === null) {\n return 0;\n }\n const x =\n this.getDrawableX() +\n this.getCenterX() -\n (otherObject.getDrawableX() + otherObject.getCenterX());\n const y =\n this.getDrawableY() +\n this.getCenterY() -\n (otherObject.getDrawableY() + otherObject.getCenterY());\n return gdjs.toDegrees(Math.atan2(-y, -x));\n }\n\n /**\n * Compute the X position when given an angle and distance relative to the starting object.\n * This is also known as getting the cartesian coordinates of a 2D vector, using its polar coordinates.\n * @param angle The angle, in degrees.\n * @param distance The distance from the object, in pixels\n */\n getXFromAngleAndDistance(angle: float, distance: float): float {\n return (\n this.getDrawableX() +\n this.getCenterX() +\n distance * Math.cos(gdjs.toRad(angle))\n );\n }\n\n /**\n * Compute the Y position when given an angle and distance relative to the starting object.\n * This is also known as getting the cartesian coordinates of a 2D vector, using its polar coordinates.\n * @param angle The angle, in degrees.\n * @param distance The distance from the object, in pixels\n */\n getYFromAngleAndDistance(angle: float, distance: float): float {\n return (\n this.getDrawableY() +\n this.getCenterY() +\n distance * Math.sin(gdjs.toRad(angle))\n );\n }\n\n /**\n * Get the angle, in degrees, from the *object center* to a position.\n * @param targetX Target X position\n * @param targetY Target Y position\n */\n getAngleToPosition(targetX: float, targetY: float): float {\n const x = this.getDrawableX() + this.getCenterX() - targetX;\n const y = this.getDrawableY() + this.getCenterY() - targetY;\n return gdjs.toDegrees(Math.atan2(-y, -x));\n }\n\n /**\n * Put the object around a position, with a specific distance and angle.\n * The distance and angle are computed between the position and *the center of the object*.\n *\n * @param x The x position of the target\n * @param y The y position of the target\n * @param distance The distance between the object and the target, in pixels.\n * @param angleInDegrees The angle between the object and the target, in degrees.\n */\n putAround(\n x: float,\n y: float,\n distance: float,\n angleInDegrees: float\n ): void {\n const angleInRadians = gdjs.toRad(angleInDegrees);\n\n this.setCenterXInScene(x + Math.cos(angleInRadians) * distance);\n this.setCenterYInScene(y + Math.sin(angleInRadians) * distance);\n }\n\n /**\n * Put the object around another object, with a specific distance and angle.\n * The distance and angle are computed between *the centers of the objects*.\n *\n * @param obj The target object\n * @param distance The distance between the object and the target\n * @param angleInDegrees The angle between the object and the target, in degrees.\n */\n putAroundObject(\n obj: gdjs.RuntimeObject | null,\n distance: float,\n angleInDegrees: float\n ): void {\n if (!obj) return;\n\n this.putAround(\n obj.getDrawableX() + obj.getCenterX(),\n obj.getDrawableY() + obj.getCenterY(),\n distance,\n angleInDegrees\n );\n }\n\n /**\n * @deprecated\n * @param objectsLists Tables of objects\n */\n separateObjectsWithoutForces(objectsLists: ObjectsLists): void {\n //Prepare the list of objects to iterate over.\n const objects = gdjs.staticArray(\n RuntimeObject.prototype.separateObjectsWithoutForces\n );\n objects.length = 0;\n const lists = gdjs.staticArray2(\n RuntimeObject.prototype.separateObjectsWithoutForces\n );\n objectsLists.values(lists);\n for (let i = 0, len = lists.length; i < len; ++i) {\n objects.push.apply(objects, lists[i]);\n }\n for (let i = 0, len = objects.length; i < len; ++i) {\n if (objects[i].id != this.id) {\n if (this.getDrawableX() < objects[i].getDrawableX()) {\n this.setX(objects[i].getDrawableX() - this.getWidth());\n } else {\n if (\n this.getDrawableX() + this.getWidth() >\n objects[i].getDrawableX() + objects[i].getWidth()\n ) {\n this.setX(objects[i].getDrawableX() + objects[i].getWidth());\n }\n }\n if (this.getDrawableY() < objects[i].getDrawableY()) {\n this.setY(objects[i].getDrawableY() - this.getHeight());\n } else {\n if (\n this.getDrawableY() + this.getHeight() >\n objects[i].getDrawableY() + objects[i].getHeight()\n ) {\n this.setY(objects[i].getDrawableY() + objects[i].getHeight());\n }\n }\n }\n }\n }\n\n /**\n * @deprecated\n * @param objectsLists Tables of objects\n */\n separateObjectsWithForces(objectsLists: ObjectsLists): void {\n //Prepare the list of objects to iterate over.\n const objects = gdjs.staticArray(\n RuntimeObject.prototype.separateObjectsWithForces\n );\n objects.length = 0;\n const lists = gdjs.staticArray2(\n RuntimeObject.prototype.separateObjectsWithForces\n );\n objectsLists.values(lists);\n for (let i = 0, len = lists.length; i < len; ++i) {\n objects.push.apply(objects, lists[i]);\n }\n for (let i = 0, len = objects.length; i < len; ++i) {\n if (objects[i].id != this.id) {\n if (\n this.getDrawableX() + this.getCenterX() <\n objects[i].getDrawableX() + objects[i].getCenterX()\n ) {\n let av = this.hasNoForces() ? 0 : this.getAverageForce().getX();\n this.addForce(-av - 10, 0, 0);\n } else {\n let av = this.hasNoForces() ? 0 : this.getAverageForce().getX();\n this.addForce(-av + 10, 0, 0);\n }\n if (\n this.getDrawableY() + this.getCenterY() <\n objects[i].getDrawableY() + objects[i].getCenterY()\n ) {\n let av = this.hasNoForces() ? 0 : this.getAverageForce().getY();\n this.addForce(0, -av - 10, 0);\n } else {\n let av = this.hasNoForces() ? 0 : this.getAverageForce().getY();\n this.addForce(0, -av + 10, 0);\n }\n }\n }\n }\n\n /**\n * Return true if the hitboxes of two objects are overlapping\n * @static\n * @param obj1 The first runtimeObject\n * @param obj2 The second runtimeObject\n * @param ignoreTouchingEdges If true, then edges that are touching each other, without the hitbox polygons actually overlapping, won't be considered in collision.\n * @param ignoredObject1Polygon A polygon from the `obj1` collision mask to ignore\n * @return true if obj1 and obj2 are in collision\n */\n static collisionTest(\n obj1: gdjs.RuntimeObject,\n obj2: gdjs.RuntimeObject,\n ignoreTouchingEdges: boolean,\n ignoredObject1Polygon: gdjs.Polygon | null = null\n ): boolean {\n //First check if bounding circle are too far.\n const o1centerX = obj1.getCenterX();\n const o1centerY = obj1.getCenterY();\n const obj1BoundingRadius = Math.sqrt(\n computeSqBoundingRadius(\n obj1.getWidth(),\n obj1.getHeight(),\n o1centerX,\n o1centerY\n )\n );\n\n const o2centerX = obj2.getCenterX();\n const o2centerY = obj2.getCenterY();\n const obj2BoundingRadius = Math.sqrt(\n computeSqBoundingRadius(\n obj2.getWidth(),\n obj2.getHeight(),\n o2centerX,\n o2centerY\n )\n );\n\n const o1AbsoluteCenterX = obj1.getDrawableX() + o1centerX;\n const o1AbsoluteCenterY = obj1.getDrawableY() + o1centerY;\n const o2AbsoluteCenterX = obj2.getDrawableX() + o2centerX;\n const o2AbsoluteCenterY = obj2.getDrawableY() + o2centerY;\n\n const diffX = o1AbsoluteCenterX - o2AbsoluteCenterX;\n const diffY = o1AbsoluteCenterY - o2AbsoluteCenterY;\n if (\n Math.sqrt(diffX * diffX + diffY * diffY) >\n obj1BoundingRadius + obj2BoundingRadius\n ) {\n return false;\n }\n\n // Do a real check if necessary.\n const hitBoxes1 = obj1.getHitBoxesAround(\n o2AbsoluteCenterX - obj2BoundingRadius,\n o2AbsoluteCenterY - obj2BoundingRadius,\n o2AbsoluteCenterX + obj2BoundingRadius,\n o2AbsoluteCenterY + obj2BoundingRadius\n );\n const hitBoxes2 = obj2.getHitBoxesAround(\n o1AbsoluteCenterX - obj1BoundingRadius,\n o1AbsoluteCenterY - obj1BoundingRadius,\n o1AbsoluteCenterX + obj1BoundingRadius,\n o1AbsoluteCenterY + obj1BoundingRadius\n );\n\n for (const hitBox1 of hitBoxes1) {\n if (hitBox1 === ignoredObject1Polygon) {\n continue;\n }\n for (const hitBox2 of hitBoxes2) {\n if (\n gdjs.Polygon.collisionTest(hitBox1, hitBox2, ignoreTouchingEdges)\n .collision\n ) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * @param x The raycast source X\n * @param y The raycast source Y\n * @param endX The raycast end position X\n * @param endY The raycast end position Y\n * @param closest Get the closest or farthest collision mask result?\n * @return A raycast result with the contact points and distances\n */\n raycastTest(\n x: float,\n y: float,\n endX: float,\n endY: float,\n closest: boolean\n ): RaycastTestResult {\n // First check if bounding circles are too far\n const objCenterX = this.getCenterX();\n const objCenterY = this.getCenterY();\n const objSqBoundingRadius = computeSqBoundingRadius(\n this.getWidth(),\n this.getHeight(),\n objCenterX,\n objCenterY\n );\n\n const rayCenterWorldX = (x + endX) / 2;\n const rayCenterWorldY = (y + endY) / 2;\n const raySqBoundingRadius =\n (endX - x) * (endX - x) + (endY - y) * (endY - y);\n\n const diffX = this.getDrawableX() + objCenterX - rayCenterWorldX;\n const diffY = this.getDrawableY() + objCenterY - rayCenterWorldY;\n\n let result = raycastTestStatics.result;\n result.collision = false;\n if (\n // As an optimization, avoid computing the square root of the two boundings radius\n // and the distance by comparing the squared values instead.\n diffX * diffX + diffY * diffY >\n objSqBoundingRadius +\n raySqBoundingRadius +\n 2 * Math.sqrt(raySqBoundingRadius * objSqBoundingRadius)\n ) {\n return result;\n }\n\n // Do a real check if necessary.\n if (closest) {\n let sqDistMin = Number.MAX_VALUE;\n const hitBoxes = this.getHitBoxesAround(x, y, endX, endY);\n for (const hitBox of hitBoxes) {\n const res = gdjs.Polygon.raycastTest(hitBox, x, y, endX, endY);\n if (res.collision && res.closeSqDist < sqDistMin) {\n sqDistMin = res.closeSqDist;\n gdjs.Polygon.copyRaycastTestResult(res, result);\n }\n }\n } else {\n let sqDistMax = -Number.MAX_VALUE;\n const hitBoxes = this.getHitBoxesAround(x, y, endX, endY);\n for (const hitBox of hitBoxes) {\n const res = gdjs.Polygon.raycastTest(hitBox, x, y, endX, endY);\n if (\n res.collision &&\n res.farSqDist > sqDistMax &&\n res.farSqDist <= raySqBoundingRadius\n ) {\n sqDistMax = res.farSqDist;\n gdjs.Polygon.copyRaycastTestResult(res, result);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Return true if the specified position is inside object bounding box.\n *\n * The position should be in \"world\" coordinates, i.e use gdjs.Layer.convertCoords\n * if you need to pass the mouse or a touch position that you get from gdjs.InputManager.\n * To check if a point is inside the object collision mask, you can use `isCollidingWithPoint` instead.\n *\n */\n insideObject(x: float, y: float): boolean {\n if (this.hitBoxesDirty) {\n this.updateHitBoxes();\n this.updateAABB();\n this.hitBoxesDirty = false;\n }\n return (\n this.aabb.min[0] <= x &&\n this.aabb.max[0] >= x &&\n this.aabb.min[1] <= y &&\n this.aabb.max[1] >= y\n );\n }\n\n /**\n * Check the distance between two objects.\n * @static\n */\n static distanceTest(\n obj1: RuntimeObject,\n obj2: RuntimeObject,\n distance: float\n ): boolean {\n return obj1.getSqDistanceToObject(obj2) <= distance;\n }\n\n /**\n * Return true if the cursor, or any touch, is on the object.\n *\n * @return true if the cursor, or any touch, is on the object.\n */\n cursorOnObject(): boolean {\n const workingPoint: FloatPoint = gdjs.staticArray(\n RuntimeObject.prototype.cursorOnObject\n ) as FloatPoint;\n workingPoint.length = 2;\n const instanceContainer = this.getInstanceContainer();\n const inputManager = instanceContainer.getGame().getInputManager();\n const layer = instanceContainer.getLayer(this.layer);\n const mousePos = layer.convertCoords(\n inputManager.getCursorX(),\n inputManager.getCursorY(),\n 0,\n workingPoint\n );\n if (this.insideObject(mousePos[0], mousePos[1])) {\n return true;\n }\n const touchIds = inputManager.getAllTouchIdentifiers();\n for (let i = 0; i < touchIds.length; ++i) {\n const touchPos = layer.convertCoords(\n inputManager.getTouchX(touchIds[i]),\n inputManager.getTouchY(touchIds[i]),\n 0,\n workingPoint\n );\n if (this.insideObject(touchPos[0], touchPos[1])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if a point is inside the object collision hitboxes.\n * @param pointX The point x coordinate.\n * @param pointY The point y coordinate.\n * @return true if the point is inside the object collision hitboxes.\n */\n isCollidingWithPoint(pointX: float, pointY: float): boolean {\n const hitBoxes = this.getHitBoxesAround(pointX, pointY, pointX, pointY);\n for (const hitBox of hitBoxes) {\n if (gdjs.Polygon.isPointInside(hitBox, pointX, pointY)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get the identifier associated to an object name.\n * Some features may want to compare objects name a large number of time. In this case,\n * it may be more efficient to compare objects name identifiers.\n *\n * @static\n */\n static getNameIdentifier(name: string): integer {\n if (RuntimeObject._identifiers.containsKey(name)) {\n return RuntimeObject._identifiers.get(name);\n }\n RuntimeObject._newId = (RuntimeObject._newId || 0) + 1;\n const newIdentifier = RuntimeObject._newId;\n RuntimeObject._identifiers.put(name, newIdentifier);\n return newIdentifier;\n }\n\n /**\n * Table containing the id corresponding to an object name. Do not use directly or modify.\n * @static\n */\n static _identifiers = new Hashtable<integer>();\n\n /**\n * The next available unique identifier for an object. Do not use directly or modify.\n * @static\n */\n static _newId = 0;\n\n /**\n * Global container for unused forces, avoiding recreating forces each tick.\n * @static\n */\n static forcesGarbage: Array<gdjs.Force> = [];\n\n getVariableNumber = RuntimeObject.getVariableNumber;\n returnVariable = RuntimeObject.returnVariable;\n getVariableString = RuntimeObject.getVariableString;\n setVariableNumber = RuntimeObject.setVariableNumber;\n setVariableString = RuntimeObject.setVariableString;\n getVariableBoolean = RuntimeObject.getVariableBoolean;\n setVariableBoolean = RuntimeObject.setVariableBoolean;\n getVariableChildCount = RuntimeObject.getVariableChildCount;\n getFirstVariableNumber = RuntimeObject.getFirstVariableNumber;\n getFirstVariableString = RuntimeObject.getFirstVariableString;\n getLastVariableNumber = RuntimeObject.getLastVariableNumber;\n getLastVariableString = RuntimeObject.getLastVariableString;\n toggleVariableBoolean = RuntimeObject.toggleVariableBoolean;\n variableChildExists = RuntimeObject.variableChildExists;\n variableRemoveChild = RuntimeObject.variableRemoveChild;\n variableClearChildren = RuntimeObject.variableClearChildren;\n variablePushCopy = RuntimeObject.variablePushCopy;\n valuePush = RuntimeObject.valuePush;\n variableRemoveAt = RuntimeObject.variableRemoveAt;\n\n /**\n * Get the squared distance, in pixels, from the *object center* to a position.\n * @param pointX X position\n * @param pointY Y position\n * @deprecated Use `getSqDistanceToPosition` instead.\n */\n getSqDistanceTo = RuntimeObject.prototype.getSqDistanceToPosition;\n }\n gdjs.registerObject('', gdjs.RuntimeObject);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -52,6 +52,10 @@ declare type BasicObjectNetworkSyncData = {
52
52
  y: number;
53
53
  /** The position of the instance on the Z axis. Defined only for 3D games */
54
54
  z?: number;
55
+ /** The width of the instance */
56
+ w: number;
57
+ /** The height of the instance */
58
+ h: number;
55
59
  /** Z order of the instance */
56
60
  zo: number;
57
61
  /** The angle of the instance. */
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdcore-tools",
3
- "version": "2.0.0-gd-v5.5.236-autobuild",
3
+ "version": "2.0.0-gd-v5.5.237-autobuild",
4
4
  "description": "A package of GDevelop's Core library with additional helper tools.",
5
5
  "types": "./types/index.d.ts",
6
6
  "exports": {