gdharness 1.3.42 → 1.3.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/build/cli.js +383 -243
  2. package/build/godot/addons/auto_reload/auto_reload.gd +18 -19
  3. package/build/godot/addons/gdharness_editor/animation_reads.gd +55 -33
  4. package/build/godot/addons/gdharness_editor/bridge_client.gd +53 -58
  5. package/build/godot/addons/gdharness_editor/declared_values.gd +68 -32
  6. package/build/godot/addons/gdharness_editor/file_reads.gd +83 -42
  7. package/build/godot/addons/gdharness_editor/file_walk.gd +12 -5
  8. package/build/godot/addons/gdharness_editor/headless_check.gd +68 -44
  9. package/build/godot/addons/gdharness_editor/plugin.gd +2 -3
  10. package/build/godot/addons/gdharness_editor/property_paths.gd +22 -12
  11. package/build/godot/addons/gdharness_editor/property_values.gd +143 -78
  12. package/build/godot/addons/gdharness_editor/reading.gd +51 -17
  13. package/build/godot/addons/gdharness_editor/same_values.gd +4 -4
  14. package/build/godot/addons/gdharness_editor/scene_file.gd +127 -80
  15. package/build/godot/addons/gdharness_editor/scene_uids.gd +12 -6
  16. package/build/godot/addons/gdharness_editor/serialisation.gd +75 -51
  17. package/build/godot/addons/gdharness_editor/setting_reads.gd +7 -6
  18. package/build/godot/addons/gdharness_editor/tool_executor.gd +3 -6
  19. package/build/godot/addons/gdharness_editor/tools/animation_states.gd +37 -27
  20. package/build/godot/addons/gdharness_editor/tools/animation_tools.gd +79 -49
  21. package/build/godot/addons/gdharness_editor/tools/animation_tracks.gd +70 -40
  22. package/build/godot/addons/gdharness_editor/tools/class_tools.gd +65 -42
  23. package/build/godot/addons/gdharness_editor/tools/filesystem_tools.gd +24 -22
  24. package/build/godot/addons/gdharness_editor/tools/navigation_bake.gd +49 -29
  25. package/build/godot/addons/gdharness_editor/tools/play_tools.gd +26 -21
  26. package/build/godot/addons/gdharness_editor/tools/profile_tools.gd +40 -40
  27. package/build/godot/addons/gdharness_editor/tools/resource_tools.gd +166 -107
  28. package/build/godot/addons/gdharness_editor/tools/scene_groups.gd +16 -9
  29. package/build/godot/addons/gdharness_editor/tools/scene_kin.gd +68 -41
  30. package/build/godot/addons/gdharness_editor/tools/scene_paths.gd +35 -20
  31. package/build/godot/addons/gdharness_editor/tools/scene_placing.gd +28 -13
  32. package/build/godot/addons/gdharness_editor/tools/scene_sharing.gd +12 -5
  33. package/build/godot/addons/gdharness_editor/tools/scene_tools.gd +113 -67
  34. package/build/godot/addons/gdharness_editor/tools/script_paths.gd +20 -8
  35. package/build/godot/addons/gdharness_editor/tools/settings_tools.gd +11 -8
  36. package/build/godot/addons/gdharness_editor/tools/signal_tools.gd +47 -34
  37. package/build/godot/addons/gdharness_editor/tools/tileset_tools.gd +77 -50
  38. package/build/godot/addons/gdharness_editor/value_shapes.gd +5 -6
  39. package/build/godot/addons/gdharness_runtime/call_errors.gd +1 -2
  40. package/build/godot/addons/gdharness_runtime/declared_values.gd +68 -32
  41. package/build/godot/addons/gdharness_runtime/error_report.gd +1 -2
  42. package/build/godot/addons/gdharness_runtime/reading.gd +51 -17
  43. package/build/godot/addons/gdharness_runtime/runtime_accessibility.gd +84 -63
  44. package/build/godot/addons/gdharness_runtime/runtime_autoload.gd +149 -147
  45. package/build/godot/addons/gdharness_runtime/runtime_capture.gd +64 -42
  46. package/build/godot/addons/gdharness_runtime/runtime_changes.gd +184 -122
  47. package/build/godot/addons/gdharness_runtime/runtime_frames.gd +2 -2
  48. package/build/godot/addons/gdharness_runtime/runtime_hover.gd +24 -20
  49. package/build/godot/addons/gdharness_runtime/runtime_input.gd +134 -92
  50. package/build/godot/addons/gdharness_runtime/runtime_items.gd +29 -13
  51. package/build/godot/addons/gdharness_runtime/runtime_menus.gd +0 -1
  52. package/build/godot/addons/gdharness_runtime/runtime_mouse.gd +34 -17
  53. package/build/godot/addons/gdharness_runtime/runtime_pad.gd +17 -13
  54. package/build/godot/addons/gdharness_runtime/runtime_paths.gd +84 -46
  55. package/build/godot/addons/gdharness_runtime/runtime_queries.gd +117 -79
  56. package/build/godot/addons/gdharness_runtime/runtime_says.gd +14 -17
  57. package/build/godot/addons/gdharness_runtime/runtime_screen.gd +23 -16
  58. package/build/godot/addons/gdharness_runtime/runtime_targets.gd +117 -66
  59. package/build/godot/addons/gdharness_runtime/runtime_touch.gd +15 -15
  60. package/build/godot/addons/gdharness_runtime/runtime_typing.gd +44 -27
  61. package/build/godot/addons/gdharness_runtime/runtime_values.gd +108 -73
  62. package/build/godot/addons/gdharness_runtime/runtime_waits.gd +111 -84
  63. package/build/godot/addons/gdharness_runtime/runtime_words.gd +10 -7
  64. package/build/godot/addons/gdharness_runtime/serialisation.gd +75 -51
  65. package/build/godot/addons/gdharness_runtime/value_shapes.gd +5 -6
  66. package/build/godot/addons/gdharness_tests/bench.gd +4 -5
  67. package/build/godot/addons/gdharness_tests/event.gd +10 -5
  68. package/build/godot/addons/gdharness_tests/share.gd +38 -18
  69. package/build/godot/addons/gdharness_tests/suites.gd +3 -3
  70. package/build/godot/addons/gdharness_tests/wait.gd +3 -2
  71. package/build/godot/loader/loader.gd +9 -9
  72. package/build/godot/operations/animation_reads.gd +55 -33
  73. package/build/godot/operations/audio_buses.gd +48 -19
  74. package/build/godot/operations/class_cache.gd +16 -11
  75. package/build/godot/operations/classdb_queries.gd +89 -44
  76. package/build/godot/operations/declared_values.gd +68 -32
  77. package/build/godot/operations/dependencies.gd +190 -109
  78. package/build/godot/operations/editor_tools.gd +10 -10
  79. package/build/godot/operations/export_presets.gd +100 -54
  80. package/build/godot/operations/file_reads.gd +83 -42
  81. package/build/godot/operations/file_walk.gd +12 -5
  82. package/build/godot/operations/gdscript_analysis.gd +86 -65
  83. package/build/godot/operations/gdscript_authoring.gd +83 -36
  84. package/build/godot/operations/godot_operations.gd +17 -11
  85. package/build/godot/operations/import_pipeline.gd +110 -59
  86. package/build/godot/operations/input_actions.gd +62 -39
  87. package/build/godot/operations/patterns.gd +3 -1
  88. package/build/godot/operations/plugins.gd +36 -16
  89. package/build/godot/operations/project_config.gd +61 -32
  90. package/build/godot/operations/project_diagnostics.gd +24 -11
  91. package/build/godot/operations/project_file.gd +16 -16
  92. package/build/godot/operations/project_validation.gd +71 -44
  93. package/build/godot/operations/property_paths.gd +22 -12
  94. package/build/godot/operations/property_values.gd +143 -78
  95. package/build/godot/operations/reading.gd +51 -17
  96. package/build/godot/operations/rename_checks.gd +2 -2
  97. package/build/godot/operations/resource_files.gd +11 -9
  98. package/build/godot/operations/same_values.gd +4 -4
  99. package/build/godot/operations/scene_connections.gd +27 -13
  100. package/build/godot/operations/script_check.gd +52 -49
  101. package/build/godot/operations/serialisation.gd +75 -51
  102. package/build/godot/operations/setting_reads.gd +7 -6
  103. package/build/godot/operations/value_shapes.gd +5 -6
  104. package/build/godot/tests/listed.gd +321 -268
  105. package/build/keeper.js +43 -43
  106. package/package.json +1 -1
