126 lines
4.5 KiB
GDScript
126 lines
4.5 KiB
GDScript
# editor/pokemon_importer.gd
|
|
@tool
|
|
class_name PokeApiPokemonImporter
|
|
extends RefCounted
|
|
|
|
signal message(text : String)
|
|
|
|
var _client : PokeApiClient
|
|
var _fs : EditorFileSystem
|
|
var _overwrite : bool
|
|
var _languages : PackedStringArray
|
|
var _pending : Array = [] # pokémon récupérés, en attente de sauvegarde
|
|
|
|
func _init(client : PokeApiClient, fs : EditorFileSystem, overwrite : bool) -> void:
|
|
_client = client
|
|
_fs = fs
|
|
_overwrite = overwrite
|
|
_languages = PokeApiSettings.languages()
|
|
|
|
func run(tokens : Array) -> void:
|
|
DirAccess.make_dir_recursive_absolute(PokeApiSettings.pokemon_dir())
|
|
DirAccess.make_dir_recursive_absolute(PokeApiSettings.sprites_dir())
|
|
if !DirAccess.dir_exists_absolute(PokeApiSettings.moves_dir()):
|
|
message.emit("[color=orange]Aucune capacité importée : les learnsets seront vides.[/color]")
|
|
|
|
_pending.clear()
|
|
await _client.run_parallel(tokens, _fetch_pokemon) # phase 1 : téléchargement
|
|
await _save_all() # phase 2 : sprites + .tres
|
|
_pending.clear()
|
|
message.emit("Pokémon terminés.")
|
|
|
|
func _fetch_pokemon(token : Variant) -> void:
|
|
var j = await _client.get_json(PokeApiClient.API + "pokemon/" + str(token))
|
|
if j == null:
|
|
message.emit("[color=red]Introuvable : %s[/color]" % str(token))
|
|
return
|
|
|
|
var poke_name : String = j["name"]
|
|
var stem := PokeApiSettings.pokemon_stem(int(j["id"]), poke_name)
|
|
var path : String = PokeApiSettings.pokemon_dir() + stem + ".tres"
|
|
if !_overwrite and FileAccess.file_exists(path):
|
|
message.emit("Déjà présent : %s" % poke_name)
|
|
return
|
|
|
|
var species = await _client.get_json(j["species"]["url"])
|
|
|
|
var d := PokemonData.new()
|
|
d.id = j["id"]
|
|
d.api_name = poke_name
|
|
d.height = j["height"] / 10.0
|
|
d.weight = j["weight"] / 10.0
|
|
for t in j["types"]:
|
|
d.types.append(t["type"]["name"])
|
|
for a in j["abilities"]:
|
|
d.abilities.append(a["ability"]["name"])
|
|
for s in j["stats"]:
|
|
d.base_stats[s["stat"]["name"]] = s["base_stat"]
|
|
|
|
d.names = {"en": poke_name.capitalize()} # repli si l'espèce est indisponible
|
|
if species != null:
|
|
d.names = PokeApiText.names(species["names"], _languages)
|
|
d.descriptions = PokeApiText.flavors(species["flavor_text_entries"], _languages)
|
|
|
|
var sprites : Dictionary = j["sprites"]
|
|
var art : Dictionary = sprites.get("other", {}).get("official-artwork", {})
|
|
var sprite_url = art.get("front_default", sprites.get("front_default"))
|
|
var shiny_url = art.get("front_shiny", sprites.get("front_shiny"))
|
|
var dir := PokeApiSettings.sprites_dir()
|
|
|
|
_pending.append({
|
|
"data": d, "path": path, "moves": j["moves"],
|
|
"png": await _client.download_file(sprite_url, dir + stem + ".png"),
|
|
"shiny_png": await _client.download_file(shiny_url, dir + stem + "_shiny.png"),
|
|
})
|
|
|
|
func _save_all() -> void:
|
|
var pngs := PackedStringArray()
|
|
for p in _pending:
|
|
for key in ["png", "shiny_png"]:
|
|
if p[key] != "": pngs.append(p[key])
|
|
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 d : PokemonData = p["data"]
|
|
d.menu_sprite = _load_texture(p["png"])
|
|
d.shiny_menu_sprite = _load_texture(p["shiny_png"])
|
|
_link_models(d)
|
|
d.learnset = _build_learnset(p["moves"])
|
|
ResourceSaver.save(d, p["path"])
|
|
message.emit("OK : %s (%d capacités)" % [d.get_display_name(), d.learnset.size()])
|
|
|
|
_fs.scan()
|
|
|
|
func _load_texture(path : String) -> Texture2D:
|
|
if path.is_empty(): return null
|
|
return ResourceLoader.load(path, "Texture2D", ResourceLoader.CACHE_MODE_REPLACE) as Texture2D
|
|
|
|
func _link_models(d : PokemonData) -> void:
|
|
var dir := PokeApiSettings.models_dir()
|
|
if dir.is_empty(): return
|
|
var model_path := "%s/%s.glb" % [dir, d.api_name]
|
|
if ResourceLoader.exists(model_path):
|
|
d.model_scene = load(model_path) as PackedScene
|
|
var tex_path := "%s/%s_shiny.png" % [dir, d.api_name]
|
|
if ResourceLoader.exists(tex_path):
|
|
d.shiny_albedo = load(tex_path) as Texture2D
|
|
|
|
func _build_learnset(raw_moves : Array) -> Array[LearnedMove]:
|
|
var result : Array[LearnedMove] = []
|
|
for m in raw_moves:
|
|
var move_path : String = PokeApiSettings.moves_dir() + String(m["move"]["name"]) + ".tres"
|
|
if !FileAccess.file_exists(move_path): continue
|
|
var details : Array = m["version_group_details"]
|
|
var last : Dictionary = details[details.size() - 1] # jeu le plus récent
|
|
var lm := LearnedMove.new()
|
|
lm.move = load(move_path) as MoveData
|
|
lm.level = last["level_learned_at"]
|
|
lm.method = last["move_learn_method"]["name"]
|
|
result.append(lm)
|
|
result.sort_custom(func(a : LearnedMove, b : LearnedMove) -> bool: return a.level < b.level)
|
|
return result
|