pokeapi_importer/editor/item_importer.gd
2026-10-04 13:43:32 +02:00

109 lines
3.7 KiB
GDScript

# editor/item_importer.gd
@tool
class_name PokeApiItemImporter
extends RefCounted
signal message(text : String)
var _client : PokeApiClient
var _fs : EditorFileSystem
var _overwrite : bool
var _languages : PackedStringArray
var _pending : Array = [] # objets récupérés, en attente de sauvegarde des sprites
func _init(client : PokeApiClient, fs : EditorFileSystem, overwrite : bool) -> void:
_client = client
_fs = fs
_overwrite = overwrite
_languages = PokeApiSettings.languages()
## Retourne un tableau de {"name": String, "count": int}, trié par nom.
func list_categories() -> Array:
var list = await _client.get_json(PokeApiClient.API + "item-category?limit=100")
if list == null: return []
var names : Array = []
for r in PokeApiJson.get_array(list, "results"):
names.append(PokeApiJson.get_str(r, "name"))
var counts : Dictionary = {} # nom -> count, rempli par les tâches parallèles
await _client.run_parallel(names, func(cat_name : String) -> void:
var cat = await _client.get_json(PokeApiClient.API + "item-category/" + cat_name)
counts[cat_name] = PokeApiJson.get_array(cat, "items").size() if cat != null else 0)
names.sort()
var out : Array = []
for cat_name in names:
out.append({"name": cat_name, "count": counts.get(cat_name, 0)})
return out
func run(category_names : Array) -> void:
DirAccess.make_dir_recursive_absolute(PokeApiSettings.items_dir())
_pending.clear()
var entries : Array = []
for cat_name in category_names:
var cat = await _client.get_json(PokeApiClient.API + "item-category/" + cat_name)
if cat == null:
message.emit("[color=red]Catégorie introuvable : %s[/color]" % cat_name)
continue
for r in cat["items"]:
entries.append(r)
if entries.is_empty():
message.emit("Rien à importer.")
return
message.emit("%d objets à traiter..." % entries.size())
await _client.run_parallel(entries, _fetch_item)
await _save_all()
_pending.clear()
message.emit("Objets terminés.")
func _fetch_item(entry : Dictionary) -> void:
var path : String = PokeApiSettings.items_dir() + entry["name"] + ".tres"
if !_overwrite and FileAccess.file_exists(path): return
var j = await _client.get_json(entry["url"])
if j == null:
message.emit("[color=red]Échec : %s[/color]" % entry["name"])
return
var it := ItemData.new()
it.id = PokeApiJson.get_int(j, "id")
it.api_name = PokeApiJson.get_str(j, "name", entry["name"])
it.category = PokeApiJson.get_dict_name(j, "category")
it.names = PokeApiText.names(PokeApiJson.get_array(j, "names"), _languages)
it.descriptions = PokeApiText.item_flavors(PokeApiJson.get_array(j, "flavor_text_entries"), _languages)
it.cost = PokeApiJson.get_int(j, "cost")
it.fling_power = PokeApiJson.get_int(j, "fling_power")
var sprite_url := PokeApiJson.get_str(PokeApiJson.get_dict(j, "sprites"), "default")
var png_path := await _client.download_file(sprite_url if sprite_url != "" else null, PokeApiSettings.items_dir() + it.api_name + ".png")
_pending.append({"data": it, "path": path, "png": png_path})
func _save_all() -> void:
if _pending.is_empty():
message.emit("[color=orange]Rien à sauvegarder : tous les objets ont été ignorés ou ont échoué.[/color]")
return
var pngs := PackedStringArray()
for p in _pending:
if p["png"] != "": pngs.append(p["png"])
if !pngs.is_empty():
_fs.scan()
while _fs.is_scanning():
await _client.get_tree().process_frame
_fs.reimport_files(pngs)
for p in _pending:
var it : ItemData = p["data"]
if p["png"] != "":
it.sprite = ResourceLoader.load(p["png"], "Texture2D", ResourceLoader.CACHE_MODE_REPLACE)
var err := ResourceSaver.save(it, p["path"])
if err != OK:
message.emit("[color=red]Échec de sauvegarde : %s (code %d)[/color]" % [it.api_name, err])
_fs.scan()