@@ -1,6 +1,5 @@
1
1
  @tool
2
2
  extends "animation_tools.gd"
3
-
4
3
  ## The states and transitions of an AnimationTree's state machines, beside the players and tracks
5
4
  ## the script it extends edits, whose helpers it shares.
6
5
 
@@ -16,9 +15,9 @@ func add_animation_state(args: Dictionary) -> Dictionary:
16
15
  var state_name: String = str(args.get("stateName", ""))
17
16
  var animation_name: String = str(args.get("animationName", ""))
18
17
  if state_name.is_empty():
19
- return {"ok": false, "error": "Missing stateName"}
18
+ return { "ok": false, "error": "Missing stateName" }
20
19
  if animation_name.is_empty():
21
- return {"ok": false, "error": "Missing animationName"}
20
+ return { "ok": false, "error": "Missing animationName" }
22
21
  var machine: Array = _machine_at(args)
23
22
  if machine[1] == null:
24
23
  return machine[3]
@@ -59,7 +58,9 @@ func add_animation_state(args: Dictionary) -> Dictionary:
59
58
  # Written all the same, as the editor writes one: a state machine is often laid out before its
60
59
  # animations are made, and refusing it stopped a tree being built in that order.
61
60
  if player == null:
62
- answer["animationMissing"] = GdhAnimationReads.no_player(str(anim_tree.anim_player), reached)
61
+ answer["animationMissing"] = GdhAnimationReads.no_player(
62
+ str(anim_tree.anim_player), reached
63
+ )
63
64
  elif not found:
