109 lines
3.7 KiB
GDScript
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()
|