pokemon-base/tools/sprite_generator.gd
2025-01-26 20:23:56 +01:00

153 lines
5 KiB
GDScript

@tool
extends Node2D
const outDir = "res://Resources/Pokemon/SpriteFrames"
# steps: Steps to load. 2 + nr of frames
# uid: Id for this resouce (uid://bla)
const resource_header_template = """[gd_resource type="SpriteFrames" load_steps={steps} format=3 uid="{uid}"]
"""
# uid: Uid of the spritesheet image
# path: Path to the spritesheet image
# img_intern: Id of the image used inside the resource
const ext_resource_template = """
[ext_resource type="Texture2D" uid="{uid}" path="{path}" id="{img_intern}"]
"""
# sub_id: random string? Identifies the sub resource inside the resource
# img_intern: Resource-internal Id of the spritesheet image
# offset: Offset in pixel from the left. Multiple of image height
# width, height: Width and height of the sub-frame. Always equal the height of the full image
const sub_resource_template = """
[sub_resource type="AtlasTexture" id="AtlasTexture_{sub_id}"]
atlas = ExtResource("{img_intern}")
region = Rect2({offset}, 0, {width}, {height})
"""
const frames_header_template = """
[resource]
animations = [{
"frames": ["""
# sub_id: Id of the sub-resource used by this frame
const frame_template = """{
"duration": 1.0,
"texture": SubResource("AtlasTexture_{sub_id}")
}"""
const frames_end_template = """],
"loop": true,
"name": &"default",
"speed": 12.0
}]"""
@export var trigger: bool = false:
set(new):
generate_dir("res://Resources/Pokemon/Raw", outDir)
@export var regen_charset: bool = false:
set(new):
charset = "0123456789abcdefghijklmnopqrstuvwxyz".split("")
var outDirBase := DirAccess.open(outDir)
var charset: Array = "0123456789abcdefghijklmnopqrstuvwxyz".split("")
func _ready() -> void:
charset = "0123456789abcdefghijklmnopqrstuvwxyz".split("")
func generate_dir(inDirString: String, outDirString: String) -> void:
print("Running generator from "+inDirString+" to "+outDirString)
var inDir := DirAccess.open(inDirString)
if not inDir:
print("Failed to access directory", inDirString)
return
var err := inDir.list_dir_begin()
if err:
print(err)
return
var inFileName := inDir.get_next()
while inFileName != "":
if inDir.current_is_dir():
generate_dir(inDirString+"/"+inFileName, outDirString+"/"+inFileName)
inFileName = inDir.get_next()
continue
if !inFileName.ends_with(".png"):
inFileName = inDir.get_next()
continue
generate_from_file(inDirString + "/" + inFileName, outDirString, inFileName.trim_suffix(".png"))
inFileName = inDir.get_next()
inDir.list_dir_end()
func generate_from_file(start_file: String, endDirString: String, file_name: String) -> void:
var end_dir := DirAccess.open(endDirString)
var out_file_name := endDirString
if endDirString.ends_with("/"):
out_file_name = out_file_name+file_name+".tres"
else:
out_file_name = out_file_name+"/"+file_name+".tres"
if end_dir.file_exists(out_file_name):
print("file "+file_name+" already exists. Ignoring")
return
var file := FileAccess.open(out_file_name, FileAccess.WRITE)
print(file.get_path_absolute())
print("Loading %s" % start_file)
var image: CompressedTexture2D = load(start_file)
if not image:
print("Failed to load %s" % start_file)
return
var height := image.get_height()
var total_len := image.get_width()
var frames := (total_len / height)-1
# print("%s dimensions: %d, frames: %d" % [start_file, height, frames])
var new_resource_id := ResourceUID.create_id()
var content := build_file_string(ResourceLoader.get_resource_uid(image.resource_path), height, frames, new_resource_id)
file.store_string(content)
file.close()
ResourceUID.add_id(new_resource_id, out_file_name)
func build_file_string(image_resource_id: int, image_height: int, frame_count: int, new_resource_id: int) -> String:
var build_steps := frame_count + 2
var resource_id := ResourceUID.id_to_text(new_resource_id)
var ext_resource_internal_id := "1_"+gen_rand_id()
var ext_resource_path := ResourceUID.get_id_path(image_resource_id)
var ext_resource_id_string := ResourceUID.id_to_text(image_resource_id)
var sub_resource_ids: Array[String] = []
for i in range(frame_count):
sub_resource_ids.push_back(gen_rand_id())
print(sub_resource_ids)
var out_string = resource_header_template.format({"steps":build_steps, "uid":resource_id})
out_string += ext_resource_template.format({"uid": ext_resource_id_string, "path": ext_resource_path, "img_intern": ext_resource_internal_id})
for i in range(len(sub_resource_ids)):
var sub_id := sub_resource_ids[i]
out_string += sub_resource_template.format({
"sub_id": sub_id,
"img_intern": ext_resource_internal_id,
"offset": i * image_height,
"width": image_height,
"height": image_height,
})
out_string += frames_header_template
for i in range(len(sub_resource_ids)):
var sub_id := sub_resource_ids[i]
print("sub_id: ", sub_id)
out_string += frame_template.format({"sub_id": sub_id})
if i != frame_count-1:
out_string += ", "
out_string += frames_end_template
return out_string
func gen_rand_id(length: int = 5) -> String:
var out = ""
for i in range(length):
out += charset.pick_random()
return out