59 lines
2.6 KiB
GDScript
59 lines
2.6 KiB
GDScript
@tool
|
|
extends RefCounted
|
|
## Shared TileSet support leaf: load, validate, save-and-reindex a TileSet
|
|
## resource, plus the layer-node version hint and the full-tile polygon every
|
|
## tileset.* command group relies on.
|
|
##
|
|
## Stateless — every function takes its inputs (file path, TileSet, tile size) as
|
|
## parameters and returns its result (a TileSet-or-error Variant, an empty-or-error
|
|
## Dictionary, a hint String, or a polygon). No cross-call state; the file is all
|
|
## static, consumed by the tileset command children via a `preload` alias.
|
|
|
|
const Modules := preload("res://addons/godot_mcp_toolkit/core/modules.gd")
|
|
const FileGuard = Modules.FileGuard
|
|
const Helpers = Modules.CommandHelpers
|
|
|
|
|
|
## Load and validate a TileSet from file_path. Returns TileSet or error Dictionary.
|
|
static func load_tileset(file_path: String) -> Variant:
|
|
var guard := FileGuard.resolve_safe(file_path)
|
|
if guard["error"] != null:
|
|
return MCPToolkitError.fail("PATH_DENIED", str(guard["reason"]))
|
|
if not FileAccess.file_exists(file_path):
|
|
return MCPToolkitError.fail("NOT_FOUND", "TileSet not found: %s" % file_path)
|
|
var ts = ResourceLoader.load(file_path, "", ResourceLoader.CACHE_MODE_IGNORE)
|
|
if ts == null or not (ts is TileSet):
|
|
return MCPToolkitError.fail("INVALID_CLASS",
|
|
"Resource at %s is not a TileSet" % file_path)
|
|
return ts
|
|
|
|
|
|
## Save a TileSet, reload cache, and index. Returns empty dict on success or error.
|
|
static func save_tileset(ts: TileSet, file_path: String) -> Dictionary:
|
|
var save_err := ResourceSaver.save(ts, file_path)
|
|
if save_err != OK:
|
|
return MCPToolkitError.fail("SAVE_FAILED",
|
|
"ResourceSaver.save returned %d (path=%s)" % [save_err, file_path])
|
|
ResourceLoader.load(file_path, "", ResourceLoader.CACHE_MODE_REPLACE)
|
|
await Helpers.ensure_file_indexed(file_path)
|
|
return {}
|
|
|
|
|
|
## Build the response-tail hint that names the node a TileSet attaches to —
|
|
## TileMapLayer on 4.3+, TileMap on 4.2 — wrapped in the caller's prefix/suffix.
|
|
static func layer_node_hint(prefix: String, suffix: String) -> String:
|
|
var ver := Modules.VersionUtils.get_engine_version_pair()
|
|
var has_tilemaplayer := Modules.VersionUtils.is_at_least(ver, "4.3")
|
|
var node_name := "TileMapLayer" if has_tilemaplayer else "TileMap"
|
|
return prefix + node_name + suffix
|
|
|
|
|
|
## The unit rectangle spanning one tile (±w/2, ±h/2) — the default collision/nav/
|
|
## occlusion shape and the "full"/"one_way" collision shorthand.
|
|
static func build_full_tile_polygon(tile_size: Vector2i) -> PackedVector2Array:
|
|
var hw := tile_size.x / 2.0
|
|
var hh := tile_size.y / 2.0
|
|
return PackedVector2Array([
|
|
Vector2(-hw, -hh), Vector2(hw, -hh),
|
|
Vector2(hw, hh), Vector2(-hw, hh)])
|