64
65
  answer["animationMissing"] = GdhAnimationReads.missing_animation(
65
66
  player, scene.path_of(player), animation_name
@@ -76,14 +77,14 @@ func connect_animation_states(args: Dictionary) -> Dictionary:
76
77
  var to_state: String = str(args.get("toState", ""))
77
78
  var transition_type: String = str(args.get("transitionType", "immediate"))
78
79
  var advance_condition: String = str(args.get("advanceCondition", ""))
79
- # Auto where it is the only mode that does what was asked: a condition is checked only on an auto
80
- # transition, and a machine leaves Start only through one. Written as the default enabled, both
81
- # did nothing, and the machine sat in Start with its conditions true.
80
+ # Auto where it is the only mode that does what was asked: a condition is checked only on an
81
+ # auto transition, and a machine leaves Start only through one. Written as the default enabled,
82
+ # both did nothing, and the machine sat in Start with its conditions true.
82
83
  var auto: bool = not advance_condition.is_empty() or from_state == "Start"
83
84
  var advance_mode: String = str(args.get("advanceMode", "auto" if auto else "enabled"))
84
85
 
85
86
  if from_state.is_empty() or to_state.is_empty():
86
- return {"ok": false, "error": "Missing fromState or toState"}
87
+ return { "ok": false, "error": "Missing fromState or toState" }
87
88
  var advances: Dictionary = {
88
89
  "auto": AnimationNodeStateMachineTransition.ADVANCE_MODE_AUTO,
89
90
  "enabled": AnimationNodeStateMachineTransition.ADVANCE_MODE_ENABLED,
@@ -92,7 +93,7 @@ func connect_animation_states(args: Dictionary) -> Dictionary:
92
93
  if not advances.has(advance_mode):
93
94
  return {
94
95
  "ok": false,
95
- "error": "Unsupported advanceMode: %s; it is auto, enabled or disabled" % advance_mode
96
+ "error": "Unsupported advanceMode: %s; it is auto, enabled or disabled" % advance_mode,
96
97
  }
97
98
  if not advance_condition.is_empty() and advance_mode != "auto":
98
99
  return {
@@ -100,11 +101,12 @@ func connect_animation_states(args: Dictionary) -> Dictionary:
100
101
  "error":
101
102
  (
102
103
  (
103
- "advanceCondition %s would never advance a transition whose advanceMode is %s: the engine"
104
- + " checks a condition only on an auto one. Leave advanceMode out, or give auto"
104
+ "advanceCondition %s would never advance a transition whose advanceMode is %s: "
105
+ + "the engine checks a condition only on an auto one. Leave advanceMode out, "
106
+ + "or give auto"
105
107
  )
106
108
  % [advance_condition, advance_mode]
107
- )
109
+ ),
108
110
  }
109
111
  var modes: Dictionary = {
110
112
  "sync": AnimationNodeStateMachineTransition.SWITCH_MODE_SYNC,
@@ -112,7 +114,7 @@ func connect_animation_states(args: Dictionary) -> Dictionary:
112
114
  "immediate": AnimationNodeStateMachineTransition.SWITCH_MODE_IMMEDIATE,
113
115
  }
114
116
  if not modes.has(transition_type):
115
- return {"ok": false, "error": "Unsupported transitionType: " + transition_type}
117
+ return { "ok": false, "error": "Unsupported transitionType: " + transition_type }
116
118
  var transition: AnimationNodeStateMachineTransition = AnimationNodeStateMachineTransition.new()
117
119
  transition.switch_mode = (
118
120
  GdhRead.as_int(modes[transition_type]) as AnimationNodeStateMachineTransition.SwitchMode
@@ -140,14 +142,16 @@ func connect_animation_states(args: Dictionary) -> Dictionary:
140
142
  scene,
141
143
  Callable(),
142
144
  files,
143
- {"ok": true, "from": from_state, "to": to_state, "advanceMode": advance_mode}
145
+ { "ok": true, "from": from_state, "to": to_state, "advanceMode": advance_mode }
144
146
  )
145
147
 
146
148
 
147
149
  ## Why [param sm] cannot take a transition from [param from_state] to [param to_state], or "".
148
150
  ## Each is a condition add_transition fails on with only a line in the editor's log, and the
149
151
  ## transition was answered as made.
150
- func _transition_problem(sm: AnimationNodeStateMachine, from_state: String, to_state: String) -> String:
152
+ func _transition_problem(
153
+ sm: AnimationNodeStateMachine, from_state: String, to_state: String
154
+ ) -> String:
151
155
  for state: String in [from_state, to_state]:
152
156
  if not sm.has_node(StringName(state)):
153
157
  return _no_state(sm, state)
@@ -172,7 +176,8 @@ static func _no_state(sm: AnimationNodeStateMachine, state_name: String) -> Stri
172
176
  var close: PackedStringArray = GdhRead.nearest(state_name, states)
173
177
  if not close.is_empty():
174
178
  return (
175
- "%s; the nearest it has %s %s." % [said, "is" if close.size() == 1 else "are", ", ".join(close)]
179
+ "%s; the nearest it has %s %s."
180
+ % [said, "is" if close.size() == 1 else "are", ", ".join(close)]
176
181
  )
177
182
  return "%s; its states are %s." % [said, ", ".join(states)]
178
183
 
@@ -183,9 +188,9 @@ func _machine_at(args: Dictionary) -> Array:
183
188
  var scene_path: String = GdhSceneFile.res_path("", str(args.get("scenePath", "")))
184
189
  var anim_tree_path: String = str(args.get("animTreePath", ""))
185
190
  if scene_path.strip_edges() == "res://":
186
- return [null, null, {}, {"ok": false, "error": "Missing scenePath"}]
191
+ return [null, null, {}, { "ok": false, "error": "Missing scenePath" }]
187
192
  if anim_tree_path.is_empty():
188
- return [null, null, {}, {"ok": false, "error": "Missing animTreePath"}]
193
+ return [null, null, {}, { "ok": false, "error": "Missing animTreePath" }]
189
194
  var opened: Array = _open_at(scene_path, anim_tree_path, "AnimationTree")
190
195
  var scene: GdhSceneFile = opened[0]
191
196
  if opened[1] == null:
@@ -206,14 +211,16 @@ func _machine_at(args: Dictionary) -> Array:
206
211
  func remove_animation_state(args: Dictionary) -> Dictionary:
207
212
  var state_name: String = str(args.get("stateName", ""))
208
213
  if state_name.is_empty():
209
- return {"ok": false, "error": "Missing stateName"}
214
+ return { "ok": false, "error": "Missing stateName" }
210
215
  var found: Array = _machine_at(args)
211
216
  if found[1] == null:
212
217
  return found[3]
213
218
  var scene: GdhSceneFile = found[0]
214
219
  var sm: AnimationNodeStateMachine = found[1]
215
220
  if state_name in ["Start", "End"]:
216
- return scene.refuse("%s is part of every state machine, so it cannot be removed." % state_name)
221
+ return scene.refuse(
222
+ "%s is part of every state machine, so it cannot be removed." % state_name
223
+ )
217
224
  if not sm.has_node(StringName(state_name)):
218
225
  return scene.refuse(_no_state(sm, state_name))
219
226
  var dropped: Array = []
@@ -221,7 +228,7 @@ func remove_animation_state(args: Dictionary) -> Dictionary:
221
228
  var from: String = str(sm.get_transition_from(index))
222
229
  var to: String = str(sm.get_transition_to(index))
223
230
  if state_name in [from, to]:
224
- dropped.append({"from": from, "to": to})
231
+ dropped.append({ "from": from, "to": to })
225
232
  sm.remove_node(StringName(state_name))
226
233
  if sm.has_node(StringName(state_name)):
227
234
  return scene.refuse("The state machine did not let go of %s." % state_name)
@@ -231,9 +238,8 @@ func remove_animation_state(args: Dictionary) -> Dictionary:
231
238
  "The state machine kept a transition of %s after the state went." % state_name
232
239
  )
