@skillcap/gdh 3.2.3 → 4.1.0
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.
- package/INSTALL-BUNDLE.json +1 -1
- package/README.md +6 -5
- package/RELEASE-SPAN-UPDATE-CONTRACTS.json +125 -0
- package/node_modules/@gdh/adapters/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/index.js +0 -2
- package/node_modules/@gdh/adapters/dist/index.js.map +1 -1
- package/node_modules/@gdh/adapters/dist/skill-rendering.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/skill-rendering.js +26 -30
- package/node_modules/@gdh/adapters/dist/skill-rendering.js.map +1 -1
- package/node_modules/@gdh/adapters/package.json +7 -7
- package/node_modules/@gdh/authoring/dist/lsp.d.ts +12 -0
- package/node_modules/@gdh/authoring/dist/lsp.d.ts.map +1 -1
- package/node_modules/@gdh/authoring/dist/lsp.js +128 -3
- package/node_modules/@gdh/authoring/dist/lsp.js.map +1 -1
- package/node_modules/@gdh/authoring/package.json +2 -2
- package/node_modules/@gdh/cli/dist/bridge-session.d.ts.map +1 -1
- package/node_modules/@gdh/cli/dist/bridge-session.js +11 -25
- package/node_modules/@gdh/cli/dist/bridge-session.js.map +1 -1
- package/node_modules/@gdh/cli/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/cli/dist/index.js +26 -537
- package/node_modules/@gdh/cli/dist/index.js.map +1 -1
- package/node_modules/@gdh/cli/dist/migrate.d.ts.map +1 -1
- package/node_modules/@gdh/cli/dist/migrate.js +25 -0
- package/node_modules/@gdh/cli/dist/migrate.js.map +1 -1
- package/node_modules/@gdh/cli/package.json +11 -11
- package/node_modules/@gdh/core/dist/editor-operation-runner.d.ts.map +1 -1
- package/node_modules/@gdh/core/dist/editor-operation-runner.js +530 -1
- package/node_modules/@gdh/core/dist/editor-operation-runner.js.map +1 -1
- package/node_modules/@gdh/core/dist/index.d.ts +14 -10
- package/node_modules/@gdh/core/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/core/dist/index.js +16 -14
- package/node_modules/@gdh/core/dist/index.js.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/entries/s3c26_to_s3c27_run_game_knowledge.d.ts +3 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s3c26_to_s3c27_run_game_knowledge.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s3c26_to_s3c27_run_game_knowledge.js +91 -0
- package/node_modules/@gdh/core/dist/migrations/entries/s3c26_to_s3c27_run_game_knowledge.js.map +1 -0
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.d.ts +7 -2
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.d.ts.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.js +9 -3
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.js.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/managed-target-surface-inventory.d.ts +20 -9
- package/node_modules/@gdh/core/dist/migrations/managed-target-surface-inventory.d.ts.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/managed-target-surface-inventory.js +22 -10
- package/node_modules/@gdh/core/dist/migrations/managed-target-surface-inventory.js.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/registry.d.ts +1 -1
- package/node_modules/@gdh/core/dist/migrations/registry.d.ts.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/registry.js +2 -0
- package/node_modules/@gdh/core/dist/migrations/registry.js.map +1 -1
- package/node_modules/@gdh/core/dist/run-game-knowledge-scaffold.d.ts +16 -0
- package/node_modules/@gdh/core/dist/run-game-knowledge-scaffold.d.ts.map +1 -0
- package/node_modules/@gdh/core/dist/run-game-knowledge-scaffold.js +89 -0
- package/node_modules/@gdh/core/dist/run-game-knowledge-scaffold.js.map +1 -0
- package/node_modules/@gdh/core/package.json +1 -1
- package/node_modules/@gdh/docs/dist/guidance.d.ts.map +1 -1
- package/node_modules/@gdh/docs/dist/guidance.js +29 -0
- package/node_modules/@gdh/docs/dist/guidance.js.map +1 -1
- package/node_modules/@gdh/docs/dist/templates/guidance/editor-bridge.md.tpl +4 -1
- package/node_modules/@gdh/docs/dist/templates/guidance/runtime.md.tpl +33 -0
- package/node_modules/@gdh/docs/package.json +2 -2
- package/node_modules/@gdh/editor/dist/index.d.ts +101 -0
- package/node_modules/@gdh/editor/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/editor/dist/index.js +166 -5
- package/node_modules/@gdh/editor/dist/index.js.map +1 -1
- package/node_modules/@gdh/editor/package.json +2 -2
- package/node_modules/@gdh/mcp/dist/bridge-tools.d.ts +3 -4
- package/node_modules/@gdh/mcp/dist/bridge-tools.d.ts.map +1 -1
- package/node_modules/@gdh/mcp/dist/bridge-tools.js +5 -77
- package/node_modules/@gdh/mcp/dist/bridge-tools.js.map +1 -1
- package/node_modules/@gdh/mcp/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/mcp/dist/index.js +832 -249
- package/node_modules/@gdh/mcp/dist/index.js.map +1 -1
- package/node_modules/@gdh/mcp/package.json +8 -8
- package/node_modules/@gdh/observability/package.json +2 -2
- package/node_modules/@gdh/runtime/dist/bridge-broker.d.ts +9 -1
- package/node_modules/@gdh/runtime/dist/bridge-broker.d.ts.map +1 -1
- package/node_modules/@gdh/runtime/dist/bridge-broker.js +267 -52
- package/node_modules/@gdh/runtime/dist/bridge-broker.js.map +1 -1
- package/node_modules/@gdh/runtime/dist/bridge-surface.js +11 -3
- package/node_modules/@gdh/runtime/dist/bridge-surface.js.map +1 -1
- package/node_modules/@gdh/runtime/package.json +2 -2
- package/node_modules/@gdh/scan/dist/onboard.d.ts.map +1 -1
- package/node_modules/@gdh/scan/dist/onboard.js +60 -180
- package/node_modules/@gdh/scan/dist/onboard.js.map +1 -1
- package/node_modules/@gdh/scan/package.json +3 -3
- package/node_modules/@gdh/verify/package.json +6 -6
- package/package.json +12 -12
|
@@ -58,6 +58,34 @@ func _dispatch_operation(operation: Dictionary) -> Dictionary:
|
|
|
58
58
|
return _resource_properties(operation)
|
|
59
59
|
"resource.set_property":
|
|
60
60
|
return _resource_set_property(operation)
|
|
61
|
+
"animation.player.inspect":
|
|
62
|
+
return _animation_player_inspect(operation)
|
|
63
|
+
"animation.clip.create":
|
|
64
|
+
return _animation_clip_create(operation)
|
|
65
|
+
"animation.clip.read":
|
|
66
|
+
return _animation_clip_read(operation)
|
|
67
|
+
"animation.clip.delete":
|
|
68
|
+
return _animation_clip_delete(operation)
|
|
69
|
+
"animation.track.add":
|
|
70
|
+
return _animation_track_add(operation)
|
|
71
|
+
"animation.track.remove":
|
|
72
|
+
return _animation_track_remove(operation)
|
|
73
|
+
"animation.keyframe.upsert":
|
|
74
|
+
return _animation_keyframe_upsert(operation)
|
|
75
|
+
"animation.keyframe.delete":
|
|
76
|
+
return _animation_keyframe_delete(operation)
|
|
77
|
+
"animation.state_machine.create":
|
|
78
|
+
return _animation_state_machine_create(operation)
|
|
79
|
+
"animation.state_machine.read":
|
|
80
|
+
return _animation_state_machine_read(operation)
|
|
81
|
+
"animation.state_machine.node.upsert":
|
|
82
|
+
return _animation_state_machine_node_upsert(operation)
|
|
83
|
+
"animation.state_machine.node.delete":
|
|
84
|
+
return _animation_state_machine_node_delete(operation)
|
|
85
|
+
"animation.state_machine.transition.upsert":
|
|
86
|
+
return _animation_state_machine_transition_upsert(operation)
|
|
87
|
+
"animation.state_machine.transition.delete":
|
|
88
|
+
return _animation_state_machine_transition_delete(operation)
|
|
61
89
|
"script.attach":
|
|
62
90
|
return _script_attach(operation)
|
|
63
91
|
"class.search":
|
|
@@ -314,6 +342,287 @@ func _resource_set_property(operation: Dictionary) -> Dictionary:
|
|
|
314
342
|
return _failure("Failed to save resource: " + resource_path, ["resource_save_failed"])
|
|
315
343
|
return _success("Resource property set.", {"resourcePath": resource_path, "propertyName": property_name})
|
|
316
344
|
|
|
345
|
+
func _animation_player_inspect(operation: Dictionary) -> Dictionary:
|
|
346
|
+
var loaded := _load_animation_player_context(operation)
|
|
347
|
+
if not loaded.get("ok", false):
|
|
348
|
+
return loaded
|
|
349
|
+
var player = loaded["player"]
|
|
350
|
+
var libraries := []
|
|
351
|
+
if player.has_method("get_animation_library_list"):
|
|
352
|
+
for library_name in player.get_animation_library_list():
|
|
353
|
+
var library = player.get_animation_library(library_name)
|
|
354
|
+
if library == null:
|
|
355
|
+
continue
|
|
356
|
+
var animations := []
|
|
357
|
+
for animation_name in library.get_animation_list():
|
|
358
|
+
var animation = library.get_animation(animation_name)
|
|
359
|
+
animations.append(_animation_clip_summary(str(library_name), str(animation_name), animation))
|
|
360
|
+
libraries.append({"name": str(library_name), "animations": animations})
|
|
361
|
+
var output := {
|
|
362
|
+
"scenePath": loaded["scenePath"],
|
|
363
|
+
"animationPlayerPath": loaded["animationPlayerPath"],
|
|
364
|
+
"class": player.get_class(),
|
|
365
|
+
"autoplay": str(player.get("autoplay")),
|
|
366
|
+
"defaultBlendTime": player.get("playback_default_blend_time"),
|
|
367
|
+
"libraries": libraries,
|
|
368
|
+
}
|
|
369
|
+
loaded["root"].queue_free()
|
|
370
|
+
return _success("Animation player inspected.", output)
|
|
371
|
+
|
|
372
|
+
func _animation_clip_create(operation: Dictionary) -> Dictionary:
|
|
373
|
+
var loaded := _load_animation_player_context(operation)
|
|
374
|
+
if not loaded.get("ok", false):
|
|
375
|
+
return loaded
|
|
376
|
+
var player = loaded["player"]
|
|
377
|
+
var library_name := str(operation.get("libraryName", ""))
|
|
378
|
+
var animation_name := str(operation.get("animationName", ""))
|
|
379
|
+
var library = _get_or_create_animation_library(player, library_name)
|
|
380
|
+
if library == null:
|
|
381
|
+
return _failure("Animation library could not be created: " + library_name, ["animation_library_unavailable"])
|
|
382
|
+
if library.has_animation(animation_name) and not bool(operation.get("overwrite", false)):
|
|
383
|
+
return _failure("Animation already exists: " + animation_name, ["animation_clip_exists"])
|
|
384
|
+
var animation := Animation.new()
|
|
385
|
+
animation.length = max(0.001, float(operation.get("length", 1.0)))
|
|
386
|
+
animation.step = max(0.001, float(operation.get("step", animation.step)))
|
|
387
|
+
animation.loop_mode = _animation_loop_mode(operation.get("loopMode", animation.loop_mode))
|
|
388
|
+
if library.has_animation(animation_name):
|
|
389
|
+
library.remove_animation(animation_name)
|
|
390
|
+
var add_err = library.add_animation(animation_name, animation)
|
|
391
|
+
if int(add_err) != OK:
|
|
392
|
+
return _failure("Animation could not be added: " + animation_name, ["animation_clip_add_failed"])
|
|
393
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
394
|
+
if not result.get("ok", false):
|
|
395
|
+
return result
|
|
396
|
+
return _success("Animation clip created.", {"scenePath": loaded["scenePath"], "animationPlayerPath": loaded["animationPlayerPath"], "libraryName": library_name, "animationName": animation_name, "length": animation.length, "loopMode": animation.loop_mode, "step": animation.step})
|
|
397
|
+
|
|
398
|
+
func _animation_clip_read(operation: Dictionary) -> Dictionary:
|
|
399
|
+
var loaded := _load_animation_player_context(operation)
|
|
400
|
+
if not loaded.get("ok", false):
|
|
401
|
+
return loaded
|
|
402
|
+
var resolved := _resolve_animation_clip(loaded["player"], operation)
|
|
403
|
+
if not resolved.get("ok", false):
|
|
404
|
+
loaded["root"].queue_free()
|
|
405
|
+
return resolved
|
|
406
|
+
var animation: Animation = resolved["animation"]
|
|
407
|
+
var include_keys := bool(operation.get("includeKeys", false))
|
|
408
|
+
var key_limit := int(operation.get("keyLimit", 200))
|
|
409
|
+
var tracks := []
|
|
410
|
+
for track_index in range(animation.get_track_count()):
|
|
411
|
+
tracks.append(_animation_track_summary(animation, track_index, include_keys, key_limit))
|
|
412
|
+
var output := _animation_clip_summary(str(resolved["libraryName"]), str(resolved["animationName"]), animation)
|
|
413
|
+
output["tracks"] = tracks
|
|
414
|
+
loaded["root"].queue_free()
|
|
415
|
+
return _success("Animation clip read.", output)
|
|
416
|
+
|
|
417
|
+
func _animation_clip_delete(operation: Dictionary) -> Dictionary:
|
|
418
|
+
var loaded := _load_animation_player_context(operation)
|
|
419
|
+
if not loaded.get("ok", false):
|
|
420
|
+
return loaded
|
|
421
|
+
var library_name := str(operation.get("libraryName", ""))
|
|
422
|
+
var animation_name := str(operation.get("animationName", ""))
|
|
423
|
+
var library = _get_animation_library(loaded["player"], library_name)
|
|
424
|
+
if library == null or not library.has_animation(animation_name):
|
|
425
|
+
return _failure("Animation clip not found: " + animation_name, ["animation_clip_not_found"])
|
|
426
|
+
library.remove_animation(animation_name)
|
|
427
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
428
|
+
if not result.get("ok", false):
|
|
429
|
+
return result
|
|
430
|
+
return _success("Animation clip deleted.", {"scenePath": loaded["scenePath"], "animationPlayerPath": loaded["animationPlayerPath"], "libraryName": library_name, "animationName": animation_name})
|
|
431
|
+
|
|
432
|
+
func _animation_track_add(operation: Dictionary) -> Dictionary:
|
|
433
|
+
var loaded := _load_animation_player_context(operation)
|
|
434
|
+
if not loaded.get("ok", false):
|
|
435
|
+
return loaded
|
|
436
|
+
var resolved := _resolve_animation_clip(loaded["player"], operation)
|
|
437
|
+
if not resolved.get("ok", false):
|
|
438
|
+
return resolved
|
|
439
|
+
var animation: Animation = resolved["animation"]
|
|
440
|
+
var track_type := _animation_track_type(operation.get("trackType", "value"))
|
|
441
|
+
if track_type < 0:
|
|
442
|
+
return _failure("Unsupported Animation track type: " + str(operation.get("trackType", "")), ["animation_track_type_unsupported"], _operation_help("animation.track.add"))
|
|
443
|
+
var at_position := int(operation.get("atPosition", -1))
|
|
444
|
+
var track_index := animation.add_track(track_type, at_position)
|
|
445
|
+
if track_index < 0:
|
|
446
|
+
return _failure("Animation track could not be added.", ["animation_track_add_failed"])
|
|
447
|
+
animation.track_set_path(track_index, NodePath(str(operation.get("trackPath", ""))))
|
|
448
|
+
if operation.has("interpolation"):
|
|
449
|
+
animation.track_set_interpolation_type(track_index, _animation_interpolation_type(operation.get("interpolation")))
|
|
450
|
+
if track_type == Animation.TYPE_VALUE and operation.has("updateMode"):
|
|
451
|
+
animation.value_track_set_update_mode(track_index, _animation_update_mode(operation.get("updateMode")))
|
|
452
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
453
|
+
if not result.get("ok", false):
|
|
454
|
+
return result
|
|
455
|
+
return _success("Animation track added.", {"scenePath": loaded["scenePath"], "animationPlayerPath": loaded["animationPlayerPath"], "animationName": str(resolved["animationName"]), "trackIndex": track_index, "trackType": track_type, "trackPath": str(animation.track_get_path(track_index))})
|
|
456
|
+
|
|
457
|
+
func _animation_track_remove(operation: Dictionary) -> Dictionary:
|
|
458
|
+
var loaded := _load_animation_player_context(operation)
|
|
459
|
+
if not loaded.get("ok", false):
|
|
460
|
+
return loaded
|
|
461
|
+
var resolved := _resolve_animation_clip(loaded["player"], operation)
|
|
462
|
+
if not resolved.get("ok", false):
|
|
463
|
+
return resolved
|
|
464
|
+
var animation: Animation = resolved["animation"]
|
|
465
|
+
var track_index := int(operation.get("trackIndex", -1))
|
|
466
|
+
if track_index < 0 or track_index >= animation.get_track_count():
|
|
467
|
+
return _failure("Animation track index is out of range.", ["animation_track_not_found"])
|
|
468
|
+
animation.remove_track(track_index)
|
|
469
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
470
|
+
if not result.get("ok", false):
|
|
471
|
+
return result
|
|
472
|
+
return _success("Animation track removed.", {"scenePath": loaded["scenePath"], "animationPlayerPath": loaded["animationPlayerPath"], "animationName": str(resolved["animationName"]), "trackIndex": track_index})
|
|
473
|
+
|
|
474
|
+
func _animation_keyframe_upsert(operation: Dictionary) -> Dictionary:
|
|
475
|
+
var loaded := _load_animation_player_context(operation)
|
|
476
|
+
if not loaded.get("ok", false):
|
|
477
|
+
return loaded
|
|
478
|
+
var resolved := _resolve_animation_clip(loaded["player"], operation)
|
|
479
|
+
if not resolved.get("ok", false):
|
|
480
|
+
return resolved
|
|
481
|
+
var animation: Animation = resolved["animation"]
|
|
482
|
+
var track_index := int(operation.get("trackIndex", -1))
|
|
483
|
+
if track_index < 0 or track_index >= animation.get_track_count():
|
|
484
|
+
return _failure("Animation track index is out of range.", ["animation_track_not_found"])
|
|
485
|
+
var time := float(operation.get("time", 0.0))
|
|
486
|
+
animation.track_remove_key_at_time(track_index, time)
|
|
487
|
+
var key_index := _animation_insert_key(animation, track_index, time, operation.get("value"), float(operation.get("transition", 1.0)))
|
|
488
|
+
if key_index < 0:
|
|
489
|
+
return _failure("Animation keyframe could not be inserted.", ["animation_keyframe_insert_failed"])
|
|
490
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
491
|
+
if not result.get("ok", false):
|
|
492
|
+
return result
|
|
493
|
+
return _success("Animation keyframe upserted.", {"scenePath": loaded["scenePath"], "animationPlayerPath": loaded["animationPlayerPath"], "animationName": str(resolved["animationName"]), "trackIndex": track_index, "keyIndex": key_index, "time": time})
|
|
494
|
+
|
|
495
|
+
func _animation_keyframe_delete(operation: Dictionary) -> Dictionary:
|
|
496
|
+
var loaded := _load_animation_player_context(operation)
|
|
497
|
+
if not loaded.get("ok", false):
|
|
498
|
+
return loaded
|
|
499
|
+
var resolved := _resolve_animation_clip(loaded["player"], operation)
|
|
500
|
+
if not resolved.get("ok", false):
|
|
501
|
+
return resolved
|
|
502
|
+
var animation: Animation = resolved["animation"]
|
|
503
|
+
var track_index := int(operation.get("trackIndex", -1))
|
|
504
|
+
if track_index < 0 or track_index >= animation.get_track_count():
|
|
505
|
+
return _failure("Animation track index is out of range.", ["animation_track_not_found"])
|
|
506
|
+
var key_index := int(operation.get("keyIndex", -1))
|
|
507
|
+
if key_index >= 0:
|
|
508
|
+
if key_index >= animation.track_get_key_count(track_index):
|
|
509
|
+
return _failure("Animation key index is out of range.", ["animation_keyframe_not_found"])
|
|
510
|
+
animation.track_remove_key(track_index, key_index)
|
|
511
|
+
elif operation.has("time"):
|
|
512
|
+
animation.track_remove_key_at_time(track_index, float(operation.get("time", 0.0)))
|
|
513
|
+
else:
|
|
514
|
+
return _failure("animation.keyframe.delete requires keyIndex or time.", ["animation_keyframe_selector_missing"])
|
|
515
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
516
|
+
if not result.get("ok", false):
|
|
517
|
+
return result
|
|
518
|
+
return _success("Animation keyframe deleted.", {"scenePath": loaded["scenePath"], "animationPlayerPath": loaded["animationPlayerPath"], "animationName": str(resolved["animationName"]), "trackIndex": track_index})
|
|
519
|
+
|
|
520
|
+
func _animation_state_machine_create(operation: Dictionary) -> Dictionary:
|
|
521
|
+
var scene_path := _res_path(str(operation.get("scenePath", "")))
|
|
522
|
+
var root = _load_scene_root(scene_path)
|
|
523
|
+
if root == null:
|
|
524
|
+
return _failure("Scene could not be loaded: " + scene_path, ["scene_load_failed"])
|
|
525
|
+
var tree_path := str(operation.get("animationTreePath", ""))
|
|
526
|
+
var tree = _find_node(root, tree_path)
|
|
527
|
+
if tree == null:
|
|
528
|
+
root.queue_free()
|
|
529
|
+
return _failure("AnimationTree not found: " + tree_path, ["animation_tree_not_found"])
|
|
530
|
+
if not (tree is AnimationTree):
|
|
531
|
+
root.queue_free()
|
|
532
|
+
return _failure("Node is not an AnimationTree: " + tree_path, ["animation_tree_invalid"])
|
|
533
|
+
var existing = tree.get("tree_root")
|
|
534
|
+
if existing != null and existing is AnimationNodeStateMachine and not bool(operation.get("overwrite", false)):
|
|
535
|
+
root.queue_free()
|
|
536
|
+
return _failure("AnimationTree already has an AnimationNodeStateMachine tree_root.", ["animation_state_machine_exists"])
|
|
537
|
+
var machine := AnimationNodeStateMachine.new()
|
|
538
|
+
_set_properties(machine, operation.get("properties", {}))
|
|
539
|
+
tree.set("tree_root", machine)
|
|
540
|
+
var result := _save_instantiated_scene(root, scene_path)
|
|
541
|
+
if not result.get("ok", false):
|
|
542
|
+
return result
|
|
543
|
+
return _success("Animation state machine created.", {"scenePath": scene_path, "animationTreePath": tree_path})
|
|
544
|
+
|
|
545
|
+
func _animation_state_machine_read(operation: Dictionary) -> Dictionary:
|
|
546
|
+
var loaded := _load_state_machine_context(operation)
|
|
547
|
+
if not loaded.get("ok", false):
|
|
548
|
+
return loaded
|
|
549
|
+
var output := _state_machine_summary(loaded["stateMachine"])
|
|
550
|
+
output["scenePath"] = loaded["scenePath"]
|
|
551
|
+
output["animationTreePath"] = loaded["animationTreePath"]
|
|
552
|
+
loaded["root"].queue_free()
|
|
553
|
+
return _success("Animation state machine read.", output)
|
|
554
|
+
|
|
555
|
+
func _animation_state_machine_node_upsert(operation: Dictionary) -> Dictionary:
|
|
556
|
+
var loaded := _load_state_machine_context(operation)
|
|
557
|
+
if not loaded.get("ok", false):
|
|
558
|
+
return loaded
|
|
559
|
+
var machine: AnimationNodeStateMachine = loaded["stateMachine"]
|
|
560
|
+
var state_name := str(operation.get("stateName", ""))
|
|
561
|
+
var graph_node = machine.get_node(state_name) if machine.has_node(state_name) else null
|
|
562
|
+
var created := false
|
|
563
|
+
if graph_node == null:
|
|
564
|
+
var node_type := str(operation.get("nodeType", "AnimationNodeAnimation"))
|
|
565
|
+
graph_node = _instantiate(node_type)
|
|
566
|
+
if graph_node == null or not (graph_node is AnimationNode):
|
|
567
|
+
return _failure("Unable to instantiate animation graph node type: " + node_type, ["animation_graph_node_type_invalid"])
|
|
568
|
+
machine.add_node(state_name, graph_node, _decode_value(operation.get("position", {"$vector2": {"x": 0, "y": 0}})))
|
|
569
|
+
created = true
|
|
570
|
+
_set_properties(graph_node, operation.get("properties", {}))
|
|
571
|
+
if operation.has("position"):
|
|
572
|
+
machine.set_node_position(state_name, _decode_value(operation.get("position")))
|
|
573
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
574
|
+
if not result.get("ok", false):
|
|
575
|
+
return result
|
|
576
|
+
return _success("Animation state-machine node upserted.", {"scenePath": loaded["scenePath"], "animationTreePath": loaded["animationTreePath"], "stateName": state_name, "created": created})
|
|
577
|
+
|
|
578
|
+
func _animation_state_machine_node_delete(operation: Dictionary) -> Dictionary:
|
|
579
|
+
var loaded := _load_state_machine_context(operation)
|
|
580
|
+
if not loaded.get("ok", false):
|
|
581
|
+
return loaded
|
|
582
|
+
var machine: AnimationNodeStateMachine = loaded["stateMachine"]
|
|
583
|
+
var state_name := str(operation.get("stateName", ""))
|
|
584
|
+
if not machine.has_node(state_name):
|
|
585
|
+
return _failure("Animation state-machine node not found: " + state_name, ["animation_graph_node_not_found"])
|
|
586
|
+
machine.remove_node(state_name)
|
|
587
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
588
|
+
if not result.get("ok", false):
|
|
589
|
+
return result
|
|
590
|
+
return _success("Animation state-machine node deleted.", {"scenePath": loaded["scenePath"], "animationTreePath": loaded["animationTreePath"], "stateName": state_name})
|
|
591
|
+
|
|
592
|
+
func _animation_state_machine_transition_upsert(operation: Dictionary) -> Dictionary:
|
|
593
|
+
var loaded := _load_state_machine_context(operation)
|
|
594
|
+
if not loaded.get("ok", false):
|
|
595
|
+
return loaded
|
|
596
|
+
var machine: AnimationNodeStateMachine = loaded["stateMachine"]
|
|
597
|
+
var from_state := str(operation.get("fromState", ""))
|
|
598
|
+
var to_state := str(operation.get("toState", ""))
|
|
599
|
+
if not machine.has_node(from_state) or not machine.has_node(to_state):
|
|
600
|
+
return _failure("Animation state-machine transition endpoints must both exist.", ["animation_graph_endpoint_not_found"])
|
|
601
|
+
if machine.has_transition(from_state, to_state):
|
|
602
|
+
machine.remove_transition(from_state, to_state)
|
|
603
|
+
var transition := AnimationNodeStateMachineTransition.new()
|
|
604
|
+
_set_properties(transition, operation.get("properties", {}))
|
|
605
|
+
machine.add_transition(from_state, to_state, transition)
|
|
606
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
607
|
+
if not result.get("ok", false):
|
|
608
|
+
return result
|
|
609
|
+
return _success("Animation state-machine transition upserted.", {"scenePath": loaded["scenePath"], "animationTreePath": loaded["animationTreePath"], "fromState": from_state, "toState": to_state})
|
|
610
|
+
|
|
611
|
+
func _animation_state_machine_transition_delete(operation: Dictionary) -> Dictionary:
|
|
612
|
+
var loaded := _load_state_machine_context(operation)
|
|
613
|
+
if not loaded.get("ok", false):
|
|
614
|
+
return loaded
|
|
615
|
+
var machine: AnimationNodeStateMachine = loaded["stateMachine"]
|
|
616
|
+
var from_state := str(operation.get("fromState", ""))
|
|
617
|
+
var to_state := str(operation.get("toState", ""))
|
|
618
|
+
if not machine.has_transition(from_state, to_state):
|
|
619
|
+
return _failure("Animation state-machine transition not found.", ["animation_graph_transition_not_found"])
|
|
620
|
+
machine.remove_transition(from_state, to_state)
|
|
621
|
+
var result := _save_instantiated_scene(loaded["root"], loaded["scenePath"])
|
|
622
|
+
if not result.get("ok", false):
|
|
623
|
+
return result
|
|
624
|
+
return _success("Animation state-machine transition deleted.", {"scenePath": loaded["scenePath"], "animationTreePath": loaded["animationTreePath"], "fromState": from_state, "toState": to_state})
|
|
625
|
+
|
|
317
626
|
func _script_attach(operation: Dictionary) -> Dictionary:
|
|
318
627
|
var scene_path := _res_path(str(operation.get("scenePath", "")))
|
|
319
628
|
var root = _load_scene_root(scene_path)
|
|
@@ -451,6 +760,202 @@ func _batch_apply(operation: Dictionary) -> Dictionary:
|
|
|
451
760
|
return _failure("Batch operation failed.", ["batch_child_failed", str(child_operation.get("kind", ""))])
|
|
452
761
|
return _success("Batch applied.", {"results": results})
|
|
453
762
|
|
|
763
|
+
func _load_animation_player_context(operation: Dictionary) -> Dictionary:
|
|
764
|
+
var scene_path := _res_path(str(operation.get("scenePath", "")))
|
|
765
|
+
var root = _load_scene_root(scene_path)
|
|
766
|
+
if root == null:
|
|
767
|
+
return _failure("Scene could not be loaded: " + scene_path, ["scene_load_failed"])
|
|
768
|
+
var player_path := str(operation.get("animationPlayerPath", ""))
|
|
769
|
+
var player = _find_node(root, player_path)
|
|
770
|
+
if player == null:
|
|
771
|
+
root.queue_free()
|
|
772
|
+
return _failure("AnimationPlayer not found: " + player_path, ["animation_player_not_found"])
|
|
773
|
+
if not player.has_method("get_animation_library") or not player.has_method("get_animation_library_list"):
|
|
774
|
+
root.queue_free()
|
|
775
|
+
return _failure("Node is not an animation mixer: " + player_path, ["animation_player_invalid"])
|
|
776
|
+
return {"ok": true, "root": root, "scenePath": scene_path, "player": player, "animationPlayerPath": player_path}
|
|
777
|
+
|
|
778
|
+
func _get_animation_library(player, library_name: String):
|
|
779
|
+
if not player.has_method("has_animation_library") or not player.has_method("get_animation_library"):
|
|
780
|
+
return null
|
|
781
|
+
if player.has_animation_library(library_name):
|
|
782
|
+
return player.get_animation_library(library_name)
|
|
783
|
+
return null
|
|
784
|
+
|
|
785
|
+
func _get_or_create_animation_library(player, library_name: String):
|
|
786
|
+
var library = _get_animation_library(player, library_name)
|
|
787
|
+
if library != null:
|
|
788
|
+
return library
|
|
789
|
+
if not player.has_method("add_animation_library"):
|
|
790
|
+
return null
|
|
791
|
+
library = AnimationLibrary.new()
|
|
792
|
+
var err = player.add_animation_library(library_name, library)
|
|
793
|
+
if int(err) != OK:
|
|
794
|
+
return null
|
|
795
|
+
return library
|
|
796
|
+
|
|
797
|
+
func _resolve_animation_clip(player, operation: Dictionary) -> Dictionary:
|
|
798
|
+
var library_name := str(operation.get("libraryName", ""))
|
|
799
|
+
var animation_name := str(operation.get("animationName", ""))
|
|
800
|
+
var library = _get_animation_library(player, library_name)
|
|
801
|
+
if library == null:
|
|
802
|
+
return _failure("Animation library not found: " + library_name, ["animation_library_not_found"])
|
|
803
|
+
if not library.has_animation(animation_name):
|
|
804
|
+
return _failure("Animation clip not found: " + animation_name, ["animation_clip_not_found"])
|
|
805
|
+
return {"ok": true, "libraryName": library_name, "animationName": animation_name, "library": library, "animation": library.get_animation(animation_name)}
|
|
806
|
+
|
|
807
|
+
func _animation_clip_summary(library_name: String, animation_name: String, animation: Animation) -> Dictionary:
|
|
808
|
+
return {"libraryName": library_name, "animationName": animation_name, "length": animation.length, "loopMode": animation.loop_mode, "step": animation.step, "trackCount": animation.get_track_count()}
|
|
809
|
+
|
|
810
|
+
func _animation_track_summary(animation: Animation, track_index: int, include_keys: bool, key_limit: int) -> Dictionary:
|
|
811
|
+
var keys := []
|
|
812
|
+
var key_count := animation.track_get_key_count(track_index)
|
|
813
|
+
if include_keys:
|
|
814
|
+
var effective_limit := key_limit if key_limit > 0 else 200
|
|
815
|
+
for key_index in range(min(key_count, effective_limit)):
|
|
816
|
+
keys.append({
|
|
817
|
+
"keyIndex": key_index,
|
|
818
|
+
"time": animation.track_get_key_time(track_index, key_index),
|
|
819
|
+
"transition": animation.track_get_key_transition(track_index, key_index),
|
|
820
|
+
"value": _encode_animation_key_value(animation, track_index, key_index),
|
|
821
|
+
})
|
|
822
|
+
return {
|
|
823
|
+
"trackIndex": track_index,
|
|
824
|
+
"type": animation.track_get_type(track_index),
|
|
825
|
+
"path": str(animation.track_get_path(track_index)),
|
|
826
|
+
"enabled": animation.track_is_enabled(track_index),
|
|
827
|
+
"imported": animation.track_is_imported(track_index),
|
|
828
|
+
"interpolation": animation.track_get_interpolation_type(track_index),
|
|
829
|
+
"keyCount": key_count,
|
|
830
|
+
"keys": keys,
|
|
831
|
+
"keysTruncated": include_keys and key_count > keys.size(),
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
func _encode_animation_key_value(animation: Animation, track_index: int, key_index: int):
|
|
835
|
+
var track_type := animation.track_get_type(track_index)
|
|
836
|
+
if track_type == Animation.TYPE_ANIMATION:
|
|
837
|
+
return str(animation.animation_track_get_key_animation(track_index, key_index))
|
|
838
|
+
if track_type == Animation.TYPE_BEZIER:
|
|
839
|
+
return animation.bezier_track_get_key_value(track_index, key_index)
|
|
840
|
+
return _encode_value(animation.track_get_key_value(track_index, key_index))
|
|
841
|
+
|
|
842
|
+
func _animation_insert_key(animation: Animation, track_index: int, time: float, raw_value, transition: float) -> int:
|
|
843
|
+
var track_type := animation.track_get_type(track_index)
|
|
844
|
+
var value = _decode_value(raw_value)
|
|
845
|
+
if track_type == Animation.TYPE_ANIMATION:
|
|
846
|
+
return animation.animation_track_insert_key(track_index, time, str(raw_value))
|
|
847
|
+
if track_type == Animation.TYPE_BEZIER:
|
|
848
|
+
return animation.bezier_track_insert_key(track_index, time, float(raw_value))
|
|
849
|
+
if track_type == Animation.TYPE_POSITION_3D:
|
|
850
|
+
return animation.position_track_insert_key(track_index, time, value)
|
|
851
|
+
if track_type == Animation.TYPE_ROTATION_3D:
|
|
852
|
+
return animation.rotation_track_insert_key(track_index, time, value)
|
|
853
|
+
if track_type == Animation.TYPE_SCALE_3D:
|
|
854
|
+
return animation.scale_track_insert_key(track_index, time, value)
|
|
855
|
+
if track_type == Animation.TYPE_BLEND_SHAPE:
|
|
856
|
+
return animation.blend_shape_track_insert_key(track_index, time, float(raw_value))
|
|
857
|
+
return animation.track_insert_key(track_index, time, value, transition)
|
|
858
|
+
|
|
859
|
+
func _animation_track_type(value) -> int:
|
|
860
|
+
if typeof(value) == TYPE_INT or typeof(value) == TYPE_FLOAT:
|
|
861
|
+
return int(value)
|
|
862
|
+
match str(value).to_lower():
|
|
863
|
+
"value", "type_value":
|
|
864
|
+
return Animation.TYPE_VALUE
|
|
865
|
+
"position_3d", "position3d", "type_position_3d":
|
|
866
|
+
return Animation.TYPE_POSITION_3D
|
|
867
|
+
"rotation_3d", "rotation3d", "type_rotation_3d":
|
|
868
|
+
return Animation.TYPE_ROTATION_3D
|
|
869
|
+
"scale_3d", "scale3d", "type_scale_3d":
|
|
870
|
+
return Animation.TYPE_SCALE_3D
|
|
871
|
+
"blend_shape", "blendshape", "type_blend_shape":
|
|
872
|
+
return Animation.TYPE_BLEND_SHAPE
|
|
873
|
+
"method", "type_method":
|
|
874
|
+
return Animation.TYPE_METHOD
|
|
875
|
+
"bezier", "type_bezier":
|
|
876
|
+
return Animation.TYPE_BEZIER
|
|
877
|
+
"audio", "type_audio":
|
|
878
|
+
return Animation.TYPE_AUDIO
|
|
879
|
+
"animation", "type_animation":
|
|
880
|
+
return Animation.TYPE_ANIMATION
|
|
881
|
+
_:
|
|
882
|
+
return -1
|
|
883
|
+
|
|
884
|
+
func _animation_interpolation_type(value) -> int:
|
|
885
|
+
if typeof(value) == TYPE_INT or typeof(value) == TYPE_FLOAT:
|
|
886
|
+
return int(value)
|
|
887
|
+
match str(value).to_lower():
|
|
888
|
+
"nearest":
|
|
889
|
+
return Animation.INTERPOLATION_NEAREST
|
|
890
|
+
"cubic":
|
|
891
|
+
return Animation.INTERPOLATION_CUBIC
|
|
892
|
+
"linear_angle":
|
|
893
|
+
return Animation.INTERPOLATION_LINEAR_ANGLE
|
|
894
|
+
"cubic_angle":
|
|
895
|
+
return Animation.INTERPOLATION_CUBIC_ANGLE
|
|
896
|
+
_:
|
|
897
|
+
return Animation.INTERPOLATION_LINEAR
|
|
898
|
+
|
|
899
|
+
func _animation_update_mode(value) -> int:
|
|
900
|
+
if typeof(value) == TYPE_INT or typeof(value) == TYPE_FLOAT:
|
|
901
|
+
return int(value)
|
|
902
|
+
match str(value).to_lower():
|
|
903
|
+
"discrete":
|
|
904
|
+
return Animation.UPDATE_DISCRETE
|
|
905
|
+
"capture":
|
|
906
|
+
return Animation.UPDATE_CAPTURE
|
|
907
|
+
_:
|
|
908
|
+
return Animation.UPDATE_CONTINUOUS
|
|
909
|
+
|
|
910
|
+
func _animation_loop_mode(value) -> int:
|
|
911
|
+
if typeof(value) == TYPE_INT or typeof(value) == TYPE_FLOAT:
|
|
912
|
+
return int(value)
|
|
913
|
+
match str(value).to_lower():
|
|
914
|
+
"linear", "loop_linear":
|
|
915
|
+
return Animation.LOOP_LINEAR
|
|
916
|
+
"pingpong", "ping_pong", "loop_pingpong":
|
|
917
|
+
return Animation.LOOP_PINGPONG
|
|
918
|
+
_:
|
|
919
|
+
return Animation.LOOP_NONE
|
|
920
|
+
|
|
921
|
+
func _load_state_machine_context(operation: Dictionary) -> Dictionary:
|
|
922
|
+
var scene_path := _res_path(str(operation.get("scenePath", "")))
|
|
923
|
+
var root = _load_scene_root(scene_path)
|
|
924
|
+
if root == null:
|
|
925
|
+
return _failure("Scene could not be loaded: " + scene_path, ["scene_load_failed"])
|
|
926
|
+
var tree_path := str(operation.get("animationTreePath", ""))
|
|
927
|
+
var tree = _find_node(root, tree_path)
|
|
928
|
+
if tree == null:
|
|
929
|
+
root.queue_free()
|
|
930
|
+
return _failure("AnimationTree not found: " + tree_path, ["animation_tree_not_found"])
|
|
931
|
+
if not (tree is AnimationTree):
|
|
932
|
+
root.queue_free()
|
|
933
|
+
return _failure("Node is not an AnimationTree: " + tree_path, ["animation_tree_invalid"])
|
|
934
|
+
var state_machine = tree.get("tree_root")
|
|
935
|
+
if state_machine == null or not (state_machine is AnimationNodeStateMachine):
|
|
936
|
+
root.queue_free()
|
|
937
|
+
return _failure("AnimationTree tree_root is not an AnimationNodeStateMachine.", ["animation_state_machine_not_found"])
|
|
938
|
+
return {"ok": true, "root": root, "scenePath": scene_path, "tree": tree, "animationTreePath": tree_path, "stateMachine": state_machine}
|
|
939
|
+
|
|
940
|
+
func _state_machine_summary(machine: AnimationNodeStateMachine) -> Dictionary:
|
|
941
|
+
var nodes := []
|
|
942
|
+
for state_name in machine.get_node_list():
|
|
943
|
+
var graph_node = machine.get_node(state_name)
|
|
944
|
+
nodes.append({"name": str(state_name), "type": graph_node.get_class() if graph_node != null else "", "position": _encode_value(machine.get_node_position(state_name)), "properties": _selected_properties(graph_node, ["animation"]) if graph_node != null else {}})
|
|
945
|
+
var transitions := []
|
|
946
|
+
for index in range(machine.get_transition_count()):
|
|
947
|
+
var transition = machine.get_transition(index)
|
|
948
|
+
transitions.append({"index": index, "from": str(machine.get_transition_from(index)), "to": str(machine.get_transition_to(index)), "properties": _selected_properties(transition, ["advance_mode", "advance_condition", "xfade_time", "priority", "switch_mode"])})
|
|
949
|
+
return {"graphOffset": _encode_value(machine.get_graph_offset()), "nodes": nodes, "transitions": transitions}
|
|
950
|
+
|
|
951
|
+
func _selected_properties(object: Object, names: Array) -> Dictionary:
|
|
952
|
+
var values := {}
|
|
953
|
+
if object == null:
|
|
954
|
+
return values
|
|
955
|
+
for property_name in names:
|
|
956
|
+
values[str(property_name)] = _encode_value(object.get(str(property_name)))
|
|
957
|
+
return values
|
|
958
|
+
|
|
454
959
|
func _load_scene_root(scene_path: String):
|
|
455
960
|
var loaded = load(scene_path)
|
|
456
961
|
if loaded == null or not (loaded is PackedScene):
|
|
@@ -492,6 +997,12 @@ func _decode_value(value):
|
|
|
492
997
|
if value.has("$vector2"):
|
|
493
998
|
var vector = value["$vector2"]
|
|
494
999
|
return Vector2(float(vector.get("x", 0.0)), float(vector.get("y", 0.0)))
|
|
1000
|
+
if value.has("$vector3"):
|
|
1001
|
+
var vector = value["$vector3"]
|
|
1002
|
+
return Vector3(float(vector.get("x", 0.0)), float(vector.get("y", 0.0)), float(vector.get("z", 0.0)))
|
|
1003
|
+
if value.has("$quaternion"):
|
|
1004
|
+
var quaternion = value["$quaternion"]
|
|
1005
|
+
return Quaternion(float(quaternion.get("x", 0.0)), float(quaternion.get("y", 0.0)), float(quaternion.get("z", 0.0)), float(quaternion.get("w", 1.0)))
|
|
495
1006
|
if value.has("$color"):
|
|
496
1007
|
var color = value["$color"]
|
|
497
1008
|
return Color(float(color.get("r", 0.0)), float(color.get("g", 0.0)), float(color.get("b", 0.0)), float(color.get("a", 1.0)))
|
|
@@ -504,6 +1015,10 @@ func _encode_value(value, depth := 0):
|
|
|
504
1015
|
return {"$truncated": "max_depth", "text": str(value)}
|
|
505
1016
|
if value is Vector2:
|
|
506
1017
|
return {"$vector2": {"x": value.x, "y": value.y}}
|
|
1018
|
+
if value is Vector3:
|
|
1019
|
+
return {"$vector3": {"x": value.x, "y": value.y, "z": value.z}}
|
|
1020
|
+
if value is Quaternion:
|
|
1021
|
+
return {"$quaternion": {"x": value.x, "y": value.y, "z": value.z, "w": value.w}}
|
|
507
1022
|
if value is Color:
|
|
508
1023
|
return {"$color": {"r": value.r, "g": value.g, "b": value.b, "a": value.a}}
|
|
509
1024
|
if value is Resource:
|
|
@@ -658,13 +1173,27 @@ func _operation_help(kind: String) -> Dictionary:
|
|
|
658
1173
|
"node.inspect": {"kind": "node.inspect", "scenePath": "res://path/to/scene.tscn", "nodePath": ".", "includePropertyList": true, "propertyLimit": 40},
|
|
659
1174
|
"resource.read": {"kind": "resource.read", "resourcePath": "res://path/to/resource.tres", "propertyNames": ["name"]},
|
|
660
1175
|
"resource.properties": {"kind": "resource.properties", "resourcePath": "res://path/to/resource.tres"},
|
|
1176
|
+
"animation.player.inspect": {"kind": "animation.player.inspect", "scenePath": "res://path/to/scene.tscn", "animationPlayerPath": "AnimationPlayer"},
|
|
1177
|
+
"animation.clip.create": {"kind": "animation.clip.create", "scenePath": "res://path/to/scene.tscn", "animationPlayerPath": "AnimationPlayer", "animationName": "idle", "length": 1.0},
|
|
1178
|
+
"animation.clip.read": {"kind": "animation.clip.read", "scenePath": "res://path/to/scene.tscn", "animationPlayerPath": "AnimationPlayer", "animationName": "idle", "includeKeys": true},
|
|
1179
|
+
"animation.clip.delete": {"kind": "animation.clip.delete", "scenePath": "res://path/to/scene.tscn", "animationPlayerPath": "AnimationPlayer", "animationName": "idle"},
|
|
1180
|
+
"animation.track.add": {"kind": "animation.track.add", "scenePath": "res://path/to/scene.tscn", "animationPlayerPath": "AnimationPlayer", "animationName": "idle", "trackType": "value", "trackPath": "Sprite2D:modulate:a"},
|
|
1181
|
+
"animation.track.remove": {"kind": "animation.track.remove", "scenePath": "res://path/to/scene.tscn", "animationPlayerPath": "AnimationPlayer", "animationName": "idle", "trackIndex": 0},
|
|
1182
|
+
"animation.keyframe.upsert": {"kind": "animation.keyframe.upsert", "scenePath": "res://path/to/scene.tscn", "animationPlayerPath": "AnimationPlayer", "animationName": "idle", "trackIndex": 0, "time": 0.0, "value": 1.0},
|
|
1183
|
+
"animation.keyframe.delete": {"kind": "animation.keyframe.delete", "scenePath": "res://path/to/scene.tscn", "animationPlayerPath": "AnimationPlayer", "animationName": "idle", "trackIndex": 0, "time": 0.0},
|
|
1184
|
+
"animation.state_machine.create": {"kind": "animation.state_machine.create", "scenePath": "res://path/to/scene.tscn", "animationTreePath": "AnimationTree"},
|
|
1185
|
+
"animation.state_machine.read": {"kind": "animation.state_machine.read", "scenePath": "res://path/to/scene.tscn", "animationTreePath": "AnimationTree"},
|
|
1186
|
+
"animation.state_machine.node.upsert": {"kind": "animation.state_machine.node.upsert", "scenePath": "res://path/to/scene.tscn", "animationTreePath": "AnimationTree", "stateName": "Idle", "nodeType": "AnimationNodeAnimation", "properties": {"animation": "idle"}},
|
|
1187
|
+
"animation.state_machine.node.delete": {"kind": "animation.state_machine.node.delete", "scenePath": "res://path/to/scene.tscn", "animationTreePath": "AnimationTree", "stateName": "Idle"},
|
|
1188
|
+
"animation.state_machine.transition.upsert": {"kind": "animation.state_machine.transition.upsert", "scenePath": "res://path/to/scene.tscn", "animationTreePath": "AnimationTree", "fromState": "Idle", "toState": "Run"},
|
|
1189
|
+
"animation.state_machine.transition.delete": {"kind": "animation.state_machine.transition.delete", "scenePath": "res://path/to/scene.tscn", "animationTreePath": "AnimationTree", "fromState": "Idle", "toState": "Run"},
|
|
661
1190
|
"class.search": {"kind": "class.search", "query": "Label"},
|
|
662
1191
|
"class.info": {"kind": "class.info", "className": "Label", "propertyQuery": "text"},
|
|
663
1192
|
"editor.state": {"kind": "editor.state"},
|
|
664
1193
|
}
|
|
665
1194
|
var example = examples.get(kind, {"kind": "editor.state"})
|
|
666
1195
|
return {
|
|
667
|
-
"usage": "Use editor.operation.run with operation.kind, or prefer focused MCP tools
|
|
1196
|
+
"usage": "Use editor.operation.run with operation.kind, or prefer focused MCP tools such as editor.state, editor.scene.tree, editor.node.inspect, editor.resource.read, editor.resource.properties, editor.class.search, editor.class.info, and editor.animation.*.",
|
|
668
1197
|
"helpCommand": "gdh editor operation run --help",
|
|
669
1198
|
"examples": [example],
|
|
670
1199
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-operation-runner.js","sourceRoot":"","sources":["../src/editor-operation-runner.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,MAAM,UAAU,2BAA2B;IACzC,OAAO
|
|
1
|
+
{"version":3,"file":"editor-operation-runner.js","sourceRoot":"","sources":["../src/editor-operation-runner.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,MAAM,UAAU,2BAA2B;IACzC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6qCR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,oCAAoC;IAClD,MAAM,MAAM,GAAG,2BAA2B,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,iEAAiE,CAAC;IACjF,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC"}
|