Compare commits

...

887 Commits

Author SHA1 Message Date
Florian Rival
d924cb4269 Add support for touch controls in editor 2025-09-28 19:15:47 +02:00
Florian Rival
c2f17f9348 Improve rendering of the 2D plane in 3D so it's not cut when rotating the camera (#7857)
Allow the 2D plane in the 3D world to be rendered at the position "where
the 3D camera is looking at" (by projecting the camera frustrum on the Z
plane, with a "maximum drawing distance" to avoid a too large area). The
2D rendering texture size is not changed, so an area too big can create
blurry rendering near the camera - but this is expected.

In practice, 2D objects culling will limit the distance anyway of what's
visible.
2025-09-27 15:33:01 +02:00
Davy Hélard
0ba59d5d7f Remove log 2025-09-26 17:48:26 +02:00
Davy Hélard
6878a4cd75 Handle grid in variant tabs 2025-09-26 17:45:09 +02:00
Davy Hélard
33eed58c62 Save editor settings for variant tabs 2025-09-26 17:45:08 +02:00
Florian Rival
f516eff739 Fix toolbar not updating when enabling grid 2025-09-26 17:39:09 +02:00
Florian Rival
baefc272f6 Remove some TODOs and fix enabling/disabling grid 2025-09-26 17:25:51 +02:00
Florian Rival
2badc72dfb Remove useless fields 2025-09-26 16:44:10 +02:00
Davy Hélard
5e54f02061 Handle grid setting changes 2025-09-26 16:37:40 +02:00
Davy Hélard
827bb2d08d Fix grid axe when Alt is pressed 2025-09-25 17:30:28 +02:00
Davy Hélard
0fda0baa48 Remove log 2025-09-25 17:00:45 +02:00
Davy Hélard
e655cc0661 Fix undefined cell depth 2025-09-25 16:53:27 +02:00
Davy Hélard
225d1b37ab Remove log 2025-09-25 16:27:22 +02:00
Davy Hélard
5a0ab9dffa Snap objects on the grid (no grid setting update) 2025-09-25 16:08:23 +02:00
Davy Hélard
9300604d56 Round angles 2025-09-24 17:18:58 +02:00
Davy Hélard
02fcf1dbc2 Fix scaling control rotation 2025-09-24 17:04:25 +02:00
Florian Rival
a70b2e2c2c Fix low framerate when dragging a new instance 2025-09-24 12:55:59 +02:00
Davy Hélard
3e04b5a82f Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-09-24 10:36:54 +02:00
D8H
7c4617da99 Add a skybox effect (#7843) 2025-09-23 21:14:44 +02:00
Florian Rival
cbcf0b7b70 Fix undo/redo stacking empty changes when selection is not even moved 2025-09-23 18:39:49 +02:00
Florian Rival
5d1fe83655 Fix undo/redo for default values of instances 2025-09-23 18:01:17 +02:00
Clément Pasteau
d6d7c5c1fb Fix templates not accessible when bought via an unlisted bundle (#7844) 2025-09-23 11:18:15 +02:00
Florian Rival
7cf70a6fd7 Reverse Q/E 2025-09-23 00:46:10 +02:00
Florian Rival
24c2dbc340 Add some tolerance radius when selecting an object 2025-09-22 23:26:31 +02:00
Florian Rival
290901849c Fix in-game edition framerate limitation 2025-09-22 17:47:51 +02:00
github-actions[bot]
b7f7a39aa7 Update translations [skip ci] (#7840)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-09-22 17:05:31 +02:00
Clément Pasteau
8c04771a87 Allow opening a bundle with a link via category (#7842)
Do not show in changelog
2025-09-22 16:36:16 +02:00
Clément Pasteau
febf15b279 Slightly improve Course page overload (#7841)
Do not show in changelog
2025-09-22 13:58:55 +02:00
Florian Rival
59721cba7e Reduce scale speed 2025-09-22 13:08:30 +02:00
Florian Rival
53cd78bb45 Allow to scroll directly with mouse wheel click (even if shift not pressed) 2025-09-22 12:39:52 +02:00
Florian Rival
49f8ce9385 Remove default shortcut S to open scene properties to avoid conflict when using the new editor 2025-09-22 12:26:05 +02:00
D8H
a05e4b7ecc Fix groups wrongly underlined in red while having the right behaviors in the Events Sheet (#7839) 2025-09-22 11:25:37 +02:00
Florian Rival
de2a9725f9 Adapt framerate of in-game editor according to usage/visibility 2025-09-21 22:29:14 +02:00
Florian Rival
b2ec3b5387 Merge branch 'master' into experimental-build/move-instance-in-game-2 2025-09-21 15:18:17 +02:00
Florian Rival
1873b5e592 Fix useless methods 2025-09-20 15:59:06 +02:00
Florian Rival
e47e35c090 Add shift + mouse wheel to pan 2025-09-20 15:45:23 +02:00
Florian Rival
ae572683f1 Add free camera speed boost with Shift 2025-09-20 12:14:44 +02:00
Florian Rival
f8e387230f Add ESC to clear selection, default to free camera, show a grab cursor when space pressed to pan (even if in orbit) 2025-09-20 12:09:52 +02:00
Florian Rival
9451e5969f Fix moving on the plane orthogonal to the camera with arrows/mouse wheel or Q/E 2025-09-19 16:51:36 +02:00
Florian Rival
ad7ddf09a3 Fix warning 2025-09-19 14:04:36 +02:00
Davy Hélard
8e70930d8d Fix default light not being exported 2025-09-18 17:15:42 +02:00
Florian Rival
3568a999f9 Update README [skip ci] [ci skip] 2025-09-18 16:48:48 +02:00
Davy Hélard
ab3bda24dc Fix a crash when undoing and a custom object is in the scene 2025-09-18 13:29:32 +02:00
Florian Rival
d33a7331b3 Fix custom object extraction on web-app 2025-09-18 12:19:12 +02:00
Davy Hélard
4d3793815f Fix a crash when adding a layer 2025-09-18 11:40:28 +02:00
Florian Rival
207097bf03 Bump newIDE version 2025-09-18 10:01:44 +02:00
github-actions[bot]
0e3d2b9570 Update translations [skip ci] (#7831)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-09-18 10:01:32 +02:00
D8H
87fac429e8 Underline groups having missing behaviors in the Events Sheet (#7832) 2025-09-18 10:00:28 +02:00
Florian Rival
e1835d1144 Fix orbit camera restore 2025-09-17 19:16:08 +02:00
Florian Rival
72068460e1 Fix free camera in-game editor restore 2025-09-17 19:11:35 +02:00
Florian Rival
5da76ae655 Try to fix camera restore on in-game edition startup 2025-09-17 18:59:42 +02:00
D8H
3b1097931b Fix child object creation when called from another function (#7836) 2025-09-17 18:38:06 +02:00
Florian Rival
b5b25ad710 Fix editor shortcuts on macOS 2025-09-17 18:28:04 +02:00
Florian Rival
2279f069af Only show transform controls on non sealed/locked objects and adapt selection color to make it more obvious when a locked object is selected 2025-09-17 16:50:40 +02:00
D8H
ec7e408cd1 Fix button labels no longer updating in the editor (#7835) 2025-09-17 15:37:39 +02:00
Florian Rival
f8a99b9cfa Add prices and currency to store analytics (#7833)
Don't show in changelog
2025-09-16 15:44:35 +02:00
D8H
4c7231e6ae Fix a crash at runtime when behaviors are missing in functions (#7830) 2025-09-15 16:40:21 +02:00
D8H
883d32515c Rename "community" extensions as "experimental" extensions (#7828) 2025-09-15 14:04:31 +02:00
Florian Rival
f0f3c257fa Bump newIDE version 2025-09-14 16:11:02 +02:00
github-actions[bot]
42fce7d9ce Update translations [skip ci] (#7810)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-09-14 16:10:35 +02:00
Florian Rival
facac37fff Fix opening of the scene after creating project with AI
Don't show in changelog
2025-09-14 15:44:04 +02:00
Florian Rival
1272b601c6 Add many AI improvements (#7819)
* Allow the AI to start a game from a template
* Improved instances manipulation
* Better variables support
* Allow AI to swap an object by another one from the asset store
* Allow AI to change multiple properties at the same time
* Fix AI not properly removing behaviors associated to a behavior just removed
2025-09-13 18:01:35 +02:00
D8H
58e35cfaf5 Allow extensions to define labels for properties with string selectors (#7825) 2025-09-12 18:30:10 +02:00
Davy Hélard
f0a68db0d4 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-09-12 16:17:17 +02:00
Davy Hélard
15ed28ad8d Fix a crash at hot-reload after adding a scene 2025-09-12 16:17:10 +02:00
D8H
2befc9781b Fix the list of assets suggested for sliders and toggle switches (#7826) 2025-09-12 15:42:10 +02:00
Florian Rival
8fb2872c36 Disable spell check on comments
Don't show in changelog
2025-09-12 10:25:41 +02:00
D8H
98033515c8 Fix a 1-frame delay when applying anchors to child-objects (#7820) 2025-09-11 15:19:45 +02:00
D8H
25c02cea2e Add a link to an help page for asynchronous functions (#7823) 2025-09-11 14:53:15 +02:00
D8H
6d5be78fec Forbid to import an extension which has the same name as a built-in one (#7822) 2025-09-11 14:52:49 +02:00
D8H
f6e60085db Fix missing extension dependencies in exported assets (#7821) 2025-09-11 14:52:32 +02:00
Florian Rival
a61648af70 Fix landscape/portrait orientation not working on iOS 2025-09-11 10:50:06 +02:00
Davy Hélard
4291d5597a Update some todo 2025-09-10 16:26:37 +02:00
D8H
2b496c6fd3 Fix custom object extraction behavior check (#7818)
- Don't show in changelog
2025-09-10 12:30:48 +02:00
Davy Hélard
7af3fa5f2f Fix warning happening on messages which are not answers 2025-09-10 12:24:34 +02:00
Davy Hélard
5ce9591f68 Avoid a useless code generation when extracting a custom object 2025-09-09 18:45:21 +02:00
Davy Hélard
d5929010a7 Fix flow 2025-09-09 18:44:11 +02:00
Davy Hélard
30f2f5256b Fix custom object extraction behavior check 2025-09-09 14:21:20 +02:00
Davy Hélard
806d59fb88 Ask the selection AABB to all debuggers 2025-09-09 14:20:35 +02:00
Davy Hélard
e5f18ae2d8 Factorize the children configuration override check to ensure the hot-reload is consistent with the runtime 2025-09-09 11:55:24 +02:00
Davy Hélard
15a7fd1f85 Force the fov to 45° in the editor 2025-09-09 11:30:49 +02:00
Davy Hélard
3678a0dd45 Remove todo because this dialog should rarely happen and it now reload the editor instead of the game 2025-09-09 11:14:50 +02:00
Florian Rival
1e984f0965 Fix the chosen preset for AI not always valid when switching between chat and agent 2025-09-08 18:18:53 +02:00
Davy Hélard
197bd913b8 Explain why the new position is ignored when an object is dropped 2025-09-08 16:35:39 +02:00
Davy Hélard
baef911d61 Add type declaration 2025-09-08 13:43:49 +02:00
Davy Hélard
771e16e779 Refer to scene and external layout by name to launch previews 2025-09-08 12:11:08 +02:00
Davy Hélard
a2cf8e694b Factorize dragNewInstance 2025-09-08 11:55:18 +02:00
Davy Hélard
cb151ea30e Factorize _removeSelectionControls 2025-09-08 11:37:46 +02:00
Davy Hélard
7d1ebc8963 Fix screen adaptation 2025-09-05 17:55:07 +02:00
Davy Hélard
510a699c03 Remove useless todo 2025-09-05 17:05:09 +02:00
Florian Rival
37bed36315 Make comment events editable exactly as they look (#7812) 2025-09-05 14:46:42 +02:00
Davy Hélard
08892b68d4 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-09-04 19:43:52 +02:00
D8H
5394cc5201 Forbid to add Physics behaviors on objects inside custom objects (#7809) 2025-09-04 19:37:57 +02:00
Davy Hélard
e079fa4108 Forbid to extract objects with Physics behaviors 2025-09-04 18:51:05 +02:00
Florian Rival
5a26e883b8 Make text to drop objects more visible on small screens 2025-09-04 18:36:14 +02:00
Florian Rival
6bf5b389b5 Make the embedded game frame works on small screen 2025-09-04 18:33:29 +02:00
Florian Rival
5e3dfb0e9c Add condition to check if a key was just pressed (#7808) 2025-09-04 17:32:25 +02:00
Clément Pasteau
f6a6c981f8 Add a small intro explaining how to follow the courses (#7807) 2025-09-04 16:10:37 +02:00
Davy Hélard
2837a2906a Forbid to add Physics behaviors on child objects 2025-09-04 15:03:05 +02:00
Davy Hélard
8c63fae2f2 Fix flow 2025-09-04 14:37:19 +02:00
Davy Hélard
f837c22290 Display a message when trying to drag a 2D object 2025-09-04 12:21:48 +02:00
Davy Hélard
465bfa4deb Rename to notifyChangesToInGameEditor 2025-09-04 11:16:39 +02:00
Davy Hélard
a047ecdf9c Show a pop-up when the InGameEditor crashes 2025-09-03 18:31:31 +02:00
Clément Pasteau
415c1bfd2f Fix bundles showing up in new object search (#7806) 2025-09-03 14:11:16 +02:00
Davy Hélard
04c28de00b Hide the object icon when dragging a new object in the 3D editor 2025-09-03 11:52:23 +02:00
github-actions[bot]
e4a911db25 Update translations [skip ci] (#7804)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-09-03 10:42:14 +02:00
Clément Pasteau
5fcd67d77b Additional bundles are added to the Learn & Shop sections (#7805)
* A premium bundle, including multiple courses, asset packs, templates and a gold subscription
* A curated platformer-specific bundle, including everything needed to learn & create a platformer game
2025-09-03 10:30:24 +02:00
Davy Hélard
a7df6de044 Forbid to add 2D objects. 2025-09-02 19:46:57 +02:00
Davy Hélard
81c3199d00 Avoid hot-reloads when the extension doesn't have any custom object 2025-09-02 18:12:26 +02:00
Davy Hélard
dbe93a4bfd Hot-reload when changes are done in extensions 2025-09-02 17:48:34 +02:00
Davy Hélard
e0edbe8d57 Forbid interactions with text inputs from the editor 2025-09-02 11:41:07 +02:00
Davy Hélard
c25d51805f Forbid custom objects to use services from the editor 2025-09-02 11:21:03 +02:00
Davy Hélard
ab695370bb Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-09-01 18:35:05 +02:00
Davy Hélard
15ee216e33 Fix camera distance not being restored when changing tabs 2025-09-01 18:34:45 +02:00
Davy Hélard
3fac0522c9 Fix a crash when switching of scene 2025-09-01 18:05:10 +02:00
Florian Rival
86db08ac3f Fix npm start on Windows
Don't show in changelog
2025-09-01 15:49:21 +02:00
Florian Rival
8d502d7c5c Make it work on the web-app 2025-09-01 15:40:46 +02:00
github-actions[bot]
8d735fc726 Update translations [skip ci] (#7800)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-09-01 14:32:50 +02:00
Clément Pasteau
1e1f4bb2a3 Merge Bundle page into 1 component + small design fixes (#7803)
Do not show in changelog
2025-09-01 14:17:33 +02:00
Davy Hélard
12d18c45bc Rename variables 2025-09-01 13:56:40 +02:00
Davy Hélard
d255ab458b Fix tab switching when extracting a custom object 2025-09-01 12:26:42 +02:00
Florian Rival
fbfa0315de Merge branch 'master' into move-instance-in-game-2 2025-09-01 00:51:10 +02:00
Florian Rival
d8000aca10 Simplify editor README [skip ci] [ci skip] 2025-09-01 00:00:14 +02:00
Florian Rival
a2660ff0dc Allow to easily work on the game engine using the web-app development version (#7802) 2025-08-31 23:54:44 +02:00
Florian Rival
000d5785cf Improve AI agent performance by removing old object properties
Don't show in changelog
2025-08-30 17:29:49 +02:00
Florian Rival
9fe04712a9 Improve AI ability to update existing instances 2025-08-30 16:59:09 +02:00
Florian Rival
846afd9e0a Improve documentation with reference of all available effects. 2025-08-30 14:16:00 +02:00
Davy Hélard
9575705d29 Fix the inner area calculus when extracting a custom object 2025-08-29 19:49:27 +02:00
Florian Rival
6125ff0f90 Allow AI to change layers/effects/scene and some game properties (#7799) 2025-08-29 19:15:50 +02:00
github-actions[bot]
a5428a8843 Update translations [skip ci] (#7798)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-08-29 15:58:38 +02:00
Ansel Games
19be45cda6 Fix grammar in text font size change warning (#7797) 2025-08-29 14:26:04 +02:00
Clément Pasteau
889c97cb27 Update Bundle Page with more details about content and limited offer (#7795) 2025-08-29 14:24:49 +02:00
Davy Hélard
1223eaa348 Fix a crash in 2D projects 2025-08-29 12:14:52 +02:00
Davy Hélard
21ea077768 Better default zoom for variants 2025-08-29 11:14:18 +02:00
Davy Hélard
11895decd9 Fix switching to a variant was switching on the previous scene instead 2025-08-29 11:08:53 +02:00
Davy Hélard
c0e1e9fac6 Never generate scene event code for the editor 2025-08-28 19:54:15 +02:00
Davy Hélard
bd9c631e1b Fix inner area not displaying 2025-08-28 19:24:31 +02:00
Davy Hélard
4a6e8ef664 Fix missing included files to edit variants 2025-08-28 19:03:37 +02:00
Davy Hélard
e25345000d Rename to make it clear that the generation is for scenes events 2025-08-28 13:20:31 +02:00
Davy Hélard
111d37fc15 Make the difference between edited layers and camera layers easier to understand 2025-08-27 17:54:25 +02:00
Florian Rival
1d83da41a9 Improve physics extensions descriptions to tell about the scale and typical force values 2025-08-27 16:42:41 +02:00
Davy Hélard
4a83c9eb59 Fix inner area no longer displaying 2025-08-27 15:53:51 +02:00
Davy Hélard
177cb2c519 Move createSceneWithCustomObject in the editor 2025-08-27 15:08:32 +02:00
Davy Hélard
b5d69dee4c Clarify a comment 2025-08-27 14:50:43 +02:00
Davy Hélard
fbdaebe575 Avoid to switch the scene 2 times when changing of tab 2025-08-27 13:31:00 +02:00
Davy Hélard
2a2fd75ca3 Fix selection loss at hot-reload 2025-08-27 11:46:17 +02:00
github-actions[bot]
a65f2174eb Update translations [skip ci] (#7781)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-08-27 10:05:59 +02:00
Davy Hélard
af7563b4b7 Fix advanced properties not being hot-reloaded 2025-08-27 09:57:23 +02:00
D8H
9db493e87e Refactor tab opening (#7794)
- Don't show in changelogs
2025-08-26 17:29:42 +02:00
Florian Rival
49a3a18b51 Make clear in-app tutorials are free
Don't show in changelog
2025-08-26 15:53:55 +02:00
Davy Hélard
1861c3be41 Handle missing zoom actions 2025-08-26 15:49:51 +02:00
Florian Rival
0489e7036b Rework stories for TeamSection 2025-08-26 12:07:57 +02:00
Davy Hélard
895dc625eb Display the screen size rectangle 2025-08-26 11:48:05 +02:00
Florian Rival
794d5a781c Add support for setting a full name for a student account (#7788) 2025-08-26 11:09:19 +02:00
Davy Hélard
52aea76677 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-08-26 11:07:40 +02:00
Davy Hélard
4f87191176 Fix runtime crash report for in-game editor 2025-08-26 11:02:49 +02:00
Davy Hélard
43d4e2e8cc Force 2D+3D rendering mode. 2025-08-26 10:38:09 +02:00
D8H
c21dfbcc1f Optimize used resources search during export (#7790) 2025-08-25 20:12:17 +02:00
Davy Hélard
cbfaa13978 Remove log 2025-08-25 17:39:11 +02:00
Davy Hélard
0aba5cf551 Delay the display of loader modals 2025-08-25 17:30:48 +02:00
Clément Pasteau
cc75db6d09 Fix crash when accessing an owned archived product in the store (#7789)
Do not show in changelog
2025-08-25 17:03:30 +02:00
Davy Hélard
a3ef07c163 Fix editor frame adaptation 2025-08-25 16:44:19 +02:00
Davy Hélard
a8ede5eee7 Fix generated events reload 2025-08-25 16:37:52 +02:00
Davy Hélard
ce965ca31c Fix libraries reload 2025-08-25 16:23:41 +02:00
Davy Hélard
039fbb8b1b Allow to launch back the editor preview after an error 2025-08-25 14:25:28 +02:00
Davy Hélard
80c1e67146 Refactor InGameEditor to no longer rely on SceneStack 2025-08-22 18:46:07 +02:00
Davy Hélard
2591cabdd0 Remove dead code 2025-08-22 16:28:48 +02:00
Davy Hélard
45620d6bf4 Avoid to return a string value from a static function. 2025-08-22 14:41:55 +02:00
Davy Hélard
89a59cdd35 Make a parameter const 2025-08-22 14:20:52 +02:00
Davy Hélard
17b819a423 Avoid to copy strings 2025-08-22 14:12:43 +02:00
Davy Hélard
afb4e3c1c6 Optimize DataProject serialization. 2025-08-22 11:59:56 +02:00
Davy Hélard
e5f8fe1bf8 Make the in-game editor resources from the project folder 2025-08-21 19:11:41 +02:00
Davy Hélard
30de5c6fa9 Use a different folder for editor previews 2025-08-21 15:55:21 +02:00
Davy Hélard
79a29cf7d5 Fix the "Include and libs export" time log 2025-08-21 15:33:00 +02:00
Davy Hélard
98a1323bf5 Allow to skip library files copy. 2025-08-21 15:08:19 +02:00
Davy Hélard
0fe6585897 Fix custom object hot-reloading 2025-08-18 19:14:16 +02:00
Florian Rival
48d35a50b5 Fix wrong redirection to AI tab when using initial-dialog=ask-ai in the web-app 2025-08-15 11:06:40 +02:00
Davy Hélard
33dd605c57 Remove logs 2025-08-14 19:47:22 +02:00
Florian Rival
3a0888046f Add a selector to switch the AI used or choose a preset (#7782) 2025-08-14 16:14:39 +02:00
github-actions[bot]
7917994835 Update translations (#7763)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-08-14 13:55:44 +02:00
Florian Rival
9e2bab43f7 Rework display of course specializations
Don't show in changelog
2025-08-14 13:54:41 +02:00
Davy Hélard
bab0c227f8 Remove editedObjectDataList 2025-08-14 12:50:37 +02:00
Davy Hélard
5ad2be4a8a Remove log 2025-08-14 12:49:45 +02:00
Florian Rival
7e03f47f08 Bump newIDE version 2025-08-14 12:37:27 +02:00
Davy Hélard
39e18678f5 Keep the camera 2025-08-14 10:56:35 +02:00
Davy Hélard
f54b13a9f5 Avoid to hot-reload when replacing a resource with another one from the project. 2025-08-13 19:52:48 +02:00
Florian Rival
7c6137a4fc Ensure behaviors used in events generated by AI are automatically added to objects 2025-08-13 18:02:24 +02:00
Davy Hélard
703adc090a Avoid to call onChange when the resource name stay the same 2025-08-13 14:50:28 +02:00
Davy Hélard
81f0047dab Avoid to call triggerResourcesHaveChanged if no resource are added to the project 2025-08-12 19:14:49 +02:00
Davy Hélard
ef70add27b Format 2025-08-12 19:13:46 +02:00
Davy Hélard
d45932cc04 Allow to attach an external layout to a scene 2025-08-12 17:27:05 +02:00
Davy Hélard
081a97a5fc Remove log 2025-08-12 16:49:57 +02:00
Davy Hélard
2b3cedb441 Fast reload of project data for scene list changes 2025-08-12 16:49:37 +02:00
Davy Hélard
76426117ff Always rebuild the scene for editor hot-reload 2025-08-12 12:44:58 +02:00
Davy Hélard
e8720780eb Review changes: comment and object parameter 2025-08-11 19:30:12 +02:00
Davy Hélard
e5ed642121 Avoid to launch 2 previews when opening a project 2025-08-11 19:16:09 +02:00
Davy Hélard
a6602292b7 Remove log 2025-08-11 19:04:47 +02:00
Davy Hélard
859d8e08a0 Squash the hot-reloads for editing images when the editor dialog is closed 2025-08-11 18:31:05 +02:00
Davy Hélard
8128adfd7b Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-08-11 15:58:27 +02:00
Davy Hélard
f9317dd17f Refresh the resources without a hard-reload. 2025-08-11 15:54:50 +02:00
D8H
0cbd6e2fe9 Fix cached materials not being cleared when unloading resources (#7780) 2025-08-11 15:50:22 +02:00
Davy Hélard
32a169014a Fix a crash in preview for 2D games. 2025-08-11 15:30:14 +02:00
Davy Hélard
37d3fd99eb Fix cached materials not being cleared when unloading the resource 2025-08-11 14:27:53 +02:00
D8H
5acc1f5560 Remove unused imports (#7779)
Don't show in changelog
2025-08-11 12:30:49 +02:00
D8H
887693a90d Forbid camera zoom to be set to 0 (#7778) 2025-08-11 10:30:28 +02:00
D8H
fbb985833f Optimize JavaScript events (avoid a list copy) (#7775)
Only show in developer changelog
2025-08-09 17:58:12 +02:00
D8H
1b3734ff6b Add the unit for 3D angle parameter descriptions (#7774) 2025-08-08 17:13:06 +02:00
D8H
6288b30ac3 Add an alert when editing the default variant of an extension from the store (#7773) 2025-08-08 16:39:50 +02:00
D8H
ee435f7081 Fix the tint action of Sprite to handle floating point color components (#7772) 2025-08-08 15:57:19 +02:00
Gleb Volkov
d75b4eb2a9 Add debug flag to GDJS build script (#7771) 2025-08-08 14:17:26 +02:00
Davy Hélard
e0973a8231 Clean up hot reload 2025-08-08 11:51:50 +02:00
Davy Hélard
876ce0d0a5 Add a todo for preview crash pop-up 2025-08-08 11:51:50 +02:00
Davy Hélard
9f614ce7e0 Refactor unloadResource 2025-08-08 11:51:50 +02:00
Florian Rival
5eeb505807 Fix tests
Don't show in changelog
2025-08-08 11:36:33 +02:00
Florian Rival
30566e35ce Fix changing language not reloading courses in this language 2025-08-08 10:14:57 +02:00
Florian Rival
e058b7f295 Add line height property for Text objects (#7769) 2025-08-07 18:47:02 +02:00
Florian Rival
902a30a9f8 Update capability user-friendly name and fix test
Don't show in changelog
2025-08-07 16:55:52 +02:00
Davy Hélard
63de997e60 Fix making object as global. 2025-08-06 19:42:52 +02:00
Davy Hélard
d2aa49fd1c Rename a type 2025-08-06 16:17:12 +02:00
Davy Hélard
d355c16bdf Fix wrong preview level. 2025-08-06 16:14:04 +02:00
Davy Hélard
8c7f5d1ea8 Remove log 2025-08-06 14:59:20 +02:00
Davy Hélard
08635de08e Avoid 2 previews to run at the same time for the editor. 2025-08-06 14:56:54 +02:00
Davy Hélard
4dc8676848 Fix flow 2025-08-06 14:19:33 +02:00
Davy Hélard
164a230cbc Fix key codes for redo and cut. 2025-08-06 12:01:54 +02:00
Davy Hélard
f3dc551284 Fix delete and redo. 2025-08-06 11:53:28 +02:00
Davy Hélard
ec674e85d6 Fix the side panel from switching to instance when a hot-reload happens 2025-08-06 10:26:35 +02:00
Davy Hélard
32f47900cd Fix Scene3DTools not being exported for empty projects. 2025-08-06 10:13:11 +02:00
Davy Hélard
320774c8d8 Fix forcing perspective in 3D editor. 2025-08-05 21:55:49 +02:00
Davy Hélard
1594f44a72 Make newIDE keep track of 3D editor cameras 2025-08-05 16:04:44 +02:00
Florian Rival
8669b94fb0 Improve project information sent to AI with the game resolution
Don't show in changelog
2025-08-05 14:29:58 +02:00
Florian Rival
7fb08aea62 Fix default light effects not added for scenes created by AI 2025-08-04 21:35:52 +02:00
Florian Rival
e7a1548b0e Fix default UI layer position for AI 2025-08-04 15:36:33 +02:00
Florian Rival
bdcb6f0533 Improve extension descriptions 2025-08-04 15:36:21 +02:00
Davy Hélard
726d3a8816 Update the camera of 2d layers. 2025-08-01 18:40:09 +02:00
Davy Hélard
097f13db42 Always export Three.js for the in-game editor. 2025-08-01 18:34:31 +02:00
github-actions[bot]
97849ce6f1 Update translations [skip ci] (#7760)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-08-01 18:05:51 +02:00
Clément Pasteau
d1c937caf4 Allow redeeming a code from the profile page directly (#7761) 2025-08-01 17:56:43 +02:00
Davy Hélard
15585c2007 Fix event tab were focused instead of scene tab 2025-08-01 16:46:56 +02:00
Davy Hélard
ca0a2c3215 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-08-01 16:18:49 +02:00
Florian Rival
5ffe6279a2 Fix warning 2025-08-01 16:08:28 +02:00
Clément Pasteau
9260e2b77a Improve bundle listing (#7759)
Do not show in changelog
2025-08-01 15:44:16 +02:00
D8H
593465e2ec Optimize event-function calls (#7758) 2025-08-01 15:19:26 +02:00
github-actions[bot]
8820350760 Update translations [skip ci] (#7756)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-08-01 14:12:21 +02:00
Florian Rival
7e1668229a Change how bundle price is calculated to avoid API calls (#7757) 2025-08-01 13:50:26 +02:00
D8H
387b96b9a0 Allow anchors to set the wrapping width of bitmap texts and BBCode texts (#7755) 2025-08-01 11:47:10 +02:00
Davy Hélard
d2820bdf2a Remove log. 2025-07-31 20:16:12 +02:00
Davy Hélard
947e5eb9a3 Fix object hot-reload when objects are added or removed. 2025-07-31 19:24:34 +02:00
Davy Hélard
5901e34f6d Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-07-31 17:56:31 +02:00
github-actions[bot]
5f52d786c6 Update translations [skip ci] (#7749)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-07-31 14:54:34 +02:00
Clément Pasteau
e0db597f9d A new Bundle to get started with GDevelop is now available (#7751)
* including multiple game templates and asset packs
* including a redemption code for a premium subscription
* including multiple official game dev courses
2025-07-31 14:18:05 +02:00
Davy Hélard
1c942d2f9d Fix 1st object of a type not appearing in the 3D editor. 2025-07-31 13:00:04 +02:00
Florian Rival
41b0315ec6 Improve rating banner for course chapters 2025-07-30 18:49:27 +02:00
Davy Hélard
b419bf8f35 Save the 2D editor camera position 2025-07-30 18:37:20 +02:00
Davy Hélard
7edfa1284a Fix object deletion 2025-07-30 16:27:10 +02:00
Davy Hélard
32e4006b2c Fix duplicate and paste 2025-07-30 15:56:28 +02:00
Davy Hélard
e773a1dbfc Fix object renaming. 2025-07-30 15:19:45 +02:00
Davy Hélard
3942214ba1 Make sure the 3D editor doesn't mess with the selection when disabled 2025-07-30 15:11:53 +02:00
Florian Rival
a930a4085e Add basic button to rate premium course chapter 2025-07-30 14:56:46 +02:00
Davy Hélard
461fc36401 Fix editor hot-reload no longer being triggered. 2025-07-30 11:12:24 +02:00
Florian Rival
d0dbbfac07 Add "StrReplaceOne" and "StrReplaceAll" expressions (#7750) 2025-07-30 10:10:29 +02:00
Davy Hélard
fa9198174e Fix the default object size. 2025-07-29 19:17:08 +02:00
Davy Hélard
96460d92d3 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-07-28 18:22:19 +02:00
Davy Hélard
e0d376c15b Handle background color changes. 2025-07-28 18:20:23 +02:00
Davy Hélard
46e0301dd0 Fix a crash when previewing a game. 2025-07-28 15:09:45 +02:00
Florian Rival
3dc24b46f4 Fix warning
Don't show in changelog
2025-07-28 13:54:12 +02:00
Florian Rival
8e44a357b4 Fix Android build and player authentication sometimes not working (#7748)
- Player authentication window could not open if no action/condition related to player authentication was used
- Fix Android build by using an updated dependency for opening the authentication window
2025-07-28 12:55:58 +02:00
Florian Rival
dd462310cc Reduce network requests at startup by lazily loading course chapters when opened 2025-07-26 16:37:38 +02:00
Florian Rival
a1935fa0cd Reduce a bit more unnecessary fetches for course chapters
Don't show in changelog
2025-07-26 14:38:54 +02:00
Florian Rival
b45c57246b Add animation names to inspected object properties for AI 2025-07-26 14:21:44 +02:00
Davy Hélard
14aa26c651 Fix hot-reload triggering to often. 2025-07-25 20:47:40 +02:00
Davy Hélard
ab59dfaa86 Remove useless code. 2025-07-25 19:39:15 +02:00
Davy Hélard
4841f46d95 Fix a mistake in previous commit. 2025-07-25 17:54:06 +02:00
Davy Hélard
faccc6a6f2 Handle copy and paste. 2025-07-25 17:41:04 +02:00
Florian Rival
c481ecd6b5 Bump newIDE version 2025-07-25 15:47:07 +02:00
github-actions[bot]
e0898dd9b0 Update translations [skip ci] (#7737)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-07-25 13:40:41 +02:00
Clément Pasteau
5561334efa Fix Send icon color (#7745) 2025-07-25 13:33:02 +02:00
Florian Rival
6c4bb4f79e Fix selection of face orientation in 3D Cube editor 2025-07-25 10:04:14 +02:00
Florian Rival
f336e76a86 Fix size of 2D/3D toggle on small screens 2025-07-24 23:56:17 +02:00
Florian Rival
811604d15a Fix pointer events to use the 3D editor 2025-07-24 19:09:27 +02:00
Davy Hélard
dd005941e9 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-07-24 18:16:29 +02:00
D8H
8b2d2e2fe7 Fix "edit children" drop-down menu item activation (#7744)
- don't show in changelog
2025-07-24 14:04:25 +02:00
Florian Rival
49d128c964 Display "Ask AI" as a separate pane (or drawer on small screens) (#7738) 2025-07-24 13:20:52 +02:00
D8H
f24d1e0916 Add a deprecation message for custom objects using old "configuration overriding" (#7742) 2025-07-24 13:19:23 +02:00
D8H
9faa4c0c69 Fix button labels not refreshing when modified from the side panel (#7741) 2025-07-24 10:32:48 +02:00
D8H
a04b8f65db Allow to select a custom object variant in the properties panel (#7740)
* Also show a dialog to duplicate a variant before opening them if necessary.
2025-07-23 17:26:03 +02:00
D8H
e1cf7d23cd Various fixes for variants (#7739)
- Forbid to edit the default variant of published extensions
- Hide the children configuration from the side panel when a variant is used
- Fix the Z-order of nested custom objects in the editor
- Fix a memory crash when updating an extension where behaviors must be removed from child-objects
2025-07-22 19:06:33 +02:00
github-actions[bot]
b74b221844 Update translations [skip ci] (#7730)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-07-22 11:43:45 +02:00
Clément Pasteau
38affc15b4 Fix making too many calls for courses (#7736)
Do not show in changelog
2025-07-22 11:43:21 +02:00
D8H
948488d92b [Top-down movement] Fix the legacy turning back mode (#7735) 2025-07-21 22:07:00 +02:00
Florian Rival
f5902d0346 Enable visibility of 3D cube backface by default 2025-07-21 10:52:41 +02:00
Davy Hélard
311381332f Remove logs 2025-07-18 20:29:08 +02:00
Davy Hélard
50173c4127 Avoid to log EDIT in the history when the selection change 2025-07-18 20:13:52 +02:00
Davy Hélard
e030adbb72 Handle undo and redo. 2025-07-18 18:20:41 +02:00
Davy Hélard
3762ccf639 Factorize a log. 2025-07-18 14:55:50 +02:00
Clément Pasteau
f28dc8e88a Fix images pixelated because of border (#7732)
Do not show in changelog
2025-07-18 14:37:06 +02:00
Davy Hélard
d2758400e0 Ensure no hot-reload is done in 2D mode.
Fix 3D editor not switching while in 2D mode.
2025-07-18 13:23:37 +02:00
Clément Pasteau
1f41749fa3 Fix carousel mobile (#7729)
Do not show in changelog
2025-07-17 15:49:36 +02:00
Davy Hélard
1551ec440e Hide the diagnostic report for the in-game editor. 2025-07-17 15:05:15 +02:00
Florian Rival
a4908a4d42 Add spell check option for text input (disabled by default) (#7728) 2025-07-17 14:39:30 +02:00
Davy Hélard
bd493e39e4 Update the 3D editor with changes done on instances with the 2D editor. 2025-07-17 14:01:23 +02:00
Davy Hélard
2fb663b63f Fix selection between 2D and 3D editors. 2025-07-17 12:03:06 +02:00
Davy Hélard
3878f35107 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-07-17 10:37:52 +02:00
Clément Pasteau
aa7754e658 Fixes responsive design and courses (#7726)
Do not show in changelog
2025-07-17 10:20:02 +02:00
github-actions[bot]
58ea9387aa Update extension translations [skip ci] (#7727)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-07-17 10:17:37 +02:00
github-actions[bot]
775266c974 Update translations [skip ci] (#7722)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-07-17 10:15:12 +02:00
Florian Rival
eb9794cd1f Bump newIDE version 2025-07-17 09:42:20 +02:00
Florian Rival
130732adde Refactor to make choice between chat or agent explicit
Don't show in changelog
2025-07-17 00:32:05 +02:00
Florian Rival
7a98e73d61 Fix AI not drawing properly multiple instances 2025-07-17 00:08:25 +02:00
D8H
1f26b72b4b Fix Physics3D from also creating a solid when the character behavior is re-activated (#7723) 2025-07-16 19:52:38 +02:00
D8H
a15ffb5b47 Add missing onSceneObjectsDeleted for custom object tabs (#7724) 2025-07-16 19:51:41 +02:00
Florian Rival
1a5f72283a Update price tag design 2025-07-16 18:36:25 +02:00
github-actions[bot]
0460b283ba Update translations [skip ci] (#7703)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-07-16 12:08:11 +02:00
Yaroslav Nazarenko
e212e7c780 Add an action to join a specific lobby using its identifier, and an expression to get the current lobby ID (#7694) 2025-07-16 12:07:32 +02:00
Clément Pasteau
84100fc7cf Introducing a new Learn page (#7705)
* The Get Started page has been removed and replaced by the Learn page as the first page displayed when GDevelop launches
  * The Learn page has been completely reworked to put forward the different resources a creator can use to improve their skills with Game Creation
  * A new option in the Preferences allows users to define the Create page as the default first page on launch
* Courses can now be purchased as a whole instead of per chapter, making it simpler to follow a full course
  * Bundles with multiple courses are coming up soon!
2025-07-16 11:59:56 +02:00
D8H
11a8682b07 Fix a crash of the scene editor when a custom object extension is updated (#7720) 2025-07-16 11:40:28 +02:00
Florian Rival
d3a0bbdfb1 Disable autorun of npm start when opening VSCode [skip ci] [ci skip] (#7719)
Only show in developer changelog
2025-07-16 10:56:09 +02:00
D8H
15f3a45d6a Fix 3D impulse and force toward a point actions (#7716) 2025-07-15 15:27:31 +02:00
D8H
f0a4f352cc Fix effect default values (#7706) 2025-07-15 13:56:20 +02:00
D8H
d16b3e8154 Fix multiplayer synchronization of custom object positions (#7715)
---------

Co-authored-by: Clément Pasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-07-15 13:38:23 +02:00
D8H
614fb97288 Fix 3D physics behaviors activation and deactivation (#7710) 2025-07-15 13:35:54 +02:00
D8H
8a40d3645a Fix the check box to stop sounds at scene start up not being applied properly (#7714) 2025-07-15 10:38:18 +02:00
D8H
2b7dadf2a8 Fix text input displayed position when inside a custom object whose layer is moved (#7713) 2025-07-14 17:47:44 +02:00
D8H
c338e16e4f Fix the "cursor is on" condition when used on custom object parent object (#7712) 2025-07-14 17:46:11 +02:00
Florian Rival
aded08471d Adapt sentences displaying free AI requests
Don't show in changelog
2025-07-13 19:40:10 +02:00
Florian Rival
cccb59b1c5 Fix AI agent not working with games with a lot of extensions or that were too big 2025-07-12 16:50:38 +02:00
Davy Hélard
e055c0edbf Remove some todo. 2025-07-11 19:43:14 +02:00
Davy Hélard
a02afc4c68 Fix resource reload. 2025-07-11 19:41:28 +02:00
Davy Hélard
30130df6fb Factorize 2025-07-11 17:45:56 +02:00
Davy Hélard
400cd2e22c Use a hard-reload to update asset content. 2025-07-11 17:29:07 +02:00
Davy Hélard
dc25a0e87f Remove a log 2025-07-11 14:29:15 +02:00
Davy Hélard
d21abd97a7 Allow to reload resources on hot-reload. 2025-07-11 14:14:15 +02:00
Davy Hélard
bd38eaf924 Handle all free camera keys for the switch. 2025-07-10 13:07:12 +02:00
Davy Hélard
360e98b3ee Fix to allow to reset to default size. 2025-07-10 12:45:16 +02:00
D8H
3592fb7e62 Fix hemisphere light orientation when the top is set on Z+ (#7708) 2025-07-10 12:09:18 +02:00
Davy Hélard
e03908da83 Fix update of instances without custom size. 2025-07-09 18:47:02 +02:00
Florian Rival
64e7afea7c Fix 2d/3d toggle way too large on large screens 2025-07-09 16:46:00 +02:00
D8H
307c92991c Fix shadow casting and receiving that were inverted for 3D boxes (#7704) 2025-07-09 13:43:01 +02:00
Davy Hélard
13077f7ce8 Fix hot-reload when an effect type is changed. 2025-07-09 10:37:33 +02:00
Davy Hélard
ef68f4e7f6 Refactor camera handling. 2025-07-08 17:17:06 +02:00
Florian Rival
eaeef23bc6 Fix warning 2025-07-08 16:13:22 +02:00
Florian Rival
5a3b12a257 Ensure keys are not stuck when losing focus during in-game edition 2025-07-08 15:47:19 +02:00
Davy Hélard
794b74a90c Trigger an hot-reload when an effect is added. 2025-07-08 13:15:40 +02:00
Florian Rival
ac4a500fff Hard reload the in-game edition in case the connection to the editor is lost 2025-07-08 11:15:12 +02:00
Florian Rival
4b3f077669 Bump newIDE version 2025-07-08 10:59:24 +02:00
github-actions[bot]
352bae518e Update translations [skip ci] (#7689)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-07-08 10:58:42 +02:00
Florian Rival
13a5939550 Add proper toggle between classic and 3d, real-time editor 2025-07-07 23:47:02 +02:00
Florian Rival
e560f0f08b Fix resizing/dragging of panels and set transparent background only for the 3D editor 2025-07-07 22:48:55 +02:00
Davy Hélard
3894720a93 Fix some original size implementation. 2025-07-07 17:19:02 +02:00
Davy Hélard
2a89b95510 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-07-07 16:16:27 +02:00
Florian Rival
e8e4bf07df Add checkbox to switch between editors
Also ensure custom object custom size is not reset.
TODO: getOriginalWidth and similar must be added on all objects

Fix crash because of deleted initalVariables in instance data
2025-07-07 15:58:53 +02:00
D8H
c958f4d522 Fix directional light orientation and missing settings in the 3D cube editor (#7701) 2025-07-07 15:10:11 +02:00
D8H
35bbb37ad2 Fix hot-reloading of custom objects (#7698) 2025-07-07 08:37:08 +02:00
D8H
1d48acc841 Fix custom objects being destroyed too soon (#7695) 2025-07-07 08:27:00 +02:00
Florian Rival
87702edccc Show an highlight on newly generated AI events to make it easier to find them (#7696) 2025-07-06 19:20:41 +02:00
Florian Rival
1f0ba7c19a Update package.json 2025-07-04 16:45:43 +02:00
Florian Rival
b4d08a99ad Add setting to customize shadow bias 2025-07-04 16:44:55 +02:00
Davy Hélard
4d3b98f78b Fix camera dragging and rectangle selection conflict. 2025-07-04 15:16:26 +02:00
Florian Rival
8acaa06e42 Fix formatting [ci skip] [skip ci]
Don't show in changelog
2025-07-04 14:11:13 +02:00
Florian Rival
27ee85b5d4 Add shadow biais to avoid shadow acne
Don't show in changelog
2025-07-04 12:48:38 +02:00
Arthur Pacaud (arthuro555)
bbe2d1854e Update "Pick all instances" to avoid crashes when a lot of objects are picked (#7439) 2025-07-03 23:29:44 +02:00
Davy Hélard
42ee73b046 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-07-03 18:08:27 +02:00
Florian Rival
d338690ff5 Fix loading of 3D resources
This was a regresssion since the refactoring to allow unloading resources

Don't show in changelog
2025-07-03 17:56:30 +02:00
Florian Rival
571a6d8c1a Fix directional light settings not applied when scene starts
Don't show in changelog
2025-07-03 15:33:06 +02:00
Florian Rival
ddb5157c0a Bump newIDE version 2025-07-03 13:53:29 +02:00
Florian Rival
64f01354bc Fix formatting 2025-07-03 13:50:16 +02:00
Florian Rival
37fd99e542 Add user friendly labels to select fields in object and effect properties 2025-07-03 13:09:43 +02:00
Florian Rival
23be4a5849 Update shadow quality choices to be lowercase
Don't show in changelog
2025-07-03 12:34:57 +02:00
github-actions[bot]
64c0ee8f98 Update translations [skip ci] (#7683)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-07-03 12:23:19 +02:00
Davy Hélard
0a5df21c1b Fix an merge issue. 2025-07-02 17:27:48 +02:00
Davy Hélard
b0ea0c262b Fix an exception in 2D projects. 2025-07-02 16:56:02 +02:00
D8H
e5ecce3abf [Platformer] Fix wrongly allowed double jump when jumping from a slope (#7687) 2025-07-02 16:48:38 +02:00
Davy Hélard
ffa9c45692 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-07-02 16:19:14 +02:00
Davy Hélard
15f6f16d22 Fix missing hot-reload when extracting a layout 2025-07-02 16:18:44 +02:00
ViktorVovk
5c71a4da56 Allow to unload scene resources when a scene is exited (#7381)
* This adds two new settings, available in the Project Properties and in the Scene Properties dialog, to allow to specify the strategy for preloading resources of the scenes and unloading them. By default, a game will preload in background the resources of all scenes. It will never unload these resources (so scene switching is fast).
* You can now choose to unload the resources of a scene when the scene is left using the "Resources unloading" field. If the scene is launched again later, it will load its resources again.
* You can also choose to change the preloading to disable it for all scenes (by modifying the setting in the project properties) or enable it/disable it on a scene by scene basis. This can be useful for large or modular games where you anticipate the player to only play some scenes, or if you want to reduce the resources that needs to be loaded on a web game.
2025-07-02 16:09:52 +02:00
Neyl
dff99b79cb Add basic support for shadows (#7592)
* Shadows are rendered for 3D objects when a **Directional Light** is set up on your scene layer - which is now the case by default for new games and new layers: they will have both a Directional Light and an Ambient Light. This renders shadows like it could be done by the sun.
* 3D models and 3D cubes are now casting shadows. To see them, you must ensure you the "Standard" material type in their configuration (and not the "Basic", which means they don't react to light) and be sure to enable "Shadow casting" and "Shadow receiving". This is done by default for new objects you create or import from the Asset Store.
* Shadows are rendered around the camera on an area that is large enough for most games while giving still good quality results. This means they should work out of the box and be adapted to most games, including large maps. 
  You can adapt the quality of shadows, intensity of the light (and so shadows), the size of the rendered area by editing the Effects of the layer in the scene (as for other effects).
2025-07-02 15:49:26 +02:00
github-actions[bot]
5fe46ea8ea Update extension translations [skip ci] (#7682)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-07-02 11:50:59 +02:00
Clément Pasteau
4a590adac4 Add new marketing specialization course (#7684) 2025-07-02 11:50:27 +02:00
Davy Hélard
c3240b6767 Avoid to interrupt users with hot-reload too often 2025-07-01 19:33:56 +02:00
Clément Pasteau
279d41cdb7 Fix resource selector text color on light theme (#7681) 2025-07-01 14:58:50 +02:00
Davy Hélard
2f7fe905b8 Fix hot-reload when installing an extension and the focused tab is not a graphical editor. 2025-07-01 14:58:46 +02:00
github-actions[bot]
5cf65a9f62 Update translations [skip ci] (#7675)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-07-01 14:58:24 +02:00
Davy Hélard
0de1d42d73 Fix hot-reload when adding a new object. 2025-07-01 12:25:44 +02:00
Davy Hélard
c4c8931c73 Add a toggle to disable layer effects. 2025-06-30 19:38:59 +02:00
D8H
08b05c13b6 Fix a crash when using the "Fixed rotation" action on a 3D character (#7680) 2025-06-30 15:24:14 +02:00
Aurélien Vivet
eb55c85f4e Fix "Wheel offset Z" and "Front wheel drive" properties of the 3D car behavior (#7678) 2025-06-30 15:23:41 +02:00
Florian Rival
8a243440db Improve some mathematical tools descriptions 2025-06-29 14:25:36 +02:00
Florian Rival
b3e4e6b89c Fix missing MassCenterZ expression for the 3D physics behavior 2025-06-28 16:35:37 +02:00
Davy Hélard
1c9eb654ce Allow to duplicate the selection with Ctrl + draggging. 2025-06-27 19:06:27 +02:00
Davy Hélard
ee5b55cfbb Fix selected instances being updated continuously. 2025-06-27 18:10:30 +02:00
Davy Hélard
7e121526ca Drag all the selection. 2025-06-27 17:26:56 +02:00
Davy Hélard
79dfec1feb Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-06-27 14:06:28 +02:00
Davy Hélard
d30a278b97 Handle instance lock. 2025-06-27 14:05:36 +02:00
Davy Hélard
5ae9e80987 Avoid to move the camera when saving. 2025-06-26 18:38:07 +02:00
Davy Hélard
245fb1b3ab Force orthographic camera type. 2025-06-26 18:32:10 +02:00
Davy Hélard
bedf8a48a2 Fix hard-reload 2025-06-26 17:58:44 +02:00
Davy Hélard
3c77c9e2d8 Avoid some crashes on 2D projects. 2025-06-26 16:46:03 +02:00
Davy Hélard
92ba2c3111 Fix a crash when creating a new EBO 2025-06-26 15:18:13 +02:00
Florian Rival
a1a25f6df4 Bump newIDE version 2025-06-26 13:46:07 +02:00
Aurélien Vivet
6114a6cec1 Update the Create action with information about object picking (#7673) 2025-06-26 12:32:20 +02:00
github-actions[bot]
5058964937 Update translations [skip ci] (#7672)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-06-26 12:32:02 +02:00
Florian Rival
4488675540 Fix tutorials not always showing the element to scroll to for behaviors or extensions 2025-06-26 11:25:38 +02:00
D8H
6a2d2c9e67 Hide the behavior update dialog during in-app tutorial (#7674) 2025-06-26 11:02:55 +02:00
Florian Rival
b43c42d763 Fix broken tutorials 2025-06-25 18:50:58 +02:00
Davy Hélard
3ea754bba2 Display the selection rectangle. 2025-06-25 18:15:38 +02:00
Davy Hélard
a3429fb687 Add some TODO 2025-06-25 17:03:41 +02:00
Davy Hélard
476a107c46 Fix instance disappearing when changing of tab if they were added after an asset installation 2025-06-25 12:48:40 +02:00
github-actions[bot]
69112183d4 Update translations [skip ci] (#7665)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-06-24 18:50:23 +02:00
Davy Hélard
f98d28bee2 Round positions 2025-06-24 16:38:04 +02:00
Davy Hélard
df5ee8732a Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-06-24 16:31:45 +02:00
Florian Rival
a4c2778b8d Fix keyboard avoidance on touchscreens for Ask AI tab (#7670)
* Fix keyboard avoidance on touchscreens for Ask AI tab
* Add placementId for in-app analytics

Don't show in changelog
2025-06-24 15:43:08 +02:00
D8H
f26e56c3bf Fix resource not loading when a custom object has both a variant and children overriding (#7668)
Don't show in changelog
2025-06-24 14:25:58 +02:00
Florian Rival
f5f9944fc4 Upgade m4pro.medium and XCode for CircleCI macOS build (#7669)
* This reduces total build time by ~40%.
2025-06-24 11:45:29 +02:00
D8H
9467caf1e9 Fix changing of variant not being applied at hot-reload (#7666) 2025-06-24 10:41:57 +02:00
Florian Rival
00376f39d5 Fix formatting and macOS CI build uploads
Don't show in changelog
2025-06-24 09:47:54 +02:00
Florian Rival
40b6a34dc5 Improve AI agent style
Don't show in changelog
2025-06-24 01:18:03 +02:00
Florian Rival
17d2b8c2c2 Improve the style of the text input for the AI agent/chat
Don't show in changelog
2025-06-23 23:41:29 +02:00
Florian Rival
935af42d23 Fix error when positioning instances in the AI agent
+ tentative fix for failing upload of macOS builds on the CI

Don't show in changelog
2025-06-23 20:05:26 +02:00
Florian Rival
d4a8d468cb Improve AI scene instance creation (#7667) 2025-06-23 18:52:39 +02:00
Davy Hélard
bd500f5a90 Fix changing of variant not being applied at hot-reload 2025-06-23 18:09:26 +02:00
Davy Hélard
536518f4bb Fix hot-reload of custom objects 2025-06-23 16:19:57 +02:00
Florian Rival
b16099aee0 Bump newIDE version 2025-06-23 12:51:33 +02:00
Davy Hélard
7e11936fee Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-06-23 10:48:55 +02:00
github-actions[bot]
c17b918a43 Update translations [skip ci] (#7663)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-06-23 09:42:28 +02:00
D8H
d58e8c7ef9 Fix hot-reload when custom objects are in an external layout (#7664) 2025-06-21 13:51:37 +02:00
Davy Hélard
b0da0508e1 Format 2025-06-21 13:10:35 +02:00
Davy Hélard
48cc5a27f6 Fix hot-reload when custom objects are in an external layout. 2025-06-21 13:02:08 +02:00
Davy Hélard
d470513f84 Make sure camera tools are exported when there are 3D objects 2025-06-21 13:00:49 +02:00
Florian Rival
ddd6b6e3a8 Open a new AI chat when clicking on button to try the AI agent 2025-06-21 12:22:54 +02:00
Florian Rival
e629c132ea Improve opening of scene and events tab for AI
Don't show in changelog
2025-06-20 18:01:44 +02:00
github-actions[bot]
b80e03f153 Update translations [skip ci] (#7660)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-06-20 15:46:09 +02:00
Florian Rival
11e36ff3f1 Fix CI not failing if macOS build upload failed 2025-06-20 15:16:03 +02:00
Davy Hélard
baaeb4317f Disable the nagging screen for in-game editor hot-reload. 2025-06-20 14:46:15 +02:00
Davy Hélard
40156c5e74 Trigger an full data hot-reload when assets are installed. 2025-06-20 14:10:28 +02:00
Florian Rival
22de356413 Improve animation names support for AI and add retry for macOS build deployment
Don't show in changelog
2025-06-20 12:56:46 +02:00
Florian Rival
caefa04fbe Give AI the names of the animations of animatable objects
Don't show in changelog
2025-06-20 11:53:13 +02:00
Florian Rival
cf2e7d67d7 Improve robustness of AI event generation
Don't show in changelog
2025-06-20 11:34:12 +02:00
Davy Hélard
da0a47b487 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-06-20 11:10:46 +02:00
D8H
685e444b2d Comply variants when an extension is updated for an asset (#7661)
- Don't show in changelog
2025-06-20 10:31:42 +02:00
Davy Hélard
ee12b0b372 Hot-reload events when an EBO is installed or updated. 2025-06-19 19:08:32 +02:00
Davy Hélard
31f7ec3a17 Comply variants when an extension is updated. 2025-06-19 19:06:59 +02:00
Davy Hélard
3ec7617b14 Load resources for custom object tabs. 2025-06-19 14:50:58 +02:00
Florian Rival
a9c1045afd Avoid extra scrollbar in dialog to create a project with AI
Don't show in changelog
2025-06-18 14:56:48 +02:00
Davy Hélard
69e9eebd8e Trigger an full data hot-reload when a resource is changed in an object 2025-06-18 14:39:35 +02:00
Florian Rival
24e0d37583 Improve draggable behavior condition descriptions 2025-06-18 12:56:38 +02:00
Florian Rival
d44997d372 Fix AI agent unable to change boolean properties 2025-06-18 00:09:45 +02:00
Florian Rival
062aa888f8 Disable AI agent chat when started for another project
Don't show in changelog
2025-06-17 18:07:26 +02:00
github-actions[bot]
de4c2ae4ad Update translations (#7633)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-06-17 17:24:50 +02:00
Florian Rival
29ad7308c3 Introduce an experimental AI agent (#7659)
- This is an AI agent that takes a request and takes actions on a project: it can create scenes, find and create objects, add, remove behaviors, modify them, put instances on the scene, create or modify events, and more to come (layers, setup leaderboards, etc...).
- It's still in beta and there is room for improvement on many things, but is already useful for prototyping and learning - beginners notably are able to see what the AI can do and learn the concepts of GDevelop. For intermediate and power users, it's useful to try new things, or get things done while working on something else.
- Experiment with it and always make backup of your project before starting - in the future restoration points will be added to go back to a previous state if the result is not good or broken.
2025-06-17 16:25:03 +02:00
Davy Hélard
268af00ce8 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-06-17 10:54:35 +02:00
D8H
19b21c280e Fix a case where neither the variant nor the children are shown in the object editor (#7658)
- Don't show in changelog
2025-06-16 19:06:55 +02:00
Florian Rival
fbfe8b246a Fix broken scroll to current search result in the Events Sheet
Don't show in changelog
2025-06-15 20:51:42 +02:00
Davy Hélard
ad748e4ed5 Allow to drag an object on top of another one. 2025-06-13 17:28:35 +02:00
Davy Hélard
f933736f1f Fix inner area not being cleared on tab change. 2025-06-13 14:07:32 +02:00
Davy Hélard
89861de544 Fix selection in custom object editor. 2025-06-13 14:00:58 +02:00
Davy Hélard
d503fff76b Display the inner area of custom objects. 2025-06-13 13:00:17 +02:00
Davy Hélard
e8dc9e3b20 Fix variant tabs. 2025-06-12 18:35:22 +02:00
Davy Hélard
e40cdfca95 Restore camera location when changing of tab. 2025-06-12 17:34:34 +02:00
Davy Hélard
e357fca9c0 Fix selection 2025-06-12 16:57:51 +02:00
Davy Hélard
6b4f022157 Handle locked layers. 2025-06-12 16:28:01 +02:00
Florian Rival
73f66eb51f Fix flickering when switching between events editors (#7655)
- Thanks @necaTecnico for the investigation and first version of the fix
2025-06-12 15:47:13 +02:00
Florian Rival
d62ba2b9a0 Make the button to add an object more visible 2025-06-12 15:11:53 +02:00
Davy Hélard
29c276d061 Add new instance to the selected layer. 2025-06-12 13:51:35 +02:00
Davy Hélard
b28eec1071 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-06-12 11:24:45 +02:00
D8H
323a2b6c2f [Top-down movement] Revert the modes (#7654) 2025-06-12 11:23:58 +02:00
D8H
8e4cccd562 Notice about extension breaking changes when installing assets (#7640)
- Add a pop-up to suggest to update behavior when attaching one to an object
- Keep the "community" label and the info button on installed extensions
2025-06-11 18:08:57 +02:00
D8H
795795ba40 Remove unused imports (#7651) 2025-06-11 14:08:54 +02:00
D8H
4af86b36e5 [Top-down movement] Turn back at least as fast as it decelerate (#7649)
- Add a new property that allows to choose between 3 modes
  - "Sharp turn with smooth turn back" which is what you are used to
  - "Sharp turn" which is more responsive
  - "Smooth turn" which keeps inertia
- Turn back at least as fast as it decelerate
  - You need to go in advanced and deprecated sections and uncheck the property to enable this in existing projects.
- Make analog stick controls more responsive
2025-06-11 11:11:59 +02:00
D8H
b00632a625 Remove big buttons to add objects and groups (#7650) 2025-06-11 10:25:57 +02:00
D8H
6f23f76441 [Platformer] Forbid repeated jumps while holding the jump key (#7648) 2025-06-09 19:14:49 +02:00
D8H
a6cd4b3c5d Fix missing behavior shared properties for global objects (#7647) 2025-06-09 13:37:23 +02:00
D8H
81d63c41b6 Fix panel sprite disappearing when left or top border is 0 (#7646)
- Don't show in changelog
2025-06-09 11:06:59 +02:00
Florian Rival
a924840228 Fix local variables sometimes briefly shown as invalid in the Events Sheet 2025-06-09 10:51:11 +02:00
Florian Rival
b013297c8e Fix events rendering regression (some sub-events not visible when expanded)
Don't shown in changelog
2025-06-09 10:00:23 +02:00
Florian Rival
ca77a31037 Use a CDN and updated endpoints to load the list of examples
Only show in developer changelog
2025-06-06 17:06:35 +02:00
Florian Rival
5adb2240d5 Use a CDN and updated endpoints to load extensions and behaviors (#7644)
Only show in developer changelog
2025-06-06 13:59:52 +02:00
D8H
9d42be3362 Fix panel sprite rendering when the size is smaller than margins (#7643)
* The borders will be shrunk proportionally to their size.
2025-06-06 13:59:02 +02:00
Dima Lifanchuk
21201dec29 Extract playback sound logic in separate methods (#7641)
Only show in developer changelog
2025-06-05 17:52:16 +02:00
Aurélien Vivet
08229cbe1d Fix typo (#7639) 2025-06-05 15:07:04 +02:00
Florian Rival
96e9dd7c4b Update Tween description
Don't show in changelog
2025-06-04 19:46:14 +02:00
Aurélien Vivet
7dbc687200 Fix spacing in the documentation (#7638)
Don't show in changelog
2025-06-04 17:30:22 +02:00
Florian Rival
7e1f2c6c97 Add support search (and replace) in Link events (#7637) 2025-06-04 16:42:26 +02:00
Aurélien Vivet
37cba12e4a Add a mention in the reference pages of extensions telling no installation is required (#7635) 2025-06-04 15:35:49 +02:00
Florian Rival
cdd80bca9e Build and sign the Windows build with CircleCI (#7630)
* Code signing is somehow broken on AppVeyor. Keep AppVeyor in case it works again (but deployment is disabled)
* Use a "medium" worker for Windows as it's long a few minutes longer than "large" and 3x less expensive.
2025-06-03 19:40:08 +02:00
Florian Rival
3293d24c36 Remove roundtrip to the API by using CDN directly for public assets 2025-06-03 15:43:55 +02:00
Florian Rival
bf31781d7a Lazily load subscription plans to reduce requests at startup (#7631) 2025-06-03 14:16:02 +02:00
Florian Rival
f6c43b2db3 Improve description of the 2D particle emitter 2025-05-30 17:17:57 +02:00
Florian Rival
f00156a654 Improve "Destroy Outside" behavior descriptions 2025-05-30 16:52:17 +02:00
Florian Rival
41fd1cbcee Make Events Sheet more robust against changes in events made outside of the tab (#7625)
Only show in developer changelog
2025-05-29 18:17:14 +02:00
Florian Rival
52c807d74a Use separately built GDevelop.js for Windows and Linux builds (#7627)
Only show in developer changelog
2025-05-28 18:51:10 +02:00
D8H
8713a496b4 Declare the assets dimensions according to their variants in exported GDO (#7623) 2025-05-27 19:30:25 +02:00
Clément Pasteau
a3033f2db1 Update badge link to suggest opening profile after first click (#7624) 2025-05-27 10:59:57 +02:00
Florian Rival
5fb8faffc1 Improve Particle emitter description
Don't show in changelog
2025-05-25 17:02:02 +02:00
Davy Hélard
c3c774579d Fix free camera vertical rotation. 2025-05-23 16:11:32 +02:00
Davy Hélard
193977d6d2 Move zoom functions next to each other. 2025-05-23 15:36:08 +02:00
Davy Hélard
931bb10edb Automatically toggle in orbit mode when a zoom action is used. 2025-05-23 15:34:15 +02:00
Davy Hélard
408b9c151c Allow to toggle between free camera or orbit. 2025-05-22 20:17:09 +02:00
Clément Pasteau
a883955703 Add the Premium course to the Education curriculum (#7619) 2025-05-22 15:38:29 +02:00
Davy Hélard
bd96a63087 Filter messages according to the editorId. 2025-05-21 13:39:00 +02:00
Davy Hélard
dd5eb3b96f Format and type 2025-05-21 11:07:31 +02:00
Davy Hélard
cd46428b81 Show a box at hovering. 2025-05-20 19:16:59 +02:00
Davy Hélard
29926f057e Handle rectangular selection (without displaying the rectangle yet) 2025-05-20 17:30:29 +02:00
Clément Pasteau
b39d7adcbc Fix displaying Teach tab if no members (#7617)
Do not show in changelog
2025-05-20 17:19:24 +02:00
Davy Hélard
5444896b76 Fix tabs unregistration. 2025-05-19 17:42:32 +02:00
Davy Hélard
4adb7295bd Update InstanceData to avoid old data to override new ones when changing of tab. 2025-05-19 14:44:06 +02:00
github-actions[bot]
c577c8db71 Update extension translations [skip ci] (#7615)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-05-16 15:53:02 +02:00
Davy Hélard
2edd127d68 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-05-16 10:47:40 +02:00
Clément Pasteau
d7d17400dd Fix error accessing deleted objects after an object is deleted from a scene (#7612) 2025-05-15 18:18:09 +02:00
D8H
b219d50fd8 Fix a typo in the "hand brake" action (#7613)
- Don't show in changelog
2025-05-15 16:48:30 +02:00
Clément Pasteau
88f318e6df Bump to 5.5.231 (#7610)
Do not show in changelog
2025-05-15 11:03:54 +02:00
github-actions[bot]
d12ac44b7d Update translations [skip ci] (#7611)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-05-15 11:03:32 +02:00
Clément Pasteau
7155eea716 Show gd.games homepage on play section by default on mobile (#7609) 2025-05-15 10:46:49 +02:00
github-actions[bot]
ca0796f131 Update translations [skip ci] (#7595)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-05-15 10:35:56 +02:00
Clément Pasteau
c4b33e2481 Prevent continuing to use GDevelop if not all extensions have been loaded (#7608)
* GDevelop sometimes has faulty updates, for instance when the computer is shut down during an update. This was causing the app to be incomplete and projects to become corrupted after a save (ex: BBText objects being broken)
* This check shows an unskippable dialog suggesting a re-install of GDevelop
2025-05-15 10:15:42 +02:00
Davy Hélard
eb45ed8b9a Avoid to create objects where they can't be seen. 2025-05-14 21:03:20 +02:00
Davy Hélard
3a81c76741 Keep layer and object changes when switching of tabs. 2025-05-14 17:13:01 +02:00
Davy Hélard
14e2a6236a Keep the selection when switching of tabs. 2025-05-14 16:13:35 +02:00
D8H
ff95564b6b Add new 3D physics-based vehicle behavior (#7479)
* You can now simulate realistic 3D cars using the new Vehicle behavior powered by the 3D physics engine.
* Advanced details can be customized: from wheel setup and gear ratios to engine torque, steering, brakes, anti-roll bars, and drivetrain (front/rear).
* The default setup offers a semi-realistic, arcade-style driving feel. For smoother gameplay, explore the example projects to see how fine-tuning makes a big difference.
* Jolt physics engine was upgraded to version 0.34.0.
2025-05-14 10:52:47 +02:00
Clément Pasteau
cecf1ab791 Fix crash when selecting a resource after switching tabs in the Resource selection dialog (#7607) 2025-05-14 10:28:12 +02:00
Davy Hélard
1ea065dec6 Fix registration to previewDebuggerServer when a new tab is open. 2025-05-13 15:20:19 +02:00
Davy Hélard
db42bbef62 Better margin for zoom to fit. 2025-05-13 12:40:52 +02:00
Davy Hélard
bd0b610a90 Avoid the in-game editor to crash on 2D projects. 2025-05-13 12:34:26 +02:00
Davy Hélard
f46213ce6e Fix onEditorHidden when another project is open. 2025-05-13 12:17:12 +02:00
Davy Hélard
0909e1d5fe Fix zoom to objects 2025-05-13 12:17:12 +02:00
Davy Hélard
95c15b2edb Fix camera jumps when starting to drag. 2025-05-12 18:49:04 +02:00
Davy Hélard
e48115336d Fix flow 2025-05-12 18:32:45 +02:00
Davy Hélard
daa957fa7b Fix drop-down menu no showing up when several tabs are open. 2025-05-12 18:20:38 +02:00
D8H
a571445e0e Allow custom objects to self-destruct (#7605) 2025-05-12 14:03:21 +02:00
Davy Hélard
3d5a997633 Merge remote-tracking branch 'official/master' into test6 2025-05-12 12:31:44 +02:00
Davy Hélard
ca15d0316d Handle duplication, deletion and cutting. 2025-05-12 12:25:19 +02:00
Davy Hélard
96a9c28e44 Handle copy and paste. 2025-05-12 12:25:19 +02:00
D8H
006f8b1900 Fix grid snapping of pasted instances (#7602) 2025-05-12 12:24:55 +02:00
D8H
89e418cd24 Fix grid snapping of pasted instances (#7602) 2025-05-12 11:41:42 +02:00
Florian Rival
896ccfcffa Add hint that mapper behaviors should be used for platformer (#7601)
Don't show in changelog
2025-05-12 10:51:09 +02:00
Clément Pasteau
d98d181755 Fix typo (#7604)
Do not show in changelog
2025-05-12 10:30:08 +02:00
Florian Rival
3c63f9b617 Update 3D extension internal descriptions
Only show in developer changelog
2025-05-08 12:26:54 +02:00
Davy Hélard
d576b3ede8 Remove logs. 2025-05-07 17:03:44 +02:00
Davy Hélard
195664ee09 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-05-07 16:23:58 +02:00
Davy Hélard
bf85daf354 Fix the instance position sent to the instance property editor. 2025-05-07 16:22:35 +02:00
Davy Hélard
d3192734a1 Fix the default dimensions in the instance property editor. 2025-05-07 16:20:58 +02:00
Davy Hélard
16f5ecdd0b Remove logs. 2025-05-07 15:35:17 +02:00
D8H
8312bbe4f8 Fix 3D Physics "apply force/impulse toward position" action (#7600) 2025-05-06 21:04:02 +02:00
Davy Hélard
b17fa8e9ae Use native resolution and show the drop-down menu. 2025-05-06 18:36:47 +02:00
Davy Hélard
88bcd797e9 Fix object hot-reload for external layouts and custom objects. 2025-05-06 14:45:49 +02:00
Davy Hélard
577d605b87 Plug fast hot-reload for layers. 2025-05-06 14:25:58 +02:00
Davy Hélard
a5e29a7f14 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-05-06 10:46:48 +02:00
Clément Pasteau
bb77a71f26 Bump to 5.5.230 (#7593)
Do not show in changelog
2025-05-06 10:10:48 +02:00
D8H
4353469554 Fix bitmap text alignment and rotation (#7597)
* Fix BBText rotation
2025-05-05 20:10:21 +02:00
Clément Pasteau
46ea431f62 Fix firebase tests (#7594)
Do not show in changelog
2025-05-05 15:16:39 +02:00
github-actions[bot]
2d29d43355 Update translations [skip ci] (#7577)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-05-05 11:22:08 +02:00
Davy Hélard
7f27526c7c Handle select all instances 2025-05-05 10:43:20 +02:00
Clément Pasteau
28a4e253a1 Update desktop & web icons with latest GDevelop branding (#7578) 2025-05-05 10:22:40 +02:00
Davy Hélard
f3adb4e876 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-05-05 09:57:43 +02:00
D8H
f3dcb8eec8 Fix asset export for objects with unused children overriding (#7590) 2025-05-05 09:53:11 +02:00
Florian Rival
bf9e38ff31 Improve descriptions of boolean logic conditions
Only show in developer changelog
2025-05-04 16:08:36 +02:00
Davy Hélard
c571a65a32 Handle the instance list selection. 2025-05-02 18:11:19 +02:00
Davy Hélard
55f38231a9 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-05-02 14:16:32 +02:00
D8H
87649b9def Ensure variants downloaded from the store comply to their events-based object (#7587) 2025-05-02 12:51:58 +02:00
D8H
60d332e872 Fix rendered custom objects in the editor with an overriding of children configuration (#7585)
- Fix children overriding to only apply to the default variant at runtime
2025-05-02 12:51:14 +02:00
D8H
bdab12b1e6 Fix variant edition: forbid to edit variants from the store (they should be duplicated instead) (#7586) 2025-05-02 12:05:49 +02:00
Davy Hélard
6a2e37d147 Handle zoom commands. 2025-05-01 17:16:44 +02:00
Davy Hélard
f6ec9634ce Allow to unselect objects. 2025-04-30 11:29:54 +02:00
Davy Hélard
eedb030619 Format 2025-04-30 11:28:29 +02:00
Davy Hélard
c828c2cace Allow custom objects 3D edition. 2025-04-29 18:19:12 +02:00
Davy Hélard
b4188893a0 Display the content of custom object editors. 2025-04-29 14:17:07 +02:00
Florian Rival
02f795f2c1 Update AI requests wording 2025-04-29 09:52:19 +02:00
AlexandreS
6e64d8521f Submit ai question with Ctrl+Enter or Go to button of mobile soft keyboard (#7579)
Don't show in changelog
2025-04-28 18:51:39 +02:00
Clément Pasteau
0e9aea1c9d Fix showing Checkered background on sprite project resources (#7580)
Do not show in changelog
2025-04-28 18:31:24 +02:00
Davy Hélard
8ea26ec148 Enable interaction for external layouts. 2025-04-28 12:31:37 +02:00
Clément Pasteau
99901bf539 Bump newIDE version (#7576) 2025-04-28 12:07:23 +02:00
Davy Hélard
bf73e430f8 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-04-28 11:17:26 +02:00
github-actions[bot]
53f1d745f5 Update translations [skip ci] (#7572)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-04-28 10:28:31 +02:00
D8H
b72034a475 Fix the sentence parameter of "loading progress" condition (#7574) 2025-04-28 10:27:04 +02:00
Davy Hélard
343f6a572d Allow to edit custom object instances in the editor 2025-04-25 19:09:20 +02:00
AlexandreS
926f6a2c56 Remove useless param when changing user subscription (#7573)
Don't show in changelog
2025-04-25 17:20:23 +02:00
Davy Hélard
66134e95ce Handle object configuration changes. 2025-04-25 15:43:58 +02:00
Davy Hélard
1ffb03ccd5 Fix controls not moving with the instance edited from the panel 2025-04-25 11:55:37 +02:00
D8H
32cc6a3109 Fix an anchor behavior test (#7571)
- Don't show in changelogs
2025-04-25 11:04:48 +02:00
github-actions[bot]
f9ab65155d Update translations [skip ci] (#7561)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-04-25 10:57:40 +02:00
github-actions[bot]
d700a9d26d Update extension translations [skip ci] (#7565)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-04-25 10:57:08 +02:00
Florian Rival
297b88ed60 Improve description of the condition to compare a timer value 2025-04-24 17:14:52 +02:00
Davy Hélard
998bf76e72 Merge commit 'c5dd26c93b65ded5ec7972699e93c57dd320360b' into move-instance-in-game-2 2025-04-24 16:12:00 +02:00
Aurélien Vivet
06cef654b0 Add explanatory tooltip to game analytics graph (#7559) 2025-04-24 15:17:14 +02:00
D8H
c5dd26c93b Remove another unused import (#7568)
Don't show in changelog
2025-04-24 12:28:21 +02:00
D8H
e0f3b221bd Remove unused import (#7567)
Don't show in changelog
2025-04-24 12:07:43 +02:00
D8H
896f56e850 Allow to switch between variants of custom objects (#7403)
- Variants allows to restyle custom objects
- They can be customized with the graphical editor
- The asset store will progressively use them notably for UI elements (buttons, sliders)
2025-04-24 11:05:00 +02:00
Aurélien Vivet
cee43ce9df Fix typo in GuidedLessons.js (#7566)
Do not show in changelog
2025-04-24 10:11:56 +02:00
D8H
5e61712e55 Fix various issues with the 3D physics engine (#7564)
* Fix the box shape to always be oriented on Z
* Fix memory leaks
2025-04-23 19:55:06 +02:00
Davy Hélard
47553bc020 Display rotation and size in fields. 2025-04-22 19:07:32 +02:00
Davy Hélard
c84b2410b9 Fix the rotation. 2025-04-22 15:11:38 +02:00
Davy Hélard
fbbac73e94 Fix the toggle. 2025-04-22 14:13:00 +02:00
Clément Pasteau
b3fa34ce3c Typo in description (#7560)
Do not show in changelog
2025-04-22 10:14:19 +02:00
Davy Hélard
c2f0f9b9a3 Handle rotation and scaling. 2025-04-18 19:10:36 +02:00
github-actions[bot]
1bdb4c0369 Update extension translations [skip ci] (#7558)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-04-18 18:21:21 +02:00
github-actions[bot]
2822fab5ed Update translations [skip ci] (#7553)
Co-authored-by: AlexandreSi <32449369+AlexandreSi@users.noreply.github.com>
2025-04-18 18:20:58 +02:00
AlexandreS
658ac381fb Send language when requesting chapters when not authenticated (#7557)
Don't show in changelog
2025-04-18 17:10:19 +02:00
Davy Hélard
4d02ae092b Fix the dragging of a new object. 2025-04-18 16:15:44 +02:00
Davy Hélard
7db2849404 Fix the raycast when objects are found in several layers. 2025-04-18 13:34:42 +02:00
D8H
80cf54cb1b Fix anchored object position when the object and the camera is moved (#7556) 2025-04-18 12:50:43 +02:00
AlexandreS
2f56f6b715 Add new course about UI/UX essentials (#7555)
Keep learning with GDevelop with this new course about UI/UX essentials to make sure your game delivers the best experience to your players!
2025-04-18 11:13:04 +02:00
Clément Pasteau
9784113574 Fix allowing resource swap in resource editor on web (#7554)
Do not show in changelog
2025-04-16 17:59:54 +02:00
Clément Pasteau
e2de3bec34 Update worker url logic + consistent lights + fix using in resources list (#7551)
Do not show in changelog
2025-04-16 16:27:24 +02:00
Davy Hélard
d5a3b55e98 Merge remote-tracking branch 'official/master' into move-instance-in-game-2 2025-04-15 17:18:23 +02:00
github-actions[bot]
e837df4882 Update translations [skip ci] (#7550)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-04-15 16:13:22 +02:00
Clément Pasteau
2f44dab18b 3D models can now be previewed (#7547)
* Screenshots are taken for each 3D Model (using .glb extension) so they can be easily recognized in the editor
* Those previews are visible in the Resources tab, in the 3D Model object dialog, or when swapping/selecting from a project resource
2025-04-15 16:02:55 +02:00
Aurélien Vivet
10049ce42a Add a button to copy the Ask AI response (#7548) 2025-04-15 15:59:32 +02:00
D8H
8d9a60f819 Use a shorter label for the button to toggle parameters in drop-down list (#7549) 2025-04-15 15:58:38 +02:00
Florian Rival
8ea8c421b2 Fix TextContainerExtension description 2025-04-14 18:42:03 +02:00
github-actions[bot]
f7b026f1cc Update translations [skip ci] (#7544)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-04-14 17:27:25 +02:00
Florian Rival
623535f7fd Revert test timemout (not supported by CRA)
Don't show in changelog
2025-04-14 09:20:28 +02:00
Florian Rival
3f0ff4a9de Increase default timeout for IDE tests
Avoid failing an AppVeyor Windows build because of a timeout
2025-04-11 14:08:53 +02:00
Clément Pasteau
883ca6d535 Allow selecting resources that are already in the project when editing an object (#7541) 2025-04-11 12:21:06 +02:00
github-actions[bot]
77f56829b3 Update translations [skip ci] (#7537)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-04-08 10:36:24 +02:00
Clément Pasteau
12a842e197 Fix Piskel crashing with black screen when doing multiple undos (#7539) 2025-04-08 09:33:16 +02:00
Clément Pasteau
7145e6d049 Hide Ask AI for student accounts (#7533)
Do not show in changelog
2025-04-07 11:10:52 +02:00
László Nyiri
caa18e5fcb Fix "Never reached character" error during GDevelop.js build (#7536)
Only show in developer changelog
2025-04-07 09:20:26 +02:00
github-actions[bot]
61bf8a7cab Update translations [skip ci] (#7529)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-04-04 11:32:48 +02:00
Clément Pasteau
98b3687157 Fix cmake version for mac builds (#7531)
Do not show in changelog
2025-04-04 11:20:20 +02:00
github-actions[bot]
4b4fba2c7a Update extension translations [skip ci] (#7532)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-04-04 11:18:44 +02:00
Clément Pasteau
cedb9429c7 Improve languages dialog display (#7528)
Do not show in changelog
2025-04-02 11:28:27 +02:00
github-actions[bot]
d844b4d380 Update extension translations [skip ci] (#7527)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-04-02 10:07:12 +02:00
github-actions[bot]
e4265553e0 Update translations [skip ci] (#7526)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-04-02 09:13:15 +02:00
Florian Rival
2524b0b9d2 Update wording
Don't show in changelog
2025-04-01 18:02:37 +02:00
Florian Rival
20d16b8a57 Add minor improvements to Ask AI
Don't show in changelog
2025-04-01 13:26:14 +02:00
github-actions[bot]
67aa1ce062 Update translations [skip ci] (#7524)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-04-01 10:37:54 +02:00
Florian Rival
1759dda870 Fix formatting 2025-04-01 00:21:01 +02:00
Florian Rival
03dce1d90a Add dialog to report AI message feedback 2025-04-01 00:16:31 +02:00
Florian Rival
4e9556e948 Fix tests and improve wording of tilemaps 2025-03-31 22:53:07 +02:00
D8H
a02b8dcfe0 Add vertical alignement for BitmapText and BBText (#7523) 2025-03-31 21:00:58 +02:00
Florian Rival
416ef44ee1 Improve Ask AI tab
Don't show in changelog
2025-03-31 18:46:48 +02:00
github-actions[bot]
aa90621899 Update translations [skip ci] (#7516)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-31 11:14:33 +02:00
github-actions[bot]
3d3f04f63e Update extension translations [skip ci] (#7521)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-31 10:42:15 +02:00
Clément Pasteau
e1cc21c225 Bump to 5.5.228 (#7515) 2025-03-28 16:47:06 +01:00
github-actions[bot]
9f90bf595e Update translations [skip ci] (#7510)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-03-28 16:43:58 +01:00
Florian Rival
94d49d8c36 Make variable internal naming consistent and update max height for compact text area fields
Don't show in changelog
2025-03-28 16:34:52 +01:00
github-actions[bot]
1d8c435fe0 Update extension translations [skip ci] (#7514)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-28 15:04:01 +01:00
Clément Pasteau
573eafe777 Fix tab tooltip being stuck when closing tab + improve design (#7513) 2025-03-28 11:33:06 +01:00
Florian Rival
15ff9bedd9 Add "Ask AI" (#7486)
* The "Ask AI" tab allows you to access an AI that is a GDevelop expert. _Think of it as "ChatGPT" but that is trained on GDevelop and knows everything about it._ It can give you advices and guide you through GDevelop, features, extensions and has knowledge of what you use in your game (scenes, objects, behaviors).
  * Unsure how to do something? Ask the AI.
  * Want to get a better understanding of a concept you don't understand? Ask the AI.
  * Have an idea but unsure where to start? Ask the AI.
* The AI gives its answer according to the full knowledge of features, reviewed extensions and game building with GDevelop. It's perfect for beginners or when you want to quickly get an answer without having to search for a long time.
* This is experimental. As with any AI, it can make mistakes or give answers that are wrong or not the best way to do something - you can put a thumb up or thumb down on each answer if you want to report something.
  Feel free to check answers with the members of the community on the forum or on Discord. We'll actively improve the AI according to the results it gives.
* The AI was worked to be concise, efficient and fast. If you have a GDevelop membership (silver, gold, pro) you will have an allowance for free AI request every month. You can unlock more AI requests or get some with a free account with credits.
2025-03-27 15:31:16 +01:00
Clément Pasteau
9431ee7316 Remove useless commits in changelog script (#7511)
Do not show in changelog
2025-03-27 13:58:47 +01:00
Florian Rival
333de61ead Reduce some analytics events frequency (#7512)
Don't show in changelog
2025-03-27 13:19:32 +01:00
Clément Pasteau
1433a5f65c Bump 5.5.227 (#7509)
Do not show in changelog
2025-03-27 10:50:53 +01:00
github-actions[bot]
ab1e566aef Update translations [skip ci] (#7506)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-26 14:54:50 +01:00
Clément Pasteau
1a4f9317d1 Slightly improve guided lessons design on mobile (#7504) 2025-03-26 14:45:58 +01:00
Clément Pasteau
af4a6a9313 Fix "Manage subscription" Profile button not working (#7507) 2025-03-26 14:40:39 +01:00
Florian Rival
5f3066d35a Update physics engine/behavior description (#7505)
Only show in developer changelog
2025-03-25 19:38:11 +01:00
Clément Pasteau
3d4f4c1441 Fix locale import (#7503)
Do not show in changelog
2025-03-25 15:25:51 +01:00
github-actions[bot]
4da5efcff2 Update translations [skip ci] (#7497)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-25 15:00:44 +01:00
Clément Pasteau
dde472fd31 Improve locales import (#7502)
Do not show in changelog
2025-03-25 14:48:42 +01:00
Clément Pasteau
94e8cf2229 Update CrazyGames logo to official version (#7499) 2025-03-24 18:30:24 +01:00
github-actions[bot]
17f1bff1cd Update extension translations [skip ci] (#7498)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-24 18:05:50 +01:00
Clément Pasteau
a0c0c3d7b0 Show possible announcements on Create section (#7496)
Do not show in changelog
2025-03-24 15:08:46 +01:00
github-actions[bot]
41b255fdd9 Update translations [skip ci] (#7490)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-03-21 16:37:41 +01:00
D8H
085b425431 Add a deprecation warning on text entry object actions (#7484) 2025-03-21 15:57:11 +01:00
github-actions[bot]
5957738070 Update translations [skip ci] (#7471)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-21 15:44:13 +01:00
Clément Pasteau
7caeae93d6 Fix translation update script (#7489)
Do not show in changelog
2025-03-21 15:23:37 +01:00
Clément Pasteau
ae09ad50ec Automatically translate reviewed extensions and their actions and conditions (#7478) 2025-03-21 15:09:06 +01:00
AlexandreS
495b99356d Add tooltip for tabs (#7482) 2025-03-20 10:27:38 -07:00
D8H
e432a7fa67 Fix extension bug report link (#7483) 2025-03-19 14:58:41 +01:00
AlexandreS
8ba69ce338 Send message to gd.games iframe when soft keyboard opens (#7472) 2025-03-18 09:55:24 -07:00
D8H
767b632db9 Fix the Anchor behavior when the deprecated property is used (#7481) 2025-03-18 17:42:59 +01:00
D8H
49749fbd88 Fix 3D model animations when a negative time scale is used (#7474) 2025-03-14 14:26:06 +01:00
Clément Pasteau
99873e5c76 Fix youtube link (#7470)
Do not show in changelog
2025-03-12 15:41:49 +01:00
github-actions[bot]
3e87e5f76a Update translations [skip ci] (#7467)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-12 10:00:43 +01:00
Clément Pasteau
be5cc49928 Fix discord role claim & other display issues in the profile (#7468) 2025-03-12 09:48:06 +01:00
Clément Pasteau
4bdf7172a6 Merge pull request #7466 from 4ian/youtube-highlight
Highlight youtube sub in profile
2025-03-11 13:05:39 +01:00
Clément Pasteau
9f9f7824ef Highlight youtube sub in profile 2025-03-11 13:00:10 +01:00
Florian Rival
b24e0b79bd Merge pull request #7465 from 4ian/bump-226
Bump to 5.5.226
2025-03-11 09:44:25 +00:00
Clément Pasteau
827b2cf3d8 Merge pull request #7458 from 4ian/chore/update-translations
[Auto PR] Update translations
2025-03-11 10:43:43 +01:00
ClementPasteau
7a4142a1c9 Update translations [skip ci] 2025-03-11 09:37:46 +00:00
Clément Pasteau
78671abb91 Bump to 5.5.226 2025-03-11 10:37:30 +01:00
Clément Pasteau
11df078b74 Merge pull request #7463 from 4ian/youtube-sub-badge
New badge can be unlocked when subscribing to YouTube channel
2025-03-11 10:30:43 +01:00
Clément Pasteau
9001bfd8e2 Merge pull request #7461 from 4ian/fix-animation-crossfade-switch-problem
fix "is finished" animation condition
2025-03-11 10:26:26 +01:00
Neyl
0d2778c8db Update Model3DRuntimeObject3DRenderer.ts 2025-03-11 09:51:58 +01:00
Neyl
ee98e8a329 Update Model3DRuntimeObject3DRenderer.ts 2025-03-11 09:42:16 +01:00
Clément Pasteau
a2e48fdd6c Fix display on desktop 2025-03-10 18:08:17 +01:00
D8H
187018cdd3 [Spine] Fix "Animation finished" condition (#7464) 2025-03-10 17:57:27 +01:00
Neyl
c7622c3abe Update Model3DRuntimeObject3DRenderer.ts 2025-03-10 16:47:08 +01:00
Clément Pasteau
7dca48b8bd New badge can be unlocked when subscribing to YouTube channel 2025-03-10 16:33:50 +01:00
D8H
e9c625abc6 Automatically rename and delete object instance variables (#7454) 2025-03-10 16:05:39 +01:00
Neyl
71f7b59ab5 nitpicked 2025-03-10 15:10:08 +01:00
Neyl
8630452b89 updated comments 2025-03-10 14:57:57 +01:00
Clément Pasteau
b1a91bdc4c Update player token logic to be fetched on project opening (#7460)
Do not show in changelog
2025-03-10 14:51:33 +01:00
Neyl
638c661138 Update Model3DRuntimeObject3DRenderer.ts 2025-03-10 14:41:03 +01:00
Neyl
5dfd26c6f6 fix animation crossfade issue 2025-03-10 14:39:09 +01:00
D8H
a79e87dc7a Fix 3D sprites being all black (#7459) 2025-03-10 13:06:05 +01:00
ViktorVovk
6490c1c4ad Refactor logic to get file URLs in gdjs.SoundManager (#7433)
Only show in developer changelog

Co-authored-by: Vovk Viktor <vvovk@playtika.com>
2025-03-10 11:34:16 +01:00
D8H
05963806f1 Close the extension tabs when it's updated (#7453) 2025-03-10 11:29:15 +01:00
D8H
c4e1d2e5f8 Improve animation state displaying in the capabilities test example (#7455)
- Don't show in changelog
2025-03-10 10:16:34 +01:00
AlexandreS
92f13abafc Fix tile set not updated when tilemap resource file is change outside of GDevelop (#7457) 2025-03-10 09:36:36 +01:00
Clément Pasteau
ae3438b5f9 Send event when opening play section + rename event (#7452)
Do not show in changelog
2025-03-07 16:22:58 +01:00
D8H
ff572a2777 Close the extension tabs when it's updated (#7451) 2025-03-07 16:11:00 +01:00
Clément Pasteau
e2320ec717 Add events when swapping assets (#7450)
Do not show in changelog
2025-03-07 15:50:06 +01:00
Clément Pasteau
bce459b2d2 Add missing event data (#7449)
Do not show in changelog
2025-03-06 15:31:26 +01:00
D8H
95dddc48b6 Deprecate old variable actions and conditions in extensions (#7406)
- The extension variables must be used instead
- Old extensions can be maintained by copy-pasting existing old actions and conditions from the extension events
2025-03-06 13:13:14 +01:00
Clément Pasteau
d39f210630 Bump 5.5.225 (#7447) 2025-03-06 12:08:31 +01:00
github-actions[bot]
090649f125 Update translations [skip ci] (#7440)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-06 12:01:45 +01:00
Clément Pasteau
7c8c02911c Improve Guided Lessons by preventing clicking outside of the next action (#7444) 2025-03-06 11:54:37 +01:00
D8H
0c6a28c0a1 Fix onCreated functions not being called on behaviors added at hot-reload (#7443) 2025-03-04 14:26:21 +01:00
Florian Rival
b9d5974356 Fix expression documentation not displaying parameters 2025-03-04 00:13:22 +01:00
D8H
74a1e11cfc Improve the abs expression documentation (#7442) 2025-03-03 21:53:52 +01:00
D8H
c712d0bb9e Forbid to install assets or behaviors from extensions incompatible with the editor (#7441) 2025-03-03 20:43:48 +01:00
Clément Pasteau
828e6e031a Update AdMob extension to handle Consent & Tracking Authorization on iOS (#7431)
* Admob will now initialize 2 seconds after the app loads, giving more control to when it starts. This is particularily helpful for App Store validations, with Tracking Authorization message.
* New conditions are available to know AdMob initialization status: "AdMob initializing" and "AdMob Initialized".
* New action to stop the auto-initialization: "Prevent AdMob auto initialization" and new action to trigger the initialization: "Initialize AdMob manually".
  * Typically, you'd prevent the initialization at the beginning of the scene, and trigger it manually when a user interacts with a button or something, so you can control when they'll see the consent messages.
2025-03-03 10:53:59 +01:00
D8H
727f991c01 Allow anchored objects to be moved from their initial position (#7417)
* If an anchored object is moved using events (or another behavior), it will stay on its new position.
  This allows to anchor objects on the left, right, top or bottom of the screen (or inside the bounds of a custom object, for example in a dialog) and still allow them to move.
2025-03-03 10:52:15 +01:00
D8H
5d4523b925 Fix object parameter not shown when editing an action/condition when the object doesn't exist (#7373) 2025-03-03 10:40:06 +01:00
github-actions[bot]
3f7cbc731a Update translations [skip ci] (#7434)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-03-03 10:38:44 +01:00
D8H
c1dfa34f0d Deprecate internal actions and conditions to set and compare property values in extension events (#7405)
- The unified variable action and condition must be used instead.
2025-03-03 10:31:05 +01:00
D8H
cf39de49d6 Allow custom objects to declare multi-line text properties (#7436) 2025-02-28 17:23:51 +01:00
D8H
5b325dd8ec Fix access to objects in variable expressions of "for each child variable" loops (#7435) 2025-02-28 11:06:51 +01:00
Clément Pasteau
1f42331cbf Allow selecting a Pixel Art version of 2D starting points (#7425)
* Available for Platformer, Top-Down & Physics templates
2025-02-27 18:06:15 +01:00
Florian Rival
224f17b90a Add missing await 2025-02-27 17:27:58 +01:00
D8H
3541d356e0 Fix text alignment at runtime (#7432) 2025-02-27 10:58:18 +01:00
github-actions[bot]
63e79d678a Update translations [skip ci] (#7416)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-02-27 09:32:51 +01:00
Florian Rival
812153ffb3 Allow the embedded games platform to ask for opening external urls
Don't show in changelog
2025-02-26 15:26:26 +01:00
Clément Pasteau
c62ea9e10a Show error if games frame does not load (#7430) 2025-02-26 14:13:54 +01:00
Clément Pasteau
04c63b2c74 Fix using non-existing vars in calc() (#7427)
Do not show in changelog
2025-02-26 11:15:18 +01:00
Florian Rival
dcc3bae17e Fix warning
Don't show in changelog
2025-02-25 10:31:21 +01:00
Florian Rival
441834cad5 Prepare custom token to speed up embedded game frame login (#7423)
Don't show in changelog
2025-02-25 10:14:15 +01:00
Florian Rival
d4352ba5d9 Adapt embedded game frame position and allow sharing
Don't show in changelog
2025-02-24 19:35:29 +01:00
Clément Pasteau
163239d08d Fix toggle "update game page" sometimes not being visible when publishing. (#7422)
* This could happen when the last build was too old, and the interface considered the game as new, so published it automatically to the game page.
2025-02-24 15:23:39 +01:00
Florian Rival
e3e9b41672 Display first letter of tabs when at minimum size 2025-02-24 12:24:17 +01:00
inspace
7ba7c220e9 Ensure cursor position is correct when a mouse down event is detected (#7412)
Only show in developer changelog
2025-02-24 11:30:36 +01:00
AlexandreS
617bf2c5b9 Add missing keys in keyboard condition/action (#7421)
- Added Left and Right bracket and the Menu keys
2025-02-24 10:38:14 +01:00
Clément Pasteau
d647d1e397 Fix top bar to be draggable on desktop, except tabs (#7420) 2025-02-24 10:32:44 +01:00
Florian Rival
c5bf9730aa Refactor toolbar and titlebar display and ensure game iframe is hidden when not on the Play tab (#7419)
Don't show in changelog
2025-02-23 15:28:32 +01:00
Florian Rival
c5022596b8 Make the games/page in Play section to take the full width
Don't shown in changelog
2025-02-22 14:37:36 +01:00
D8H
6e61c48898 Fix a regression that hid all 3D models in the editor (#7418)
Don't show in changelog
2025-02-22 14:00:56 +01:00
Clément Pasteau
75fc55bac4 Rework the Play section to have games played inside the app (#7372) 2025-02-20 18:46:00 +01:00
github-actions[bot]
8a4916fd93 Update translations [skip ci] (#7414) 2025-02-20 10:08:45 +01:00
AlexandreS
b008863281 Do not show the reminder if the editor was just idle for too long (#7413) 2025-02-19 15:56:25 +01:00
github-actions[bot]
f0377771a8 Update translations [skip ci] (#7399)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-02-19 09:33:26 +01:00
D8H
299ef90f93 [3D character] Fix the "is moving" condition when moving sideways (#7411) 2025-02-17 14:01:37 +01:00
D8H
800c3333d4 Improve typing of the 3D object editor renderers (#7410)
- Don't show in changelog
2025-02-17 12:57:27 +01:00
AlexandreS
303ebfaf1b Refresh in app tutorial message in preview when hot reloading preview (#7407)
Don't show in changelog
2025-02-17 12:06:44 +01:00
AlexandreS
288e4f4b75 Fix: Remove crash when opening 3D Racing game example external layouts
- Use default values when updating Cube 3D three object in editor (#7408)
2025-02-17 11:30:54 +01:00
Clément Pasteau
15db4be4a1 Fix typo (#7402)
Do not show in changelog
2025-02-14 10:08:01 +01:00
D8H
925ffa74ec Allow to tween 3D boxes tint color (#7401)
- Don't show in changelog
2025-02-13 12:35:52 +01:00
D8H
752d047464 Upgrade GDJS to Prettier 3.4.2 (#7398)
- Don't show in changelog
2025-02-12 18:50:02 +01:00
D8H
7a21f9533e Upgrade to TypeScript 5.4.5 (#7394)
- Don't show in changelog
2025-02-12 17:51:36 +01:00
Ansel Games
9820770fb3 Update "Create objects from an external layout" action to show all parameters in the events sheet (#7383) 2025-02-12 17:49:23 +01:00
D8H
a92784295a Fix GDJS test resource paths (#7397) 2025-02-12 17:41:19 +01:00
Neyl
81f6c62bb1 Update Animation Crossfade default value to a more realistic one (100ms) (#7395) 2025-02-12 17:13:36 +01:00
github-actions[bot]
a1bbb1c14c Update translations [skip ci] (#7388)
Co-authored-by: AlexandreSi <32449369+AlexandreSi@users.noreply.github.com>
2025-02-12 16:56:29 +01:00
Clément Pasteau
9154144228 Fix a project opened from a file being always detected as a new game in the dashboard (#7392) 2025-02-12 16:55:59 +01:00
AlexandreS
c0176dfb2b Add lightweight markdown interpreter for in-app tutorial in-game messages (#7391)
Don't show in changelog
2025-02-12 14:35:32 +01:00
AlexandreS
23cd527d94 Fix spatial sound action not applied if sound is not playing yet (#7393) 2025-02-12 14:33:46 +01:00
Neyl
fa2cdb1624 fix crossfade duration in 3D model editor 2025-02-12 12:02:08 +01:00
Clément Pasteau
03eca4de4b Upgrade pixi to 7.4.2 (#7190) 2025-02-11 14:20:59 +01:00
Clément Pasteau
841484e5b7 Disable lazy loading on authorized images, fixing the image stuck with a loader (#7389) 2025-02-11 10:58:47 +01:00
github-actions[bot]
b88c5b08f5 Update translations [skip ci] (#7370)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-02-11 09:36:17 +01:00
Aurélien Vivet
3f2043f248 Add a clearer warning before the deletion of a game and a project. (#7368)
* This is mainly to prevent accidental deletion of games
2025-02-11 09:35:33 +01:00
Florian Rival
6941e64418 Adapt tabs width according to screen width, to keep them visible on screen as much as possible (#7387) 2025-02-10 18:24:48 +01:00
Neyl
fb7bb9181d add support for crossfading animations for 3D models
the new option allows to smoothly transition between animations. The fading duration can be customized with an action.
2025-02-10 17:56:18 +01:00
AlexandreS
7ee50a2568 Fix: Prevent accidentally saving a project in the root folder of the editor 2025-02-10 13:04:23 +01:00
AlexandreS
90cdc875a9 Add possibility to display message in the preview when an in-app tutorial is running (#7379) 2025-02-10 10:59:35 +01:00
Florian Rival
47d0fba205 Fix a crash when searching instructions after extension are re-generated (#7377)
* Also improve the display of actions/conditions/expressions when searched with a clearer visual separator for their folders
2025-02-07 16:03:09 +01:00
Aurélien Vivet
db745369dc Re-order in-app tutorials (#7378) 2025-02-07 15:30:19 +01:00
D8H
7c49346bed Add a warning on array children with inconsistent type (#7376) 2025-02-06 18:29:38 +01:00
AlexandreS
b9a7786ab0 Add an action to join a lobby in one-click (#7352) 2025-02-06 18:04:41 +01:00
Florian Rival
79206fbfee WIP: Drag new instance 2025-02-06 15:26:29 +01:00
AlexandreS
76c09908c8 Fix border radius added by browser on text input (#7375) 2025-02-06 14:45:54 +01:00
Neyl
b6e186e775 Tint color for 3D cube (#7354)
add a tint color property for 3D cube.
2025-02-06 11:10:39 +01:00
D8H
8c98239e12 Allow to swap assets of any object type (#7365) 2025-02-04 17:22:53 +01:00
AlexandreS
4d56333ae7 Display shorter title in Curriculum's table of content when available (#7371) 2025-02-04 16:22:13 +01:00
AlexandreS
146794d33a Bump newIDE version (#7369) 2025-02-04 15:32:07 +01:00
AlexandreS
3a685c62df Refine free conditions/actions search to give priority to results with the search word in the displayed name (#7360) 2025-02-04 11:28:43 +01:00
github-actions[bot]
8bcbf9bd47 Update translations [skip ci] (#7353)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-02-04 10:25:13 +01:00
Clément Pasteau
601a4e214e Fix games sometimes disappearing from the dashboard (#7366)
* This was caused by games wrongly being considered as not saved during the export, and they were hidden from the dashboard afterwards
2025-02-04 10:07:06 +01:00
D8H
3d0b264130 [Physics3D] Fix remaining hit-boxes of deleted character (#7359)
- Also fix 3D character behavior deactivation
2025-02-03 17:54:38 +01:00
D8H
97e989dee0 Ensure behaviors are compatible with the object before pasting them (#7343) 2025-02-03 13:02:41 +01:00
D8H
6440149fc8 Change documentation pages of some actions and conditions to point to more specific pages (#7364) 2025-02-03 12:58:28 +01:00
Neyl
232359f0a4 FIX the destroy of the form, "is submitted" condition icon, and readonly & disable feature (#7363)
Fix the destroy of the form, readonly and disable feature, and a typo for "is submitted" condition icon
2025-02-03 12:52:57 +01:00
Florian Rival
bf7ecd9ceb Add "Scroll" text to in-app tutorial highlights (#7356)
Don't show in changelog
2025-01-30 11:31:30 +01:00
Florian Rival
2089e29664 WIP: display selection boxes in 3D editor 2025-01-29 17:49:06 +01:00
Florian Rival
38c5425d0c Fix selection of 3D models 2025-01-29 14:58:48 +01:00
D8H
2ba7075a7a Update the "trigger once" help page link (#7355) 2025-01-28 19:05:58 +01:00
Clément Pasteau
e45256cebb Fix a few issues with displaying projects correctly in the create section (#7349) 2025-01-27 18:51:25 +01:00
Florian Rival
1ee2d57d2f Bump newIDE version 2025-01-27 18:35:49 +01:00
github-actions[bot]
e890d8f211 Update translations [skip ci] (#7348)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-01-27 18:34:42 +01:00
Florian Rival
e70f8532f6 Improve course display 2025-01-27 16:54:42 +01:00
Florian Rival
446494156b Fix crash when adding/modifying functions in extensions (#7351) 2025-01-26 21:40:11 +01:00
Florian Rival
b0d45e80de Improve outline pass rendering 2025-01-26 16:28:04 +01:00
Florian Rival
2ac5beee0c Improve camera movement in 3D space 2025-01-25 14:23:30 +01:00
Florian Rival
c99c73fa96 WIP: handle multiselection movement and camera rotation 2025-01-25 13:02:01 +01:00
Florian Rival
f796228d06 Merge branch 'master' into move-instance-in-game-2 2025-01-25 11:17:11 +01:00
D8H
15a1d392a1 Fix extension usage listing for example web pages (#7339) 2025-01-24 15:19:49 +01:00
AlexandreS
65b5aa6bac Use new compact UI in the Preferences dialog (#7345) 2025-01-24 14:02:48 +01:00
Florian Rival
cbaa785b95 Fix log and extra character
Don't show in changelog
2025-01-24 13:46:05 +01:00
Florian Rival
ca3836b3c7 WIP: Handle deletion from in-game editor 2025-01-24 13:29:41 +01:00
github-actions[bot]
b6091de09a Update translations [skip ci] (#7341)
Co-authored-by: AlexandreSi <32449369+AlexandreSi@users.noreply.github.com>
2025-01-24 13:29:17 +01:00
Clément Pasteau
b53dc29f43 Add preferences menu item back in the File menu (#7346) 2025-01-24 13:28:56 +01:00
Aurélien Vivet
0848a109d4 Bring consistency on arrow direction for UI items that can be opened/closed (#7322) 2025-01-24 10:50:51 +01:00
Florian Rival
4bf21e94eb Change in-app tutorials order 2025-01-24 10:43:05 +01:00
Clément Pasteau
2d6b2c1753 Improve homepage bottom bar icons on mobile (#7342) 2025-01-23 18:31:04 +01:00
AlexandreS
c4e230d9ba Split text input padding into 2 separate properties (#7338)
Don't show in changelog
2025-01-23 16:12:18 +01:00
D8H
56ab2fdd05 Revert "Fix used extension check false positive from usused object or behavior events (#7331)" (#7340)
This reverts commit cb24f191fd.

Don't show in changelog
2025-01-23 14:11:13 +01:00
github-actions[bot]
872f4032ff Update translations [skip ci] (#7337)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-01-23 11:56:54 +01:00
D8H
428b4c21a8 Disable panel sprite tilling by default (#7335)
* This ensures the rendering is more performant by default
2025-01-23 09:43:40 +01:00
Florian Rival
918f8ec989 WIP: handle selection in in-game editor 2025-01-22 22:50:20 +01:00
D8H
cb24f191fd Fix used extension check false positive from usused object or behavior events (#7331)
- Don't show in changelog
2025-01-22 17:17:39 +01:00
github-actions[bot]
994f6bf150 Update translations [skip ci] (#7334)
Co-authored-by: AlexandreSi <32449369+AlexandreSi@users.noreply.github.com>
2025-01-22 15:55:56 +01:00
AlexandreS
3e2f05460a Bump newIDE version (#7333) 2025-01-22 15:46:04 +01:00
github-actions[bot]
c775cde9df Update translations [skip ci] (#7318)
Co-authored-by: NeylMahfouf2608 <26115084+NeylMahfouf2608@users.noreply.github.com>
2025-01-22 15:37:51 +01:00
AlexandreS
6ab736a048 Return exact matches when searching for an instruction (#7330) 2025-01-22 15:35:12 +01:00
Neyl
f805182ce4 Improvement features for Input text box (#7308)
padding, max-length and text-align can now be configured on the text input object
new condition "Input is submitted" to check if the input has been submitted with the keyboard on all platforms
2025-01-22 14:20:29 +01:00
D8H
a14f1a187e Fix a few typo in Physics3D (#7332)
- Don't show in changelog
2025-01-22 11:35:52 +01:00
D8H
d08bf97471 Fix conflict between variable or property and parameter in variable setters (#7329)
- Don't show in changelog
2025-01-21 19:16:43 +01:00
Florian Rival
f44d9682ee WIP: Allow more changes to instances 2025-01-20 16:05:50 +01:00
Florian Rival
ce6800164d WIP: replicate mouse/trackpad movement from the existing editor 2025-01-20 15:13:39 +01:00
D8H
093e15e105 Fix EventsFunctionsContainer copy constructor now copy the owner (#7327)
- Don't show in changelog
2025-01-20 14:35:37 +01:00
D8H
60e36f37b1 Remove EventsFunctionsExtension inheritance to EventsFunctionsContainer (#7326)
- developer changelog only
2025-01-20 11:29:55 +01:00
Florian Rival
4afb2de178 WIP: add some camera movement 2025-01-19 22:17:28 +01:00
Florian Rival
9865fd3663 Simplify InGameEditor and add camera zooming (in 2D plane) with mouse wheel 2025-01-19 18:51:37 +01:00
Florian Rival
5501527974 Merge branch 'master' into move-instance-in-game-2 2025-01-19 16:14:14 +01:00
D8H
ad7ce3c725 [3D character] Fix the "is falling" condition from being true when the character is going up (#7325) 2025-01-19 01:00:43 +01:00
D8H
c6f83f4431 Fix behavior property generation and value. (#7324) 2025-01-19 01:00:05 +01:00
D8H
4a685db574 Fix parameters list not updating when the function configuration was changed (#7321) 2025-01-17 20:06:08 +01:00
D8H
f3dea010fb Fix syntax errors not showing up on mouse button and key parameters (#7320)
- Don't show in changelog
2025-01-17 20:05:29 +01:00
D8H
5025e03dff Fix 3D physics characters to keep rotation around X and Y intact (#7319) 2025-01-17 15:42:46 +01:00
Florian Rival
64771c6faf Give back focus to preview, when updating a preview on the web-app 2025-01-17 13:10:09 +01:00
github-actions[bot]
d4987c4739 Update translations [skip ci] (#7314)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-01-17 10:48:59 +01:00
Clément Pasteau
56575e7afd Introduce new subscription dialog design for creators without a plan (#7316) 2025-01-17 10:39:04 +01:00
Florian Rival
9a0df077b3 Fix a crash when opening a project missing a custom object that was loaded in the previously opened project (#7317) 2025-01-16 23:27:32 +01:00
AlexandreS
4bf3ef8ad4 Use the folder structure when choosing an object/group in an action/condition (#7297) 2025-01-16 12:03:58 +01:00
Clément Pasteau
6242e8c97a Fix not being able to drag the app from the top bar (#7315)
Do not show in changelog
2025-01-16 12:02:47 +01:00
D8H
d6c99b27af Allow to use parameters and properties in the variable action and condition (#7124) 2025-01-15 23:28:18 +01:00
AlexandreS
7844ee102e Fix issue that was not showing cubes when they have all their faces shown with no textures (#7313) 2025-01-15 18:17:38 +01:00
github-actions[bot]
7d713d9428 Update translations [skip ci] (#7311)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-01-15 17:36:12 +01:00
Clément Pasteau
22056d3c08 Fix adding draggable space only on title bar (#7312)
Do not show in changelog
2025-01-15 17:28:43 +01:00
D8H
2ce35a1520 Allow 3D physics characters to push each other (#7292) 2025-01-15 10:52:21 +01:00
AlexandreS
b04c15f23c Add objects installed from the asset store in selected folder (#7287) 2025-01-15 10:32:15 +01:00
D8H
2ab246696b Add autocompletion for keyboard key properties in the behavior editor (#7310) 2025-01-15 09:57:45 +01:00
Florian Rival
6b4c00c987 Add missing JS files thumbnail
Don't show in changelog
2025-01-15 09:52:56 +01:00
github-actions[bot]
9c4a190a4d Update translations [skip ci] (#7300)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-01-15 09:50:36 +01:00
Florian Rival
3e4826bafc Fix memory leak with outlining in-game edited object 2025-01-15 09:50:09 +01:00
Clément Pasteau
1070a489e7 Fix dialog overflow because of cross (#7309)
Don't show in changelog
2025-01-15 09:24:37 +01:00
Clément Pasteau
d2a8cb6727 Improve title bar on multiple platforms optimizing the space at the top of the app (#7306) 2025-01-14 17:29:55 +01:00
D8H
2638c4f593 Fix getter and setter generation for animation properties (#7307)
- Don't show in changelog
2025-01-14 14:51:27 +01:00
D8H
4be2386efe Allow to toggle between drop-down list and expression for mouse button and key parameters (#7305) 2025-01-14 13:53:10 +01:00
AlexandreS
8be099d50a Add possibility to open GDevelop in the browser on the premium course (#7304) 2025-01-13 19:12:14 +01:00
Clément Pasteau
713698d3d6 Fix wrong margins for dense design of sub card (#7303)
Do not show in changelog
2025-01-13 13:32:11 +01:00
Clément Pasteau
8b36908fd8 Merge project manager & app burger menu buttons (#7289)
* The goal of this change is to simplify the top left corner of the app, by merging the App burger menu and the Project manager button into one. Having 2 buttons was causing confusion in the flow of using the app, by mistakenly pressing the wrong button.
* The app menu buttons that are useful are now displayed at the top of the project manager drawer, on the relevant platforms: Web, Windows & mobile, because other platforms have a built-in OS menu.
2025-01-13 10:11:32 +01:00
D8H
c0722dc441 [2D Physics] Reduce the CPU footprint of static objects (#7299) 2025-01-10 16:39:20 +01:00
D8H
9c6a1bed2c [3D Physics] Reduce the CPU footprint of static objects (#7298) 2025-01-10 12:58:53 +01:00
github-actions[bot]
a8a4d14ee1 Update translations [skip ci] (#7291)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-01-10 10:23:16 +01:00
Florian Rival
b27abfbe5d Add text vertical alignment in quick customzation
Don't show in changelog
2025-01-10 10:07:37 +01:00
Neyl
28b585aefa Allow behavior properties to be an animation name, displayed with a selector 2025-01-09 14:21:04 +01:00
AlexandreS
0623b6acd9 Fix variable list usability (#7290)
- When renaming a variable in the instance panel:
  - the caret position is kept
  - the user can erase the whole field without the name being replaced by "Unnamed" instantly
- When opening the variables editor from a variable field, the currently selected variable is selected in the list (even if child of a variable)
2025-01-08 16:44:13 +01:00
AlexandreSi
d914f9f5be Add comment 2025-01-07 15:51:40 +01:00
AlexandreSi
ab8c90dd41 Send layout name to runtime game when editing instance in editor 2025-01-07 15:32:52 +01:00
AlexandreSi
8882841a8d Fix position offset 2025-01-07 15:19:24 +01:00
AlexandreSi
3d357950f9 Send message to game when updating an instance position from the editor 2025-01-07 14:51:31 +01:00
github-actions[bot]
1a833bc388 Update translations [skip ci] (#7272)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-01-07 11:04:19 +01:00
D8H
827f187e10 Add Pixi and Three type definitions for JS events (#7266) 2025-01-07 10:34:51 +01:00
Florian Rival
0f25b80a66 Fix margins
Don't show in changelog
2025-01-06 22:06:15 +01:00
Clément Pasteau
fbf9710cc5 Use premium colors in most places where a subscription can be purchased (#7284) 2025-01-06 20:56:49 +01:00
Clément Pasteau
3d80709029 Fix correctly exporting desktop icon when project is saved in the cloud (#7282) 2025-01-06 17:54:59 +01:00
AlexandreS
5ab9c565b0 Simplify shop navigation state to avoid useless renderings (#7283)
Only show in developer changelog
2025-01-06 17:01:41 +01:00
Florian Rival
e237fc4b21 Add experimental support for importing JS source files in extensions (#7278)
* See more about using [JavaScript on this page](https://wiki.gdevelop.io/gdevelop5/events/js-code/javascript-in-extensions/#experimental-new-option-javascript-files-in-your-project).

Only show in developer changelog
2025-01-06 11:02:28 +01:00
D8H
18892f97f3 Remove unused import and fix a typo (#7277) 2025-01-04 11:19:42 +01:00
D8H
0ec0654032 Allow to make custom objects private to an extension (#7275) 2025-01-03 19:36:38 +01:00
D8H
8e29c723e8 [3D physics character] Fix a 1-frame delay on the "is falling" condition (#7276) 2025-01-03 19:33:33 +01:00
AlexandreSi
ef5d2651c0 Update instance when receiving update from game and hot reload game 2025-01-03 17:15:32 +01:00
AlexandreSi
1dd4bb9b7a Add method to get instance persistent uuid 2025-01-03 16:39:06 +01:00
AlexandreSi
682e6f6b03 Send instances updated back to editor when modifying them with transform controls 2025-01-03 15:51:55 +01:00
Clément Pasteau
6acde2865a Fix opening windows in foreground on windows everywhere in app (#7274)
* Ensure electron/remote is used
2025-01-02 16:36:43 +01:00
Clément Pasteau
49e176a98f Scroll to projects when opening from dashboard (#7273)
Do not show in changelog
2025-01-02 15:16:30 +01:00
AlexandreSi
b468c28ae8 Improve usability of the in-game instance control 2025-01-02 14:57:31 +01:00
D8H
71c2a0be01 Add a property to choose the maximum stair height a 3D character can walk (#7265) 2025-01-02 13:18:46 +01:00
AlexandreSi
9fc9452a08 Better handle gizmos 2025-01-02 12:29:53 +01:00
AlexandreSi
3b176b7152 Fix cleaning of listeners and helpers 2025-01-02 11:46:56 +01:00
AlexandreSi
f1d1a9b66b Remove unused import 2025-01-02 11:27:41 +01:00
AlexandreSi
c0d2f491a8 Fix code after rebase 2025-01-02 11:27:41 +01:00
Clément Pasteau
4ad1a0dd68 Bump 221 (#7271) 2025-01-02 11:20:00 +01:00
github-actions[bot]
a556690307 Update translations [skip ci] (#7269)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-01-02 11:17:46 +01:00
Clément Pasteau
6950f323b3 Disable type checking in JS Events until all autocompletions are properly handled (#7270) 2025-01-02 11:09:59 +01:00
AlexandreSi
aeecce2ea8 Avoid creating transform controls on each click 2025-01-02 11:05:05 +01:00
AlexandreSi
647ee149ff Fix hovered object outline 2025-01-02 11:05:05 +01:00
AlexandreSi
22313e148a Import changes to render without step 2025-01-02 11:05:05 +01:00
AlexandreSi
31f2d7ce2e Select object on click 2025-01-02 11:03:59 +01:00
AlexandreSi
4a0efec6c2 Add TransformControls to Three addons 2025-01-02 11:03:59 +01:00
AlexandreSi
5f555df5c1 Add outline pass in layer composer 2025-01-02 11:03:59 +01:00
AlexandreSi
53a611a1b9 Add outline pass to three addons 2025-01-02 11:03:59 +01:00
AlexandreSi
14511b23af WIP 2025-01-02 11:03:59 +01:00
github-actions[bot]
de129f6cc4 Update translations [skip ci] (#7252)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-01-02 10:57:33 +01:00
Clément Pasteau
b3b88a0445 Fix wrong prop name & add translations (#7268)
Do not show in changelog
2025-01-02 10:57:08 +01:00
D8H
8e8f3a7d55 Fix the collision conditions for 3D physics characters (#7264)
* Migrate to Jolt 0.31.0
2024-12-31 16:58:08 +01:00
D8H
cc6b4a283a Enable type checking on the Dialog Tree implementation (#7263)
- Don't show in changelog
2024-12-31 13:03:16 +01:00
D8H
f393f36bad Add a tooltip on some physics properties (#7262) 2024-12-30 18:23:20 +01:00
1402 changed files with 116577 additions and 35835 deletions

View File

@@ -13,17 +13,18 @@ orbs:
aws-cli: circleci/aws-cli@2.0.6
macos: circleci/macos@2.5.1 # For Rosetta (see below)
node: circleci/node@5.2.0 # For a recent npm version (see below)
win: circleci/windows@5.1.0
jobs:
# Build the **entire** app for macOS.
# Build the **entire** app for macOS (including the GDevelop.js library).
build-macos:
macos:
xcode: 14.2.0
resource_class: macos.m1.large.gen1
xcode: 16.4.0
resource_class: m4pro.medium
steps:
- checkout
# Install Rosetta for AWS CLI and disable TSO to speed up S3 uploads (https://support.circleci.com/hc/en-us/articles/19334402064027-Troubleshooting-slow-uploads-to-S3-for-jobs-using-an-m1-macOS-resource-class)
- macos/install-rosetta
- run: sudo sysctl net.inet.tcp.tso=0
# - run: sudo sysctl net.inet.tcp.tso=0
# Install a recent version of npm to workaround a notarization issue because of a symlink made by npm: https://github.com/electron-userland/electron-builder/issues/7755
# Node.js v20.14.0 comes with npm v10.7.0.
@@ -46,9 +47,9 @@ jobs:
# GDevelop.js dependencies
- restore_cache:
keys:
- gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
- gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}-{{ checksum "GDJS/package-lock.json" }}
# fallback to using the latest cache if no exact match is found
- gd-macos-nodejs-dependencies---
- gd-macos-nodejs-dependencies-
- run:
name: Install GDevelop.js dependencies
@@ -69,7 +70,8 @@ jobs:
- newIDE/electron-app/node_modules
- newIDE/app/node_modules
- GDevelop.js/node_modules
key: gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
- GDJS/node_modules
key: gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}-{{ checksum "GDJS/package-lock.json" }}
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
# Note: Code signing is done using CSC_LINK (see https://www.electron.build/code-signing).
@@ -86,15 +88,37 @@ jobs:
- store_artifacts:
path: newIDE/electron-app/dist
# Upload artifacts (AWS)
- run:
name: Deploy to S3 (specific commit)
command: export PATH=~/.local/bin:$PATH && aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/
command: |
export PATH=~/.local/bin:$PATH
for i in 1 2 3 4 5 6 7; do
aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/ && break
echo "Retry $i failed... retrying in 10 seconds"
sleep 10
done
if [ $i -eq 7 ]; then
echo "All retries for deployment failed!" >&2
exit 1
fi
- run:
name: Deploy to S3 (latest)
command: export PATH=~/.local/bin:$PATH && aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
command: |
export PATH=~/.local/bin:$PATH
for i in 1 2 3 4 5 6 7; do
aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/ && break
echo "Retry $i failed... retrying in 10 seconds"
sleep 10
done
if [ $i -eq 7 ]; then
echo "All retries for deployment failed!" >&2
exit 1
fi
# Build the **entire** app for Linux.
# Build the app for Linux (using a pre-built GDevelop.js library).
build-linux:
# CircleCI docker workers are failing if they don't have enough memory (no swap)
resource_class: xlarge
@@ -107,51 +131,33 @@ jobs:
- checkout
- aws-cli/setup
# System dependencies (for Electron Builder and Emscripten)
# System dependencies (for Electron Builder)
- run:
name: Install dependencies for Emscripten
command: sudo apt-get update && sudo apt install cmake
- run:
name: Install Python3 dependencies for Emscripten
command: sudo apt install python-is-python3 python3-distutils -y
- run:
name: Install Emscripten (for GDevelop.js)
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd ..
name: Update system dependencies
command: sudo apt-get update
- run:
name: Install system dependencies for Electron builder
command: sudo apt install icnsutils && sudo apt install graphicsmagick && sudo apt install rsync
# GDevelop.js dependencies
- restore_cache:
keys:
- gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
- gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}-{{ checksum "GDJS/package-lock.json" }}
# fallback to using the latest cache if no exact match is found
- gd-linux-nodejs-dependencies---
- gd-linux-nodejs-dependencies-
- run:
name: Install GDevelop.js dependencies and build it
command: cd GDevelop.js && npm install && cd ..
# Build GDevelop.js (and run tests to ensure it works)
- run:
name: Build GDevelop.js
# Use "--runInBand" as it's faster and avoid deadlocks on CircleCI Linux machines (probably because limited in processes number).
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test -- --runInBand && cd ..
# GDevelop IDE dependencies (after building GDevelop.js to avoid downloading a pre-built version)
# GDevelop IDE dependencies (using an exact version of GDevelop.js, built previously)
- run:
name: Install GDevelop IDE dependencies
command: cd newIDE/app && npm install && cd ../electron-app && npm install
command: export REQUIRES_EXACT_LIBGD_JS_VERSION=true && cd newIDE/app && npm install && cd ../electron-app && npm install
- save_cache:
paths:
- newIDE/electron-app/node_modules
- newIDE/app/node_modules
- GDevelop.js/node_modules
key: gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
- GDJS/node_modules
key: gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}-{{ checksum "GDJS/package-lock.json" }}
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
- run:
@@ -295,14 +301,203 @@ jobs:
name: Deploy to S3 (specific commit)
command: aws s3 sync Binaries/embuild/GDevelop.js s3://gdevelop-gdevelop.js/$(git rev-parse --abbrev-ref HEAD)/variant/debug-sanitizers/commit/$(git rev-parse HEAD)/
# Trigger AppVeyor build, which also does a Windows build (keep it for redundancy).
trigger-appveyor-windows-build:
docker:
- image: cimg/node:16.13
steps:
- run:
name: Trigger AppVeyor Windows build
command: |
curl -H "Content-Type: application/json" \
-H "Authorization: Bearer ${APPVEYOR_API_KEY}" \
--data "{
\"accountName\": \"4ian\",
\"projectSlug\": \"gdevelop\",
\"branch\": \"${CIRCLE_BRANCH}\"
}" \
-X POST https://ci.appveyor.com/api/builds
build-windows:
executor:
name: win/default
size: medium
working_directory: /home/circleci/project
steps:
- checkout
- run:
# See https://www.ssl.com/how-to/how-to-integrate-esigner-cka-with-ci-cd-tools-for-automated-code-signing/
#
# This is necessary because of "signing to be FIPS-140 compliant". See
# https://github.com/electron-userland/electron-builder/issues/6158
#
# Make sure to DISABLE "malware blocker" in SSL.com to avoid errors like:
# Error information: "Error: SignerSign() failed." (-2146893821/0x80090003)
name: Download and Unzip eSignerCKA Setup
command: |
Invoke-WebRequest -OutFile eSigner_CKA_1.0.3.zip "https://www.ssl.com/download/ssl-com-esigner-cka-1-0-3"
Expand-Archive -Force eSigner_CKA_1.0.3.zip
Remove-Item eSigner_CKA_1.0.3.zip
Move-Item -Destination "eSigner_CKA_1.0.3.exe" -Path "eSigner_CKA_*\*.exe"
- run:
name: Setup eSignerCKA in Silent Mode
command: |
mkdir -p "/home/circleci/project/eSignerCKA"
./eSigner_CKA_1.0.3.exe /CURRENTUSER /VERYSILENT /SUPPRESSMSGBOXES /DIR="/home/circleci/project/eSignerCKA" | Out-Null
- run:
name: Config Account Information on eSignerCKA
command: |
/home/circleci/project/eSignerCKA/eSignerCKATool.exe config -mode product -user "$env:ESIGNER_USER_NAME" -pass "$env:ESIGNER_USER_PASSWORD" -totp "$env:ESIGNER_USER_TOTP" -key "/home/circleci/project/eSignerCKA/master.key" -r
- run:
name: Load Certificate into Windows Store
command: |
/home/circleci/project/eSignerCKA/eSignerCKATool.exe unload
/home/circleci/project/eSignerCKA/eSignerCKATool.exe load
- run:
name: Select Certificate From Windows Store and Sign Sample File with SignTool
command: |
$CodeSigningCert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
echo Certificate: $CodeSigningCert
- restore_cache:
name: Restore node_modules cache
keys:
- v1-win-node-{{ checksum "newIDE/app/package-lock.json" }}-{{ checksum "newIDE/electron-app/package-lock.json" }}-{{ checksum "GDJS/package-lock.json" }}
- v1-win-node-
- run:
name: Install dependencies
no_output_timeout: 25m
# Remove package-lock.json because they seems to cause the npm install to be stuck. We should try again after re-generating them.
# Also install setuptools as something requires distutils in electron-app, and it was removed in Python 3.12.
# setuptools will make distutils available again (but we should migrate our packages probably).
command: |
pip install setuptools
cd newIDE\app
npm -v
Remove-Item package-lock.json
$Env:REQUIRES_EXACT_LIBGD_JS_VERSION = "true"
npm install
cd ..\electron-app
Remove-Item package-lock.json
npm install
cd ..\..
- save_cache:
name: Save node_modules cache
key: v1-win-node-{{ checksum "newIDE/app/package-lock.json" }}-{{ checksum "newIDE/electron-app/package-lock.json" }}-{{ checksum "GDJS/package-lock.json" }}
paths:
- newIDE/app/node_modules
- newIDE/electron-app/node_modules
- GDJS/node_modules
- run:
name: Build NSIS executable (with code signing)
command: |
cd newIDE\electron-app
$CodeSigningCert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
echo Certificate: $CodeSigningCert
# Use a custom signtool path because of the signtool.exe bundled withy electron-builder not working for some reason.
# Can also be found in versioned folders like "C:/Program Files (x86)/Windows Kits/10/bin/10.0.22000.0/x86/signtool.exe".
# or "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe".
$Env:SIGNTOOL_PATH = "C:\Program Files (x86)\Windows Kits\10\App Certification Kit\signtool.exe"
# Extract thumbprint and subject name of the certificate (will be passed to electron-builder).
$Env:GD_SIGNTOOL_THUMBPRINT = $CodeSigningCert.Thumbprint
$Env:GD_SIGNTOOL_SUBJECT_NAME = ($CodeSigningCert.Subject -replace ", ?", "`n" | ConvertFrom-StringData).CN
# Build the nsis installer (signed: electron-builder will use SignTool.exe with the certificate)
node scripts/build.js --win nsis --publish=never
cd ..\..
- run:
name: Build AppX (without code signing)
# Don't sign the appx (it will be signed by the Microsoft Store).
command: |
cd newIDE\electron-app
# Build the appx (not signed). Ensure all variables used for code signing are empty.
$Env:GD_SIGNTOOL_THUMBPRINT = ''
$Env:GD_SIGNTOOL_SUBJECT_NAME = ''
$Env:CSC_LINK = ''
$Env:CSC_KEY_PASSWORD = ''
node scripts/build.js --skip-app-build --win appx --publish=never
cd ..\..
- run:
name: Clean binaries
shell: cmd.exe
command: |
rmdir /s /q newIDE\electron-app\dist\win-unpacked
- run:
name: Install AWS CLI
command: |
# Install the CLI for the current user
pip install --quiet --upgrade --user awscli
# Add the user-Scripts dir to PATH for this step and the next.
$binDir = (python -m site --user-base) + "\Scripts"
$Env:Path += ";$binDir"
# Sanity check:
aws --version
# Upload artifacts (S3)
- run:
name: Deploy to S3 (specific commit)
command: |
aws s3 sync newIDE\electron-app\dist "s3://gdevelop-releases/$Env:CIRCLE_BRANCH/commit/$Env:CIRCLE_SHA1/"
- run:
name: Deploy to S3 (latest)
command: |
aws s3 sync newIDE\electron-app\dist "s3://gdevelop-releases/$Env:CIRCLE_BRANCH/latest/"
# Upload artifacts (CircleCI)
- store_artifacts:
path: newIDE/electron-app/dist
workflows:
gdevelop_js-wasm:
jobs:
- build-gdevelop_js-wasm-only
gdevelop_js-wasm-extra-checks:
jobs:
- build-gdevelop_js-debug-sanitizers-and-extra-checks:
# Extra checks are resource intensive so don't all run them.
# Extra checks are resource intensive so don't always run them.
filters:
branches:
only:
@@ -310,13 +505,36 @@ workflows:
- /experimental-build.*/
builds:
jobs:
- build-gdevelop_js-wasm-only
- build-macos:
# The macOS version builds by itself GDevelop.js
# (so we verify we can build it on macOS).
# requires:
# - build-gdevelop_js-wasm-only
filters:
branches:
only:
- master
- /experimental-build.*/
- build-linux:
requires:
- build-gdevelop_js-wasm-only
filters:
branches:
only:
- master
- /experimental-build.*/
- build-windows:
requires:
- build-gdevelop_js-wasm-only
filters:
branches:
only:
- master
- /experimental-build.*/
- trigger-appveyor-windows-build:
requires:
- build-gdevelop_js-wasm-only
filters:
branches:
only:

View File

@@ -0,0 +1,47 @@
# GitHub Action to update extension translations.
# It copies the latest messages.js files from the GDevelop-extensions repository
# and opens a Pull Request with the changes on GDevelop's repository.
name: Update extension translations
on:
push:
branches:
- master
tags-ignore:
- "**" # Don't run on new tags
workflow_dispatch: # Allows manual triggering from the Actions tab
jobs:
update-extension-translations:
runs-on: ubuntu-latest
steps:
- name: Checkout current repository
uses: actions/checkout@v3
- name: Clone GDevelop-extensions repository
run: git clone https://github.com/GDevelopApp/GDevelop-extensions.git /tmp/GDevelop-extensions
- name: Copy and rename translation files
run: |
mkdir -p newIDE/app/src/locales
for folder in /tmp/GDevelop-extensions/.translations/*; do
if [ -d "$folder" ]; then
lang=$(basename "$folder")
mkdir -p "newIDE/app/src/locales/$lang"
cp "$folder/messages.js" "newIDE/app/src/locales/$lang/extension-messages.js"
fi
done
cp /tmp/GDevelop-extensions/.translations/LocalesMetadata.js newIDE/app/src/locales/ExtensionLocalesMetadata.js
- name: Create Pull Request with updated translations
uses: peter-evans/create-pull-request@v6
with:
commit-message: Update extension translations [skip ci]
branch: chore/update-extension-translations
delete-branch: true
title: "[Auto PR] Update extension translations"
body: |
This updates the extension translations by copying the latest messages.js files from the GDevelop-extensions repository.
Each messages.js file is renamed to extension-messages.js and placed in the corresponding language folder under `newIDE/app/src/locales`.
Please review the changes carefully before merging.

1
.gitignore vendored
View File

@@ -33,3 +33,4 @@
.Spotlight-V100
.Trashes
Thumbs.db
.claude

3
.vscode/tasks.json vendored
View File

@@ -38,8 +38,7 @@
"presentation": {
"reveal": "silent"
},
"isBackground": true,
"runOptions": { "instanceLimit": 1, "runOn": "folderOpen" }
"isBackground": true
},
{
"type": "npm",

View File

@@ -61,10 +61,12 @@ void GroupEvent::UnserializeFrom(gd::Project& project,
project, events, element.GetChild("events"));
parameters.clear();
gd::SerializerElement& parametersElement = element.GetChild("parameters");
parametersElement.ConsiderAsArrayOf("parameters");
for (std::size_t i = 0; i < parametersElement.GetChildrenCount(); ++i)
parameters.push_back(parametersElement.GetChild(i).GetValue().GetString());
if (element.HasChild("parameters")) {
gd::SerializerElement& parametersElement = element.GetChild("parameters");
parametersElement.ConsiderAsArrayOf("parameters");
for (std::size_t i = 0; i < parametersElement.GetChildrenCount(); ++i)
parameters.push_back(parametersElement.GetChild(i).GetValue().GetString());
}
}
void GroupEvent::SetBackgroundColor(unsigned int colorR_,

View File

@@ -163,6 +163,21 @@ void LinkEvent::UnserializeFrom(gd::Project& project,
// end of compatibility code
}
vector<gd::String> LinkEvent::GetAllSearchableStrings() const {
vector<gd::String> allSearchableStrings;
allSearchableStrings.push_back(target);
return allSearchableStrings;
}
bool LinkEvent::ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString) {
if (newSearchableString[0] == target) return false;
SetTarget(newSearchableString[0]);
return true;
}
bool LinkEvent::AcceptVisitor(gd::EventVisitor &eventVisitor) {
return BaseEvent::AcceptVisitor(eventVisitor) ||
eventVisitor.VisitLinkEvent(*this);

View File

@@ -109,6 +109,10 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
virtual bool IsExecutable() const override { return true; };
virtual std::vector<gd::String> GetAllSearchableStrings() const override;
virtual bool ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString) override;
virtual void SerializeTo(SerializerElement& element) const override;
virtual void UnserializeFrom(gd::Project& project,
const SerializerElement& element) override;

View File

@@ -329,7 +329,6 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
condition.SetParameters(parameters);
}
gd::EventsCodeGenerator::CheckBehaviorParameters(condition, instrInfos);
// Verify that there are no mismatches between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) {
@@ -357,6 +356,11 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
}
}
}
bool isAnyBehaviorMissing =
gd::EventsCodeGenerator::CheckBehaviorParameters(condition, instrInfos);
if (isAnyBehaviorMissing) {
return "/* Missing behavior - skipped. */";
}
if (instrInfos.IsObjectInstruction()) {
gd::String objectName = condition.GetParameter(0).GetPlainString();
@@ -488,14 +492,16 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
return outputCode;
}
void EventsCodeGenerator::CheckBehaviorParameters(
bool EventsCodeGenerator::CheckBehaviorParameters(
const gd::Instruction &instruction,
const gd::InstructionMetadata &instrInfos) {
gd::ParameterMetadataTools::IterateOverParameters(
bool isAnyBehaviorMissing = false;
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(), instrInfos.parameters,
[this](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue,
const gd::String &lastObjectName) {
[this, &isAnyBehaviorMissing,
&instrInfos](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName, size_t lastObjectIndex) {
if (ParameterMetadata::IsBehavior(parameterMetadata.GetType())) {
const gd::String &behaviorName = parameterValue.GetPlainString();
const gd::String &actualBehaviorType =
@@ -506,13 +512,25 @@ void EventsCodeGenerator::CheckBehaviorParameters(
if (!expectedBehaviorType.empty() &&
actualBehaviorType != expectedBehaviorType) {
const auto &objectParameterMetadata =
instrInfos.GetParameter(lastObjectIndex);
// Event functions crash if some objects in a group are missing
// the required behaviors, since they lose reference to the original
// objects. Missing behaviors are considered "fatal" only for
// ObjectList parameters, in order to minimize side effects on
// built-in functions.
if (objectParameterMetadata.GetType() == "objectList") {
isAnyBehaviorMissing = true;
}
gd::ProjectDiagnostic projectDiagnostic(
gd::ProjectDiagnostic::ErrorType::MissingBehavior, "",
actualBehaviorType, expectedBehaviorType, lastObjectName);
if (diagnosticReport) diagnosticReport->Add(projectDiagnostic);
if (diagnosticReport)
diagnosticReport->Add(projectDiagnostic);
}
}
});
return isAnyBehaviorMissing;
}
/**
@@ -552,7 +570,6 @@ gd::String EventsCodeGenerator::GenerateActionCode(
action.SetParameters(parameters);
}
gd::EventsCodeGenerator::CheckBehaviorParameters(action, instrInfos);
// Verify that there are no mismatches between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) {
@@ -579,6 +596,11 @@ gd::String EventsCodeGenerator::GenerateActionCode(
}
}
}
bool isAnyBehaviorMissing =
gd::EventsCodeGenerator::CheckBehaviorParameters(action, instrInfos);
if (isAnyBehaviorMissing) {
return "/* Missing behavior - skipped. */";
}
// Call free function first if available
if (instrInfos.IsObjectInstruction()) {
@@ -769,7 +791,7 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
} else {
outputCode += actionCode;
}
outputCode += "}";
outputCode += "}\n";
}
return outputCode;
@@ -1358,12 +1380,30 @@ gd::String EventsCodeGenerator::GeneratePropertyGetter(const gd::PropertiesConta
return "getProperty" + property.GetName() + "As" + type + "()";
}
gd::String EventsCodeGenerator::GeneratePropertyGetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property) {
return "getProperty" + property.GetName() + "()";
}
gd::String EventsCodeGenerator::GeneratePropertySetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property,
const gd::String &operandCode) {
return "setProperty" + property.GetName() + "(" + operandCode + ")";
}
gd::String EventsCodeGenerator::GenerateParameterGetter(const gd::ParameterMetadata& parameter,
const gd::String& type,
gd::EventsCodeGenerationContext& context) {
return "getParameter" + parameter.GetName() + "As" + type + "()";
}
gd::String EventsCodeGenerator::GenerateParameterGetterWithoutCasting(
const gd::ParameterMetadata &parameter) {
return "getParameter" + parameter.GetName() + "()";
}
EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
const gd::Layout& layout,
const gd::Platform& platform_)

View File

@@ -467,7 +467,14 @@ class GD_CORE_API EventsCodeGenerator {
*/
virtual gd::String GetCodeNamespace() { return ""; };
enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE, ANY_VARIABLE };
enum VariableScope {
LAYOUT_VARIABLE = 0,
PROJECT_VARIABLE,
OBJECT_VARIABLE,
ANY_VARIABLE,
VARIABLE_OR_PROPERTY,
VARIABLE_OR_PROPERTY_OR_PARAMETER
};
/**
* Generate a single unique number for the specified instruction.
@@ -510,6 +517,11 @@ class GD_CORE_API EventsCodeGenerator {
GenerateAnyOrSceneVariableGetter(const gd::Expression &variableExpression,
EventsCodeGenerationContext &context);
virtual gd::String GeneratePropertySetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property,
const gd::String &operandCode);
protected:
virtual const gd::String GenerateRelationalOperatorCodes(
const gd::String& operatorString);
@@ -565,7 +577,8 @@ protected:
const gd::String& variableName,
const VariableScope& scope,
gd::EventsCodeGenerationContext& context,
const gd::String& objectName) {
const gd::String& objectName,
bool hasChild) {
// This code is only used as a mock.
// See the real implementation in GDJS.
if (scope == LAYOUT_VARIABLE) {
@@ -573,7 +586,9 @@ protected:
} else if (scope == PROJECT_VARIABLE) {
return "getProjectVariable(" + variableName + ")";
} else if (scope == ANY_VARIABLE) {
} else if (scope == ANY_VARIABLE || scope == VARIABLE_OR_PROPERTY ||
scope == VARIABLE_OR_PROPERTY_OR_PARAMETER) {
// TODO Split the 3 cases to make tests stronger.
return "getAnyVariable(" + variableName + ")";
}
@@ -627,11 +642,18 @@ protected:
const gd::String& type,
gd::EventsCodeGenerationContext& context);
virtual gd::String GeneratePropertyGetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property);
virtual gd::String GenerateParameterGetter(
const gd::ParameterMetadata& parameter,
const gd::String& type,
gd::EventsCodeGenerationContext& context);
virtual gd::String
GenerateParameterGetterWithoutCasting(const gd::ParameterMetadata &parameter);
/**
* \brief Generate the code to reference an object which is
* in an empty/null state.
@@ -815,7 +837,7 @@ protected:
virtual gd::String GenerateGetBehaviorNameCode(
const gd::String& behaviorName);
void CheckBehaviorParameters(
bool CheckBehaviorParameters(
const gd::Instruction &instruction,
const gd::InstructionMetadata &instrInfos);

View File

@@ -135,18 +135,20 @@ void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
EventsCodeGenerator::VariableScope scope =
type == "variable"
? gd::EventsCodeGenerator::ANY_VARIABLE
: type == "globalvar"
? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar"
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
: type == "variableOrProperty"
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY
: type == "variableOrPropertyOrParameter"
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY_OR_PARAMETER
: type == "globalvar" ? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar" ? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetObjectsContainersList(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.name, scope, context, objectName);
node.name, scope, context, objectName, node.child != nullptr);
if (node.child) node.child->Visit(*this);
} else {
// The node represents a variable or an object variable in an expression waiting for its *value* to be returned.
@@ -163,7 +165,7 @@ void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
output += codeGenerator.GenerateGetVariable(
node.name, gd::EventsCodeGenerator::ANY_VARIABLE, context, "");
node.name, gd::EventsCodeGenerator::ANY_VARIABLE, context, "", node.child != nullptr);
if (node.child) node.child->Visit(*this);
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
@@ -184,8 +186,9 @@ void ExpressionCodeGenerator::OnVisitVariableAccessorNode(
VariableAccessorNode& node) {
if (!objectNameToUseForVariableAccessor.empty()) {
// Use the name of the object passed by the parent, as we need both to access an object variable.
output += codeGenerator.GenerateGetVariable(node.name,
gd::EventsCodeGenerator::OBJECT_VARIABLE, context, objectNameToUseForVariableAccessor);
output += codeGenerator.GenerateGetVariable(
node.name, gd::EventsCodeGenerator::OBJECT_VARIABLE, context,
objectNameToUseForVariableAccessor, node.child != nullptr);
// We have accessed an object variable, from now we can continue accessing the child variables
// (including using the bracket notation).
@@ -222,24 +225,27 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
output +=
codeGenerator.GenerateObject(node.identifierName, type, context);
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
EventsCodeGenerator::VariableScope scope =
EventsCodeGenerator::VariableScope scope =
type == "variable"
? gd::EventsCodeGenerator::ANY_VARIABLE
: type == "globalvar"
? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar"
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
: type == "variableOrProperty"
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY
: type == "variableOrPropertyOrParameter"
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY_OR_PARAMETER
: type == "globalvar" ? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar" ? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetObjectsContainersList(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.identifierName, scope, context, objectName);
if (!node.childIdentifierName.empty()) {
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
codeGenerator.GetPlatform(), codeGenerator.GetObjectsContainersList(),
rootObjectName, node);
output += codeGenerator.GenerateGetVariable(
node.identifierName, scope, context, objectName,
!node.childIdentifierName.empty());
if (!node.childIdentifierName.empty()) {
output +=
codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}
} else {
const auto& variablesContainersList = codeGenerator.GetProjectScopedContainers().GetVariablesContainersList();
const auto& propertiesContainersList = codeGenerator.GetProjectScopedContainers().GetPropertiesContainersList();
@@ -249,12 +255,13 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
codeGenerator.GetProjectScopedContainers().MatchIdentifierWithName<void>(node.identifierName, [&]() {
// Generate the code to access the object variable.
output += codeGenerator.GenerateGetVariable(
node.childIdentifierName, gd::EventsCodeGenerator::OBJECT_VARIABLE, context, node.identifierName);
node.childIdentifierName, gd::EventsCodeGenerator::OBJECT_VARIABLE,
context, node.identifierName, !node.childIdentifierName.empty());
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
output += codeGenerator.GenerateGetVariable(
node.identifierName, gd::EventsCodeGenerator::ANY_VARIABLE, context,
"");
node.identifierName, gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY_OR_PARAMETER, context,
"", !node.childIdentifierName.empty());
if (!node.childIdentifierName.empty()) {
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}

View File

@@ -18,8 +18,6 @@ namespace gd {
EventsList BaseEvent::badSubEvents;
VariablesContainer BaseEvent::badLocalVariables;
std::vector<gd::String> BaseEvent::emptyDependencies;
gd::String BaseEvent::emptySourceFile;
BaseEvent::BaseEvent()
: totalTimeDuringLastSession(0),

View File

@@ -175,26 +175,6 @@ class GD_CORE_API BaseEvent {
noExpr;
return noExpr;
};
/**
* \brief Returns the dependencies on source files of the project.
* \note Default implementation returns an empty list of dependencies. This is
* fine for most events that are not related to adding custom user source
* code.
*/
virtual const std::vector<gd::String>& GetSourceFileDependencies() const {
return emptyDependencies;
};
/**
* \brief Returns the name of the source file associated with the event
* \note Default implementation returns an empty string. This is fine for most
* events that are not related to adding custom user source code.
*/
virtual const gd::String& GetAssociatedGDManagedSourceFile(
gd::Project& project) const {
return emptySourceFile;
};
///@}
/** \name Code generation
@@ -306,6 +286,20 @@ class GD_CORE_API BaseEvent {
* \brief True if the event should be folded in the events editor.
*/
bool IsFolded() const { return folded; }
/**
* \brief Set the AI generated event ID.
*/
void SetAiGeneratedEventId(const gd::String& aiGeneratedEventId_) {
aiGeneratedEventId = aiGeneratedEventId_;
}
/**
* \brief Get the AI generated event ID.
*/
const gd::String& GetAiGeneratedEventId() const {
return aiGeneratedEventId;
}
///@}
std::weak_ptr<gd::BaseEvent>
@@ -324,11 +318,10 @@ class GD_CORE_API BaseEvent {
bool disabled; ///< True if the event is disabled and must not be executed
gd::String type; ///< Type of the event. Must be assigned at the creation.
///< Used for saving the event for instance.
gd::String aiGeneratedEventId; ///< When generated by an AI/external tool.
static gd::EventsList badSubEvents;
static gd::VariablesContainer badLocalVariables;
static std::vector<gd::String> emptyDependencies;
static gd::String emptySourceFile;
};
/**

View File

@@ -221,6 +221,8 @@ void EventsListSerialization::UnserializeEventsFrom(
event->SetDisabled(eventElem.GetBoolAttribute("disabled", false));
event->SetFolded(eventElem.GetBoolAttribute("folded", false));
event->SetAiGeneratedEventId(
eventElem.GetStringAttribute("aiGeneratedEventId", ""));
list.InsertEvent(event, list.GetEventsCount());
}
@@ -236,6 +238,8 @@ void EventsListSerialization::SerializeEventsTo(const EventsList& list,
if (event.IsDisabled())
eventElem.SetAttribute("disabled", event.IsDisabled());
if (event.IsFolded()) eventElem.SetAttribute("folded", event.IsFolded());
if (!event.GetAiGeneratedEventId().empty())
eventElem.SetAttribute("aiGeneratedEventId", event.GetAiGeneratedEventId());
eventElem.AddChild("type").SetValue(event.GetType());
event.SerializeTo(eventElem);

View File

@@ -141,7 +141,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"res/function32.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced();
.MarkAsAdvanced()
.SetHidden();
extension
.AddExpression(
@@ -177,7 +178,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters(
"number", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition(
@@ -191,7 +193,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters(
"string", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
}
} // namespace gd

View File

@@ -37,8 +37,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetIcon("res/actions/position24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Angle"))
.SetIcon("res/actions/direction24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
.SetIcon("res/actions/scale24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Size")).SetIcon(
"res/actions/scale24_black.png");
gd::ObjectMetadata& obj = extension.AddObject<gd::ObjectConfiguration>(
"", _("Base object"), _("Base object"), "res/objeticon24.png");
@@ -117,7 +117,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Change the position of the center of _PARAM0_: _PARAM1_ "
"_PARAM2_ (x "
"axis), _PARAM3_ _PARAM4_ (y axis)"),
_("Position/Center"),
_("Position Center"),
"res/actions/position24_black.png",
"res/actions/position_black.png")
.AddParameter("object", _("Object"))
@@ -133,7 +133,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Center X position"),
_("the X position of the center of rotation"),
_("the X position of the center"),
_("Position/Center"),
_("Position Center"),
"res/actions/position24_black.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -144,7 +144,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Center Y position"),
_("the Y position of the center of rotation"),
_("the Y position of the center"),
_("Position/Center"),
_("Position Center"),
"res/actions/position24_black.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -155,7 +155,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) left position"),
_("the bounding box left position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-left_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -166,7 +166,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Bounding box top position"),
_("the bounding box (the area encapsulating the object) top position"),
_("the bounding box top position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-top_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -177,7 +177,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) right position"),
_("the bounding box right position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-right_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -188,7 +188,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) bottom position"),
_("the bounding box bottom position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-bottom_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -199,7 +199,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) center X position"),
_("the bounding box center X position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-center_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -210,7 +210,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) center Y position"),
_("the bounding box center Y position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-center_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -235,7 +235,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction("SetAngle",
_("Angle"),
_("Change the angle of rotation of an object (in degrees)."),
_("Change the angle of rotation of an object (in degrees). For "
"3D objects, this is the rotation around the Z axis."),
_("the angle"),
_("Angle"),
"res/actions/direction24_black.png",
@@ -250,12 +251,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction("Rotate",
_("Rotate"),
_("Rotate an object, clockwise if the speed is positive, "
"counterclockwise otherwise."),
"counterclockwise otherwise. For 3D objects, this is the "
"rotation around the Z axis."),
_("Rotate _PARAM0_ at speed _PARAM1_ deg/second"),
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angular speed (in degrees per second)"))
.AddCodeOnlyParameter("currentScene", "")
@@ -269,7 +270,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle to rotate towards (in degrees)"))
.AddParameter("expression", _("Angular speed (in degrees per second)"))
@@ -285,7 +285,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
@@ -304,12 +303,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Speed on X axis (in pixels per second)"))
.AddParameter("expression", _("Speed on Y axis (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0");
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddAction("AddForceAL",
_("Add a force (angle)"),
@@ -321,12 +320,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction(
@@ -339,13 +338,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction(
@@ -360,13 +359,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/forceTourne24.png",
"res/actions/forceTourne.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", "X position of the center")
.AddParameter("expression", "Y position of the center")
.AddParameter("expression", "Speed (in Degrees per seconds)")
.AddParameter("expression", "Distance (in pixels)")
.AddParameter("forceMultiplier", "Force multiplier")
.SetHelpPath("/tutorials/how-to-move-objects/")
.SetHidden();
obj.AddAction("Arreter",
@@ -376,8 +375,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/arreter24.png",
"res/actions/arreter.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction("Delete",
@@ -418,7 +417,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddAction("SetNumberObjectVariable",
_("Change variable value"),
_("Change object variable value"),
_("Modify the number value of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
@@ -429,10 +428,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddAction("SetStringObjectVariable",
_("Change text variable"),
_("Change object variable value"),
_("Modify the text of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
@@ -443,10 +443,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddAction("SetBooleanObjectVariable",
_("Change boolean variable"),
_("Change object variable value"),
_("Modify the boolean value of an object variable."),
_("Change the variable _PARAM1_ of _PARAM0_: _PARAM2_"),
_("Variables"),
@@ -458,10 +459,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
.AddCodeOnlyParameter("yesorno", _("Value"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddCondition("NumberObjectVariable",
_("Variable value"),
_("Object variable value"),
_("Compare the number value of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
@@ -472,10 +474,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddCondition("StringObjectVariable",
_("Text variable"),
_("Object variable value"),
_("Compare the text of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
@@ -486,10 +489,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddCondition("BooleanObjectVariable",
_("Boolean variable"),
_("Object variable value"),
_("Compare the boolean value of an object variable."),
_("The variable _PARAM1_ of _PARAM0_ is _PARAM2_"),
_("Variables"),
@@ -502,6 +506,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
.AddCodeOnlyParameter("yesorno", _("Value"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddAction("ModVarObjet",
@@ -514,6 +519,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
@@ -528,6 +534,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
@@ -544,6 +551,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddAction(
@@ -560,6 +568,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("ObjectVariableChildExists",
@@ -567,24 +576,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Check if the specified child of the object "
"structure variable exists."),
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Structure variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction("ObjectVariableRemoveChild",
_("Remove a child"),
_("Remove a child from an object structure variable."),
_("Remove child _PARAM2_ from variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction("ObjectVariableClearChildren",
@@ -592,11 +603,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Remove all the children from the object array or structure "
"variable."),
_("Clear children from variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array or structure variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction("Cache",
@@ -624,7 +636,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddCondition("Angle",
_("Angle"),
_("Compare the angle of the specified object."),
_("Compare the angle, in degrees, of the specified object. "
"For 3D objects, this is the angle around the Z axis."),
_("the angle (in degrees)"),
_("Angle"),
"res/conditions/direction24_black.png",
@@ -691,8 +704,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/conditions/arret24.png",
"res/conditions/arret.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddCondition("Vitesse",
@@ -702,10 +715,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/conditions/vitesse24.png",
"res/conditions/vitesse.png")
.AddParameter("object", _("Object"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
// Deprecated
@@ -722,6 +735,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddCondition("IsTotalForceAngleAround",
@@ -735,6 +749,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddCondition("VarObjet",
@@ -749,6 +764,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("VarObjetTxt",
@@ -763,6 +779,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("ObjectVariableAsBoolean",
@@ -777,6 +794,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("VarObjetDef",
@@ -793,42 +811,44 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction(
"PushStringToObjectVariable",
_("Add text variable"),
_("Add value to object array variable"),
_("Adds a text (string) to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForLayoutEventsOnly();
obj.AddAction("PushNumberToObjectVariable",
_("Add variable array value"),
_("Add value to object array variable"),
_("Adds a number to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForLayoutEventsOnly();
obj.AddAction(
"PushBooleanToObjectVariable",
_("Add boolean variable"),
_("Adds a boolean to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
obj.AddAction("PushBooleanToObjectVariable",
_("Add value to object array variable"),
_("Adds a boolean to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForLayoutEventsOnly();
@@ -838,7 +858,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add existing variable"),
_("Adds an existing variable to the end of an object array variable."),
_("Add variable _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
@@ -847,6 +867,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetParameterLongDescription(_("The content of the object variable will "
"*be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetHidden();
@@ -855,7 +876,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add existing variable"),
_("Adds an existing variable to the end of an object array variable."),
_("Add variable _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
@@ -864,6 +885,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetParameterLongDescription(_("The content of the object variable will "
"*be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction(
@@ -871,12 +893,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add text variable"),
_("Adds a text (string) to the end of an object array variable."),
_("Add text _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
@@ -884,12 +907,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add number variable"),
_("Adds a number to the end of an object array variable."),
_("Add number _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
@@ -898,12 +922,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add boolean variable"),
_("Adds a boolean to the end of an object array variable."),
_("Add boolean _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
@@ -914,12 +939,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"variable."),
_("Remove variable at index _PARAM2_ from array variable _PARAM1_ of "
"_PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddCondition(
@@ -927,13 +953,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Number of children"),
_("Compare the number of children in an object array variable."),
_("The number of children in the array variable _PARAM1_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddStrExpression(
@@ -941,40 +968,44 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("First text child"),
_("Get the value of the first element of an object array variable, if "
"it is a text (string) variable."),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"));
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddExpression(
"ArrayVariableFirstNumber",
_("First number child"),
_("Get the value of the first element of an object array variable, if "
"it is a number variable."),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"));
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddStrExpression(
"ArrayVariableLastString",
_("Last text child"),
_("Get the value of the last element of an object array variable, if "
"it is a text (string) variable."),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"));
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddExpression(
"ArrayVariableLastNumber",
_("Last number child"),
_("Get the value of the last element of an object array variable, if "
"it is a number variable."),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"));
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddCondition("BehaviorActivated",
_("Behavior activated"),
@@ -1009,12 +1040,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/forceVers24.png",
"res/actions/forceVers.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Target Object"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction(
@@ -1029,13 +1060,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/forceTourne24.png",
"res/actions/forceTourne.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Rotate around this object"))
.AddParameter("expression", _("Speed (in degrees per second)"))
.AddParameter("expression", _("Distance (in pixels)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction("MettreAutour",
@@ -1063,10 +1094,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.SetHidden()
.AddParameter("object", _("Object"))
.AddParameter("objectList", "Object 2 (won't move)");
.AddParameter("objectList", "Object 2 (won't move)")
.SetHelpPath("/tutorials/how-to-move-objects/");
// Deprecated action
obj.AddAction("Ecarter",
@@ -1090,7 +1121,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Position"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.AddParameter("object", _("Object"))
.AddParameter("objectList", _("Objects (won't move)"))
.AddParameter("yesorno",
@@ -1099,6 +1129,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"",
true)
.SetDefaultValue("no")
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple();
obj.AddCondition("CollisionPoint",
@@ -1111,6 +1142,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position of the point"))
.AddParameter("expression", _("Y position of the point"))
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple();
extension
@@ -1142,6 +1174,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("expression", _("Time in seconds"))
.SetHelpPath("/all-features/timers-and-time/")
.SetHidden();
obj.AddCondition(
@@ -1157,6 +1190,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("relationalOperator", _("Sign of the test"), "time")
.AddParameter("expression", _("Time in seconds"))
.SetHelpPath("/all-features/timers-and-time/")
.SetManipulatedType("number");
obj.AddCondition("ObjectTimerPaused",
@@ -1168,6 +1202,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/conditions/timerPaused.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddAction(
@@ -1180,7 +1215,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/timer24.png",
"res/actions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer");
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/");
obj.AddAction("PauseObjectTimer",
_("Pause an object timer"),
@@ -1191,6 +1227,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/pauseTimer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddAction("UnPauseObjectTimer",
@@ -1202,6 +1239,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/unPauseTimer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddAction("RemoveObjectTimer",
@@ -1213,6 +1251,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddExpression("X",
@@ -1231,7 +1270,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddExpression("Angle",
_("Angle"),
_("Current angle, in degrees, of the object"),
_("Current angle, in degrees, of the object. For 3D "
"objects, this is the angle around the Z axis."),
_("Angle"),
"res/actions/direction_black.png")
.AddParameter("object", _("Object"));
@@ -1241,28 +1281,32 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("X coordinate of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("ForceY",
_("Y coordinate of the sum of forces"),
_("Y coordinate of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("ForceAngle",
_("Angle of the sum of forces"),
_("Angle of the sum of forces (in degrees)"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("ForceLength",
_("Length of the sum of forces"),
_("Length of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("Longueur",
_("Length of the sum of forces"),
@@ -1270,6 +1314,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.SetHidden();
obj.AddExpression("Width",
@@ -1366,10 +1411,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"VariableChildCount",
_("Number of children"),
_("Number of children in an object array or structure variable"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array or structure variable"));
.AddParameter("objectvar", _("Array or structure variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddStrExpression("VariableString",
_("Text variable"),
@@ -1378,6 +1424,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddExpression("ObjectTimerElapsedTime",
@@ -1386,7 +1433,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Timers"),
"res/actions/time.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer");
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/");
obj.AddExpression("AngleToObject",
_("Angle between two objects"),
@@ -1526,7 +1574,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
extension
.AddAction("Create",
_("Create an object"),
_("Create an object at specified position"),
_("Create an instance of the object at the specified position."
"The created object instance will be available for the next "
"actions and sub-events."),
_("Create object _PARAM1_ at position _PARAM2_;_PARAM3_ "
"(layer: _PARAM4_)"),
"",
@@ -1606,6 +1656,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/doMove24.png",
"res/actions/doMove.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
extension
@@ -1621,6 +1672,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectList", _("Object 2"))
.AddParameter("expression", _("Tolerance, in degrees"))
.AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
extension
@@ -1753,6 +1805,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"",
true)
.SetDefaultValue("no")
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple();
extension
@@ -1815,6 +1868,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/all-features/collisions/")
.MarkAsAdvanced();
extension
@@ -1846,6 +1900,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/all-features/collisions/")
.MarkAsAdvanced();
extension

View File

@@ -18,21 +18,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("AnimatableCapability",
_("Animatable capability"),
_("Animate objects."),
_("Objects with animations"),
_("Actions and conditions for objects having animations (sprite, 3D models...)."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Animatable capability"))
extension.AddInstructionOrExpressionGroupMetadata(_("Objects with animations"))
.SetIcon("res/actions/animation24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Animations and images"))
.SetIcon("res/actions/animation24.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"AnimatableBehavior",
_("Animatable capability"),
_("Objects with animations"),
"Animation",
_("Animate objects."),
_("Actions and conditions for objects having animations (sprite, 3D models...).."),
"",
"res/actions/animation24.png",
"AnimatableBehavior",

View File

@@ -18,8 +18,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("EffectCapability",
_("Effect capability"),
_("Apply visual effects to objects."),
_("Objects with effects"),
_("Actions/conditions to enable/disable and change parameters of visual effects applied on objects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
@@ -28,9 +28,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
gd::BehaviorMetadata& aut = extension.AddBehavior(
"EffectBehavior",
_("Effect capability"),
_("Objects with effects"),
"Effect",
_("Apply visual effects to objects."),
_("Actions/conditions to enable/disable and change parameters of visual effects applied on objects."),
"",
"res/actions/effect_black.svg",
"EffectBehavior",

View File

@@ -18,8 +18,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("FlippableCapability",
_("Flippable capability"),
_("Flip objects."),
_("Flippable objects"),
_("Actions/conditions for objects which can be flipped horizontally or vertically."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
@@ -28,9 +28,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
gd::BehaviorMetadata& aut = extension.AddBehavior(
"FlippableBehavior",
_("Flippable capability"),
_("Flippable objects"),
"Flippable",
_("Flip objects."),
_("Actions/conditions for objects which can be flipped horizontally or vertically."),
"",
"res/actions/flipX24.png",
"FlippableBehavior",

View File

@@ -18,27 +18,30 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("OpacityCapability",
_("Opacity capability"),
_("Change the object opacity."),
_("Objects with opacity"),
_("Action/condition/expression to change or "
"check the opacity of an object (0-255)."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Opacity capability"))
extension.AddInstructionOrExpressionGroupMetadata(_("Objects with opacity"))
.SetIcon("res/actions/opacity24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
.SetIcon("res/actions/opacity24.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"OpacityBehavior",
_("Opacity capability"),
"Opacity",
_("Change the object opacity."),
"",
"res/actions/opacity24.png",
"OpacityBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
gd::BehaviorMetadata& aut =
extension
.AddBehavior("OpacityBehavior",
_("Objects with opacity"),
"Opacity",
_("Action/condition/expression to change or check the "
"opacity of an object (0-255)."),
"",
"res/actions/opacity24.png",
"OpacityBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddExpressionAndConditionAndAction(
"number",
@@ -52,8 +55,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "OpacityBehavior")
.UseStandardParameters(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Opacity (0-255)")))
"number",
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Opacity (0-255)")))
.SetFunctionName("setOpacity")
.SetGetter("getOpacity");
aut.GetAllExpressions()["Value"].SetGroup("");

View File

@@ -16,11 +16,13 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsResizableExtension(
gd::PlatformExtension &extension) {
extension
.SetExtensionInformation("ResizableCapability",
_("Resizable capability"),
_("Change the object dimensions."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionInformation(
"ResizableCapability",
_("Resizable objects"),
_("Change or compare the size (width/height) of an object which can "
"be resized (i.e: most objects)."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Size")).SetIcon(
"res/actions/scale24_black.png");
@@ -28,9 +30,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsResizableExtension(
gd::BehaviorMetadata &aut =
extension
.AddBehavior("ResizableBehavior",
_("Resizable capability"),
_("Resizable objects"),
"Resizable",
_("Change the object dimensions."),
_("Change or compare the size (width/height) of an "
"object which can be resized (i.e: most objects)."),
"",
"res/actions/scale24_black.png",
"ResizableBehavior",

View File

@@ -18,27 +18,30 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("ScalableCapability",
_("Scalable capability"),
_("Change the object scale."),
_("Scalable objects"),
_("Actions/conditions/expression to change or "
"check the scale of an object (default: 1)."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable capability"))
.SetIcon("res/actions/scale24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable objects"))
.SetIcon("res/actions/scale24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Size")).SetIcon(
"res/actions/scale24_black.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"ScalableBehavior",
_("Scalable capability"),
"Scale",
_("Change the object scale."),
"",
"res/actions/scale24_black.png",
"ResizableBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
gd::BehaviorMetadata& aut =
extension
.AddBehavior("ScalableBehavior",
_("Scalable objects"),
"Scale",
_("Actions/conditions/expression to change or check the "
"scale of an object (default: 1)."),
"",
"res/actions/scale24_black.png",
"ResizableBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddExpressionAndConditionAndAction(
"number",

View File

@@ -18,19 +18,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTextContainerExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("TextContainerCapability",
_("Text capability"),
_("Animate objects."),
_("Objects containing a text"),
_("Allows an object to contain a text, usually shown on screen, that can be modified."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Text capability"))
extension.AddInstructionOrExpressionGroupMetadata(_("Objects containing a text"))
.SetIcon("res/conditions/text24_black.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"TextContainerBehavior",
_("Text capability"),
_("Objects containing a text"),
"Text",
_("Access objects text."),
_("Allows an object to contain a text, usually shown on screen, that can be modified."),
"",
"res/conditions/text24_black.png",
"TextContainerBehavior",

View File

@@ -16,7 +16,9 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
.SetExtensionInformation(
"BuiltinCommonConversions",
_("Conversion"),
"Expressions to convert number, texts and quantities.",
"Expressions to convert numbers to string, strings to numbers, "
"angles (degrees from/to radians) and a GDevelop variable to/from a "
"JSON string.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/common-conversions");
@@ -41,7 +43,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
extension
.AddStrExpression("LargeNumberToString",
_("Number > Text ( without scientific notation )"),
_("Number > Text (without scientific notation)"),
_("Convert the result of the expression to text, "
"without using the scientific notation"),
"",
@@ -72,7 +74,8 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Convert a variable to JSON"),
_("JSON"),
"res/conditions/toujours24_black.png")
.AddParameter("variable", _("The variable to be stringified"),
.AddParameter("variable",
_("The variable to be stringified"),
"AllowUndeclaredVariable");
// Deprecated

View File

@@ -59,47 +59,57 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
// end of compatibility code
extension
.AddCondition("Or",
_("Or"),
_("Check if one of the sub conditions is true"),
_("If one of these conditions is true:"),
"",
"res/conditions/or24_black.png",
"res/conditions/or_black.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
extension
.AddCondition("And",
_("And"),
_("Check if all sub conditions are true"),
_("If all of these conditions are true:"),
"",
"res/conditions/and24_black.png",
"res/conditions/and_black.png")
.AddCondition(
"Or",
_("Or"),
_("Checks if at least one sub-condition is true. If no "
"sub-condition is specified, it will always be false. "
"This is rarely used — multiple events and sub-events are "
"usually a better approach."),
_("If one of these conditions is true:"),
"",
"res/conditions/or24_black.png",
"res/conditions/or_black.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
extension
.AddCondition(
"Not",
_("Not"),
_("Return the contrary of the result of the sub conditions"),
_("Invert the logical result of these conditions:"),
"And",
_("And"),
_("Checks if all sub-conditions are true. If no sub-condition is "
"specified, it will always be false. This is rarely needed, as "
"events already check all conditions before running actions."),
_("If all of these conditions are true:"),
"",
"res/conditions/not24_black.png",
"res/conditions/not_black.png")
"res/conditions/and24_black.png",
"res/conditions/and_black.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
extension.AddCondition(
"Once",
_("Trigger once while true"),
_("Run actions only once, for each time the conditions have been met."),
_("Trigger once"),
"",
"res/conditions/once24.png",
"res/conditions/once.png");
extension
.AddCondition("Not",
_("Not"),
_("Returns the opposite of the sub-condition(s) result. "
"This is rarely needed, as most conditions can be "
"inverted or expressed more simply."),
_("Invert the logical result of these conditions:"),
"",
"res/conditions/not24_black.png",
"res/conditions/not_black.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
extension
.AddCondition("Once",
_("Trigger once while true"),
_("Run actions only once, for each time the conditions "
"have been met."),
_("Trigger once"),
"",
"res/conditions/once24.png",
"res/conditions/once.png")
.SetHelpPath("/all-features/advanced-conditions/trigger-once");
extension
.AddCondition("CompareNumbers",

View File

@@ -28,7 +28,7 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
.AddAction("CreateObjectsFromExternalLayout",
_("Create objects from an external layout"),
_("Create objects from an external layout."),
_("Create objects from the external layout named _PARAM1_"),
_("Create objects from the external layout named _PARAM1_ at position _PARAM2_;_PARAM3_;_PARAM4_"),
"",
"res/ribbon_default/externallayout32.png",
"res/ribbon_default/externallayout32.png")

View File

@@ -15,10 +15,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
.SetExtensionInformation(
"BuiltinKeyboard",
_("Keyboard"),
_("Allows your game to respond to keyboard input. Note that this "
_("Conditions to check keys pressed on a keyboard. Note that this "
"does not work with on-screen keyboard on touch devices: use "
"instead conditions related to touch when making a game for "
"mobile/touchscreen devices."),
"instead mouse/touch conditions when making a game for "
"mobile/touchscreen devices or when making a new game from "
"scratch."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/keyboard")
@@ -35,7 +36,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("key", _("Key"));
.AddParameter("key", _("Key to check"))
.SetHidden();
extension
.AddCondition("KeyReleased",
@@ -46,33 +48,47 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("key", _("Key"));
.AddParameter("key", _("Key to check"))
.SetHidden();
extension
.AddCondition("KeyFromTextPressed",
_("Key pressed (text expression)"),
_("Check if a key, retrieved from the result of the "
"expression, is pressed"),
_("_PARAM1_ key is pressed"),
.AddCondition(
"KeyFromTextPressed",
_("Key pressed"),
_("Check if a key is pressed. This stays true as long as "
"the key is held down. To check if a key was pressed during "
"the frame, use \"Key just pressed\" instead."),
_("_PARAM1_ key is pressed"),
"",
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("keyboardKey", _("Key to check"))
.MarkAsSimple();
extension
.AddCondition("KeyFromTextJustPressed",
_("Key just pressed"),
_("Check if a key was just pressed."),
_("_PARAM1_ key was just pressed"),
"",
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Expression generating the key to check"))
.MarkAsAdvanced();
.AddParameter("keyboardKey", _("Key to check"))
.MarkAsSimple();
extension
.AddCondition("KeyFromTextReleased",
_("Key released (text expression)"),
_("Check if a key, retrieved from the result of the "
"expression, was just released"),
_("Key released"),
_("Check if a key was just released."),
_("_PARAM1_ key is released"),
"",
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Expression generating the key to check"))
.MarkAsAdvanced();
.AddParameter("keyboardKey", _("Key to check"))
.MarkAsSimple();
extension
.AddCondition("AnyKeyPressed",
@@ -84,7 +100,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
extension
extension
.AddCondition("AnyKeyReleased",
_("Any key released"),
_("Check if any key is released"),

View File

@@ -72,7 +72,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension
.AddExpression("normalize",
_("Normalize a value between `min` and `max` to a value between 0 and 1."),
_("Normalize a value between `min` and `max` to a value "
"between 0 and 1."),
_("Remap a value between 0 and 1."),
"",
"res/mathfunction.png")
@@ -124,7 +125,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension
.AddExpression("mod",
_("Modulo"),
_("x mod y"),
_("Compute \"x mod y\". GDevelop does NOT support the \% "
"operator. Use this mod(x, y) function instead."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("x (as in x mod y)"))
@@ -151,7 +153,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension
.AddExpression("abs",
_("Absolute value"),
_("Absolute value"),
_("Return the non-negative value by removing the sign. "
"The absolute value of -8 is 8."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -183,11 +186,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression("asinh",
_("Arcsine"),
_("Arcsine"),
"",
"res/mathfunction.png")
.AddExpression(
"asinh", _("Arcsine"), _("Arcsine"), "", "res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -217,11 +217,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression("cbrt",
_("Cube root"),
_("Cube root"),
"",
"res/mathfunction.png")
.AddExpression(
"cbrt", _("Cube root"), _("Cube root"), "", "res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -259,12 +256,13 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"), "", true);
extension
.AddExpression("cos",
_("Cosine"),
_("Cosine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddExpression(
"cos",
_("Cosine"),
_("Cosine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -292,29 +290,20 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression("int",
_("Round"),
_("Round a number"),
"",
"res/mathfunction.png")
.AddExpression(
"int", _("Round"), _("Round a number"), "", "res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
extension
.AddExpression("rint",
_("Round"),
_("Round a number"),
"",
"res/mathfunction.png")
.AddExpression(
"rint", _("Round"), _("Round a number"), "", "res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
extension
.AddExpression("round",
_("Round"),
_("Round a number"),
"",
"res/mathfunction.png")
.AddExpression(
"round", _("Round"), _("Round a number"), "", "res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -323,8 +312,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
_("Round a number to the Nth decimal place"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"))
.AddParameter("expression", _("Expression"), "", true);
.AddParameter("expression", _("Number to Round"))
.AddParameter("expression", _("Decimal Places"), "", true);
extension
.AddExpression("exp",
@@ -335,19 +324,13 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression("log",
_("Logarithm"),
_("Logarithm"),
"",
"res/mathfunction.png")
.AddExpression(
"log", _("Logarithm"), _("Logarithm"), "", "res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("ln",
_("Logarithm"),
_("Logarithm"),
"",
"res/mathfunction.png")
.AddExpression(
"ln", _("Logarithm"), _("Logarithm"), "", "res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -386,11 +369,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("The exponent (n in x^n)"));
extension
.AddExpression("sec",
_("Secant"),
_("Secant"),
"",
"res/mathfunction.png")
.AddExpression(
"sec", _("Secant"), _("Secant"), "", "res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -402,12 +382,13 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression("sin",
_("Sine"),
_("Sine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddExpression(
"sin",
_("Sine"),
_("Sine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -427,12 +408,13 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression("tan",
_("Tangent"),
_("Tangent of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `tan(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddExpression(
"tan",
_("Tangent"),
_("Tangent of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `tan(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -462,26 +444,28 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("x (in a+(b-a)*x)"));
extension
.AddExpression("XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddExpression(
"XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
extension
.AddExpression("YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddExpression(
"YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
@@ -496,7 +480,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension
.AddExpression("lerpAngle",
_("Lerp (Linear interpolation) between two angles"),
_("Linearly interpolates between two angles (in degrees) by taking the shortest direction around the circle."),
_("Linearly interpolates between two angles (in degrees) "
"by taking the shortest direction around the circle."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Starting angle, in degrees"))

View File

@@ -16,8 +16,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.SetExtensionInformation(
"BuiltinMouse",
_("Mouse and touch"),
"Conditions and actions to handle either the mouse or touches on "
"touchscreen. By default, conditions related to the mouse will also "
"Conditions, actions and expressions to handle either the mouse or "
"touches on a touchscreen. Notably: cursor position, mouse wheel, "
"mouse buttons, touch positions, started/end touches, etc...\n"
"\n"
"By default, conditions related to the mouse will also "
"handle the touches - so that it's easier to handle both in your "
"game. You can disable this behavior if you want to handle them "
"separately in different events.",
@@ -252,7 +255,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to check"))
.MarkAsSimple();
.MarkAsSimple()
.SetHidden();
// Support for deprecated names:
extension.AddDuplicatedCondition("SourisBouton", "MouseButtonPressed")
@@ -262,49 +266,39 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddCondition("MouseButtonReleased",
_("Mouse button released"),
_("Check if the specified mouse button was released."),
_("_PARAM1_ mouse button was released"),
_("Touch or _PARAM1_ mouse button is released"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to check"))
.MarkAsSimple()
.SetHidden();
extension
.AddCondition("MouseButtonFromTextPressed",
_("Mouse button pressed or touch held"),
_("Check if the specified mouse button is pressed or "
"if a touch is in contact with the screen."),
_("Touch or _PARAM1_ mouse button is down"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouseButton", _("Button to check"))
.MarkAsSimple();
extension
.AddCondition(
"MouseButtonFromTextPressed",
_("Mouse button pressed or touch held (text expression)"),
_("Check if a mouse button, retrieved from the result of the "
"expression, is pressed."),
_("_PARAM1_ mouse button is pressed"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCondition("MouseButtonFromTextReleased",
_("Mouse button released"),
_("Check if the specified mouse button was released."),
_("Touch or _PARAM1_ mouse button is released"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("stringWithSelector",
_("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
extension
.AddCondition(
"MouseButtonFromTextReleased",
_("Mouse button released (text expression)"),
_("Check if a mouse button, retrieved from the result of the "
"expression, was just released."),
_("_PARAM1_ mouse button is released"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("stringWithSelector",
_("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
.AddParameter("mouseButton", _("Button to check"))
.MarkAsSimple();
extension
.AddExpressionAndCondition("number",

View File

@@ -15,8 +15,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
.SetExtensionInformation(
"BuiltinNetwork",
_("Network"),
_("Features to send web requests, communicate with external \"APIs\" "
"and other network related tasks."),
_("Actions to send web requests, communicate with external \"APIs\" "
"and other network related tasks. Also contains an action to open "
"a URL on the device browser."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/network")

View File

@@ -4,8 +4,8 @@
* reserved. This project is released under the MIT License.
*/
#include "AllBuiltinExtensions.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
@@ -16,7 +16,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
.SetExtensionInformation(
"BuiltinScene",
_("Scene"),
_("Actions and conditions to manipulate the scenes during the game."),
_("Actions/conditions to change the current scene (or pause it and "
"launch another one, or go back to the previous one), check if a "
"scene or the game has just started/resumed, preload assets of a "
"scene, get the current scene name or loading progress, quit the "
"game, set background color, or disable input when focus is lost."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
@@ -166,25 +170,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
.AddCodeOnlyParameter("currentScene", "");
extension
.AddAction("PrioritizeLoadingOfScene",
_("Preload scene"),
_("Preload a scene resources as soon as possible in background."),
_("Preload scene _PARAM1_ in background"),
"",
"res/actions/hourglass_black.svg",
"res/actions/hourglass_black.svg")
.AddAction(
"PrioritizeLoadingOfScene",
_("Preload scene"),
_("Preload a scene resources as soon as possible in background."),
_("Preload scene _PARAM1_ in background"),
"",
"res/actions/hourglass_black.svg",
"res/actions/hourglass_black.svg")
.SetHelpPath("/all-features/resources-loading")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Name of the new scene"))
.MarkAsAdvanced();
extension.AddExpressionAndCondition("number",
"SceneLoadingProgress",
_("Scene loading progress"),
_("The progress of resources loading in background for a scene (between 0 and 1)."),
_("_PARAM0_ loading progress"),
_(""),
"res/actions/hourglass_black.svg")
extension
.AddExpressionAndCondition("number",
"SceneLoadingProgress",
_("Scene loading progress"),
_("The progress of resources loading in "
"background for a scene (between 0 and 1)."),
_("_PARAM1_ loading progress"),
_(""),
"res/actions/hourglass_black.svg")
.SetHelpPath("/all-features/resources-loading")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Scene name"))
@@ -192,13 +199,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
.MarkAsAdvanced();
extension
.AddCondition("AreSceneAssetsLoaded",
_("Scene preloaded"),
_("Check if scene resources have finished to load in background."),
_("Scene _PARAM1_ was preloaded in background"),
"",
"res/actions/hourglass_black.svg",
"res/actions/hourglass_black.svg")
.AddCondition(
"AreSceneAssetsLoaded",
_("Scene preloaded"),
_("Check if scene resources have finished to load in background."),
_("Scene _PARAM1_ was preloaded in background"),
"",
"res/actions/hourglass_black.svg",
"res/actions/hourglass_black.svg")
.SetHelpPath("/all-features/resources-loading")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Scene name"))

View File

@@ -15,12 +15,13 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("Sprite",
_("Sprite"),
_("Sprite are animated object which can be used "
"for most elements of a game."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionInformation(
"Sprite",
_("Sprite"),
_("Sprite are animated objects which can be used "
"for most elements of a 2D game."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects/sprite");
extension.AddInstructionOrExpressionGroupMetadata(_("Sprite"))
.SetIcon("CppPlatform/Extensions/spriteicon.png");
@@ -30,7 +31,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.AddObject<SpriteObject>("Sprite",
_("Sprite"),
_("Animated object which can be used for "
"most elements of a game."),
"most elements of a 2D game."),
"CppPlatform/Extensions/spriteicon.png")
.SetCategoryFullName(_("General"))
.SetOpenFullEditorLabel(_("Edit animations"))
@@ -645,11 +646,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/sprite.png")
.AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("AnimationFrameCount",
_("Number of frames"),
_("Number of frames in the current animation of the object"),
_("Animations and images"),
"res/actions/sprite.png")
obj.AddExpression(
"AnimationFrameCount",
_("Number of frames"),
_("Number of frames in the current animation of the object"),
_("Animations and images"),
"res/actions/sprite.png")
.AddParameter("object", _("Object"), "Sprite");
// Deprecated

View File

@@ -16,7 +16,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.SetExtensionInformation(
"BuiltinStringInstructions",
_("Text manipulation"),
"Provides expressions to manipulate strings (also called texts).",
"Provides expressions to manipulate strings (also called texts): new "
"line, upper/lowercase, substring, find, replace, etc...",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
@@ -191,7 +192,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"res/conditions/toujours24_black.png")
.AddParameter("string", _("Text in which the replacement must be done"))
.AddParameter("string", _("Text to find inside the first text"))
.AddParameter("string", _("Replacement to put instead of the text to find"));
.AddParameter("string",
_("Replacement to put instead of the text to find"));
extension
.AddStrExpression("StrReplaceAll",
@@ -199,10 +201,11 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Replace all occurrences of a text by another."),
"",
"res/conditions/toujours24_black.png")
.AddParameter("string", _("Text in which the replacement(s) must be done"))
.AddParameter("string",
_("Text in which the replacement(s) must be done"))
.AddParameter("string", _("Text to find inside the first text"))
.AddParameter("string", _("Replacement to put instead of the text to find"));
.AddParameter("string",
_("Replacement to put instead of the text to find"));
}
} // namespace gd

View File

@@ -15,9 +15,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.SetExtensionInformation(
"BuiltinTime",
_("Timers and time"),
"Actions and conditions to run timers, get the current time or "
"modify the time scale (speed at which the game is running - useful "
"for slow motion effects).",
"Actions and conditions to start, pause or reset scene timers, "
"modify the time scale (speed at which the game "
"is running - useful for slow motion effects). Also contains an "
"action that wait for a delay before running the next actions and "
"sub-events and expressions to read the time scale, time delta of "
"the last frame or timer elapsed time.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/timers-and-time");
@@ -43,7 +46,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddCondition("CompareTimer",
_("Value of a scene timer"),
_("Compare the elapsed time of a scene timer. This "
"condition doesn't start the timer."),
"condition doesn't start the timer and will always be "
"false if the timer was not started previously (whatever "
"the comparison being made)."),
_("The timer _PARAM1_ _PARAM2_ _PARAM3_ seconds"),
"",
@@ -190,26 +195,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
extension
.AddExpression("TimerElapsedTime",
_("Scene timer value"),
_("Value of a scene timer"),
_("Value of a scene timer (in seconds)"),
"",
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer");
extension
.AddExpression("TimeFromStart",
_("Time elapsed since the beginning of the scene"),
_("Time elapsed since the beginning of the scene"),
"",
"res/actions/time.png")
.AddExpression(
"TimeFromStart",
_("Time elapsed since the beginning of the scene (in seconds)."),
_("Time elapsed since the beginning of the scene (in seconds)."),
"",
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("TempsDebut",
_("Time elapsed since the beginning of the scene"),
_("Time elapsed since the beginning of the scene"),
"",
"res/actions/time.png")
.AddExpression(
"TempsDebut",
_("Time elapsed since the beginning of the scene (in seconds)."),
_("Time elapsed since the beginning of the scene (in seconds)."),
"",
"res/actions/time.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "");
@@ -224,16 +231,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
extension
.AddExpression("Time",
_("Current time"),
_("Current time"),
_("Gives the current time"),
"",
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter(
"stringWithSelector",
_("Hour: hour - Minutes: min - Seconds: sec - Day of month: "
"mday - Months since January: mon - Year since 1900: year - Days "
"since Sunday: wday - Days since Jan 1st: yday - Timestamp (ms): "
"timestamp\""),
_("- Hour of the day: \"hour\"\n"
"- Minutes: \"min\"\n"
"- Seconds: \"sec\"\n"
"- Day of month: \"mday\"\n"
"- Months since January: \"mon\"\n"
"- Year since 1900: \"year\"\n"
"- Days since Sunday: \"wday\"\n"
"- Days since Jan 1st: \"yday\"\n"
"- Timestamp (ms): \"timestamp\""),
"[\"hour\", \"min\", \"sec\", \"mon\", \"year\", \"wday\", \"mday\", "
"\"yday\", \"timestamp\"]");
}

View File

@@ -33,7 +33,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions());
@@ -45,7 +45,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions());
@@ -58,7 +58,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
// This parameter allows to keep the operand expression
@@ -73,32 +73,32 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrProperty", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions());
extension
.AddAction("SetStringVariable",
_("Change text variable"),
_("Change variable value"),
_("Modify the text (string) of a variable."),
_("the variable _PARAM0_"),
"",
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrProperty", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions());
extension
.AddAction(
"SetBooleanVariable",
_("Change boolean variable"),
_("Change variable value"),
_("Modify the boolean value of a variable."),
_("Change the variable _PARAM0_: _PARAM1_"),
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrProperty", _("Variable"))
.AddParameter("operator", _("Value"), "boolean")
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
@@ -116,6 +116,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddParameter("variable", _("Array variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -129,6 +130,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -142,6 +144,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -154,6 +157,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Structure or array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -170,12 +174,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction(
"PushString",
_("Add text variable"),
_("Add value to array variable"),
_("Adds a text (string) at the end of a array variable."),
_("Add the value _PARAM1_ to array variable _PARAM0_"),
_("Arrays and structures"),
@@ -183,11 +188,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction("PushNumber",
_("Add variable array value"),
_("Add value to array variable"),
_("Adds a number at the end of an array variable."),
_("Add the value _PARAM1_ to array variable _PARAM0_"),
_("Arrays and structures"),
@@ -195,11 +201,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction("PushBoolean",
_("Add boolean variable"),
_("Add value to array variable"),
_("Adds a boolean at the end of an array variable."),
_("Add the value _PARAM1_ to array variable _PARAM0_"),
_("Arrays and structures"),
@@ -207,6 +214,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -221,6 +229,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -231,7 +240,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"it is a text (string)."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"));
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddExpression(
@@ -241,7 +251,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"it is a number."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"));
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddStrExpression(
@@ -251,7 +262,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"it is a text (string)."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"));
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddExpression(
@@ -261,7 +273,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"it is a number."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"));
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
// Legacy instructions
@@ -270,26 +283,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number variable"),
_("Compare the number value of a scene variable."),
_("The number of scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition("VarSceneTxt",
_("Text variable"),
_("Compare the text (string) of a scene variable."),
_("The text of scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition(
@@ -297,13 +312,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean variable"),
_("Compare the boolean value of a scene variable."),
_("The boolean value of scene variable _PARAM0_ is _PARAM1_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition("VariableChildExists",
@@ -311,12 +327,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Check if the specified child of the scene structure "
"variable exists."),
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -325,12 +343,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Check if the specified child of the global structure "
"variable exists."),
_("Child _PARAM1_ of global variable _PARAM0_ exists"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -338,7 +358,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"Variable defined",
"Test if the scene variable exists.",
"Scene variable _PARAM0_ is defined",
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -350,13 +370,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number variable"),
_("Compare the number value of a global variable."),
_("the global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -364,13 +385,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Text variable"),
_("Compare the text (string) of a global variable."),
_("the text of the global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -379,20 +401,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean variable"),
_("Compare the boolean value of a global variable."),
_("The boolean value of global variable _PARAM0_ is _PARAM1_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition("VarGlobalDef",
"Variable defined",
"Test if a global variable exists.",
"Global variable _PARAM0_ is defined",
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -405,26 +428,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change number variable"),
_("Modify the number value of a scene variable."),
_("the scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("ModVarSceneTxt",
_("Change text variable"),
_("Modify the text (string) of a scene variable."),
_("the text of scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction(
@@ -432,12 +457,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change boolean variable"),
_("Modify the boolean value of a scene variable."),
_("Set the boolean value of scene variable _PARAM0_ to _PARAM1_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("ToggleSceneVariableAsBoolean",
@@ -446,24 +472,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("If it was true, it will become false, and if it was "
"false it will become true."),
_("Toggle the boolean value of scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("ModVarGlobal",
_("Change number variable"),
_("Modify the number value of a global variable."),
_("the global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -471,13 +499,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change text variable"),
_("Modify the text (string) of a global variable."),
_("the text of global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -486,12 +515,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change boolean variable"),
_("Modify the boolean value of a global variable."),
_("Set the boolean value of global variable _PARAM0_ to _PARAM1_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("ToggleGlobalVariableAsBoolean",
@@ -500,11 +530,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("If it was true, it will become false, and if it was "
"false it will become true."),
_("Toggle the boolean value of global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction(
@@ -512,13 +543,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"),
_("Remove a child from a scene structure variable."),
_("Remove child _PARAM1_ from scene structure variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction(
@@ -526,13 +559,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"),
_("Remove a child from a global structure variable."),
_("Remove child _PARAM1_ from global structure variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("VariableClearChildren",
@@ -540,11 +575,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove all the children from the scene structure or array "
"variable."),
_("Clear children from scene variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Structure or array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -553,11 +590,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove all the children from the global structure or array "
"variable."),
_("Clear children from global variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Structure or array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -566,7 +605,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Adds an existing variable at the end of a scene array "
"variable."),
_("Add variable _PARAM1_ to array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
@@ -574,7 +613,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -583,12 +624,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add text variable"),
_("Adds a text (string) at the end of a scene array variable."),
_("Add text _PARAM1_ to array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -596,12 +639,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add number variable"),
_("Adds a number at the end of a scene array variable."),
_("Add number _PARAM1_ to array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -609,12 +654,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add boolean variable"),
_("Adds a boolean at the end of a scene array variable."),
_("Add boolean _PARAM1_ to array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -624,12 +671,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"variable."),
_("Remove variable at index _PARAM1_ from scene array "
"variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -638,13 +687,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number of children"),
_("Compare the number of children in a scene array variable."),
_("The number of children in the array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Array variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -653,10 +704,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("First text child"),
_("Get the value of the first element of a scene array variable, if "
"it is a text (string)."),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression(
@@ -664,10 +717,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("First number child"),
_("Get the value of the first element of a scene array variable, if "
"it is a number."),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddStrExpression(
@@ -675,10 +730,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last text child"),
_("Get the value of the last element of a scene array variable, if "
"it is a text (string)."),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression(
@@ -686,10 +743,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last number child"),
_("Get the value of the last element of a scene array variable, if "
"it is a number."),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction(
@@ -697,7 +756,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add existing variable"),
_("Adds an existing variable at the end of a global array variable."),
_("Add variable _PARAM1_ to array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
@@ -705,7 +764,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -715,12 +776,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"array variable."),
_("Remove variable at index _PARAM1_ from global array "
"variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -729,12 +792,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add text variable"),
_("Adds a text (string) at the end of a global array variable."),
_("Add text _PARAM1_ to array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -742,12 +807,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add number variable"),
_("Adds a number at the end of a global array variable."),
_("Add number _PARAM1_ to array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -755,12 +822,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add boolean variable"),
_("Adds a boolean at the end of a global array variable."),
_("Add boolean _PARAM1_ to array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -769,13 +838,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number of children"),
_("Compare the number of children in a global array variable."),
_("The number of children of the array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Array variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -783,20 +854,24 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("First text child"),
_("Value of the first element of a global array "
"variable, if it is a text (string) variable."),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression("GlobalVariableFirstNumber",
_("First number child"),
_("Value of the first element of a global array "
"variable, if it is a number variable"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddStrExpression(
@@ -804,10 +879,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last text child"),
_("Value of the last element of a global array variable, if "
"it is a text (string) variable."),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression(
@@ -815,20 +892,23 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last number child"),
_("Value of the last element of a global array variable, if "
"it is a number variable"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression("GlobalVariableChildCount",
_("Number of children"),
_("Number of children in a global array or "
"structure variable"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array or structure variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression("VariableChildCount",
@@ -837,43 +917,48 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"structure variable"),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array or structure variable"), "AllowUndeclaredVariable");
.AddParameter("variable", _("Array or structure variable"), "AllowUndeclaredVariable")
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddExpression("Variable",
_("Number variable"),
_("Number value of a scene variable"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddStrExpression("VariableString",
_("Text variable"),
_("Text of a scene variable"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression("GlobalVariable",
_("Number variable"),
_("Number value of a global variable"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Name of the global variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddStrExpression("GlobalVariableString",
_("Text variable"),
_("Text of a global variable"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
}
} // namespace gd

View File

@@ -15,16 +15,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
.SetExtensionInformation(
"BuiltinWindow",
_("Game window and resolution"),
"Provides actions and conditions to manipulate the game window. "
"Actions and conditions to manipulate the game window or change how "
"the game is resized according to the screen size. "
"Depending on the platform on which the game is running, not all of "
"these features can be applied.",
"these features can be applied.\n"
"Also contains expressions to read the screen size.",
"Florian Rival",
"Open source (MIT License)")
.SetCategory("User interface")
.SetExtensionHelpPath("/all-features/window");
extension
.AddInstructionOrExpressionGroupMetadata(
_("Game window and resolution"))
.AddInstructionOrExpressionGroupMetadata(_("Game window and resolution"))
.SetIcon("res/actions/window24.png");
extension

View File

@@ -272,7 +272,7 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
* Check if the behavior is private - it can't be used outside of its
* extension.
*/
bool IsPrivate() const { return isPrivate; }
bool IsPrivate() const override { return isPrivate; }
/**
* Set that the behavior is private - it can't be used outside of its
@@ -298,6 +298,19 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
return *this;
}
/**
* Check if the behavior can be used on objects from event-based objects.
*/
bool IsRelevantForChildObjects() const { return isRelevantForChildObjects; }
/**
* Set that behavior can't be used on objects from event-based objects.
*/
BehaviorMetadata &MarkAsIrrelevantForChildObjects() {
isRelevantForChildObjects = false;
return *this;
}
QuickCustomization::Visibility GetQuickCustomizationVisibility() const {
return quickCustomizationVisibility;
}
@@ -393,6 +406,7 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
mutable std::vector<gd::String> requiredBehaviors;
bool isPrivate = false;
bool isHidden = false;
bool isRelevantForChildObjects = true;
gd::String openFullEditorLabel;
QuickCustomization::Visibility quickCustomizationVisibility = QuickCustomization::Visibility::Default;

View File

@@ -174,6 +174,7 @@ public:
virtual const gd::String &GetFullName() const = 0;
virtual const gd::String &GetDescription() const = 0;
virtual const gd::String &GetIconFilename() const = 0;
virtual bool IsPrivate() const = 0;
/**
* \brief Return a reference to a map containing the names of the actions

View File

@@ -277,6 +277,10 @@ class GD_CORE_API MetadataProvider {
return &metadata == &badObjectInfo;
}
static bool IsBadEffectMetadata(const gd::EffectMetadata& metadata) {
return &metadata == &badEffectMetadata;
}
virtual ~MetadataProvider();
private:

View File

@@ -46,30 +46,25 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24)
: ObjectMetadata(extensionNamespace_,
name_,
fullname_,
description_,
icon24x24,
[]() -> std::unique_ptr<gd::ObjectConfiguration> {
gd::LogFatalError(
"Error: Event-based objects don't have blueprint. "
"This method should never be called.");
return nullptr;
}) {}
: name(name_),
iconFilename(icon24x24),
extensionNamespace(extensionNamespace_) {
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
}
ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24,
CreateFunPtr createFunPtrP)
: name(name_),
iconFilename(icon24x24),
createFunPtr(createFunPtrP),
extensionNamespace(extensionNamespace_) {
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
CreateFunPtr createFunPtr_)
: ObjectMetadata(extensionNamespace_,
name_,
fullname_,
description_,
icon24x24) {
createFunPtr = createFunPtr_;
}
gd::InstructionMetadata& ObjectMetadata::AddCondition(

View File

@@ -39,6 +39,8 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
/**
* \brief Construct an object metadata, using a "blueprint" object that will
* be copied when a new object is requested.
*
* \note This is used for objects declared in JavaScript extensions.
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
@@ -47,9 +49,9 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
const gd::String& icon24x24_,
std::shared_ptr<gd::ObjectConfiguration> blueprintObject_);
/**
* \brief Construct an object metadata, without "blueprint" object
* \brief Construct an object metadata.
*
* \note This is used by events based objects.
* \note This is used by events based objects ("custom objects").
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
@@ -60,14 +62,17 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
/**
* \brief Construct an object metadata, with a function that will be called
* to instantiate a new object.
*
* \note This is used for objects declared in C++ extensions.
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24_,
CreateFunPtr createFunPtrP);
ObjectMetadata() : createFunPtr(NULL) {}
CreateFunPtr createFunPtr_);
ObjectMetadata() {}
virtual ~ObjectMetadata(){};
/**
@@ -300,6 +305,22 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
*/
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() override { return strExpressionsInfos; };
/**
* Check if the behavior is private - it can't be used outside of its
* extension.
*/
bool IsPrivate() const override { return isPrivate; }
/**
* Set that the behavior is private - it can't be used outside of its
* extension.
*/
ObjectMetadata &SetPrivate() {
isPrivate = true;
return *this;
}
/**
* \brief Set the object to be hidden in the IDE.
*
@@ -344,7 +365,7 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
std::vector<gd::String> includeFiles;
gd::String className;
CreateFunPtr createFunPtr;
CreateFunPtr createFunPtr = nullptr;
private:
gd::String extensionNamespace;
@@ -356,6 +377,7 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
gd::String iconFilename;
gd::String categoryFullName;
std::set<gd::String> defaultBehaviorTypes;
bool isPrivate = false;
bool hidden = false;
bool isRenderedIn3D = false;
gd::String openFullEditorLabel;

View File

@@ -33,7 +33,8 @@ void ParameterMetadataTools::ParametersToObjectsContainer(
const auto& parameter = parameters.GetParameter(i);
if (parameter.GetName().empty()) continue;
if (gd::ParameterMetadata::IsObject(parameter.GetType())) {
auto &valueTypeMetadata = parameter.GetValueTypeMetadata();
if (valueTypeMetadata.IsObject()) {
const gd::String& objectName = parameter.GetName();
const gd::String& objectType = parameter.GetExtraInfo();
allObjectNames.insert(objectName);
@@ -68,7 +69,7 @@ void ParameterMetadataTools::ParametersToObjectsContainer(
// Search "lastObjectName" in the codebase for other place where this
// convention is enforced.
lastObjectName = objectName;
} else if (gd::ParameterMetadata::IsBehavior(parameter.GetType())) {
} else if (valueTypeMetadata.IsBehavior()) {
if (!lastObjectName.empty()) {
if (outputObjectsContainer.HasObjectNamed(lastObjectName)) {
const gd::String& behaviorName = parameter.GetName();
@@ -193,7 +194,8 @@ void ParameterMetadataTools::IterateOverParameters(
[&fn](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName) {
const gd::String& lastObjectName,
size_t lastObjectIndex) {
fn(parameterMetadata, parameterValue, lastObjectName);
});
}
@@ -204,8 +206,10 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName)> fn) {
const gd::String& lastObjectName,
size_t lastObjectIndex)> fn) {
gd::String lastObjectName = "";
size_t lastObjectIndex = 0;
for (std::size_t pNb = 0; pNb < parametersMetadata.GetParametersCount();
++pNb) {
const gd::ParameterMetadata &parameterMetadata =
@@ -217,15 +221,17 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
? Expression(parameterMetadata.GetDefaultValue())
: parameterValue;
fn(parameterMetadata, parameterValueOrDefault, pNb, lastObjectName);
fn(parameterMetadata, parameterValueOrDefault, pNb, lastObjectName, lastObjectIndex);
// Memorize the last object name. By convention, parameters that require
// an object (mainly, "objectvar" and "behavior") should be placed after
// the object in the list of parameters (if possible, just after).
// Search "lastObjectName" in the codebase for other place where this
// convention is enforced.
if (gd::ParameterMetadata::IsObject(parameterMetadata.GetType()))
if (gd::ParameterMetadata::IsObject(parameterMetadata.GetType())) {
lastObjectName = parameterValueOrDefault.GetPlainString();
lastObjectIndex = pNb;
}
}
}

View File

@@ -64,7 +64,8 @@ class GD_CORE_API ParameterMetadataTools {
std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName)> fn);
const gd::String& lastObjectName,
size_t lastObjectIndex)> fn);
/**
* Iterate over the parameters of a FunctionCallNode.

View File

@@ -0,0 +1,56 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/String.h"
#include "GDCore/Serialization/SerializerElement.h"
namespace gd {
/**
* \brief Contains information about a source file that must be included
* when an extension is used.
*/
class GD_CORE_API SourceFileMetadata {
public:
/**
* Construct a new dependency metadata, though you probably want to call
* `AddSourceFile` on gd::PlatformExtension.
*
* \see gd::PlatformExtension
*/
SourceFileMetadata() {};
SourceFileMetadata& SetResourceName(const gd::String& resourceName_) {
resourceName = resourceName_;
return *this;
};
SourceFileMetadata& SetIncludePosition(const gd::String& includePosition_) {
includePosition = includePosition_;
return *this;
};
const gd::String& GetResourceName() const { return resourceName; };
gd::String& GetResourceName() { return resourceName; };
const gd::String& GetIncludePosition() const { return includePosition; };
void SerializeTo(SerializerElement& element) const {
element.AddChild("resourceName").SetStringValue(resourceName);
element.AddChild("includePosition").SetStringValue(includePosition);
}
void UnserializeFrom(const SerializerElement& element) {
resourceName = element.GetStringAttribute("resourceName");
includePosition = element.GetStringAttribute("includePosition", "last");
}
private:
gd::String resourceName; ///< The name of the resource in the project.
gd::String includePosition = "last"; ///< "first" or "last".
};
} // namespace gd

View File

@@ -79,6 +79,8 @@ const gd::String ValueTypeMetadata::colorValueType = "color";
const gd::String ValueTypeMetadata::choiceValueType = "stringWithSelector";
const gd::String ValueTypeMetadata::behaviorValueType = "behavior";
const gd::String ValueTypeMetadata::leaderboardIdValueType = "leaderboardId";
const gd::String ValueTypeMetadata::objectAnimationNameValueType = "objectAnimationName";
const gd::String ValueTypeMetadata::keyboardKeyValueType = "keyboardKey";
const gd::String &ValueTypeMetadata::ConvertPropertyTypeToValueType(
const gd::String &propertyType) {
@@ -94,8 +96,12 @@ const gd::String &ValueTypeMetadata::ConvertPropertyTypeToValueType(
return behaviorValueType;
} else if (propertyType == "LeaderboardId") {
return leaderboardIdValueType;
} else if (propertyType == "ObjectAnimationName") {
return objectAnimationNameValueType;
} else if (propertyType == "KeyboardKey") {
return keyboardKeyValueType;
}
// For "String" or default
// For "String", "Resource", "MultilineString" or default
return stringValueType;
};

View File

@@ -129,7 +129,7 @@ class GD_CORE_API ValueTypeMetadata {
}
/**
* \brief Return true if the type of the parameter is a number.
* \brief Return true if the type of the parameter is a variable.
* \note If you had a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor, ParameterRenderingService
* and ExpressionAutocompletion) and in the EventsCodeGenerator.
@@ -148,6 +148,19 @@ class GD_CORE_API ValueTypeMetadata {
return gd::ValueTypeMetadata::GetPrimitiveValueType(type) == "variable";
}
/**
* \brief Return true if the type of the parameter is a variable and not a
* property or a parameter.
*/
bool IsVariableOnly() const {
return
// Any variable.
name == "variable" ||
// Old, "pre-scoped" variables:
name == "objectvar" || name == "globalvar" ||
name == "scenevar";
}
/**
* \brief Return true if the type is a variable but from a specific scope
* (scene, project or object). In new code, prefer to use the more generic "variable"
@@ -212,15 +225,20 @@ class GD_CORE_API ValueTypeMetadata {
parameterType == "functionParameterName" ||
parameterType == "externalLayoutName" ||
parameterType == "leaderboardId" ||
parameterType == "keyboardKey" ||
parameterType == "mouseButton" ||
parameterType == "identifier";
} else if (type == "boolean") {
return parameterType == "yesorno" || parameterType == "trueorfalse";
} else if (type == "variable") {
return
parameterType == "variable" || // Any variable.
// Old, "pre-scoped" variables:
parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";
// Any variable.
parameterType == "variable" ||
parameterType == "variableOrProperty" ||
parameterType == "variableOrPropertyOrParameter" ||
// Old, "pre-scoped" variables:
parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";
} else if (type == "resource") {
return parameterType == "fontResource" ||
parameterType == "audioResource" ||
@@ -316,6 +334,8 @@ class GD_CORE_API ValueTypeMetadata {
static const gd::String choiceValueType;
static const gd::String behaviorValueType;
static const gd::String leaderboardIdValueType;
static const gd::String objectAnimationNameValueType;
static const gd::String keyboardKeyValueType;
};
} // namespace gd

View File

@@ -38,12 +38,14 @@ bool Platform::AddExtension(std::shared_ptr<gd::PlatformExtension> extension) {
extensionsLoaded.push_back(extension);
// Load all creation/destruction functions for objects provided by the
// extension
// Load all creation functions for objects provided by the
// extension.
vector<gd::String> objectsTypes = extension->GetExtensionObjectsTypes();
for (std::size_t i = 0; i < objectsTypes.size(); ++i) {
creationFunctionTable[objectsTypes[i]] =
extension->GetObjectCreationFunctionPtr(objectsTypes[i]);
CreateFunPtr createFunPtr = extension->GetObjectCreationFunctionPtr(objectsTypes[i]);
if (createFunPtr != nullptr) {
creationFunctionTable[objectsTypes[i]] = createFunPtr;
}
}
for (const auto& it :
@@ -62,7 +64,9 @@ void Platform::RemoveExtension(const gd::String& name) {
if (extension->GetName() == name) {
vector<gd::String> objectsTypes = extension->GetExtensionObjectsTypes();
for (std::size_t i = 0; i < objectsTypes.size(); ++i) {
creationFunctionTable.erase(objectsTypes[i]);
if (creationFunctionTable.find(objectsTypes[i]) != creationFunctionTable.end()) {
creationFunctionTable.erase(objectsTypes[i]);
}
}
}
}

View File

@@ -18,8 +18,8 @@
#include "GDCore/Extensions/Platform.h"
#include "GDCore/IDE/PlatformManager.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/ObjectConfiguration.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/ObjectConfiguration.h"
#include "GDCore/Tools/Localization.h"
namespace gd {
@@ -200,11 +200,11 @@ PlatformExtension::AddExpressionAndConditionAndAction(
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
return MultipleInstructionMetadata::WithExpressionAndConditionAndAction(
expression, condition, action);
@@ -215,6 +215,11 @@ gd::DependencyMetadata& PlatformExtension::AddDependency() {
return extensionDependenciesMetadata.back();
}
gd::SourceFileMetadata& PlatformExtension::AddSourceFile() {
extensionSourceFilesMetadata.push_back(SourceFileMetadata());
return extensionSourceFilesMetadata.back();
}
gd::ObjectMetadata& PlatformExtension::AddObject(
const gd::String& name,
const gd::String& fullname,
@@ -239,12 +244,10 @@ gd::ObjectMetadata& PlatformExtension::AddEventsBasedObject(
const gd::String& description,
const gd::String& icon24x24) {
gd::String nameWithNamespace = GetNameSpace() + name;
objectsInfos[nameWithNamespace] = ObjectMetadata(GetNameSpace(),
nameWithNamespace,
fullname,
description,
icon24x24)
.SetHelpPath(GetHelpPath());
objectsInfos[nameWithNamespace] =
ObjectMetadata(
GetNameSpace(), nameWithNamespace, fullname, description, icon24x24)
.SetHelpPath(GetHelpPath());
return objectsInfos[nameWithNamespace];
}
@@ -348,8 +351,7 @@ gd::BehaviorMetadata& PlatformExtension::GetBehaviorMetadata(
return badBehaviorMetadata;
}
bool PlatformExtension::HasBehavior(
const gd::String& behaviorType) const {
bool PlatformExtension::HasBehavior(const gd::String& behaviorType) const {
return behaviorsInfo.find(behaviorType) != behaviorsInfo.end();
}
@@ -381,7 +383,7 @@ gd::InstructionMetadata& PlatformExtension::AddDuplicatedAction(
auto copiedAction = actionsInfos.find(copiedNameWithNamespace);
if (copiedAction == actionsInfos.end()) {
gd::LogError("Could not find an action with name " +
copiedNameWithNamespace + " to copy.");
copiedNameWithNamespace + " to copy.");
} else {
actionsInfos[newNameWithNamespace] = copiedAction->second;
}
@@ -401,7 +403,7 @@ gd::InstructionMetadata& PlatformExtension::AddDuplicatedCondition(
auto copiedCondition = conditionsInfos.find(copiedNameWithNamespace);
if (copiedCondition == conditionsInfos.end()) {
gd::LogError("Could not find a condition with name " +
copiedNameWithNamespace + " to copy.");
copiedNameWithNamespace + " to copy.");
} else {
conditionsInfos[newNameWithNamespace] = copiedCondition->second;
}
@@ -418,7 +420,7 @@ gd::ExpressionMetadata& PlatformExtension::AddDuplicatedExpression(
auto copiedExpression = expressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == expressionsInfos.end()) {
gd::LogError("Could not find an expression with name " +
copiedNameWithNamespace + " to copy.");
copiedNameWithNamespace + " to copy.");
} else {
expressionsInfos[newNameWithNamespace] = copiedExpression->second;
}
@@ -435,7 +437,7 @@ gd::ExpressionMetadata& PlatformExtension::AddDuplicatedStrExpression(
auto copiedExpression = strExpressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == strExpressionsInfos.end()) {
gd::LogError("Could not find a string expression with name " +
copiedNameWithNamespace + " to copy.");
copiedNameWithNamespace + " to copy.");
} else {
strExpressionsInfos[newNameWithNamespace] = copiedExpression->second;
}
@@ -463,10 +465,24 @@ PlatformExtension::GetAllStrExpressions() {
return strExpressionsInfos;
}
const std::vector<gd::DependencyMetadata>&
PlatformExtension::GetAllDependencies() const {
return extensionDependenciesMetadata;
}
std::vector<gd::DependencyMetadata>& PlatformExtension::GetAllDependencies() {
return extensionDependenciesMetadata;
}
const std::vector<gd::SourceFileMetadata>&
PlatformExtension::GetAllSourceFiles() const {
return extensionSourceFilesMetadata;
}
std::vector<gd::SourceFileMetadata>& PlatformExtension::GetAllSourceFiles() {
return extensionSourceFilesMetadata;
}
std::map<gd::String, gd::EventMetadata>& PlatformExtension::GetAllEvents() {
return eventsInfos;
}
@@ -598,37 +614,6 @@ void PlatformExtension::SetNameSpace(gd::String nameSpace_) {
nameSpace = nameSpace_ + GetNamespaceSeparator();
}
std::vector<gd::String> PlatformExtension::GetBuiltinExtensionsNames() {
std::vector<gd::String> builtinExtensions;
builtinExtensions.push_back("Sprite");
builtinExtensions.push_back("BuiltinObject");
builtinExtensions.push_back("BuiltinAudio");
builtinExtensions.push_back("BuiltinMouse");
builtinExtensions.push_back("BuiltinKeyboard");
builtinExtensions.push_back("BuiltinJoystick");
builtinExtensions.push_back("BuiltinTime");
builtinExtensions.push_back("BuiltinFile");
builtinExtensions.push_back("BuiltinVariables");
builtinExtensions.push_back("BuiltinCamera");
builtinExtensions.push_back("BuiltinWindow");
builtinExtensions.push_back("BuiltinNetwork");
builtinExtensions.push_back("BuiltinScene");
builtinExtensions.push_back("BuiltinAdvanced");
builtinExtensions.push_back("BuiltinCommonConversions");
builtinExtensions.push_back("BuiltinStringInstructions");
builtinExtensions.push_back("BuiltinMathematicalTools");
builtinExtensions.push_back("BuiltinExternalLayouts");
builtinExtensions.push_back("BuiltinCommonInstructions");
return builtinExtensions;
}
bool PlatformExtension::IsBuiltin() const {
std::vector<gd::String> builtinExtensions = GetBuiltinExtensionsNames();
return std::find(builtinExtensions.begin(), builtinExtensions.end(), name) !=
builtinExtensions.end();
}
void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
for (std::map<gd::String, gd::InstructionMetadata>::iterator it =
GetAllActions().begin();
@@ -774,41 +759,28 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
}
}
gd::String
PlatformExtension::GetEventsFunctionFullType(const gd::String &extensionName,
const gd::String &functionName) {
const auto &separator = GetNamespaceSeparator();
gd::String PlatformExtension::GetEventsFunctionFullType(
const gd::String& extensionName, const gd::String& functionName) {
const auto& separator = GetNamespaceSeparator();
return extensionName + separator + functionName;
}
gd::String PlatformExtension::GetBehaviorEventsFunctionFullType(
const gd::String &extensionName, const gd::String &behaviorName,
const gd::String &functionName) {
const auto &separator = GetNamespaceSeparator();
const gd::String& extensionName,
const gd::String& behaviorName,
const gd::String& functionName) {
const auto& separator = GetNamespaceSeparator();
return extensionName + separator + behaviorName + separator + functionName;
}
gd::String
PlatformExtension::GetBehaviorFullType(const gd::String &extensionName,
const gd::String &behaviorName) {
const auto &separator = GetNamespaceSeparator();
gd::String PlatformExtension::GetBehaviorFullType(
const gd::String& extensionName, const gd::String& behaviorName) {
const auto& separator = GetNamespaceSeparator();
return extensionName + separator + behaviorName;
}
gd::String PlatformExtension::GetObjectEventsFunctionFullType(
const gd::String &extensionName, const gd::String &objectName,
const gd::String &functionName) {
const auto &separator = GetNamespaceSeparator();
return extensionName + separator + objectName + separator + functionName;
}
gd::String PlatformExtension::GetObjectFullType(const gd::String &extensionName,
const gd::String &objectName) {
const auto &separator = GetNamespaceSeparator();
return extensionName + separator + objectName;
}
gd::String PlatformExtension::GetExtensionFromFullObjectType(const gd::String& type) {
gd::String PlatformExtension::GetExtensionFromFullBehaviorType(
const gd::String& type) {
const auto separatorIndex =
type.find(PlatformExtension::GetNamespaceSeparator());
if (separatorIndex == std::string::npos) {
@@ -817,7 +789,49 @@ gd::String PlatformExtension::GetExtensionFromFullObjectType(const gd::String& t
return type.substr(0, separatorIndex);
}
gd::String PlatformExtension::GetObjectNameFromFullObjectType(const gd::String& type) {
gd::String PlatformExtension::GetBehaviorNameFromFullBehaviorType(
const gd::String& type) {
const auto separatorIndex =
type.find(PlatformExtension::GetNamespaceSeparator());
if (separatorIndex == std::string::npos) {
return "";
}
return type.substr(separatorIndex + 2);
}
gd::String PlatformExtension::GetObjectEventsFunctionFullType(
const gd::String& extensionName,
const gd::String& objectName,
const gd::String& functionName) {
const auto& separator = GetNamespaceSeparator();
return extensionName + separator + objectName + separator + functionName;
}
gd::String PlatformExtension::GetObjectFullType(const gd::String& extensionName,
const gd::String& objectName) {
const auto& separator = GetNamespaceSeparator();
return extensionName + separator + objectName;
}
gd::String PlatformExtension::GetVariantFullType(const gd::String& extensionName,
const gd::String& objectName,
const gd::String& variantName) {
const auto& separator = GetNamespaceSeparator();
return extensionName + separator + objectName + separator + variantName;
}
gd::String PlatformExtension::GetExtensionFromFullObjectType(
const gd::String& type) {
const auto separatorIndex =
type.find(PlatformExtension::GetNamespaceSeparator());
if (separatorIndex == std::string::npos) {
return "";
}
return type.substr(0, separatorIndex);
}
gd::String PlatformExtension::GetObjectNameFromFullObjectType(
const gd::String& type) {
const auto separatorIndex =
type.find(PlatformExtension::GetNamespaceSeparator());
if (separatorIndex == std::string::npos) {

View File

@@ -17,6 +17,7 @@
#include "GDCore/Extensions/Metadata/EventMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionOrExpressionGroupMetadata.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h"
#include "GDCore/Tools/VersionPriv.h"
@@ -214,6 +215,7 @@ class GD_CORE_API PlatformExtension {
const gd::String& icon);
gd::DependencyMetadata& AddDependency();
gd::SourceFileMetadata& AddSourceFile();
/**
* \brief Declare a new object as being part of the extension.
@@ -438,12 +440,6 @@ class GD_CORE_API PlatformExtension {
*/
bool IsDeprecated() const { return deprecated; }
/**
* \brief Return true if the extension is a standard extension that cannot be
* deactivated
*/
bool IsBuiltin() const;
/**
* \brief Get the namespace of the extension.
* \note The namespace is simply the name of the extension concatenated with
@@ -552,6 +548,24 @@ class GD_CORE_API PlatformExtension {
*/
std::vector<gd::DependencyMetadata>& GetAllDependencies();
/**
* \brief Return a reference to a vector containing the metadata of all the
* dependencies of the extension.
*/
const std::vector<gd::DependencyMetadata>& GetAllDependencies() const;
/**
* \brief Return a reference to a vector containing the metadata of all the
* dependencies of the extension.
*/
std::vector<gd::SourceFileMetadata>& GetAllSourceFiles();
/**
* \brief Return a reference to a vector containing the metadata of all the
* dependencies of the extension.
*/
const std::vector<gd::SourceFileMetadata>& GetAllSourceFiles() const;
/**
* \brief Return a reference to a map containing the names of the actions,
* related to the object type, and the metadata associated with.
@@ -620,12 +634,6 @@ class GD_CORE_API PlatformExtension {
}
///@}
/**
* \brief Return the name of all the extensions which are considered provided
* by platforms.
*/
static std::vector<gd::String> GetBuiltinExtensionsNames();
/**
* \brief Get the string used to separate the name of the
* instruction/expression and the extension.
@@ -643,6 +651,10 @@ class GD_CORE_API PlatformExtension {
static gd::String GetBehaviorFullType(const gd::String& extensionName,
const gd::String& behaviorName);
static gd::String GetExtensionFromFullBehaviorType(const gd::String& type);
static gd::String GetBehaviorNameFromFullBehaviorType(const gd::String& type);
static gd::String GetObjectEventsFunctionFullType(
const gd::String& extensionName,
const gd::String& objectName,
@@ -651,6 +663,10 @@ class GD_CORE_API PlatformExtension {
static gd::String GetObjectFullType(const gd::String& extensionName,
const gd::String& objectName);
static gd::String GetVariantFullType(const gd::String& extensionName,
const gd::String& objectName,
const gd::String& variantName);
static gd::String GetExtensionFromFullObjectType(const gd::String& type);
static gd::String GetObjectNameFromFullObjectType(const gd::String& type);
@@ -687,6 +703,7 @@ class GD_CORE_API PlatformExtension {
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
std::map<gd::String, gd::ExpressionMetadata> strExpressionsInfos;
std::vector<gd::DependencyMetadata> extensionDependenciesMetadata;
std::vector<gd::SourceFileMetadata> extensionSourceFilesMetadata;
std::map<gd::String, gd::EventMetadata> eventsInfos;
std::map<gd::String, gd::PropertyDescriptor> extensionPropertiesMetadata;
std::map<gd::String, InstructionOrExpressionGroupMetadata>

View File

@@ -12,7 +12,6 @@
#include "GDCore/Project/ExternalEvents.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/SourceFile.h"
DependenciesAnalyzer::DependenciesAnalyzer(const gd::Project& project_,
const gd::Layout& layout_)
@@ -74,16 +73,6 @@ bool DependenciesAnalyzer::Analyze(const gd::EventsList& events) {
}
}
// Search for source files dependencies
std::vector<gd::String> dependencies =
events[i].GetSourceFileDependencies();
sourceFilesDependencies.insert(dependencies.begin(), dependencies.end());
const gd::String& associatedSourceFile =
events[i].GetAssociatedGDManagedSourceFile(const_cast<gd::Project&>(project));
if (!associatedSourceFile.empty())
sourceFilesDependencies.insert(associatedSourceFile);
// Analyze sub events dependencies
if (events[i].CanHaveSubEvents()) {
if (!Analyze(events[i].GetSubEvents())) return false;

View File

@@ -71,14 +71,6 @@ class GD_CORE_API DependenciesAnalyzer {
return externalEventsDependencies;
};
/**
* \brief Return the source files being dependencies of the scene or external
* events passed in the constructor.
*/
const std::set<gd::String>& GetSourceFilesDependencies() const {
return sourceFilesDependencies;
};
private:
/**
* \brief Analyze the dependencies of the events.
@@ -92,7 +84,6 @@ class GD_CORE_API DependenciesAnalyzer {
std::set<gd::String> scenesDependencies;
std::set<gd::String> externalEventsDependencies;
std::set<gd::String> sourceFilesDependencies;
std::vector<gd::String>
parentScenes; ///< Used to check for circular dependencies.
std::vector<gd::String>

View File

@@ -29,7 +29,7 @@ bool BehaviorParametersFiller::DoVisitInstruction(gd::Instruction &instruction,
instruction.GetParameters(), metadata.GetParameters(),
[&](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName) {
const gd::String &lastObjectName, size_t lastObjectIndex) {
if (parameterMetadata.GetValueTypeMetadata().IsBehavior() &&
parameterValue.GetPlainString().length() == 0) {

View File

@@ -108,12 +108,10 @@ bool EventsBehaviorRenamer::DoVisitInstruction(gd::Instruction& instruction,
platform, instruction.GetType());
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[&](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName) {
instruction.GetParameters(), metadata.GetParameters(),
[&](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName, size_t lastObjectIndex) {
const gd::String& type = parameterMetadata.GetType();
if (gd::ParameterMetadata::IsBehavior(type)) {

View File

@@ -141,7 +141,7 @@ class GD_CORE_API ExpressionParameterReplacer
parameterMetadata->GetValueTypeMetadata();
if (gd::EventsParameterReplacer::CanContainParameter(
parameterTypeMetadata)) {
isParentTypeAVariable = parameterTypeMetadata.IsVariable();
isParentTypeAVariable = parameterTypeMetadata.IsVariableOnly();
parameter->Visit(*this);
}
}
@@ -183,12 +183,10 @@ bool EventsParameterReplacer::DoVisitInstruction(gd::Instruction& instruction,
platform, instruction.GetType());
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[&](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName) {
instruction.GetParameters(), metadata.GetParameters(),
[&](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName, size_t lastObjectIndex) {
if (!gd::EventsParameterReplacer::CanContainParameter(
parameterMetadata.GetValueTypeMetadata())) {
return;
@@ -197,7 +195,7 @@ bool EventsParameterReplacer::DoVisitInstruction(gd::Instruction& instruction,
if (node) {
ExpressionParameterReplacer renamer(
platform, GetProjectScopedContainers(),
parameterMetadata.GetValueTypeMetadata().IsVariable(),
parameterMetadata.GetValueTypeMetadata().IsVariableOnly(),
oldToNewPropertyNames);
node->Visit(renamer);
@@ -221,7 +219,7 @@ bool EventsParameterReplacer::DoVisitEventExpression(
if (node) {
ExpressionParameterReplacer renamer(
platform, GetProjectScopedContainers(),
metadata.GetValueTypeMetadata().IsVariable(), oldToNewPropertyNames);
metadata.GetValueTypeMetadata().IsVariableOnly(), oldToNewPropertyNames);
node->Visit(renamer);
if (renamer.HasDoneRenaming()) {

View File

@@ -168,7 +168,7 @@ class GD_CORE_API ExpressionPropertyReplacer
parameterMetadata->GetValueTypeMetadata();
if (gd::EventsPropertyReplacer::CanContainProperty(
parameterTypeMetadata)) {
isParentTypeAVariable = parameterTypeMetadata.IsVariable();
isParentTypeAVariable = parameterTypeMetadata.IsVariableOnly();
parameter->Visit(*this);
}
}
@@ -217,12 +217,10 @@ bool EventsPropertyReplacer::DoVisitInstruction(gd::Instruction& instruction,
bool shouldDeleteInstruction = false;
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[&](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName) {
instruction.GetParameters(), metadata.GetParameters(),
[&](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName, size_t lastObjectIndex) {
if (!gd::EventsPropertyReplacer::CanContainProperty(
parameterMetadata.GetValueTypeMetadata())) {
return;
@@ -231,7 +229,7 @@ bool EventsPropertyReplacer::DoVisitInstruction(gd::Instruction& instruction,
if (node) {
ExpressionPropertyReplacer renamer(
platform, GetProjectScopedContainers(), targetPropertiesContainer,
parameterMetadata.GetValueTypeMetadata().IsVariable(),
parameterMetadata.GetValueTypeMetadata().IsVariableOnly(),
oldToNewPropertyNames, removedPropertyNames);
node->Visit(renamer);
@@ -257,7 +255,7 @@ bool EventsPropertyReplacer::DoVisitEventExpression(
if (node) {
ExpressionPropertyReplacer renamer(
platform, GetProjectScopedContainers(), targetPropertiesContainer,
metadata.GetValueTypeMetadata().IsVariable(), oldToNewPropertyNames,
metadata.GetValueTypeMetadata().IsVariableOnly(), oldToNewPropertyNames,
removedPropertyNames);
node->Visit(renamer);

View File

@@ -334,7 +334,7 @@ private:
instruction.GetParameters(), metadata.GetParameters(),
[&](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName) {
const gd::String &lastObjectName, size_t lastObjectIndex) {
if (!gd::EventsObjectReplacer::CanContainObject(
parameterMetadata.GetValueTypeMetadata())) {
return;

View File

@@ -42,18 +42,16 @@ bool EventsVariableInstructionTypeSwitcher::DoVisitInstruction(gd::Instruction&
platform, instruction.GetType());
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[&](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName) {
instruction.GetParameters(), metadata.GetParameters(),
[&](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName, size_t lastObjectIndex) {
const gd::String& type = parameterMetadata.GetType();
if (!gd::ParameterMetadata::IsExpression("variable", type) ||
!gd::VariableInstructionSwitcher::IsSwitchableVariableInstruction(
instruction.GetType())) {
return;
return;
}
const auto variableName =
gd::ExpressionVariableNameFinder::GetVariableName(
@@ -71,13 +69,19 @@ bool EventsVariableInstructionTypeSwitcher::DoVisitInstruction(gd::Instruction&
.GetObjectsContainersList()
.GetObjectOrGroupVariablesContainer(lastObjectName);
}
} else if (type == "variableOrProperty") {
variablesContainer =
&GetProjectScopedContainers()
.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyName(
variableName);
} else {
if (GetProjectScopedContainers().GetVariablesContainersList().Has(
variableName)) {
variablesContainer =
&GetProjectScopedContainers()
.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(variableName);
.GetVariablesContainerFromVariableOrPropertyOrParameterName(variableName);
}
}

View File

@@ -122,7 +122,7 @@ class GD_CORE_API ExpressionVariableReplacer
[&]() {
// This is a variable.
if (&projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(node.name) ==
.GetVariablesContainerFromVariableOrPropertyOrParameterName(node.name) ==
&targetVariablesContainer) {
// The node represents a variable, that can come from the target
// (because the target is in the scope), replace or remove it:
@@ -235,7 +235,7 @@ class GD_CORE_API ExpressionVariableReplacer
[&]() {
// This is a variable.
if (&projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(
.GetVariablesContainerFromVariableOrPropertyOrParameterName(
node.identifierName) == &targetVariablesContainer) {
// The node represents a variable, that can come from the target
// (because the target is in the scope), replace or remove it:
@@ -448,12 +448,10 @@ bool EventsVariableReplacer::DoVisitInstruction(gd::Instruction& instruction,
bool shouldDeleteInstruction = false;
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[&](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName) {
instruction.GetParameters(), metadata.GetParameters(),
[&](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName, size_t lastObjectIndex) {
const gd::String& type = parameterMetadata.GetType();
if (!gd::ParameterMetadata::IsExpression("variable", type) &&

View File

@@ -73,6 +73,7 @@ class GD_CORE_API EventsVariableReplacer
*/
const gd::String targetGroupName;
const VariablesRenamingChangesetNode &variablesRenamingChangesetRoot;
// TODO There is no reason de delete events. This dead code should be removed.
const std::unordered_set<gd::String> &removedVariableNames;
static VariablesContainer nullVariablesContainer;

View File

@@ -0,0 +1,235 @@
#include "ExampleExtensionUsagesFinder.h"
#include "GDCore/Events/Instruction.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/IDE/ProjectBrowserHelper.h"
#include "GDCore/IDE/WholeProjectRefactorer.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
namespace gd {
std::set<gd::String>
ExampleExtensionUsagesFinder::GetUsedExtensions(gd::Project &project) {
ExampleExtensionUsagesFinder worker(project);
gd::ProjectBrowserHelper::ExposeProjectObjects(project, worker);
gd::ProjectBrowserHelper::ExposeProjectEventsWithoutExtensions(project,
worker);
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
worker.isStoreExtension =
eventsFunctionsExtension.GetOriginName() == "gdevelop-extension-store";
ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
project, eventsFunctionsExtension, worker);
}
if (!worker.has3DObjects) {
worker.usedExtensions.erase("Scene3D");
}
return worker.usedExtensions;
};
void ExampleExtensionUsagesFinder::AddUsedExtension(
const gd::PlatformExtension &extension) {
usedExtensions.insert(extension.GetName());
}
void ExampleExtensionUsagesFinder::AddUsedBuiltinExtension(
const gd::String &extensionName) {
usedExtensions.insert(extensionName);
}
// Objects scanner
void ExampleExtensionUsagesFinder::DoVisitObject(gd::Object &object) {
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), object.GetType());
if (metadata.GetMetadata().IsRenderedIn3D()) {
has3DObjects = true;
}
AddUsedExtension(metadata.GetExtension());
};
// Behaviors scanner
void ExampleExtensionUsagesFinder::DoVisitBehavior(gd::Behavior &behavior) {
auto metadata = gd::MetadataProvider::GetExtensionAndBehaviorMetadata(
project.GetCurrentPlatform(), behavior.GetTypeName());
AddUsedExtension(metadata.GetExtension());
};
// Instructions scanner
bool ExampleExtensionUsagesFinder::DoVisitInstruction(
gd::Instruction &instruction, bool isCondition) {
auto metadata =
isCondition ? gd::MetadataProvider::GetExtensionAndConditionMetadata(
project.GetCurrentPlatform(), instruction.GetType())
: gd::MetadataProvider::GetExtensionAndActionMetadata(
project.GetCurrentPlatform(), instruction.GetType());
// Unused event-based objects or events-based behaviors may use object and
// behavior instructions that should not be detected as extension usage.
// The extension of actually used objects and behaviors will be detected on
// scene objects. This is why object or behavior instructions usually don't
// have any import.
// Built-in extensions that are included by default don't declare any include
// files on their instructions either. To still detect their usage, we
// consider that main events and dedicated extensions can't have dead code.
if (!isStoreExtension || !metadata.GetMetadata().GetIncludeFiles().empty()) {
AddUsedExtension(metadata.GetExtension());
}
gd::ParameterMetadataTools::IterateOverParameters(
instruction.GetParameters(), metadata.GetMetadata().GetParameters(),
[this](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue,
const gd::String &lastObjectName) {
const gd::String &parameterType = parameterMetadata.GetType();
if (gd::ParameterMetadata::IsExpression("string", parameterType)) {
rootType = "string";
parameterValue.GetRootNode()->Visit(*this);
} else if (gd::ParameterMetadata::IsExpression("number",
parameterType)) {
rootType = "number";
parameterValue.GetRootNode()->Visit(*this);
} else if (gd::ParameterMetadata::IsExpression("variable",
parameterType))
AddUsedBuiltinExtension("BuiltinVariables");
});
return false;
}
// Expressions scanner
// Ignore literals nodes
void ExampleExtensionUsagesFinder::OnVisitNumberNode(NumberNode &node){};
void ExampleExtensionUsagesFinder::OnVisitTextNode(TextNode &node){};
// Ignore nodes without valid extensions
void ExampleExtensionUsagesFinder::OnVisitEmptyNode(EmptyNode &node){};
void ExampleExtensionUsagesFinder::OnVisitObjectFunctionNameNode(
ObjectFunctionNameNode &node){};
// Visit sub-expressions
void ExampleExtensionUsagesFinder::OnVisitSubExpressionNode(
SubExpressionNode &node) {
node.expression->Visit(*this);
};
void ExampleExtensionUsagesFinder::OnVisitOperatorNode(OperatorNode &node) {
node.leftHandSide->Visit(*this);
node.rightHandSide->Visit(*this);
};
void ExampleExtensionUsagesFinder::OnVisitUnaryOperatorNode(
UnaryOperatorNode &node) {
node.factor->Visit(*this);
};
// Add variable extension and visit sub-expressions on variable nodes
void ExampleExtensionUsagesFinder::OnVisitVariableNode(VariableNode &node) {
AddUsedBuiltinExtension("BuiltinVariables");
auto type = gd::ExpressionTypeFinder::GetType(project.GetCurrentPlatform(),
GetProjectScopedContainers(),
rootType, node);
if (gd::ParameterMetadata::IsExpression("variable", type)) {
// Nothing to do (this can't reference an object)
} else {
GetProjectScopedContainers().MatchIdentifierWithName<void>(
node.name,
[&]() {
// This represents an object.
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), node.name);
AddUsedExtension(metadata.GetExtension());
},
[&]() {
// This is a variable.
},
[&]() {
// This is a property.
},
[&]() {
// This is a parameter.
},
[&]() {
// This is something else.
});
}
if (node.child)
node.child->Visit(*this);
};
void ExampleExtensionUsagesFinder::OnVisitVariableAccessorNode(
VariableAccessorNode &node) {
AddUsedBuiltinExtension("BuiltinVariables");
if (node.child)
node.child->Visit(*this);
};
void ExampleExtensionUsagesFinder::OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode &node) {
AddUsedBuiltinExtension("BuiltinVariables");
node.expression->Visit(*this);
if (node.child)
node.child->Visit(*this);
};
// Add extensions bound to Objects/Behaviors/Functions
void ExampleExtensionUsagesFinder::OnVisitIdentifierNode(IdentifierNode &node) {
auto type = gd::ExpressionTypeFinder::GetType(project.GetCurrentPlatform(),
GetProjectScopedContainers(),
rootType, node);
if (gd::ParameterMetadata::IsObject(type) ||
GetObjectsContainersList().HasObjectOrGroupNamed(node.identifierName)) {
// An object or object variable is used.
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), node.identifierName);
AddUsedExtension(metadata.GetExtension());
}
};
void ExampleExtensionUsagesFinder::OnVisitFunctionCallNode(
FunctionCallNode &node) {
// Extensions of non-free functions are already found when scanning objects.
if (!(node.objectName.empty() && node.behaviorName.empty()))
return;
gd::ExtensionAndMetadata<gd::ExpressionMetadata> metadata;
// Try to find a free number expression
metadata = gd::MetadataProvider::GetExtensionAndExpressionMetadata(
project.GetCurrentPlatform(), node.functionName);
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata.GetMetadata())) {
// Try to find a free str expression
metadata = gd::MetadataProvider::GetExtensionAndStrExpressionMetadata(
project.GetCurrentPlatform(), node.functionName);
// No valid expression found, return.
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata.GetMetadata()))
return;
}
// Unused event-based objects or events-based behaviors may use object and
// behavior expressions that should not be detected as extension usage.
// The extension of actually used objects and behaviors will be detected on
// scene objects. This is why object or behavior expressions usually don't
// have any import.
// Built-in extensions that are included by default don't declare any include
// files on their instructions either. To still detect their usage, we
// consider that main events and dedicated extensions can't have dead code.
if (!isStoreExtension || !metadata.GetMetadata().GetIncludeFiles().empty()) {
AddUsedExtension(metadata.GetExtension());
}
};
} // namespace gd

View File

@@ -0,0 +1,77 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <set>
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/String.h"
namespace gd {
class Project;
class Object;
class Behavior;
} // namespace gd
namespace gd {
/**
* @brief List extension usages for generated example web-pages.
*
* Dependency transitivity is not ensured (see UsedExtensionsFinder).
*/
class GD_CORE_API ExampleExtensionUsagesFinder
: public ArbitraryObjectsWorker,
public ArbitraryEventsWorkerWithContext,
public ExpressionParser2NodeWorker {
public:
static std::set<gd::String> GetUsedExtensions(gd::Project &project);
private:
ExampleExtensionUsagesFinder(gd::Project &project_) : project(project_){};
gd::Project &project;
gd::String rootType;
bool isStoreExtension = false;
// Result
std::set<gd::String> usedExtensions;
bool has3DObjects = false;
void AddUsedExtension(const gd::PlatformExtension &extension);
void AddUsedBuiltinExtension(const gd::String &extensionName);
// Object Visitor
void DoVisitObject(gd::Object &object) override;
// Behavior Visitor
void DoVisitBehavior(gd::Behavior &behavior) override;
// Instructions Visitor
bool DoVisitInstruction(gd::Instruction &instruction,
bool isCondition) override;
// Expression Visitor
void OnVisitSubExpressionNode(SubExpressionNode &node) override;
void OnVisitOperatorNode(OperatorNode &node) override;
void OnVisitUnaryOperatorNode(UnaryOperatorNode &node) override;
void OnVisitNumberNode(NumberNode &node) override;
void OnVisitTextNode(TextNode &node) override;
void OnVisitVariableNode(VariableNode &node) override;
void OnVisitVariableAccessorNode(VariableAccessorNode &node) override;
void OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode &node) override;
void OnVisitIdentifierNode(IdentifierNode &node) override;
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode &node) override;
void OnVisitFunctionCallNode(FunctionCallNode &node) override;
void OnVisitEmptyNode(EmptyNode &node) override;
};
}; // namespace gd

View File

@@ -1034,7 +1034,7 @@ class GD_CORE_API ExpressionCompletionFinder
description.SetVariableType(variable.GetType());
description.SetVariableScope(
projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(variableName)
.GetVariablesContainerFromVariableOrPropertyOrParameterName(variableName)
.GetSourceType());
completions.push_back(description);
@@ -1086,7 +1086,7 @@ class GD_CORE_API ExpressionCompletionFinder
description.SetVariableType(variable.GetType());
description.SetVariableScope(
projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(variableName)
.GetVariablesContainerFromVariableOrPropertyOrParameterName(variableName)
.GetSourceType());
completions.push_back(description);

View File

@@ -460,10 +460,12 @@ const gd::String& ExpressionValidator::TypeToString(Type type) {
case Type::NumberOrString:
return numberOrStringTypeString;
case Type::Variable:
return variableTypeString;
// This function is only used to display errors.
// Users don't care if it's legacy or not or
// if it allows properties and parameters.
case Type::VariableOrProperty:
case Type::VariableOrPropertyOrParameter:
case Type::LegacyVariable:
// This function is only used to display error.
// Users don't care if it's legacy or not.
return variableTypeString;
case Type::Object:
return objectTypeString;
@@ -493,8 +495,11 @@ ExpressionValidator::Type ExpressionValidator::StringToType(
ExpressionValidator::variableTypeString, type)) {
if (gd::ValueTypeMetadata::IsTypeLegacyPreScopedVariable(type)) {
return Type::LegacyVariable;
}
else {
} else if (type == "variableOrProperty") {
return Type::VariableOrProperty;
} else if (type == "variableOrPropertyOrParameter") {
return Type::VariableOrPropertyOrParameter;
} else {
return Type::Variable;
}
}

View File

@@ -203,10 +203,12 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
void OnVisitVariableNode(VariableNode& node) override {
ReportAnyError(node);
if (parentType == Type::Variable) {
if (parentType == Type::Variable ||
parentType == Type::VariableOrProperty ||
parentType == Type::VariableOrPropertyOrParameter) {
childType = parentType;
CheckVariableExistence(node.location, node.name);
CheckVariableExistence(node.location, node.name, node.child != nullptr);
if (node.child) {
node.child->Visit(*this);
}
@@ -216,7 +218,8 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
if (node.child) {
node.child->Visit(*this);
}
} else if (parentType == Type::String || parentType == Type::Number || parentType == Type::NumberOrString) {
} else if (parentType == Type::String || parentType == Type::Number ||
parentType == Type::NumberOrString) {
// The node represents a variable or an object variable in an expression waiting for its *value* to be returned.
childType = parentType;
@@ -336,11 +339,12 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
_("You must enter a number or a text, wrapped inside double quotes (example: \"Hello world\"), or a variable name."),
node.location);
}
}
else if (parentType == Type::Variable) {
CheckVariableExistence(node.location, node.identifierName);
}
else if (parentType != Type::Object && parentType != Type::LegacyVariable) {
} else if (parentType == Type::Variable ||
parentType == Type::VariableOrProperty ||
parentType == Type::VariableOrPropertyOrParameter) {
CheckVariableExistence(node.location, node.identifierName, !node.childIdentifierName.empty());
} else if (parentType != Type::Object &&
parentType != Type::LegacyVariable) {
// It can't happen.
RaiseTypeError(
_("You've entered a name, but this type was expected:") + " " + TypeToString(parentType),
@@ -376,8 +380,19 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
childType = Type::Empty;
}
private:
enum Type {Unknown = 0, Number, String, NumberOrString, Variable, LegacyVariable, Object, Empty};
private:
enum Type {
Unknown = 0,
Number,
String,
NumberOrString,
Variable,
LegacyVariable,
Object,
Empty,
VariableOrProperty,
VariableOrPropertyOrParameter
};
Type ValidateFunction(const gd::FunctionCallNode& function);
bool ValidateObjectVariableOrVariableOrProperty(const gd::IdentifierNode& identifier);
bool ValidateObjectVariableOrVariableOrProperty(
@@ -386,8 +401,10 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
const gd::String &childIdentifierName,
const gd::ExpressionParserLocation childIdentifierNameLocation);
void CheckVariableExistence(const ExpressionParserLocation &location, const gd::String& name) {
if (!currentParameterExtraInfo || *currentParameterExtraInfo != "AllowUndeclaredVariable") {
void CheckVariableExistence(const ExpressionParserLocation &location,
const gd::String &name, bool hasChild) {
if (!currentParameterExtraInfo ||
*currentParameterExtraInfo != "AllowUndeclaredVariable") {
projectScopedContainers.MatchIdentifierWithName<void>(
name,
[&]() {
@@ -402,19 +419,28 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
},
[&]() {
// This is a property.
// This error won't happen unless the priority is changed.
RaiseVariableNameCollisionError(
_("This variable has the same name as a property. Consider "
"renaming one or the other."),
location, name);
if (parentType != Type::VariableOrProperty &&
parentType != Type::VariableOrPropertyOrParameter) {
RaiseVariableNameCollisionError(
_("This variable has the same name as a property. Consider "
"renaming one or the other."),
location, name);
} else if (hasChild) {
RaiseMalformedVariableParameter(
_("Properties can't have children."), location, name);
}
},
[&]() {
// This is a parameter.
// This error won't happen unless the priority is changed.
RaiseVariableNameCollisionError(
_("This variable has the same name as a parameter. Consider "
"renaming one or the other."),
location, name);
if (parentType != Type::VariableOrPropertyOrParameter) {
RaiseVariableNameCollisionError(
_("This variable has the same name as a parameter. Consider "
"renaming one or the other."),
location, name);
} else if (hasChild) {
RaiseMalformedVariableParameter(
_("Properties can't have children."), location, name);
}
},
[&]() {
// This is something else.
@@ -476,6 +502,13 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
message, location, false, variableName, objectName);
}
void RaiseMalformedVariableParameter(const gd::String &message,
const ExpressionParserLocation &location,
const gd::String &variableName) {
RaiseError(gd::ExpressionParserError::ErrorType::MalformedVariableParameter,
message, location, true, variableName, "");
}
void RaiseTypeError(const gd::String &message,
const ExpressionParserLocation &location,
bool isFatal = true) {

View File

@@ -215,7 +215,7 @@ class GD_CORE_API ExpressionVariablePathFinder
if (projectScopedContainers.GetVariablesContainersList().Has(identifier)) {
variablesContainer =
&(projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(identifier));
.GetVariablesContainerFromVariableOrPropertyOrParameterName(identifier));
variableName = identifier;
if (childIdentifier) {
childVariableNames.push_back(*childIdentifier);
@@ -223,12 +223,28 @@ class GD_CORE_API ExpressionVariablePathFinder
}
},
[&]() {
// Ignore properties here.
// There is no support for "children" of properties.
// This is a property.
if (parameterType != "objectvar" &&
projectScopedContainers.GetVariablesContainersList().Has(
identifier)) {
variablesContainer =
&(projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyOrParameterName(identifier));
variableName = identifier;
// There is no support for "children" of properties.
}
},
[&]() {
// Ignore parameters here.
// There is no support for "children" of parameters.
// This is a parameter.
if (parameterType != "objectvar" &&
projectScopedContainers.GetVariablesContainersList().Has(
identifier)) {
variablesContainer =
&(projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyOrParameterName(identifier));
variableName = identifier;
// There is no support for "children" of parameters.
}
},
[&]() {
// Ignore unrecognised identifiers here.

View File

@@ -150,7 +150,7 @@ bool ProjectElementRenamer::DoVisitInstruction(gd::Instruction &instruction,
instruction.GetParameters(), metadata.GetParameters(),
[&](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName) {
const gd::String &lastObjectName, size_t lastObjectIndex) {
if (parameterMetadata.GetType() == "layer") {
if (parameterValue.GetPlainString().length() < 2) {
// This is either the base layer or an invalid layer name.

View File

@@ -13,6 +13,18 @@
namespace gd {
void UsedExtensionsResult::AddUsedExtension(const gd::PlatformExtension& extension) {
usedExtensions.insert(extension.GetName());
usedSourceFiles.insert(usedSourceFiles.end(),
extension.GetAllSourceFiles().begin(),
extension.GetAllSourceFiles().end());
}
void UsedExtensionsResult::AddUsedBuiltinExtension(const gd::String& extensionName) {
usedExtensions.insert(extensionName);
}
const UsedExtensionsResult UsedExtensionsFinder::ScanProject(gd::Project& project) {
UsedExtensionsFinder worker(project);
gd::ProjectBrowserHelper::ExposeProjectObjects(project, worker);
@@ -28,9 +40,9 @@ void UsedExtensionsFinder::DoVisitObject(gd::Object &object) {
if (metadata.GetMetadata().IsRenderedIn3D()) {
result.MarkAsHaving3DObjects();
}
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
result.AddUsedExtension(metadata.GetExtension());
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
result.GetUsedIncludeFiles().insert(includeFile);
result.AddUsedIncludeFiles(includeFile);
}
};
@@ -39,12 +51,12 @@ void UsedExtensionsFinder::DoVisitObject(gd::Object &object) {
void UsedExtensionsFinder::DoVisitBehavior(gd::Behavior &behavior) {
auto metadata = gd::MetadataProvider::GetExtensionAndBehaviorMetadata(
project.GetCurrentPlatform(), behavior.GetTypeName());
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
result.AddUsedExtension(metadata.GetExtension());
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
result.GetUsedIncludeFiles().insert(includeFile);
result.AddUsedIncludeFiles(includeFile);
}
for (auto &&includeFile : metadata.GetMetadata().requiredFiles) {
result.GetUsedRequiredFiles().insert(includeFile);
result.AddUsedRequiredFiles(includeFile);
}
};
@@ -57,9 +69,9 @@ bool UsedExtensionsFinder::DoVisitInstruction(gd::Instruction& instruction,
project.GetCurrentPlatform(), instruction.GetType())
: gd::MetadataProvider::GetExtensionAndActionMetadata(
project.GetCurrentPlatform(), instruction.GetType());
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
result.AddUsedExtension(metadata.GetExtension());
for (auto&& includeFile : metadata.GetMetadata().GetIncludeFiles()) {
result.GetUsedIncludeFiles().insert(includeFile);
result.AddUsedIncludeFiles(includeFile);
}
gd::ParameterMetadataTools::IterateOverParameters(
@@ -77,7 +89,7 @@ bool UsedExtensionsFinder::DoVisitInstruction(gd::Instruction& instruction,
rootType = "number";
parameterValue.GetRootNode()->Visit(*this);
} else if (gd::ParameterMetadata::IsExpression("variable", parameterType))
result.GetUsedExtensions().insert("BuiltinVariables");
result.AddUsedBuiltinExtension("BuiltinVariables");
});
return false;
@@ -110,7 +122,7 @@ void UsedExtensionsFinder::OnVisitUnaryOperatorNode(UnaryOperatorNode& node) {
// Add variable extension and visit sub-expressions on variable nodes
void UsedExtensionsFinder::OnVisitVariableNode(VariableNode& node) {
result.GetUsedExtensions().insert("BuiltinVariables");
result.AddUsedBuiltinExtension("BuiltinVariables");
auto type = gd::ExpressionTypeFinder::GetType(
project.GetCurrentPlatform(), GetProjectScopedContainers(), rootType, node);
@@ -123,9 +135,9 @@ void UsedExtensionsFinder::OnVisitVariableNode(VariableNode& node) {
// This represents an object.
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), node.name);
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
result.AddUsedExtension(metadata.GetExtension());
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
result.GetUsedIncludeFiles().insert(includeFile);
result.AddUsedIncludeFiles(includeFile);
}
}, [&]() {
// This is a variable.
@@ -143,13 +155,13 @@ void UsedExtensionsFinder::OnVisitVariableNode(VariableNode& node) {
void UsedExtensionsFinder::OnVisitVariableAccessorNode(
VariableAccessorNode& node) {
result.GetUsedExtensions().insert("BuiltinVariables");
result.AddUsedBuiltinExtension("BuiltinVariables");
if (node.child) node.child->Visit(*this);
};
void UsedExtensionsFinder::OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) {
result.GetUsedExtensions().insert("BuiltinVariables");
result.AddUsedBuiltinExtension("BuiltinVariables");
node.expression->Visit(*this);
if (node.child) node.child->Visit(*this);
};
@@ -163,9 +175,9 @@ void UsedExtensionsFinder::OnVisitIdentifierNode(IdentifierNode &node) {
// An object or object variable is used.
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), node.identifierName);
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
result.AddUsedExtension(metadata.GetExtension());
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
result.GetUsedIncludeFiles().insert(includeFile);
result.AddUsedIncludeFiles(includeFile);
}
}
};
@@ -187,9 +199,9 @@ void UsedExtensionsFinder::OnVisitFunctionCallNode(FunctionCallNode& node) {
return;
}
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
result.AddUsedExtension(metadata.GetExtension());
for (auto&& includeFile : metadata.GetMetadata().GetIncludeFiles()) {
result.GetUsedIncludeFiles().insert(includeFile);
result.AddUsedIncludeFiles(includeFile);
}
};

View File

@@ -9,6 +9,8 @@
#include <set>
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/String.h"
@@ -44,6 +46,10 @@ public:
return usedRequiredFiles;
}
const std::vector<gd::SourceFileMetadata>& GetUsedSourceFiles() const {
return usedSourceFiles;
}
/**
* \brief Return true when at least 1 object uses the 3D renderer.
*/
@@ -51,20 +57,10 @@ public:
return has3DObjects;
}
/**
* The extensions used by the project (or part of it).
*/
std::set<gd::String> &GetUsedExtensions() { return usedExtensions; }
/**
* The include files used at runtime by the project (or part of it).
*/
std::set<gd::String> &GetUsedIncludeFiles() { return usedIncludeFiles; }
/**
* The additional files required at runtime by the project (or part of it).
*/
std::set<gd::String> &GetUsedRequiredFiles() { return usedRequiredFiles; }
void AddUsedExtension(const gd::PlatformExtension& extension);
void AddUsedBuiltinExtension(const gd::String& extensionName);
void AddUsedIncludeFiles(const gd::String& includeFile) { usedIncludeFiles.insert(includeFile); }
void AddUsedRequiredFiles(const gd::String& requiredFile) { usedRequiredFiles.insert(requiredFile); }
void MarkAsHaving3DObjects() {
has3DObjects = true;
@@ -74,6 +70,7 @@ private:
std::set<gd::String> usedExtensions;
std::set<gd::String> usedIncludeFiles;
std::set<gd::String> usedRequiredFiles;
std::vector<gd::SourceFileMetadata> usedSourceFiles;
bool has3DObjects = false;
};

View File

@@ -0,0 +1,23 @@
#include "UsedObjectTypeFinder.h"
#include "GDCore/Events/Instruction.h"
#include "GDCore/IDE/ProjectBrowserHelper.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
namespace gd {
bool UsedObjectTypeFinder::ScanProject(gd::Project &project,
const gd::String &objectType) {
UsedObjectTypeFinder worker(project, objectType);
gd::ProjectBrowserHelper::ExposeProjectObjects(project, worker);
return worker.hasFoundObjectType;
};
void UsedObjectTypeFinder::DoVisitObject(gd::Object &object) {
if (!hasFoundObjectType && object.GetType() == objectType) {
hasFoundObjectType = true;
}
};
} // namespace gd

View File

@@ -0,0 +1,39 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <set>
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/String.h"
namespace gd {
class Project;
class Object;
} // namespace gd
namespace gd {
class GD_CORE_API UsedObjectTypeFinder : public ArbitraryObjectsWorker {
public:
static bool ScanProject(gd::Project &project, const gd::String &objectType);
private:
UsedObjectTypeFinder(gd::Project &project_, const gd::String &objectType_)
: project(project_), objectType(objectType_){};
gd::Project &project;
const gd::String &objectType;
bool hasFoundObjectType = false;
// Object Visitor
void DoVisitObject(gd::Object &object) override;
};
}; // namespace gd

View File

@@ -0,0 +1,154 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "EventsBasedObjectVariantHelper.h"
#include "GDCore/Project/EventsBasedObject.h"
#include "GDCore/Project/InitialInstancesContainer.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectGroup.h"
#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/ObjectsContainersList.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/Variable.h"
#include "GDCore/Project/VariablesContainer.h"
#include "GDCore/String.h"
namespace gd {
void EventsBasedObjectVariantHelper::ComplyVariantsToEventsBasedObject(
const gd::Project &project, gd::EventsBasedObject &eventsBasedObject) {
auto &defaultObjects = eventsBasedObject.GetDefaultVariant().GetObjects();
for (const auto &variant :
eventsBasedObject.GetVariants().GetInternalVector()) {
auto &objects = variant->GetObjects();
// Delete extra objects
for (auto it = objects.GetObjects().begin();
it != objects.GetObjects().end(); ++it) {
const auto &objectName = it->get()->GetName();
if (!defaultObjects.HasObjectNamed(objectName)) {
variant->GetInitialInstances().RemoveInitialInstancesOfObject(
objectName);
// Do it in last because it unalloc objectName.
objects.RemoveObject(objectName);
--it;
}
}
for (const auto &defaultObject : defaultObjects.GetObjects()) {
const auto &objectName = defaultObject->GetName();
const auto &defaultVariables = defaultObject->GetVariables();
const auto &defaultBehaviors = defaultObject->GetAllBehaviorContents();
// Copy missing objects
if (!objects.HasObjectNamed(objectName)) {
objects.InsertObject(*defaultObject,
defaultObjects.GetObjectPosition(objectName));
objects.AddMissingObjectsInRootFolder();
continue;
}
// Change object types
auto &object = objects.GetObject(objectName);
if (object.GetType() != defaultObject->GetType()) {
// Keep a copy of the old object.
auto oldObject = objects.GetObject(objectName);
objects.RemoveObject(objectName);
objects.InsertObject(*defaultObject,
defaultObjects.GetObjectPosition(objectName));
object.CopyWithoutConfiguration(oldObject);
objects.AddMissingObjectsInRootFolder();
}
// Copy missing behaviors
for (const auto &pair : defaultBehaviors) {
const auto &behaviorName = pair.first;
const auto &defaultBehavior = pair.second;
if (object.HasBehaviorNamed(behaviorName) &&
object.GetBehavior(behaviorName).GetTypeName() !=
defaultBehavior->GetTypeName()) {
object.RemoveBehavior(behaviorName);
}
if (!object.HasBehaviorNamed(behaviorName)) {
auto *behavior = object.AddNewBehavior(
project, defaultBehavior->GetTypeName(), behaviorName);
gd::SerializerElement element;
defaultBehavior->SerializeTo(element);
behavior->UnserializeFrom(element);
}
}
// Delete extra behaviors
for (auto &behaviorName : object.GetAllBehaviorNames()) {
if (!defaultObject->HasBehaviorNamed(behaviorName)) {
object.RemoveBehavior(behaviorName);
}
}
// Sort and copy missing variables
auto &variables = object.GetVariables();
for (size_t defaultVariableIndex = 0;
defaultVariableIndex < defaultVariables.Count();
defaultVariableIndex++) {
const auto &variableName =
defaultVariables.GetNameAt(defaultVariableIndex);
const auto &defaultVariable =
defaultVariables.Get(defaultVariableIndex);
auto variableIndex = variables.GetPosition(variableName);
if (variableIndex == gd::String::npos) {
variables.Insert(variableName, defaultVariable, defaultVariableIndex);
} else {
variables.Move(variableIndex, defaultVariableIndex);
}
if (variables.Get(variableName).GetType() != defaultVariable.GetType()) {
variables.Remove(variableName);
variables.Insert(variableName, defaultVariable, defaultVariableIndex);
}
}
// Remove extra variables
auto variableToRemoveCount = variables.Count() - defaultVariables.Count();
for (size_t iteration = 0; iteration < variableToRemoveCount;
iteration++) {
variables.Remove(variables.GetNameAt(variables.Count() - 1));
}
// Remove extra instance variables
variant->GetInitialInstances().IterateOverInstances(
[&objectName,
&defaultVariables](gd::InitialInstance &initialInstance) {
if (initialInstance.GetObjectName() != objectName) {
return false;
}
auto &instanceVariables = initialInstance.GetVariables();
for (size_t instanceVariableIndex = 0;
instanceVariableIndex < instanceVariables.Count();
instanceVariableIndex++) {
const auto &variableName =
defaultVariables.GetNameAt(instanceVariableIndex);
if (!defaultVariables.Has(variableName)) {
instanceVariables.Remove(variableName);
}
}
return false;
});
}
auto &defaultObjectGroups =
eventsBasedObject.GetDefaultVariant().GetObjects().GetObjectGroups();
auto &objectGroups = variant->GetObjects().GetObjectGroups();
auto objectGroupsCount = objectGroups.Count();
// Clear groups
for (size_t index = 0; index < objectGroupsCount; index++) {
objectGroups.Remove(objectGroups.Get(0).GetName());
}
// Copy groups
for (size_t index = 0; index < defaultObjectGroups.Count(); index++) {
objectGroups.Insert(defaultObjectGroups.Get(index), index);
}
}
}
} // namespace gd

View File

@@ -0,0 +1,26 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
namespace gd {
class EventsBasedObject;
class Project;
} // namespace gd
namespace gd {
class GD_CORE_API EventsBasedObjectVariantHelper {
public:
/**
* @brief Apply the changes done on events-based object children to all its
* variants.
*/
static void
ComplyVariantsToEventsBasedObject(const gd::Project &project,
gd::EventsBasedObject &eventsBasedObject);
};
} // namespace gd

View File

@@ -9,7 +9,10 @@
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/Project/EventsBasedBehavior.h"
#include "GDCore/Project/EventsBasedObject.h"
//#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/ParameterMetadataContainer.h"
#include "GDCore/Project/PropertiesContainer.h"
#include "GDCore/Project/VariablesContainer.h"
#include "GDCore/Project/EventsFunction.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
@@ -100,4 +103,72 @@ void EventsFunctionTools::ObjectEventsFunctionToObjectsContainer(
}
}
void EventsFunctionTools::ParametersToVariablesContainer(
const ParameterMetadataContainer &parameters,
gd::VariablesContainer &outputVariablesContainer) {
if (outputVariablesContainer.GetSourceType() !=
gd::VariablesContainer::SourceType::Parameters) {
throw std::logic_error("Tried to generate a variables container from "
"parameters with the wrong source type.");
}
outputVariablesContainer.Clear();
gd::String lastObjectName;
for (std::size_t i = 0; i < parameters.GetParametersCount(); ++i) {
const auto &parameter = parameters.GetParameter(i);
if (parameter.GetName().empty())
continue;
auto &valueTypeMetadata = parameter.GetValueTypeMetadata();
if (valueTypeMetadata.IsNumber()) {
auto &variable = outputVariablesContainer.InsertNew(
parameter.GetName(), outputVariablesContainer.Count());
variable.SetValue(0);
} else if (valueTypeMetadata.IsString()) {
auto &variable = outputVariablesContainer.InsertNew(
parameter.GetName(), outputVariablesContainer.Count());
variable.SetString("");
} else if (valueTypeMetadata.IsBoolean()) {
auto &variable = outputVariablesContainer.InsertNew(
parameter.GetName(), outputVariablesContainer.Count());
variable.SetBool(false);
}
}
}
void EventsFunctionTools::PropertiesToVariablesContainer(
const PropertiesContainer &properties,
gd::VariablesContainer &outputVariablesContainer) {
if (outputVariablesContainer.GetSourceType() !=
gd::VariablesContainer::SourceType::Properties) {
throw std::logic_error("Tried to generate a variables container from "
"properties with the wrong source type.");
}
outputVariablesContainer.Clear();
gd::String lastObjectName;
for (std::size_t i = 0; i < properties.GetCount(); ++i) {
const auto &property = properties.Get(i);
if (property.GetName().empty())
continue;
auto &propertyType = gd::ValueTypeMetadata::GetPrimitiveValueType(
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(
property.GetType()));
if (propertyType == "number") {
auto &variable = outputVariablesContainer.InsertNew(
property.GetName(), outputVariablesContainer.Count());
variable.SetValue(0);
} else if (propertyType == "string") {
auto &variable = outputVariablesContainer.InsertNew(
property.GetName(), outputVariablesContainer.Count());
variable.SetString("");
} else if (propertyType == "boolean") {
auto &variable = outputVariablesContainer.InsertNew(
property.GetName(), outputVariablesContainer.Count());
variable.SetBool(false);
}
}
}
} // namespace gd

View File

@@ -12,6 +12,9 @@ namespace gd {
class Project;
class EventsFunctionsContainer;
class ObjectsContainer;
class ParameterMetadataContainer;
class PropertiesContainer;
class VariablesContainer;
class ParameterMetadata;
class EventsFunction;
class EventsBasedBehavior;
@@ -68,5 +71,13 @@ class GD_CORE_API EventsFunctionTools {
const gd::EventsBasedObject& eventsBasedObject,
const gd::EventsFunction& eventsFunction,
gd::ObjectsContainer& outputObjectsContainer);
static void ParametersToVariablesContainer(
const ParameterMetadataContainer &parameters,
gd::VariablesContainer &outputVariablesContainer);
static void PropertiesToVariablesContainer(
const PropertiesContainer &properties,
gd::VariablesContainer &outputVariablesContainer);
};
} // namespace gd

View File

@@ -17,6 +17,8 @@
#include "GDCore/IDE/Project/ResourcesRenamer.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/CustomBehavior.h"
#include "GDCore/Project/CustomObjectConfiguration.h"
#include "GDCore/Project/EventsBasedObjectVariant.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
@@ -60,9 +62,6 @@ void ObjectAssetSerializer::SerializeTo(
element.SetAttribute("version", "");
element.SetIntAttribute("animationsCount", 1);
element.SetIntAttribute("maxFramesCount", 1);
// TODO Find the right object dimensions.
element.SetIntAttribute("width", 0);
element.SetIntAttribute("height", 0);
SerializerElement &authorsElement = element.AddChild("authors");
authorsElement.ConsiderAsArrayOf("author");
SerializerElement &tagsElement = element.AddChild("tags");
@@ -75,6 +74,28 @@ void ObjectAssetSerializer::SerializeTo(
cleanObject->SerializeTo(objectAssetElement.AddChild("object"));
double width = 0;
double height = 0;
std::unordered_set<gd::String> alreadyUsedVariantIdentifiers;
if (project.HasEventsBasedObject(object.GetType())) {
SerializerElement &variantsElement =
objectAssetElement.AddChild("variants");
variantsElement.ConsiderAsArrayOf("variant");
const auto *variant = ObjectAssetSerializer::GetVariant(project, object);
if (variant) {
width = variant->GetAreaMaxX() - variant->GetAreaMinX();
height = variant->GetAreaMaxY() - variant->GetAreaMinY();
}
gd::ObjectAssetSerializer::SerializeUsedVariantsTo(
project, object, variantsElement, alreadyUsedVariantIdentifiers);
}
// TODO Find the right object dimensions when their is no variant.
element.SetIntAttribute("width", width);
element.SetIntAttribute("height", height);
SerializerElement &resourcesElement =
objectAssetElement.AddChild("resources");
resourcesElement.ConsiderAsArrayOf("resource");
@@ -93,14 +114,24 @@ void ObjectAssetSerializer::SerializeTo(
resourceElement.SetAttribute("name", resource.GetName());
}
std::unordered_set<gd::String> usedExtensionNames;
usedExtensionNames.insert(extensionName);
for (auto &usedVariantIdentifier : alreadyUsedVariantIdentifiers) {
usedExtensionNames.insert(PlatformExtension::GetExtensionFromFullObjectType(
usedVariantIdentifier));
}
SerializerElement &requiredExtensionsElement =
objectAssetElement.AddChild("requiredExtensions");
requiredExtensionsElement.ConsiderAsArrayOf("requiredExtension");
if (project.HasEventsFunctionsExtensionNamed(extensionName)) {
SerializerElement &requiredExtensionElement =
requiredExtensionsElement.AddChild("requiredExtension");
requiredExtensionElement.SetAttribute("extensionName", extensionName);
requiredExtensionElement.SetAttribute("extensionVersion", "1.0.0");
for (auto &usedExtensionName : usedExtensionNames) {
if (project.HasEventsFunctionsExtensionNamed(usedExtensionName)) {
auto &extension = project.GetEventsFunctionsExtension(usedExtensionName);
SerializerElement &requiredExtensionElement =
requiredExtensionsElement.AddChild("requiredExtension");
requiredExtensionElement.SetAttribute("extensionName", usedExtensionName);
requiredExtensionElement.SetAttribute("extensionVersion",
extension.GetVersion());
}
}
// TODO This can be removed when the asset script no longer require it.
@@ -108,4 +139,59 @@ void ObjectAssetSerializer::SerializeTo(
objectAssetElement.AddChild("customization");
customizationElement.ConsiderAsArrayOf("empty");
}
void ObjectAssetSerializer::SerializeUsedVariantsTo(
gd::Project &project, const gd::Object &object,
SerializerElement &variantsElement,
std::unordered_set<gd::String> &alreadyUsedVariantIdentifiers) {
const auto *variant = ObjectAssetSerializer::GetVariant(project, object);
if (!variant) {
return;
}
const auto &variantIdentifier =
object.GetType() + gd::PlatformExtension::GetNamespaceSeparator() +
variant->GetName();
auto insertResult = alreadyUsedVariantIdentifiers.insert(variantIdentifier);
if (!insertResult.second) {
return;
}
SerializerElement &pairElement = variantsElement.AddChild("variant");
pairElement.SetAttribute("objectType", object.GetType());
SerializerElement &variantElement = pairElement.AddChild("variant");
variant->SerializeTo(variantElement);
for (auto &object : variant->GetObjects().GetObjects()) {
gd::ObjectAssetSerializer::SerializeUsedVariantsTo(
project, *object, variantsElement, alreadyUsedVariantIdentifiers);
}
}
const gd::EventsBasedObjectVariant *
ObjectAssetSerializer::GetVariant(gd::Project &project,
const gd::Object &object) {
if (!project.HasEventsBasedObject(object.GetType())) {
return nullptr;
}
const auto &eventsBasedObject =
project.GetEventsBasedObject(object.GetType());
const auto &variants = eventsBasedObject.GetVariants();
const auto *customObjectConfiguration =
dynamic_cast<const gd::CustomObjectConfiguration *>(
&object.GetConfiguration());
const auto &variantName = customObjectConfiguration->GetVariantName();
if (!variants.HasVariantNamed(variantName) &&
(customObjectConfiguration
->IsMarkedAsOverridingEventsBasedObjectChildrenConfiguration() ||
customObjectConfiguration
->IsForcedToOverrideEventsBasedObjectChildrenConfiguration())) {
return nullptr;
}
const auto &variantIdentifier =
object.GetType() + gd::PlatformExtension::GetNamespaceSeparator() +
variantName;
const auto &variant = variants.HasVariantNamed(variantName)
? variants.GetVariant(variantName)
: eventsBasedObject.GetDefaultVariant();
return &variant;
}
} // namespace gd

View File

@@ -6,6 +6,7 @@
#pragma once
#include <map>
#include <vector>
#include <unordered_set>
#include "GDCore/String.h"
@@ -20,6 +21,7 @@ class InitialInstance;
class SerializerElement;
class EffectsContainer;
class AbstractFileSystem;
class EventsBasedObjectVariant;
} // namespace gd
namespace gd {
@@ -52,6 +54,13 @@ private:
ObjectAssetSerializer(){};
static gd::String GetObjectExtensionName(const gd::Object &object);
static void SerializeUsedVariantsTo(
gd::Project &project, const gd::Object &object,
SerializerElement &variantsElement,
std::unordered_set<gd::String> &alreadyUsedVariantIdentifiers);
static const gd::EventsBasedObjectVariant* GetVariant(gd::Project &project, const gd::Object &object);
};
} // namespace gd

View File

@@ -3,9 +3,11 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "GroupVariableHelper.h"
#include "ObjectVariableHelper.h"
#include "GDCore/IDE/WholeProjectRefactorer.h"
#include "GDCore/Project/EventsBasedObject.h"
#include "GDCore/Project/InitialInstancesContainer.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectGroup.h"
#include "GDCore/Project/ObjectsContainer.h"
@@ -16,7 +18,7 @@
namespace gd {
void GroupVariableHelper::FillAnyVariableBetweenObjects(
void ObjectVariableHelper::FillAnyVariableBetweenObjects(
gd::ObjectsContainer &globalObjectsContainer,
gd::ObjectsContainer &objectsContainer,
const gd::ObjectGroup &objectGroup) {
@@ -65,7 +67,7 @@ void GroupVariableHelper::FillAnyVariableBetweenObjects(
}
}
gd::VariablesContainer GroupVariableHelper::MergeVariableContainers(
gd::VariablesContainer ObjectVariableHelper::MergeVariableContainers(
const gd::ObjectsContainersList &objectsContainersList,
const gd::ObjectGroup &objectGroup) {
gd::VariablesContainer mergedVariablesContainer;
@@ -113,7 +115,7 @@ gd::VariablesContainer GroupVariableHelper::MergeVariableContainers(
return mergedVariablesContainer;
}
void GroupVariableHelper::FillMissingGroupVariablesToObjects(
void ObjectVariableHelper::FillMissingGroupVariablesToObjects(
gd::ObjectsContainer &globalObjectsContainer,
gd::ObjectsContainer &objectsContainer, const gd::ObjectGroup &objectGroup,
const gd::SerializerElement &originalSerializedVariables) {
@@ -145,7 +147,7 @@ void GroupVariableHelper::FillMissingGroupVariablesToObjects(
// TODO Handle position changes for group variables.
// We could try to change the order of object variables in a way that the next
// call to MergeVariableContainers rebuild them in the same order.
void GroupVariableHelper::ApplyChangesToObjects(
void ObjectVariableHelper::ApplyChangesToObjects(
gd::ObjectsContainer &globalObjectsContainer,
gd::ObjectsContainer &objectsContainer,
const gd::VariablesContainer &groupVariablesContainer,
@@ -172,6 +174,7 @@ void GroupVariableHelper::ApplyChangesToObjects(
groupVariablesContainer.Get(variableName),
variablesContainer.Count());
}
// TODO Check what happens if 2 variables exchange their names.
for (const auto &pair : changeset.oldToNewVariableNames) {
const gd::String &oldVariableName = pair.first;
const gd::String &newVariableName = pair.second;
@@ -193,4 +196,109 @@ void GroupVariableHelper::ApplyChangesToObjects(
}
}
void ObjectVariableHelper::ApplyChangesToObjectInstances(
gd::VariablesContainer &objectVariablesContainer,
gd::InitialInstancesContainer &initialInstancesContainer,
const gd::String &objectName, const gd::VariablesChangeset &changeset) {
initialInstancesContainer.IterateOverInstances(
[&objectVariablesContainer, &objectName,
&changeset](gd::InitialInstance &instance) {
if (instance.GetObjectName() == objectName) {
auto &destinationVariablesContainer = instance.GetVariables();
for (const gd::String &variableName :
changeset.removedVariableNames) {
destinationVariablesContainer.Remove(variableName);
}
for (const gd::String &variableName : changeset.addedVariableNames) {
// Instance variables may already exist with another type.
if (destinationVariablesContainer.Has(variableName) &&
destinationVariablesContainer.Get(variableName).GetType() !=
objectVariablesContainer.Get(variableName).GetType()) {
destinationVariablesContainer.Remove(variableName);
}
}
// TODO Check what happens if 2 variables exchange their names.
for (const auto &pair : changeset.oldToNewVariableNames) {
const gd::String &oldVariableName = pair.first;
const gd::String &newVariableName = pair.second;
if (destinationVariablesContainer.Has(newVariableName)) {
// It can happens if an instance already had the variable.
destinationVariablesContainer.Remove(oldVariableName);
} else {
destinationVariablesContainer.Rename(oldVariableName,
newVariableName);
}
}
// Apply type changes
for (const gd::String &variableName :
changeset.valueChangedVariableNames) {
if (destinationVariablesContainer.Has(variableName) &&
destinationVariablesContainer.Get(variableName).GetType() !=
objectVariablesContainer.Get(variableName).GetType()) {
destinationVariablesContainer.Remove(variableName);
}
}
}
return false;
});
}
void ObjectVariableHelper::ApplyChangesToVariants(
gd::EventsBasedObject &eventsBasedObject, const gd::String &objectName,
const gd::VariablesChangeset &changeset) {
auto &defaultVariablesContainer = eventsBasedObject.GetDefaultVariant()
.GetObjects()
.GetObject(objectName)
.GetVariables();
for (auto &variant : eventsBasedObject.GetVariants().GetInternalVector()) {
if (!variant->GetObjects().HasObjectNamed(objectName)) {
continue;
}
auto &object = variant->GetObjects().GetObject(objectName);
auto &variablesContainer = object.GetVariables();
for (const gd::String &variableName : changeset.removedVariableNames) {
variablesContainer.Remove(variableName);
}
for (const gd::String &variableName : changeset.addedVariableNames) {
if (variablesContainer.Has(variableName)) {
// It can happens if a child-object already had the variable but it was
// missing in other variant child-object.
continue;
}
variablesContainer.Insert(variableName,
defaultVariablesContainer.Get(variableName),
variablesContainer.Count());
}
// TODO Check what happens if 2 variables exchange their names.
for (const auto &pair : changeset.oldToNewVariableNames) {
const gd::String &oldVariableName = pair.first;
const gd::String &newVariableName = pair.second;
if (variablesContainer.Has(newVariableName)) {
// It can happens if a child-object already had the variable but it was
// missing in other variant child-object.
variablesContainer.Remove(oldVariableName);
} else {
variablesContainer.Rename(oldVariableName, newVariableName);
}
}
// Apply type changes
for (const gd::String &variableName : changeset.valueChangedVariableNames) {
size_t index = variablesContainer.GetPosition(variableName);
if (variablesContainer.Has(variableName) &&
variablesContainer.Get(variableName).GetType() !=
defaultVariablesContainer.Get(variableName).GetType()) {
variablesContainer.Remove(variableName);
variablesContainer.Insert(
variableName, defaultVariablesContainer.Get(variableName), index);
}
}
gd::ObjectVariableHelper::ApplyChangesToObjectInstances(
variablesContainer, variant->GetInitialInstances(), objectName,
changeset);
}
}
} // namespace gd

View File

@@ -8,6 +8,8 @@
#include "GDCore/Project/VariablesContainer.h"
namespace gd {
class EventsBasedObject;
class InitialInstancesContainer;
class ObjectsContainersList;
class ObjectsContainer;
class ObjectGroup;
@@ -22,7 +24,7 @@ namespace gd {
*
* This is used by the object group variable editor.
*/
class GD_CORE_API GroupVariableHelper {
class GD_CORE_API ObjectVariableHelper {
public:
/**
* Copy every variable from every object of the group to the other objects
@@ -52,7 +54,7 @@ public:
* Objects can be added during the group edition and may not necessarily have
* all the variables initially shared by the group.
*
* \see gd::GroupVariableHelper::MergeVariableContainers
* \see gd::ObjectVariableHelper::MergeVariableContainers
*/
static void FillMissingGroupVariablesToObjects(
gd::ObjectsContainer &globalObjectsContainer,
@@ -70,6 +72,22 @@ public:
const gd::VariablesContainer &groupVariablesContainer,
const gd::ObjectGroup &objectGroup,
const gd::VariablesChangeset &changeset);
/**
* @brief Apply the changes done on an object to all its instances.
*/
static void ApplyChangesToObjectInstances(
gd::VariablesContainer &objectVariablesContainer,
gd::InitialInstancesContainer &initialInstancesContainer,
const gd::String &objectName, const gd::VariablesChangeset &changeset);
/**
* @brief Apply the changes done on events-based object child to all its
* variants.
*/
static void ApplyChangesToVariants(gd::EventsBasedObject &eventsBasedObject,
const gd::String &objectName,
const gd::VariablesChangeset &changeset);
};
} // namespace gd
} // namespace gd

View File

@@ -62,6 +62,11 @@ void ArbitraryResourceWorker::ExposeSpine(gd::String& resourceName){
// do.
};
void ArbitraryResourceWorker::ExposeJavaScript(gd::String& resourceName){
// Nothing to do by default - each child class can define here the action to
// do.
};
void ArbitraryResourceWorker::ExposeVideo(gd::String& videoName){
// Nothing to do by default - each child class can define here the action to
// do.
@@ -195,6 +200,10 @@ void ArbitraryResourceWorker::ExposeResourceWithType(
ExposeSpine(resourceName);
return;
}
if (resourceType == "javascript") {
ExposeJavaScript(resourceName);
return;
}
gd::LogError("Unexpected resource type: " + resourceType + " for: " + resourceName);
return;
}
@@ -218,12 +227,11 @@ bool ResourceWorkerInEventsWorker::DoVisitInstruction(gd::Instruction& instructi
platform, instruction.GetType());
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[this, &instruction](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterExpression,
size_t parameterIndex,
const gd::String& lastObjectName) {
instruction.GetParameters(), metadata.GetParameters(),
[this, &instruction](
const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterExpression, size_t parameterIndex,
const gd::String &lastObjectName, size_t lastObjectIndex) {
const String& parameterValue = parameterExpression.GetPlainString();
if (parameterMetadata.GetType() == "fontResource") {
gd::String updatedParameterValue = parameterValue;

View File

@@ -96,7 +96,7 @@ public:
* \brief Expose a 3D model, which is always a reference to a "model3D" resource.
*/
virtual void ExposeModel3D(gd::String &resourceName);
/**
* \brief Expose an atlas, which is always a reference to a "atlas" resource.
*/
@@ -112,6 +112,11 @@ public:
*/
virtual void ExposeVideo(gd::String &videoName);
/**
* \brief Expose a JavaScript file, which is always a reference to a "javascript" resource.
*/
virtual void ExposeJavaScript(gd::String &javaScriptName);
/**
* \brief Expose a bitmap font, which is always a reference to a "bitmapFont" resource.
*/

View File

@@ -38,6 +38,10 @@ void AssetResourcePathCleaner::ExposeVideo(gd::String &videoName) {
ExposeResourceAsFile(videoName);
}
void AssetResourcePathCleaner::ExposeJavaScript(gd::String &javaScriptResourceName) {
ExposeResourceAsFile(javaScriptResourceName);
}
void AssetResourcePathCleaner::ExposeBitmapFont(gd::String &bitmapFontName) {
ExposeResourceAsFile(bitmapFontName);
}

View File

@@ -46,6 +46,7 @@ public:
void ExposeTileset(gd::String &tilesetName) override;
void ExposeVideo(gd::String &videoName) override;
void ExposeBitmapFont(gd::String &bitmapFontName) override;
void ExposeJavaScript(gd::String &javaScriptResourceName) override;
void ExposeFile(gd::String &resource) override;
protected:

View File

@@ -73,6 +73,9 @@ public:
virtual void ExposeVideo(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeJavaScript(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeBitmapFont(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};

View File

@@ -7,7 +7,6 @@
#include <map>
#include "GDCore/CommonTools.h"
#include "GDCore/IDE/AbstractFileSystem.h"
#include "GDCore/IDE/Project/ResourcesAbsolutePathChecker.h"
#include "GDCore/IDE/Project/ResourcesMergingHelper.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Tools/Localization.h"
@@ -26,42 +25,37 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(
bool preserveAbsoluteFilenames,
bool preserveDirectoryStructure) {
if (updateOriginalProject) {
gd::ProjectResourcesCopier::CopyAllResourcesTo(
originalProject, originalProject, fs, destinationDirectory,
preserveAbsoluteFilenames, preserveDirectoryStructure);
gd::ProjectResourcesCopier::AdaptFilePathsAndCopyAllResourcesTo(
originalProject, fs, destinationDirectory, preserveAbsoluteFilenames,
preserveDirectoryStructure);
} else {
gd::Project clonedProject = originalProject;
gd::ProjectResourcesCopier::CopyAllResourcesTo(
originalProject, clonedProject, fs, destinationDirectory,
preserveAbsoluteFilenames, preserveDirectoryStructure);
gd::ProjectResourcesCopier::AdaptFilePathsAndCopyAllResourcesTo(
clonedProject, fs, destinationDirectory, preserveAbsoluteFilenames,
preserveDirectoryStructure);
}
return true;
}
bool ProjectResourcesCopier::CopyAllResourcesTo(
gd::Project& originalProject,
gd::Project& clonedProject,
bool ProjectResourcesCopier::AdaptFilePathsAndCopyAllResourcesTo(
gd::Project& project,
AbstractFileSystem& fs,
gd::String destinationDirectory,
bool preserveAbsoluteFilenames,
bool preserveDirectoryStructure) {
// Check if there are some resources with absolute filenames
gd::ResourcesAbsolutePathChecker absolutePathChecker(originalProject.GetResourcesManager(), fs);
gd::ResourceExposer::ExposeWholeProjectResources(originalProject, absolutePathChecker);
auto projectDirectory = fs.DirNameFrom(originalProject.GetProjectFile());
auto projectDirectory = fs.DirNameFrom(project.GetProjectFile());
std::cout << "Copying all resources from " << projectDirectory << " to "
<< destinationDirectory << "..." << std::endl;
// Get the resources to be copied
gd::ResourcesMergingHelper resourcesMergingHelper(
clonedProject.GetResourcesManager(), fs);
project.GetResourcesManager(), fs);
resourcesMergingHelper.SetBaseDirectory(projectDirectory);
resourcesMergingHelper.PreserveDirectoriesStructure(
preserveDirectoryStructure);
resourcesMergingHelper.PreserveAbsoluteFilenames(preserveAbsoluteFilenames);
gd::ResourceExposer::ExposeWholeProjectResources(clonedProject,
gd::ResourceExposer::ExposeWholeProjectResources(project,
resourcesMergingHelper);
// Copy resources

View File

@@ -50,12 +50,10 @@ class GD_CORE_API ProjectResourcesCopier {
bool preserveDirectoryStructure = true);
private:
static bool CopyAllResourcesTo(gd::Project& originalProject,
gd::Project& clonedProject,
gd::AbstractFileSystem& fs,
gd::String destinationDirectory,
bool preserveAbsoluteFilenames = true,
bool preserveDirectoryStructure = true);
static bool AdaptFilePathsAndCopyAllResourcesTo(
gd::Project &project, gd::AbstractFileSystem &fs,
gd::String destinationDirectory, bool preserveAbsoluteFilenames = true,
bool preserveDirectoryStructure = true);
};
} // namespace gd

View File

@@ -1,17 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "ResourcesAbsolutePathChecker.h"
#include "GDCore/IDE/AbstractFileSystem.h"
#include "GDCore/String.h"
namespace gd {
void ResourcesAbsolutePathChecker::ExposeFile(gd::String& resourceFilename) {
if (fs.IsAbsolute(resourceFilename)) hasAbsoluteFilenames = true;
}
} // namespace gd

View File

@@ -1,48 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/IDE/AbstractFileSystem.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/String.h"
namespace gd {
/**
* \brief Helper used to check if a project has at least a resource with an
* absolute filename.
*
* \see ArbitraryResourceWorker
*
* \ingroup IDE
*/
class GD_CORE_API ResourcesAbsolutePathChecker
: public ArbitraryResourceWorker {
public:
ResourcesAbsolutePathChecker(gd::ResourcesManager &resourcesManager,
AbstractFileSystem &fileSystem)
: ArbitraryResourceWorker(resourcesManager), hasAbsoluteFilenames(false),
fs(fileSystem){};
virtual ~ResourcesAbsolutePathChecker(){};
/**
* Return true if there is at least a resource with an absolute filename.
*/
bool HasResourceWithAbsoluteFilenames() const {
return hasAbsoluteFilenames;
};
/**
* Check if there is a resource with an absolute path
*/
virtual void ExposeFile(gd::String& resource);
private:
bool hasAbsoluteFilenames;
AbstractFileSystem& fs;
};
} // namespace gd

View File

@@ -60,6 +60,7 @@ public:
if (resourceType == "model3D") return allModel3Ds;
if (resourceType == "atlas") return allAtlases;
if (resourceType == "spine") return allSpines;
if (resourceType == "javascript") return allJavaScripts;
return emptyResources;
};
@@ -88,6 +89,9 @@ public:
virtual void ExposeVideo(gd::String& resourceName) override {
allVideos.insert(resourceName);
};
virtual void ExposeJavaScript(gd::String& resourceName) override {
allJavaScripts.insert(resourceName);
};
virtual void ExposeBitmapFont(gd::String& resourceName) override {
allBitmapFonts.insert(resourceName);
};
@@ -114,6 +118,7 @@ public:
std::set<gd::String> allModel3Ds;
std::set<gd::String> allAtlases;
std::set<gd::String> allSpines;
std::set<gd::String> allJavaScripts;
std::set<gd::String> emptyResources;
static const std::vector<gd::String> resourceTypes;

View File

@@ -22,6 +22,14 @@ void ResourcesMergingHelper::ExposeFile(gd::String& resourceFilename) {
resourceFullFilename = gd::AbstractFileSystem::NormalizeSeparator(
resourceFullFilename); // Protect against \ on Linux.
if (shouldUseOriginalAbsoluteFilenames) {
// There is no need to fill `newFilenames` and `oldFilenames` since the file
// location stays the same.
fs.MakeAbsolute(resourceFullFilename, baseDirectory);
resourceFilename = resourceFullFilename;
return;
}
// In the case of absolute filenames that we don't want to preserve, or
// in the case of copying files without preserving relative folders, the new
// names will be generated from the filename alone (with collision protection).

View File

@@ -3,8 +3,7 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef RESOURCESMERGINGHELPER_H
#define RESOURCESMERGINGHELPER_H
#pragma once
#include <map>
#include <memory>
@@ -58,6 +57,15 @@ public:
preserveAbsoluteFilenames = preserveAbsoluteFilenames_;
};
/**
* \brief Set if the absolute filenames of original files must be used for
* any resource.
*/
void SetShouldUseOriginalAbsoluteFilenames(
bool shouldUseOriginalAbsoluteFilenames_ = true) {
shouldUseOriginalAbsoluteFilenames = shouldUseOriginalAbsoluteFilenames_;
};
/**
* \brief Return a map containing the resources old absolute filename as key,
* and the resources new filenames as value. The new filenames are relative to
@@ -93,10 +101,13 @@ public:
///< absolute (C:\MyFile.png will not be
///< transformed into a relative filename
///< (MyFile.png).
/**
* Set to true if the absolute filenames of original files must be used for
* any resource.
*/
bool shouldUseOriginalAbsoluteFilenames = false;
gd::AbstractFileSystem&
fs; ///< The gd::AbstractFileSystem used to manipulate files.
};
} // namespace gd
#endif // RESOURCESMERGINGHELPER_H

View File

@@ -59,6 +59,9 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker {
virtual void ExposeVideo(gd::String& videoResourceName) override {
RenameIfNeeded(videoResourceName);
};
virtual void ExposeJavaScript(gd::String& javaScriptResourceName) override {
RenameIfNeeded(javaScriptResourceName);
};
virtual void ExposeBitmapFont(gd::String& bitmapFontName) override {
RenameIfNeeded(bitmapFontName);
};

View File

@@ -6,6 +6,7 @@
#include "SceneResourcesFinder.h"
#include "GDCore/IDE/ResourceExposer.h"
#include "GDCore/Project/EventsBasedObjectVariant.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Serialization/SerializerElement.h"
@@ -27,6 +28,14 @@ std::set<gd::String> SceneResourcesFinder::FindSceneResources(gd::Project &proje
return resourceWorker.resourceNames;
}
std::set<gd::String> SceneResourcesFinder::FindEventsBasedObjectVariantResources(gd::Project &project,
gd::EventsBasedObjectVariant &variant) {
gd::SceneResourcesFinder resourceWorker(project.GetResourcesManager());
gd::ResourceExposer::ExposeEventsBasedObjectVariantResources(project, variant, resourceWorker);
return resourceWorker.resourceNames;
}
void SceneResourcesFinder::AddUsedResource(gd::String &resourceName) {
if (resourceName.empty()) {
return;

View File

@@ -15,6 +15,7 @@ namespace gd {
class Project;
class Layout;
class SerializerElement;
class EventsBasedObjectVariant;
} // namespace gd
namespace gd {
@@ -27,7 +28,7 @@ namespace gd {
class SceneResourcesFinder : private gd::ArbitraryResourceWorker {
public:
/**
* @brief Find resource usages in a given scenes.
* @brief Find resource usages in a given scene.
*
* It doesn't include resources used globally.
*/
@@ -41,6 +42,13 @@ public:
*/
static std::set<gd::String> FindProjectResources(gd::Project &project);
/**
* @brief Find resource usages in a given events-based object variant.
*/
static std::set<gd::String>
FindEventsBasedObjectVariantResources(gd::Project &project,
gd::EventsBasedObjectVariant &variant);
virtual ~SceneResourcesFinder(){};
private:
@@ -74,6 +82,9 @@ private:
void ExposeVideo(gd::String &videoResourceName) override {
AddUsedResource(videoResourceName);
};
void ExposeJavaScript(gd::String &javaScriptResourceName) override {
AddUsedResource(javaScriptResourceName);
};
void ExposeBitmapFont(gd::String &bitmapFontName) override {
AddUsedResource(bitmapFontName);
};

View File

@@ -26,8 +26,24 @@ namespace gd {
void ProjectBrowserHelper::ExposeProjectEvents(
gd::Project &project, gd::ArbitraryEventsWorker &worker) {
// See also gd::Project::ExposeResources for a method that traverses the whole
// project (this time for resources).
// See also gd::ResourceExposer::ExposeWholeProjectResources
// for a method that traverses the whole project (this time for resources).
ExposeProjectEventsWithoutExtensions(project, worker);
// Add events based extensions
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(project, eventsFunctionsExtension, worker);
}
}
void ProjectBrowserHelper::ExposeProjectEvents(
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) {
// See also gd::ResourceExposer::ExposeWholeProjectResources
// for a method that traverses the whole project (this time for resources)
// and ExposeProjectEffects (this time for effects).
ExposeProjectEventsWithoutExtensions(project, worker);
@@ -51,6 +67,28 @@ void ProjectBrowserHelper::ExposeProjectEventsWithoutExtensions(
}
}
void ProjectBrowserHelper::ExposeProjectEventsWithoutExtensions(
gd::Project& project, gd::ArbitraryEventsWorkerWithContext& worker) {
// Add layouts events
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
auto &layout = project.GetLayout(s);
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
worker.Launch(layout.GetEvents(), projectScopedContainers);
}
// Add external events events
for (std::size_t s = 0; s < project.GetExternalEventsCount(); s++) {
const auto &externalEvents = project.GetExternalEvents(s);
const gd::String &associatedLayout = externalEvents.GetAssociatedLayout();
if (project.HasLayoutNamed(associatedLayout)) {
auto &layout = project.GetLayout(associatedLayout);
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
worker.Launch(project.GetExternalEvents(s).GetEvents(), projectScopedContainers);
}
}
}
void ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
gd::Project &project, gd::Layout &layout,
gd::ArbitraryEventsWorker &worker) {
@@ -106,48 +144,17 @@ void ProjectBrowserHelper::ExposeLayoutEventsAndDependencies(
}
for (const gd::String& sceneName : dependenciesAnalyzer.GetScenesDependencies()) {
gd::Layout& dependencyLayout = project.GetLayout(sceneName);
worker.Launch(dependencyLayout.GetEvents());
}
}
void ProjectBrowserHelper::ExposeProjectEvents(
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) {
// See also gd::Project::ExposeResources for a method that traverse the whole
// project (this time for resources) and ExposeProjectEffects (this time for
// effects).
// Add layouts events
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
auto &layout = project.GetLayout(s);
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
worker.Launch(layout.GetEvents(), projectScopedContainers);
}
// Add external events events
for (std::size_t s = 0; s < project.GetExternalEventsCount(); s++) {
const auto &externalEvents = project.GetExternalEvents(s);
const gd::String &associatedLayout = externalEvents.GetAssociatedLayout();
if (project.HasLayoutNamed(associatedLayout)) {
auto &layout = project.GetLayout(associatedLayout);
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
worker.Launch(project.GetExternalEvents(s).GetEvents(), projectScopedContainers);
}
}
// Add events based extensions
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(project, eventsFunctionsExtension, worker);
}
}
void ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::ArbitraryEventsWorker &worker) {
// Add (free) events functions
for (auto &&eventsFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&eventsFunction :
eventsFunctionsExtension.GetEventsFunctions().GetInternalVector()) {
worker.Launch(eventsFunction->GetEvents());
}
@@ -169,13 +176,18 @@ void ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::ArbitraryEventsWorkerWithContext &worker) {
// Add (free) events functions
for (auto &&eventsFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&eventsFunction :
eventsFunctionsExtension.GetEventsFunctions().GetInternalVector()) {
gd::ObjectsContainer parameterObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsFunctionsExtension, *eventsFunction,
parameterObjectsContainer);
parameterObjectsContainer, parameterVariablesContainer);
worker.Launch(eventsFunction->GetEvents(), projectScopedContainers);
}
@@ -207,15 +219,32 @@ void ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
gd::ArbitraryEventsWorkerWithContext &worker) {
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
project, eventsFunctionsExtension,
eventsBasedBehavior,
propertyVariablesContainer,
worker);
}
void ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
gd::VariablesContainer &propertyVariablesContainer,
gd::ArbitraryEventsWorkerWithContext &worker) {
auto &behaviorEventsFunctions = eventsBasedBehavior.GetEventsFunctions();
for (auto &&eventsFunction : behaviorEventsFunctions.GetInternalVector()) {
gd::ObjectsContainer parameterObjectsContainers(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForBehaviorEventsFunction(
project, eventsFunctionsExtension, eventsBasedBehavior,
*eventsFunction, parameterObjectsContainers);
*eventsFunction, parameterObjectsContainers,
parameterVariablesContainer, propertyVariablesContainer);
worker.Launch(eventsFunction->GetEvents(), projectScopedContainers);
}
@@ -235,15 +264,31 @@ void ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
gd::ArbitraryEventsWorkerWithContext &worker) {
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
project, eventsFunctionsExtension, eventsBasedObject,
propertyVariablesContainer, worker);
}
void ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
gd::VariablesContainer &propertyVariablesContainer,
gd::ArbitraryEventsWorkerWithContext &worker) {
auto &objectEventsFunctions = eventsBasedObject.GetEventsFunctions();
for (auto &&eventsFunction : objectEventsFunctions.GetInternalVector()) {
gd::ObjectsContainer parameterObjectsContainers(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForObjectEventsFunction(
project, eventsFunctionsExtension, eventsBasedObject,
*eventsFunction, parameterObjectsContainers);
*eventsFunction, parameterObjectsContainers,
parameterVariablesContainer, propertyVariablesContainer);
worker.Launch(eventsFunction->GetEvents(), projectScopedContainers);
}
@@ -269,6 +314,12 @@ void ProjectBrowserHelper::ExposeProjectObjects(
eventsFunctionsExtension.GetEventsBasedObjects().GetInternalVector()) {
auto eventsBasedObject = eventsBasedObjectUniquePtr.get();
worker.Launch(eventsBasedObject->GetObjects());
for (auto &&variantUniquePtr :
eventsBasedObject->GetVariants().GetInternalVector()) {
auto variant = variantUniquePtr.get();
worker.Launch(variant->GetObjects());
}
}
}
};
@@ -281,13 +332,19 @@ void ProjectBrowserHelper::ExposeLayoutObjects(gd::Layout &layout,
worker.Launch(layout.GetObjects());
}
void ProjectBrowserHelper::ExposeEventsBasedObjectVariantObjects(
gd::EventsBasedObjectVariant &eventsBasedObjectVariant,
gd::ArbitraryObjectsWorker &worker) {
worker.Launch(eventsBasedObjectVariant.GetObjects());
}
void ProjectBrowserHelper::ExposeProjectFunctions(
gd::Project &project, gd::ArbitraryEventsFunctionsWorker &worker) {
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
worker.Launch(eventsFunctionsExtension);
worker.Launch(eventsFunctionsExtension.GetEventsFunctions());
for (auto &&eventsBasedBehavior :
eventsFunctionsExtension.GetEventsBasedBehaviors()

View File

@@ -13,12 +13,14 @@ class EventsFunctionsExtension;
class EventsFunction;
class EventsBasedBehavior;
class EventsBasedObject;
class EventsBasedObjectVariant;
class ArbitraryEventsWorker;
class ArbitraryEventsWorkerWithContext;
class ArbitraryEventsFunctionsWorker;
class ArbitraryObjectsWorker;
class ArbitraryEventBasedBehaviorsWorker;
class ArbitraryBehaviorSharedDataWorker;
class VariablesContainer;
} // namespace gd
namespace gd {
@@ -56,6 +58,15 @@ public:
ExposeProjectEventsWithoutExtensions(gd::Project &project,
gd::ArbitraryEventsWorker &worker);
/**
* \brief Call the specified worker on all events of the project (layout and
* external events) but not events from extensions.
*
* Only use this for stats.
*/
static void ExposeProjectEventsWithoutExtensions(
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all events of a layout and
* its external events.
@@ -127,6 +138,20 @@ public:
const gd::EventsBasedBehavior &eventsBasedBehavior,
gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all events of the event-based
* behavior.
*
* This should be the preferred way to traverse all the events of an
* event-based behavior.
*/
static void ExposeEventsBasedBehaviorEvents(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
gd::VariablesContainer &propertyVariablesContainer,
gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all events of the event-based
* object.
@@ -152,6 +177,20 @@ public:
const gd::EventsBasedObject &eventsBasedObject,
gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all events of the event-based
* object.
*
* This should be the preferred way to traverse all the events of an
* event-based object.
*/
static void ExposeEventsBasedObjectEvents(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
gd::VariablesContainer &propertyVariablesContainer,
gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all ObjectContainers of the project
* (global, layouts...)
@@ -169,6 +208,17 @@ public:
static void ExposeLayoutObjects(gd::Layout &layout,
gd::ArbitraryObjectsWorker &worker);
/**
* \brief Call the specified worker on all ObjectContainers of the
* events-based object variant.
*
* This should be the preferred way to traverse all the objects of an
* events-based object variant.
*/
static void ExposeEventsBasedObjectVariantObjects(
gd::EventsBasedObjectVariant &eventsBasedObjectVariant,
gd::ArbitraryObjectsWorker &worker);
/**
* \brief Call the specified worker on all FunctionsContainers of the project
* (global, layouts...)

View File

@@ -63,7 +63,7 @@ void GD_CORE_API ProjectStripper::StripProjectForExport(gd::Project &project) {
eventsBasedObject.GetPropertyDescriptors().GetInternalVector().clear();
}
extension.GetEventsBasedBehaviors().Clear();
extension.ClearEventsFunctions();
extension.GetEventsFunctions().ClearEventsFunctions();
}
}

View File

@@ -42,6 +42,9 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
const gd::NamedPropertyDescriptor &property, const gd::String &objectType,
bool isBehavior, bool isSharedProperties) {
auto &propertyName = property.GetName();
const auto &primitiveType = gd::ValueTypeMetadata::GetPrimitiveValueType(
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(
property.GetType()));
auto &functionsContainer = eventsBasedEntity.GetEventsFunctions();
gd::String capitalizedName = CapitalizeFirstLetter(property.GetName());
gd::String setterName = "Set" + capitalizedName;
@@ -59,9 +62,9 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
property.GetLabel().empty() ? property.GetName() : property.GetLabel();
gd::String descriptionSubject =
(property.GetType() == "Boolean" ? "if " : "the ") +
(primitiveType == "boolean" ? "if " : "the ") +
UnCapitalizeFirstLetter(propertyLabel) +
(isSharedProperties || property.GetType() == "Boolean"
(isSharedProperties || primitiveType == "boolean"
? "."
: " of the object.") +
(property.GetDescription().empty() ? ""
@@ -71,19 +74,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
"objects using the behavior."
: "");
gd::String propertyGetterName =
(isSharedProperties ? "SharedProperty" : "Property") + property.GetName();
gd::String getterType =
gd::PlatformExtension::GetBehaviorEventsFunctionFullType(
extension.GetName(), eventsBasedEntity.GetName(), propertyGetterName);
gd::String setterType =
gd::PlatformExtension::GetBehaviorEventsFunctionFullType(
extension.GetName(), eventsBasedEntity.GetName(),
"Set" + propertyGetterName);
gd::String getterName = capitalizedName;
gd::String numberOrString =
property.GetType() == "Number" ? "Number" : "String";
if (!functionsContainer.HasEventsFunctionNamed(getterName)) {
auto &getter = functionsContainer.InsertNewEventsFunction(
@@ -99,7 +90,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
.SetName(legacyExpressionType)
.SetExtraInfo(GetStringifiedExtraInfo(property));
getter.SetFullName(propertyLabel).SetGroup(functionGroupName);
if (property.GetType() == "Boolean") {
if (primitiveType == "boolean") {
getter.SetFunctionType(gd::EventsFunction::Condition)
.SetDescription("Check " + descriptionSubject)
.SetSentence("_PARAM0_ " + UnCapitalizeFirstLetter(propertyLabel));
@@ -112,13 +103,12 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
auto &event =
dynamic_cast<gd::StandardEvent &>(getter.GetEvents().InsertNewEvent(
project, "BuiltinCommonInstructions::Standard", 0));
if (property.GetType() == "Boolean") {
if (primitiveType == "boolean") {
gd::Instruction condition;
condition.SetType(getterType);
condition.AddParameter("Object");
if (isBehavior) {
condition.AddParameter("Behavior");
}
condition.SetType("BooleanVariable");
condition.AddParameter(propertyName);
condition.AddParameter("True");
condition.AddParameter("");
event.GetConditions().Insert(condition, 0);
gd::Instruction action;
@@ -127,6 +117,8 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
event.GetActions().Insert(action, 0);
} else {
gd::Instruction action;
gd::String numberOrString =
primitiveType == "number" ? "Number" : "String";
action.SetType("SetReturn" + numberOrString);
action.AddParameter(property.GetName());
event.GetActions().Insert(action, 0);
@@ -136,7 +128,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
if (!functionsContainer.HasEventsFunctionNamed(setterName)) {
auto &setter = functionsContainer.InsertNewEventsFunction(
setterName, functionsContainer.GetEventsFunctionsCount());
if (property.GetType() == "Boolean") {
if (primitiveType == "boolean") {
setter.SetFunctionType(gd::EventsFunction::Action)
.SetFullName(propertyLabel)
.SetGroup(functionGroupName)
@@ -177,26 +169,24 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
setter.SetGetterName(getterName);
}
if (property.GetType() == "Boolean") {
if (primitiveType == "boolean") {
{
auto &event =
dynamic_cast<gd::StandardEvent &>(setter.GetEvents().InsertNewEvent(
project, "BuiltinCommonInstructions::Standard", 0));
gd::Instruction condition;
condition.SetType("GetArgumentAsBoolean");
condition.AddParameter("\"Value\"");
condition.SetType("BooleanVariable");
condition.AddParameter("Value");
condition.AddParameter("True");
condition.AddParameter("");
event.GetConditions().Insert(condition, 0);
gd::Instruction action;
action.SetType(setterType);
action.AddParameter("Object");
if (isBehavior) {
action.AddParameter("Behavior");
action.AddParameter("yes");
} else {
action.AddParameter("yes");
}
action.SetType("SetBooleanVariable");
action.AddParameter(propertyName);
action.AddParameter("True");
action.AddParameter("");
event.GetActions().Insert(action, 0);
}
{
@@ -205,20 +195,17 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
project, "BuiltinCommonInstructions::Standard", 0));
gd::Instruction condition;
condition.SetType("GetArgumentAsBoolean");
condition.AddParameter("\"Value\"");
condition.SetInverted(true);
condition.SetType("BooleanVariable");
condition.AddParameter("Value");
condition.AddParameter("False");
condition.AddParameter("");
event.GetConditions().Insert(condition, 0);
gd::Instruction action;
action.SetType(setterType);
action.AddParameter("Object");
if (isBehavior) {
action.AddParameter("Behavior");
action.AddParameter("no");
} else {
action.AddParameter("no");
}
action.SetType("SetBooleanVariable");
action.AddParameter(propertyName);
action.AddParameter("False");
action.AddParameter("");
event.GetActions().Insert(action, 0);
}
} else {
@@ -227,16 +214,11 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
project, "BuiltinCommonInstructions::Standard", 0));
gd::Instruction action;
action.SetType(setterType);
action.AddParameter("Object");
if (isBehavior) {
action.AddParameter("Behavior");
action.AddParameter("=");
action.AddParameter("Value");
} else {
action.AddParameter("=");
action.AddParameter("Value");
}
action.SetType(primitiveType == "number" ? "SetNumberVariable"
: "SetStringVariable");
action.AddParameter(propertyName);
action.AddParameter("=");
action.AddParameter("Value");
event.GetActions().Insert(action, 0);
}
}
@@ -245,9 +227,11 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
bool PropertyFunctionGenerator::CanGenerateGetterAndSetter(
const gd::AbstractEventsBasedEntity &eventsBasedEntity,
const gd::NamedPropertyDescriptor &property) {
auto &type = property.GetType();
if (type != "Boolean" && type != "Number" && type != "String" &&
type != "Choice" && type != "Color" && type != "LeaderboardId") {
const auto &primitiveType = gd::ValueTypeMetadata::GetPrimitiveValueType(
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(
property.GetType()));
if (primitiveType != "boolean" && primitiveType != "number" &&
primitiveType != "string") {
return false;
}
@@ -264,12 +248,13 @@ gd::String PropertyFunctionGenerator::GetStringifiedExtraInfo(
gd::String arrayString;
arrayString += "[";
bool isFirst = true;
for (const gd::String &choice : property.GetExtraInfo()) {
for (const auto &choice : property.GetChoices()) {
if (!isFirst) {
arrayString += ",";
}
isFirst = false;
arrayString += "\"" + choice + "\"";
// TODO Handle labels (and search "choice label")
arrayString += "\"" + choice.GetValue() + "\"";
}
arrayString += "]";
return arrayString;

View File

@@ -3,8 +3,7 @@
* Copyright 2008-2022 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef GDCORE_PROPERTYFUNCTIONGENERATOR_H
#define GDCORE_PROPERTYFUNCTIONGENERATOR_H
#pragma once
namespace gd {
class String;
@@ -73,5 +72,3 @@ class GD_CORE_API PropertyFunctionGenerator {
};
} // namespace gd
#endif // GDCORE_PROPERTYFUNCTIONGENERATOR_H

View File

@@ -5,21 +5,22 @@
*/
#include "ResourceExposer.h"
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/IDE/ProjectBrowserHelper.h"
#include "GDCore/Project/Effect.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/Effect.h"
#include "GDCore/String.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
namespace gd {
void ResourceExposer::ExposeWholeProjectResources(gd::Project& project, gd::ArbitraryResourceWorker& worker) {
void ResourceExposer::ExposeWholeProjectResources(
gd::Project &project, gd::ArbitraryResourceWorker &worker) {
// See also gd::ProjectBrowserHelper::ExposeProjectEvents for a method that
// traverse the whole project (this time for events) and ExposeProjectEffects
// (this time for effects).
@@ -31,13 +32,11 @@ void ResourceExposer::ExposeWholeProjectResources(gd::Project& project, gd::Arbi
// Expose event resources
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
gd::ProjectBrowserHelper::ExposeProjectEvents(
project, eventWorker);
gd::ProjectBrowserHelper::ExposeProjectEvents(project, eventWorker);
// Expose object configuration resources
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
gd::ProjectBrowserHelper::ExposeProjectObjects(
project, objectWorker);
gd::ProjectBrowserHelper::ExposeProjectObjects(project, objectWorker);
// Expose layer effect resources
for (std::size_t layoutIndex = 0; layoutIndex < project.GetLayoutsCount();
@@ -52,28 +51,47 @@ void ResourceExposer::ExposeWholeProjectResources(gd::Project& project, gd::Arbi
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount();
effectIndex++) {
auto &effect = effects.GetEffect(effectIndex);
gd::ResourceExposer::ExposeEffectResources(project.GetCurrentPlatform(),
effect, worker);
gd::ResourceExposer::ExposeEffectResources(
project.GetCurrentPlatform(), effect, worker);
}
}
}
// Expose loading screen background image if present
auto& loadingScreen = project.GetLoadingScreen();
auto &loadingScreen = project.GetLoadingScreen();
if (loadingScreen.GetBackgroundImageResourceName() != "")
worker.ExposeImage(loadingScreen.GetBackgroundImageResourceName());
// Expose extension source files
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
ExposeExtensionResources(eventsFunctionsExtension, worker);
}
}
void ResourceExposer::ExposeProjectResources(gd::Project& project, gd::ArbitraryResourceWorker& worker) {
void ResourceExposer::ExposeProjectResources(
gd::Project &project, gd::ArbitraryResourceWorker &worker) {
// Expose global objects configuration resources
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
objectWorker.Launch(project.GetObjects());
// Exposed extension event resources
// Note that using resources in extensions is very unlikely and probably not
// worth the effort of something smart.
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
gd::ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
project, eventsFunctionsExtension, eventWorker);
}
}
void ResourceExposer::ExposeLayoutResources(
gd::Project &project, gd::Layout &layout,
gd::Project &project,
gd::Layout &layout,
gd::ArbitraryResourceWorker &worker) {
// Expose object configuration resources
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
gd::ProjectBrowserHelper::ExposeLayoutObjects(layout, objectWorker);
@@ -87,28 +105,48 @@ void ResourceExposer::ExposeLayoutResources(
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount();
effectIndex++) {
auto &effect = effects.GetEffect(effectIndex);
gd::ResourceExposer::ExposeEffectResources(project.GetCurrentPlatform(),
effect, worker);
gd::ResourceExposer::ExposeEffectResources(
project.GetCurrentPlatform(), effect, worker);
}
}
// Expose event resources
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
gd::ProjectBrowserHelper::ExposeLayoutEventsAndDependencies(project, layout,
eventWorker);
gd::ProjectBrowserHelper::ExposeLayoutEventsAndDependencies(
project, layout, eventWorker);
}
// Exposed extension event resources
// Note that using resources in extensions is very unlikely and probably not
// worth the effort of something smart.
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
gd::ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(project, eventsFunctionsExtension, eventWorker);
void ResourceExposer::ExposeEventsBasedObjectVariantResources(
gd::Project &project,
gd::EventsBasedObjectVariant &eventsBasedObjectVariant,
gd::ArbitraryResourceWorker &worker) {
// Expose object configuration resources
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
gd::ProjectBrowserHelper::ExposeEventsBasedObjectVariantObjects(
eventsBasedObjectVariant, objectWorker);
// Expose layer effect resources
auto &layers = eventsBasedObjectVariant.GetLayers();
for (std::size_t layerIndex = 0; layerIndex < layers.GetLayersCount();
layerIndex++) {
auto &layer = layers.GetLayer(layerIndex);
auto &effects = layer.GetEffects();
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount();
effectIndex++) {
auto &effect = effects.GetEffect(effectIndex);
gd::ResourceExposer::ExposeEffectResources(project.GetCurrentPlatform(),
effect, worker);
}
}
// We don't check the events because it would cost too much to do it for every
// variant. Resource usage in events-based object events and their
// dependencies should be rare.
}
void ResourceExposer::ExposeEffectResources(
gd::Platform &platform, gd::Effect &effect,
gd::Platform &platform,
gd::Effect &effect,
gd::ArbitraryResourceWorker &worker) {
auto &effectMetadata =
MetadataProvider::GetEffectMetadata(platform, effect.GetEffectType());
@@ -127,11 +165,20 @@ void ResourceExposer::ExposeEffectResources(
worker.ExposeResourceWithType(resourceType,
potentiallyUpdatedResourceName);
if (potentiallyUpdatedResourceName != resourceName) {
effect.SetStringParameter(propertyName, potentiallyUpdatedResourceName);
effect.SetStringParameter(propertyName,
potentiallyUpdatedResourceName);
}
}
}
}
}
} // namespace gd
void ResourceExposer::ExposeExtensionResources(
gd::EventsFunctionsExtension &extension,
gd::ArbitraryResourceWorker &worker) {
for (auto &sourceFile : extension.GetAllSourceFiles()) {
worker.ExposeJavaScript(sourceFile.GetResourceName());
}
}
} // namespace gd

View File

@@ -9,6 +9,8 @@ namespace gd {
class Platform;
class Project;
class ArbitraryResourceWorker;
class EventsBasedObjectVariant;
class EventsFunctionsExtension;
class Effect;
class Layout;
} // namespace gd
@@ -34,7 +36,7 @@ public:
/**
* @brief Expose only the resources used globally on a project.
*
*
* It doesn't include resources used in layouts.
*/
static void ExposeProjectResources(gd::Project &project,
@@ -42,17 +44,33 @@ public:
/**
* @brief Expose the resources used in a given layout.
*
*
* It doesn't include resources used globally.
*/
static void ExposeLayoutResources(gd::Project &project, gd::Layout &layout,
gd::ArbitraryResourceWorker &worker);
static void ExposeLayoutResources(gd::Project &project,
gd::Layout &layout,
gd::ArbitraryResourceWorker &worker);
/**
* @brief Expose the resources used in a given events-based object variant.
*/
static void ExposeEventsBasedObjectVariantResources(
gd::Project &project,
gd::EventsBasedObjectVariant &eventsBasedObjectVariant,
gd::ArbitraryResourceWorker &worker);
/**
* @brief Expose the resources used in a given effect.
*/
static void ExposeEffectResources(gd::Platform &platform, gd::Effect &effect,
static void ExposeEffectResources(gd::Platform &platform,
gd::Effect &effect,
gd::ArbitraryResourceWorker &worker);
/**
* @brief Expose the resources used in an extension.
*/
static void ExposeExtensionResources(gd::EventsFunctionsExtension &extension,
gd::ArbitraryResourceWorker &worker);
};
} // namespace gd
} // namespace gd

View File

@@ -11,7 +11,7 @@
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/DependenciesAnalyzer.h"
#include "GDCore/IDE/GroupVariableHelper.h"
#include "GDCore/IDE/ObjectVariableHelper.h"
#include "GDCore/IDE/EventBasedBehaviorBrowser.h"
#include "GDCore/IDE/EventBasedObjectBrowser.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
@@ -314,9 +314,16 @@ void WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
variablesContainer.SerializeTo(editedSerializedVariables);
variablesContainer.UnserializeFrom(originalSerializedVariables);
// Rename and remove variables
// Rename variables
// Pass an empty set to avoid deletion of actions/conditions or events using
// them.
// While we support refactoring that would remove all references (actions,
// conditions...) it's both a bit dangerous for the user and we would need to
// show the user what will be removed before doing so. For now, just clear the
// removed variables so they don't trigger any refactoring.
std::unordered_set<gd::String> removedVariableNames;
gd::EventsVariableReplacer eventsVariableReplacer(
project.GetCurrentPlatform(), changeset, changeset.removedVariableNames,
project.GetCurrentPlatform(), changeset, removedVariableNames,
variablesContainer);
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
eventsVariableReplacer);
@@ -333,9 +340,25 @@ void WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
project, eventsVariableInstructionTypeSwitcher);
}
// TODO Apply the refactor to external layouts.
void WholeProjectRefactorer::ApplyRefactoringForObjectVariablesContainer(
gd::Project &project, gd::VariablesContainer &objectVariablesContainer,
gd::InitialInstancesContainer &initialInstancesContainer,
const gd::String &objectName, const gd::VariablesChangeset &changeset,
const gd::SerializerElement &originalSerializedVariables) {
gd::WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
project, objectVariablesContainer, changeset,
originalSerializedVariables);
gd::ObjectVariableHelper::ApplyChangesToObjectInstances(
objectVariablesContainer, initialInstancesContainer, objectName,
changeset);
}
void WholeProjectRefactorer::ApplyRefactoringForGroupVariablesContainer(
gd::Project &project, gd::ObjectsContainer &globalObjectsContainer,
gd::ObjectsContainer &objectsContainer,
gd::InitialInstancesContainer &initialInstancesContainer,
const gd::VariablesContainer &groupVariablesContainer,
const gd::ObjectGroup &objectGroup,
const gd::VariablesChangeset &changeset,
@@ -355,11 +378,15 @@ void WholeProjectRefactorer::ApplyRefactoringForGroupVariablesContainer(
}
auto &object = hasObject ? objectsContainer.GetObject(objectName)
: globalObjectsContainer.GetObject(objectName);
auto &variablesContainer = object.GetVariables();
auto &objectVariablesContainer = object.GetVariables();
gd::ObjectVariableHelper::ApplyChangesToObjectInstances(
objectVariablesContainer, initialInstancesContainer, objectName,
changeset);
gd::EventsVariableReplacer eventsVariableReplacer(
project.GetCurrentPlatform(), changeset,
removedVariableNames, variablesContainer);
removedVariableNames, objectVariablesContainer);
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
eventsVariableReplacer);
}
@@ -372,12 +399,12 @@ void WholeProjectRefactorer::ApplyRefactoringForGroupVariablesContainer(
eventsVariableReplacer);
// Apply changes to objects.
gd::GroupVariableHelper::FillMissingGroupVariablesToObjects(
gd::ObjectVariableHelper::FillMissingGroupVariablesToObjects(
globalObjectsContainer,
objectsContainer,
objectGroup,
originalSerializedVariables);
gd::GroupVariableHelper::ApplyChangesToObjects(
gd::ObjectVariableHelper::ApplyChangesToObjects(
globalObjectsContainer, objectsContainer, groupVariablesContainer,
objectGroup, changeset);
@@ -600,7 +627,8 @@ void WholeProjectRefactorer::RenameEventsFunctionsExtension(
// instructions after they are renamed.
// Free expressions
for (auto &&eventsFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&eventsFunction :
eventsFunctionsExtension.GetEventsFunctions().GetInternalVector()) {
if (eventsFunction->IsExpression()) {
renameEventsFunction(*eventsFunction);
}
@@ -617,7 +645,8 @@ void WholeProjectRefactorer::RenameEventsFunctionsExtension(
}
// Free instructions
for (auto &&eventsFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&eventsFunction :
eventsFunctionsExtension.GetEventsFunctions().GetInternalVector()) {
if (eventsFunction->IsAction() || eventsFunction->IsCondition()) {
renameEventsFunction(*eventsFunction);
}
@@ -697,11 +726,12 @@ void WholeProjectRefactorer::RenameEventsFunction(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::String &oldFunctionName, const gd::String &newFunctionName) {
if (!eventsFunctionsExtension.HasEventsFunctionNamed(oldFunctionName))
const auto &eventsFunctions = eventsFunctionsExtension.GetEventsFunctions();
if (!eventsFunctions.HasEventsFunctionNamed(oldFunctionName))
return;
const gd::EventsFunction &eventsFunction =
eventsFunctionsExtension.GetEventsFunction(oldFunctionName);
eventsFunctions.GetEventsFunction(oldFunctionName);
const WholeProjectBrowser wholeProjectExposer;
DoRenameEventsFunction(
@@ -714,7 +744,7 @@ void WholeProjectRefactorer::RenameEventsFunction(
if (eventsFunction.GetFunctionType() ==
gd::EventsFunction::ExpressionAndCondition) {
for (auto &&otherFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&otherFunction : eventsFunctions.GetInternalVector()) {
if (otherFunction->GetFunctionType() ==
gd::EventsFunction::ActionWithOperator &&
otherFunction->GetGetterName() == oldFunctionName) {
@@ -862,16 +892,34 @@ void WholeProjectRefactorer::RenameParameter(
}
}
void WholeProjectRefactorer::ChangeParameterType(
gd::Project &project, gd::ProjectScopedContainers &projectScopedContainers,
gd::EventsFunction &eventsFunction,
const gd::ObjectsContainer &parameterObjectsContainer,
const gd::String &parameterName) {
std::unordered_set<gd::String> typeChangedPropertyNames;
typeChangedPropertyNames.insert(parameterName);
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::EventsVariableInstructionTypeSwitcher
eventsVariableInstructionTypeSwitcher(project.GetCurrentPlatform(),
typeChangedPropertyNames,
propertyVariablesContainer);
eventsVariableInstructionTypeSwitcher.Launch(eventsFunction.GetEvents(),
projectScopedContainers);
}
void WholeProjectRefactorer::MoveEventsFunctionParameter(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::String &functionName, std::size_t oldIndex,
std::size_t newIndex) {
if (!eventsFunctionsExtension.HasEventsFunctionNamed(functionName))
const auto &eventsFunctions = eventsFunctionsExtension.GetEventsFunctions();
if (!eventsFunctions.HasEventsFunctionNamed(functionName))
return;
const gd::EventsFunction &eventsFunction =
eventsFunctionsExtension.GetEventsFunction(functionName);
eventsFunctions.GetEventsFunction(functionName);
const gd::String &eventsFunctionType =
gd::PlatformExtension::GetEventsFunctionFullType(
@@ -1175,6 +1223,42 @@ void WholeProjectRefactorer::RenameEventsBasedObjectProperty(
gd::ProjectBrowserHelper::ExposeProjectEvents(project, conditionRenamer);
}
void WholeProjectRefactorer::ChangeEventsBasedBehaviorPropertyType(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &propertyName) {
std::unordered_set<gd::String> typeChangedPropertyNames;
typeChangedPropertyNames.insert(propertyName);
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::EventsVariableInstructionTypeSwitcher
eventsVariableInstructionTypeSwitcher(project.GetCurrentPlatform(),
typeChangedPropertyNames,
propertyVariablesContainer);
gd::ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
project, eventsFunctionsExtension, eventsBasedBehavior,
propertyVariablesContainer, eventsVariableInstructionTypeSwitcher);
}
void WholeProjectRefactorer::ChangeEventsBasedObjectPropertyType(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::String &propertyName) {
std::unordered_set<gd::String> typeChangedPropertyNames;
typeChangedPropertyNames.insert(propertyName);
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::EventsVariableInstructionTypeSwitcher
eventsVariableInstructionTypeSwitcher(project.GetCurrentPlatform(),
typeChangedPropertyNames,
propertyVariablesContainer);
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
project, eventsFunctionsExtension, eventsBasedObject,
propertyVariablesContainer, eventsVariableInstructionTypeSwitcher);
}
void WholeProjectRefactorer::AddBehaviorAndRequiredBehaviors(
gd::Project &project, gd::Object &object, const gd::String &behaviorType,
const gd::String &behaviorName) {
@@ -1697,6 +1781,14 @@ void WholeProjectRefactorer::DoRenameBehavior(
projectBrowser.ExposeFunctions(project, behaviorParameterRenamer);
}
void WholeProjectRefactorer::UpdateBehaviorsSharedData(gd::Project &project) {
for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
gd::Layout &layout = project.GetLayout(i);
layout.UpdateBehaviorsSharedData(project);
}
}
void WholeProjectRefactorer::DoRenameObject(
gd::Project &project, const gd::String &oldObjectType,
const gd::String &newObjectType, const gd::ProjectBrowser &projectBrowser) {
@@ -2045,6 +2137,26 @@ void WholeProjectRefactorer::ObjectOrGroupRenamedInEventsBasedObject(
groups[g].RenameObject(oldName, newName);
}
}
for (auto &variant : eventsBasedObject.GetVariants().GetInternalVector()) {
auto &variantObjects = variant->GetObjects();
auto &variantObjectGroups = variantObjects.GetObjectGroups();
if (isObjectGroup) {
if (variantObjectGroups.Has(oldName)) {
variantObjectGroups.Get(oldName).SetName(newName);
}
// Object groups can't have instances or be in other groups
}
else {
if (variantObjects.HasObjectNamed(oldName)) {
variantObjects.GetObject(oldName).SetName(newName);
}
variant->GetInitialInstances().RenameInstancesOfObject(oldName, newName);
for (std::size_t g = 0; g < variantObjectGroups.size(); ++g) {
variantObjectGroups[g].RenameObject(oldName, newName);
}
}
}
}
void WholeProjectRefactorer::ObjectOrGroupRenamedInEventsFunction(

Some files were not shown because too many files have changed in this diff Show More