233
240
  var files: Dictionary = found[2]
234
- return _finish(
235
- scene, Callable(), files, {"ok": true, "removed": state_name, "transitionsRemoved": dropped}
236
- )
241
+ var answer: Dictionary = { "ok": true, "removed": state_name, "transitionsRemoved": dropped }
242
+ return _finish(scene, Callable(), files, answer)
237
243
 
238
244
 
239
245
  ## Takes out the transition from one state to another.
@@ -241,7 +247,7 @@ func disconnect_animation_states(args: Dictionary) -> Dictionary:
241
247
  var from_state: String = str(args.get("fromState", ""))
242
248
  var to_state: String = str(args.get("toState", ""))
243
249
  if from_state.is_empty() or to_state.is_empty():
244
- return {"ok": false, "error": "Missing fromState or toState"}
250
+ return { "ok": false, "error": "Missing fromState or toState" }
245
251
  var found: Array = _machine_at(args)
246
252
  if found[1] == null:
247
253
  return found[3]
@@ -258,9 +264,13 @@ func disconnect_animation_states(args: Dictionary) -> Dictionary:
258
264
  var said: String = "There is no transition from %s to %s" % [from_state, to_state]
259
265
  if leaving.is_empty():
260
266
  return scene.refuse("%s; none leaves %s." % [said, from_state])
