73 lines
2.5 KiB
GDScript
73 lines
2.5 KiB
GDScript
extends SceneTree
|
||
|
||
const TILESET_PATH: String = "res://assets/maps/work_zone/v13/tilesets/work_zone_road_tileset.tres"
|
||
const TEXTURE_DIR: String = "res://assets/maps/work_zone/v13/tilesets"
|
||
|
||
func _init() -> void:
|
||
var tileset := load(TILESET_PATH) as TileSet
|
||
if tileset == null:
|
||
push_error("无法加载 TileSet: %s" % TILESET_PATH)
|
||
quit(1)
|
||
return
|
||
var candidates := _load_candidates()
|
||
var replaced := 0
|
||
for source_index in tileset.get_source_count():
|
||
var source_id := tileset.get_source_id(source_index)
|
||
var atlas_source := tileset.get_source(source_id) as TileSetAtlasSource
|
||
if atlas_source == null or atlas_source.texture == null:
|
||
continue
|
||
var source_hash := _texture_hash(atlas_source.texture)
|
||
var replacement: Texture2D = candidates.get(source_hash)
|
||
if replacement == null:
|
||
_write_audit_image(source_id, atlas_source.texture)
|
||
push_error("未找到匹配的外置纹理,source=%d hash=%s" % [source_id, source_hash])
|
||
quit(2)
|
||
return
|
||
atlas_source.texture = replacement
|
||
replaced += 1
|
||
var error := ResourceSaver.save(tileset, TILESET_PATH)
|
||
if error != OK:
|
||
push_error("保存 TileSet 失败: %s" % error_string(error))
|
||
quit(3)
|
||
return
|
||
print("已外置 %d 个 TileSet 纹理源" % replaced)
|
||
quit()
|
||
|
||
func _load_candidates() -> Dictionary:
|
||
var candidates: Dictionary = {}
|
||
for file_name in DirAccess.get_files_at(TEXTURE_DIR):
|
||
if not file_name.ends_with(".png"):
|
||
continue
|
||
var path := "%s/%s" % [TEXTURE_DIR, file_name]
|
||
var texture := load(path) as Texture2D
|
||
if texture != null:
|
||
candidates[_bytes_hash(FileAccess.get_file_as_bytes(path))] = texture
|
||
return candidates
|
||
|
||
func _texture_hash(texture: Texture2D) -> String:
|
||
var image := texture.get_image()
|
||
if image == null:
|
||
return ""
|
||
return _bytes_hash(image.save_png_to_buffer())
|
||
|
||
func _bytes_hash(bytes: PackedByteArray) -> String:
|
||
var context := HashingContext.new()
|
||
var start_error := context.start(HashingContext.HASH_SHA256)
|
||
if start_error != OK:
|
||
return ""
|
||
var update_error := context.update(bytes)
|
||
if update_error != OK:
|
||
return ""
|
||
return context.finish().hex_encode()
|
||
|
||
func _write_audit_image(source_id: int, texture: Texture2D) -> void:
|
||
var directory := ProjectSettings.globalize_path("res://build/tileset-audit")
|
||
DirAccess.make_dir_recursive_absolute(directory)
|
||
var image := texture.get_image()
|
||
if image == null:
|
||
return
|
||
var path := "%s/source_%d.png" % [directory, source_id]
|
||
var error := image.save_png(path)
|
||
if error == OK:
|
||
print("已写出待核对纹理: %s (%dx%d)" % [path, image.get_width(), image.get_height()])
|