261
- return scene.refuse("%s; the ones leaving %s go to %s." % [said, from_state, ", ".join(leaving)])
267
+ return scene.refuse(
268
+ "%s; the ones leaving %s go to %s." % [said, from_state, ", ".join(leaving)]
269
+ )
262
270
  sm.remove_transition(StringName(from_state), StringName(to_state))
263
271
  if sm.has_transition(StringName(from_state), StringName(to_state)):
264
272
  return scene.refuse("The state machine did not let go of the transition.")
265
273
  var files: Dictionary = found[2]
266
- return _finish(scene, Callable(), files, {"ok": true, "removed": {"from": from_state, "to": to_state}})
274
+ return _finish(
275
+ scene, Callable(), files, { "ok": true, "removed": { "from": from_state, "to": to_state } }
276
+ )
@@ -1,8 +1,7 @@
1
1
  @tool
2
2
  extends Node
3
-
4
- ## Animations and animation trees, edited in the open editor or, for a project no editor serves, by a
5
- ## headless engine.
3
+ ## Animations and animation trees, edited in the open editor or, for a project no editor serves, by
4
+ ## a headless engine.
6
5
 
7
6
  const GdhAnimationReads = preload("../animation_reads.gd")
8
7
  const GdhHeadlessCheck = preload("../headless_check.gd")
@@ -11,9 +10,10 @@ const GdhRead = preload("../reading.gd")
11
10
  const GdhSceneFile = preload("../scene_file.gd")
12
11
  const GdhSceneUids = preload("../scene_uids.gd")
13
12
  const GdhSerialisation = preload("../serialisation.gd")
14
-
15
13
  const LOOP_MODES: Dictionary = {
16
- "none": Animation.LOOP_NONE, "linear": Animation.LOOP_LINEAR, "pingpong": Animation.LOOP_PINGPONG
14
+ "none": Animation.LOOP_NONE,
15
+ "linear": Animation.LOOP_LINEAR,
16
+ "pingpong": Animation.LOOP_PINGPONG,
17
17
  }
18
18
 
19
19
  var _editor_plugin: EditorPlugin = null
@@ -74,7 +74,9 @@ func _not_of_kind(scene: GdhSceneFile, node: Node, node_path: String, kind: Stri
74
74
 
75
75
  ## Writes [param scene] once [param check] passes, then the files of [param homes], answering
76
76
  ## [param answer] or a refusal.
77
- func _finish(scene: GdhSceneFile, check: Callable, homes: Dictionary, answer: Dictionary) -> Dictionary:
77
+ func _finish(
78
+ scene: GdhSceneFile, check: Callable, homes: Dictionary, answer: Dictionary
79
+ ) -> Dictionary:
78
80
  if not Engine.is_editor_hint():
79
81
  for file: Variant in homes:
80
82
  var home: Resource = homes[file]
@@ -85,9 +87,9 @@ func _finish(scene: GdhSceneFile, check: Callable, homes: Dictionary, answer: Di
85
87
  (
86
88
  (
87
89
  (
88
- "Nothing was written: %s holds a resource with a script that is not a tool, and what "
89
- + "that script changed when a headless engine loaded it cannot be told apart from the "
90
- + "edit. "
90
+ "Nothing was written: %s holds a resource with a script that "
91
+ + "is not a tool, and what that script changed when a headless "
92
+ + "engine loaded it cannot be told apart from the edit. "
91
93
  )
92
94
  % file
93
95
  )
@@ -102,7 +104,7 @@ func _finish(scene: GdhSceneFile, check: Callable, homes: Dictionary, answer: Di
102
104
  var resource: Resource = homes[file]
103
105
  var saving: Error = GdhSceneUids.save_keeping_uid(resource, str(file))
104
106
  if saving != OK:
105
- return {"ok": false, "error": "Failed to save %s: %s" % [file, error_string(saving)]}
107
+ return { "ok": false, "error": "Failed to save %s: %s" % [file, error_string(saving)] }
106
108
  if Engine.is_editor_hint():
107
109
  EditorInterface.get_resource_filesystem().update_file(str(file))
108
110
  return answer
@@ -112,7 +114,10 @@ func _finish(scene: GdhSceneFile, check: Callable, homes: Dictionary, answer: Di
112
114
  ## engine ran as it loaded the file.
113
115
  func _scripted(resource: Resource) -> bool:
114
116
  var script: Script = resource.get_script()
115
- return (script != null and not script.is_tool()) or GdhHeadlessCheck.holds_scripted_embedded(resource, {})
117
+ return (
118
+ (script != null and not script.is_tool())
119
+ or GdhHeadlessCheck.holds_scripted_embedded(resource, {})
120
+ )
116
121
 
117
122
 
118
123
  func _parse_json_maybe(value: Variant) -> Variant:
@@ -160,11 +165,11 @@ func _homes(scene: GdhSceneFile, held: Array) -> Array:
160
165
  false,
161
166
  (
162
167
  (
163
- "The %s is kept in %s, not in %s, and an edit here would not be saved there. Edit it "
164
- + "where it is kept instead."
168
+ "The %s is kept in %s, not in %s, and an edit here would not be saved there. "
169
+ + "Edit it where it is kept instead."
165
170
  )
166
171
  % [entry[1], at.get_slice("::", 0), scene.path]
167
- )
172
+ ),
168
173
  ]
169
174
  return [true, homes]
170
175
 
@@ -198,7 +203,9 @@ func _library_of(player: AnimationPlayer, animation_name: String) -> AnimationLi
198
203
  ## The state machine at [param state_machine_path] in [param anim_tree], with the files it is kept
199
204
  ## in, as [machine, homes, why not].
200
205
  func _machine(scene: GdhSceneFile, anim_tree: AnimationTree, state_machine_path: String) -> Array:
201
- var sm: AnimationNodeStateMachine = GdhAnimationReads.state_machine(anim_tree, state_machine_path)
206
+ var sm: AnimationNodeStateMachine = GdhAnimationReads.state_machine(
207
+ anim_tree, state_machine_path
208
+ )
202
209
  if not sm:
203
210
  return [null, {}, GdhAnimationReads.no_machine(anim_tree, state_machine_path)]
204
211
  var homes: Array = _homes(scene, [[sm, "state machine"]])
@@ -225,7 +232,7 @@ func read_animations(args: Dictionary) -> Dictionary:
225
232
  var player_node_path: String = str(args.get("playerNodePath", "."))
226
233
  var animation_name: String = str(args.get("animationName", ""))
227
234
  if scene_path.strip_edges() == "res://":
228
- return {"ok": false, "error": "Missing scenePath"}
235
+ return { "ok": false, "error": "Missing scenePath" }
229
236
 
230
237
  var opened: Array = _read_at(scene_path, player_node_path, "AnimationPlayer")
231
238
  var scene: GdhSceneFile = opened[0]
@@ -250,9 +257,9 @@ func read_animation_states(args: Dictionary) -> Dictionary:
250
257
  var anim_tree_path: String = str(args.get("animTreePath", ""))
251
258
  var state_machine_path: String = str(args.get("stateMachinePath", ""))
252
259
  if scene_path.strip_edges() == "res://":
253
- return {"ok": false, "error": "Missing scenePath"}
260
+ return { "ok": false, "error": "Missing scenePath" }
254
261
  if anim_tree_path.is_empty():
255
- return {"ok": false, "error": "Missing animTreePath"}
262
+ return { "ok": false, "error": "Missing animTreePath" }
256
263
 
257
264
  var opened: Array = _read_at(scene_path, anim_tree_path, "AnimationTree")
258
265
  var scene: GdhSceneFile = opened[0]
@@ -264,7 +271,8 @@ func read_animation_states(args: Dictionary) -> Dictionary:
264
271
  var player_path: String = "" if player == null else scene.path_of(player)
265
272
  var unplayed: String = GdhAnimationReads.no_player(str(anim_tree.anim_player), reached)
266
273
  return _read_in(
267
- scene, GdhAnimationReads.states(anim_tree, state_machine_path, player, player_path, unplayed)
274
+ scene,
275
+ GdhAnimationReads.states(anim_tree, state_machine_path, player, player_path, unplayed)
268
276
  )
269
277
 
270
278
 
@@ -278,18 +286,18 @@ func create_animation(args: Dictionary) -> Dictionary:
278
286
  var loop_mode_name: String = str(args.get("loopMode", "none"))
279
287
 
280
288
  if scene_path.strip_edges() == "res://":
281
- return {"ok": false, "error": "Missing scenePath"}
289
+ return { "ok": false, "error": "Missing scenePath" }
282
290
  if animation_name.strip_edges().is_empty():
283
- return {"ok": false, "error": "Missing animationName"}
291
+ return { "ok": false, "error": "Missing animationName" }
284
292
  var named: String = _name_refusal(animation_name)
285
293
  if not named.is_empty():
286
- return {"ok": false, "error": named}
294
+ return { "ok": false, "error": named }
287
295
  var loop_modes: Dictionary = LOOP_MODES
288
296
  if not loop_modes.has(loop_mode_name):
289
- return {"ok": false, "error": "Unsupported loopMode: " + loop_mode_name}
297
+ return { "ok": false, "error": "Unsupported loopMode: " + loop_mode_name }
290
298
  var timing: String = _timing_refusal(args)
291
299
  if not timing.is_empty():
292
- return {"ok": false, "error": timing}
300
+ return { "ok": false, "error": timing }
293
301
 
294
302
  var opened: Array = _open_at(scene_path, player_node_path, "AnimationPlayer")
295
303
  var scene: GdhSceneFile = opened[0]
@@ -310,7 +318,9 @@ func create_animation(args: Dictionary) -> Dictionary:
310
318
  anim.length = GdhRead.as_float(args.get("length", 1.0), 1.0)
311
319
  anim.loop_mode = GdhRead.as_int(loop_modes[loop_mode_name]) as Animation.LoopMode
312
320
  anim.step = GdhRead.as_float(args.get("step", 0.1), 0.1)
313
- var called: String = animation_name.get_slice("/", 1) if animation_name.contains("/") else animation_name
321
+ var called: String = (
322
+ animation_name.get_slice("/", 1) if animation_name.contains("/") else animation_name
323
+ )
314
324
  # As the editor names a new one: the file keeps it as resource_name, which the inspector shows.
315
325
  anim.resource_name = called
316
326
  var add_err: Error = anim_lib.add_animation(StringName(called), anim)
@@ -327,10 +337,12 @@ func create_animation(args: Dictionary) -> Dictionary:
327
337
  "ok": true,
328
338
  "animationName": animation_name,
329
339
  "length": GdhAnimationReads.held_seconds(anim.length),
330
- "loopMode": loop_mode_name
340
+ "loopMode": loop_mode_name,
331
341
  }
332
342
  if library[2]:
333
- answer["libraryMade"] = animation_name.get_slice("/", 0) if animation_name.contains("/") else ""
343
+ answer["libraryMade"] = (
344
+ animation_name.get_slice("/", 0) if animation_name.contains("/") else ""
345
+ )
334
346
  var files: Dictionary = homes[1]
335
347
  return _finish(scene, check, files, answer)
336
348
 
@@ -341,8 +353,8 @@ static func _name_refusal(animation_name: String) -> String:
341
353
  if animation_name.count("/") > 1:
342
354
  return (
343
355
  (
344
- "%s names a library and an animation in it with one slash, as moves/walk; a library holds no "
345
- + "libraries."
356
+ "%s names a library and an animation in it with one slash, as moves/walk; a "
357
+ + "library holds no libraries."
346
358
  )
347
359
  % animation_name
348
360
  )
@@ -372,7 +384,9 @@ static func _past_length(anim: Animation, animation_name: String) -> String:
372
384
 
373
385
  ## The pastLength sentence for [param past], keys of [param anim] each named by its track's path and
374
386
  ## time, or "" for none.
375
- static func _past_sentence(anim: Animation, animation_name: String, past: PackedStringArray) -> String:
387
+ static func _past_sentence(
388
+ anim: Animation, animation_name: String, past: PackedStringArray
389
+ ) -> String:
376
390
  if past.is_empty():
377
391
  return ""
378
392
  return (
@@ -407,7 +421,10 @@ static func _timing_refusal(args: Dictionary) -> String:
407
421
  if args.has("length"):
408
422
  var length: Variant = args["length"]
409
423
  if not (length is float or length is int) or GdhRead.as_float(length) <= 0.0:
410
- return "length is the animation's length in seconds, more than 0, and %s is not." % _given(length)
424
+ return (
425
+ "length is the animation's length in seconds, more than 0, and %s is not."
426
+ % _given(length)
427
+ )
411
428
  if args.has("step"):
412
429
  var step: Variant = args["step"]
413
430
  if not (step is float or step is int) or GdhRead.as_float(step) < 0.0:
@@ -443,16 +460,19 @@ func set_animation(args: Dictionary) -> Dictionary:
443
460
  var animation_name: String = str(args.get("animationName", ""))
444
461
  var loop_mode_name: String = str(args.get("loopMode", ""))
445
462
  if scene_path.strip_edges() == "res://":
446
- return {"ok": false, "error": "Missing scenePath"}
463
+ return { "ok": false, "error": "Missing scenePath" }
447
464
  if animation_name.strip_edges().is_empty():
448
- return {"ok": false, "error": "Missing animationName"}
465
+ return { "ok": false, "error": "Missing animationName" }
449
466
  if not (args.has("length") or args.has("loopMode") or args.has("step")):
450
- return {"ok": false, "error": "set changes length, loopMode or step, and was given none of them."}
467
+ return {
468
+ "ok": false,
469
+ "error": "set changes length, loopMode or step, and was given none of them.",
470
+ }
451
471
  if args.has("loopMode") and not LOOP_MODES.has(loop_mode_name):
452
- return {"ok": false, "error": "Unsupported loopMode: " + loop_mode_name}
472
+ return { "ok": false, "error": "Unsupported loopMode: " + loop_mode_name }
453
473
  var timing: String = _timing_refusal(args)
454
474
  if not timing.is_empty():
455
- return {"ok": false, "error": timing}
475
+ return { "ok": false, "error": timing }
456
476
 
457
477
  var found: Array = _animation_at(scene_path, player_node_path, animation_name)
458
478
  if found[1] == null:
@@ -479,7 +499,10 @@ func set_animation(args: Dictionary) -> Dictionary:
479
499
  if copy == null or not copy.has_animation(StringName(animation_name)):
480
500
  return "%s would not be in the scene when it loads." % animation_name
481
501
  if not is_equal_approx(copy.get_animation(StringName(animation_name)).length, length):
482
- return "%s would not be %s s long when the scene loads." % [animation_name, _seconds(length)]
502
+ return (
503
+ "%s would not be %s s long when the scene loads."
504
+ % [animation_name, _seconds(length)]
505
+ )
483
506
  return ""
484
507
  var answer: Dictionary = {
485
508
  "ok": true,
@@ -504,12 +527,14 @@ func rename_animation(args: Dictionary) -> Dictionary:
504
527
  var animation_name: String = str(args.get("animationName", ""))
505
528
  var new_name: String = str(args.get("newName", "")).strip_edges()
506
529
  if scene_path.strip_edges() == "res://":
507
- return {"ok": false, "error": "Missing scenePath"}
530
+ return { "ok": false, "error": "Missing scenePath" }
508
531
  if animation_name.strip_edges().is_empty():
509
- return {"ok": false, "error": "Missing animationName"}
532
+ return { "ok": false, "error": "Missing animationName" }
510
533
  if new_name.is_empty():
511
- return {"ok": false, "error": "Missing newName"}
512
- var library_name: String = animation_name.get_slice("/", 0) if animation_name.contains("/") else ""
534
+ return { "ok": false, "error": "Missing newName" }
535
+ var library_name: String = (
536
+ animation_name.get_slice("/", 0) if animation_name.contains("/") else ""
537
+ )
513
538
  var prefix: String = "" if library_name.is_empty() else library_name + "/"
514
539
  if not prefix.is_empty() and new_name.begins_with(prefix):
515
540
  new_name = new_name.trim_prefix(prefix)
@@ -519,15 +544,18 @@ func rename_animation(args: Dictionary) -> Dictionary:
519
544
  "error":
520
545
  (
521
546
  (
522
- "rename keeps an animation in its library (%s), so newName is its name there, with "
523
- + "no library before a slash."
547
+ "rename keeps an animation in its library (%s), so newName is its name there, "
548
+ + "with no library before a slash."
524
549
  )
525
550
  % ("the default one" if library_name.is_empty() else library_name)
526
551
  ),
527
552
  }
528
553
  for forbidden: String in [":", ",", "["]:
529
554
  if new_name.contains(forbidden):
530
- return {"ok": false, "error": "An animation's name cannot hold : , or [, and %s does." % new_name}
555
+ return {
556
+ "ok": false,
557
+ "error": "An animation's name cannot hold : , or [, and %s does." % new_name,
558
+ }
531
559
  var new_full: String = prefix + new_name
532
560
 
533
561
  var found: Array = _animation_at(scene_path, player_node_path, animation_name)
@@ -557,7 +585,7 @@ func rename_animation(args: Dictionary) -> Dictionary:
557
585
  # As the editor's rename sets it: the library's key alone left the file's resource_name, which
558
586
  # the inspector shows, on the old name.
559
587
  player.get_animation(StringName(new_full)).resource_name = new_name
560
- var answer: Dictionary = {"ok": true, "animationName": new_full, "was": animation_name}
588
+ var answer: Dictionary = { "ok": true, "animationName": new_full, "was": animation_name }
561
589
  if autoplayed:
562
590
  answer["autoplay"] = new_full
563
591
  var followed: Array = []
@@ -585,9 +613,9 @@ func remove_animation(args: Dictionary) -> Dictionary:
585
613
  var player_node_path: String = str(args.get("playerNodePath", "."))
586
614
  var animation_name: String = str(args.get("animationName", ""))
587
615
  if scene_path.strip_edges() == "res://":
588
- return {"ok": false, "error": "Missing scenePath"}
616
+ return { "ok": false, "error": "Missing scenePath" }
589
617
  if animation_name.strip_edges().is_empty():
590
- return {"ok": false, "error": "Missing animationName"}
618
+ return { "ok": false, "error": "Missing animationName" }
591
619
 
592
620
  var found: Array = _animation_at(scene_path, player_node_path, animation_name)
593
621
  if found[1] == null:
@@ -598,12 +626,14 @@ func remove_animation(args: Dictionary) -> Dictionary:
598
626
  var homes: Array = _homes(scene, [[library, "animation library"]])
599
627
  if not homes[0]:
600
628
  return scene.refuse(str(homes[1]))
601
- var called: String = animation_name.get_slice("/", 1) if animation_name.contains("/") else animation_name
629
+ var called: String = (
630
+ animation_name.get_slice("/", 1) if animation_name.contains("/") else animation_name
631
+ )
602
632
  var autoplayed: bool = str(player.autoplay) == animation_name
603
633
  library.remove_animation(StringName(called))
604
634
  if player.has_animation(StringName(animation_name)):
605
635
  return scene.refuse("The library did not let go of %s." % animation_name)
606
- var answer: Dictionary = {"ok": true, "removed": animation_name}
636
+ var answer: Dictionary = { "ok": true, "removed": animation_name }
607
637
  if autoplayed:
608
638
  player.autoplay = ""
609
639
  answer["autoplayCleared"] = true