Compare commits
4 commits
df7ca58c5e
...
4a1f82dd02
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a1f82dd02 | ||
|
|
5fc269b35b | ||
|
|
ad28672093 | ||
|
|
b65e6b39f2 |
115
README.md
115
README.md
|
|
@ -1,3 +1,118 @@
|
||||||
# PokeAPI Importer
|
# PokeAPI Importer
|
||||||
|
|
||||||
|
Plugin d'éditeur Godot 4 qui importe des données Pokémon depuis [PokeAPI](https://pokeapi.co) sous forme de ressources `.tres`, prêtes à être utilisées dans un jeu — sans dépendance réseau à l'exécution.
|
||||||
|
|
||||||
|
Contrairement à un import de masse, tu choisis explicitement quels pokémon importer (par id, nom, ou plage d'ids).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Ajoute ce dépôt comme sous-module dans ton projet :
|
||||||
|
|
||||||
|
```bash
|
||||||
git submodule add <url-du-depot> addons/pokeapi_importer
|
git submodule add <url-du-depot> addons/pokeapi_importer
|
||||||
|
```
|
||||||
|
|
||||||
|
Le dossier **doit** s'appeler `pokeapi_importer` : les ressources générées référencent les scripts de l'addon par leur chemin.
|
||||||
|
|
||||||
|
Puis active le plugin dans **Projet > Paramètres du projet > Extensions**.
|
||||||
|
|
||||||
|
## Réglages
|
||||||
|
|
||||||
|
Dans **Paramètres du projet**, sous `pokeapi_importer/` :
|
||||||
|
|
||||||
|
| Réglage | Défaut | Rôle |
|
||||||
|
|---|---|---|
|
||||||
|
| `data_dir` | `res://data/pokeapi` | Dossier racine où sont écrites toutes les données importées |
|
||||||
|
| `languages` | `["fr", "en"]` | Langues importées pour les noms et descriptions (codes PokeAPI) |
|
||||||
|
| `models_dir` | *(vide)* | Dossier contenant tes modèles `.glb` faits maison, pour liaison automatique. Vide = pas de liaison |
|
||||||
|
| `max_concurrent_requests` | `8` | Nombre de requêtes HTTP simultanées pendant un import |
|
||||||
|
|
||||||
|
## Utilisation
|
||||||
|
|
||||||
|
Un dock **PokeAPI** apparaît dans l'éditeur (coin supérieur droit par défaut). Ordre d'import recommandé, car chaque étape peut dépendre de la précédente :
|
||||||
|
|
||||||
|
1. **Importer les types** — indépendant, à faire une fois.
|
||||||
|
2. **Importer les talents** — indépendant, à faire une fois.
|
||||||
|
3. **Importer toutes les capacités** — indépendant, à faire une fois (~900 requêtes, quelques minutes).
|
||||||
|
4. **Importer les pokémon** — saisis une liste dans le champ texte (ids, noms, ou plages) :
|
||||||
|
```
|
||||||
|
25, eevee, 1-9, mr-mime, charizard
|
||||||
|
```
|
||||||
|
Les pokémon déjà importés sont ignorés, sauf si tu coches **Écraser les fichiers existants**.
|
||||||
|
|
||||||
|
Les formes méga-évolution et gigamax d'un pokémon sont importées automatiquement avec lui, à partir de `pokemon-species.varieties`.
|
||||||
|
|
||||||
|
## Ce qui est importé
|
||||||
|
|
||||||
|
| Donnée | Dossier | Ressource |
|
||||||
|
|---|---|---|
|
||||||
|
| Pokémon (et leurs formes méga/gmax) | `<data_dir>/pokemon/` | `PokemonData` (`.tres`), nommé `<id à 4 chiffres>_<nom>.tres` |
|
||||||
|
| Sprites (normal + shiny) | `<data_dir>/sprites/` | `.png`, liés dans `PokemonData.menu_sprite` / `shiny_menu_sprite` |
|
||||||
|
| Cri | `<data_dir>/cries/` | `.ogg`, lié dans `PokemonData.cry_latest` |
|
||||||
|
| Capacités | `<data_dir>/moves/` | `MoveData` (`.tres`), un fichier par capacité |
|
||||||
|
| Types | `<data_dir>/types/` | `TypeData` (`.tres`), un fichier par type, avec relations d'efficacité |
|
||||||
|
| Talents | `<data_dir>/abilities/` | `AbilityData` (`.tres`), un fichier par talent |
|
||||||
|
| Chaînes d'évolution | `<data_dir>/evolution/` | `EvolutionNode` (`.tres`), un fichier par chaîne, référencé depuis `PokemonData.evolution_chain` |
|
||||||
|
|
||||||
|
### `PokemonData`
|
||||||
|
|
||||||
|
Champs principaux : `id`, `api_name`, `names` / `descriptions` (par langue), `types` (`Array[TypeData]`), `abilities` (`Array[PokemonAbility]`, avec `is_hidden`), `base_stats`, `height`, `weight`, `menu_sprite`, `shiny_menu_sprite`, `cry_latest`, `learnset` (`Array[LearnedMove]`), `evolution_chain`, `forms` (`Array[PokemonForm]`).
|
||||||
|
|
||||||
|
Deux champs ne sont **jamais** remplis par l'import et à assigner toi-même dans l'inspecteur :
|
||||||
|
- `model_scene` / `shiny_albedo` — liés automatiquement seulement si `models_dir` est configuré et qu'un fichier `<nom>.glb` / `<nom>_shiny.png` existe à cet endroit.
|
||||||
|
- `TypeData.icon` — illustration de type, jamais fournie par PokeAPI ; assigne-la une fois, elle survit aux ré-imports suivants.
|
||||||
|
|
||||||
|
### Localisation
|
||||||
|
|
||||||
|
`get_display_name()` et `get_description()` (sur `PokemonData` et `MoveData`) renvoient le texte dans la langue courante de Godot (`TranslationServer.get_locale()`), avec repli sur l'anglais.
|
||||||
|
|
||||||
|
### Évolutions
|
||||||
|
|
||||||
|
Une chaîne (`EvolutionNode`) est un arbre récursif : `species_name` + `evolves_to` (`Array[EvolutionEdge]`). Chaque `EvolutionEdge` pointe vers un `EvolutionNode` cible et porte un tableau `conditions` (`Array[EvolutionCondition]`) — plusieurs conditions sur une même arête sont **alternatives** (une seule suffit), pour les cas comme Tyrogue qui évolue différemment selon ses stats.
|
||||||
|
|
||||||
|
## Ce que le plugin ne fournit pas
|
||||||
|
|
||||||
|
- **Le Pokedex** (autoload d'accès aux données en jeu) : volontairement laissé hors de l'addon, car pas utile à tous les projets. Un exemple d'implémentation est disponible dans le jeu qui a servi à concevoir ce plugin.
|
||||||
|
- **Les modèles 3D** : PokeAPI n'en fournit pas. Le plugin lie seulement tes propres `.glb` par convention de nommage.
|
||||||
|
- **Le calcul de combat, la capture, les stats réelles** (IV/EV) : ce plugin s'arrête à l'import des données brutes.
|
||||||
|
|
||||||
|
## Limitations connues
|
||||||
|
|
||||||
|
- **`EvolutionCondition.relative_physical_stats`** : l'API distingue "pas de condition" (`null`) de "attaque = défense" (`0`), ce que le champ entier ne distingue pas une fois converti. Concerne une poignée d'évolutions (Silcoon/Cascoon).
|
||||||
|
- **`PokemonForm.required_item`** est deviné à partir du nom de la forme (convention `<nom>ite` / `<nom>ite-x/-y`), PokeAPI ne liant pas explicitement l'objet de méga-évolution au pokémon. Corrige-le à la main si besoin : la valeur est préservée aux ré-imports suivants.
|
||||||
|
- **Formes régionales** (Alola, Galar, Hisui...) ne sont pas traitées comme des `PokemonForm` : ce sont des espèces à part entière à importer directement par leur nom complet (ex. `raichu-alola`).
|
||||||
|
- Le plugin télécharge à chaque import ce qui n'existe pas encore sur disque ; il ne revérifie jamais si les données de PokeAPI ont changé pour un fichier déjà présent (sauf avec **Écraser**).
|
||||||
|
|
||||||
|
## Structure du dépôt
|
||||||
|
|
||||||
|
```
|
||||||
|
pokeapi_importer/
|
||||||
|
├── plugin.cfg
|
||||||
|
├── plugin.gd # enregistrement du plugin et du dock
|
||||||
|
├── settings.gd # réglages du projet + chemins dérivés
|
||||||
|
├── data/ # types de ressources, utilisés aussi à l'exécution par le jeu
|
||||||
|
│ ├── l10n.gd
|
||||||
|
│ ├── move_data.gd
|
||||||
|
│ ├── learned_move.gd
|
||||||
|
│ ├── type_data.gd
|
||||||
|
│ ├── ability_data.gd
|
||||||
|
│ ├── pokemon_ability.gd
|
||||||
|
│ ├── evolution_condition.gd
|
||||||
|
│ ├── evolution_edge.gd
|
||||||
|
│ ├── evolution_node.gd
|
||||||
|
│ ├── pokemon_form.gd
|
||||||
|
│ └── pokemon_data.gd
|
||||||
|
└── editor/ # uniquement utilisé dans l'éditeur
|
||||||
|
├── importer_dock.gd
|
||||||
|
├── pokeapi_client.gd
|
||||||
|
├── api_text.gd
|
||||||
|
├── type_importer.gd
|
||||||
|
├── ability_importer.gd
|
||||||
|
├── move_importer.gd
|
||||||
|
├── evolution_importer.gd
|
||||||
|
└── pokemon_importer.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compatibilité
|
||||||
|
|
||||||
|
Testé avec Godot 4.4+. Le chargement des pokémon par id dans un `Pokedex` côté jeu s'appuie sur `ResourceLoader.list_directory()`, disponible à partir de la 4.4.
|
||||||
|
|
@ -7,7 +7,7 @@ extends Resource
|
||||||
@export var api_name : String
|
@export var api_name : String
|
||||||
@export var names : Dictionary = {}
|
@export var names : Dictionary = {}
|
||||||
@export var descriptions : Dictionary = {}
|
@export var descriptions : Dictionary = {}
|
||||||
@export var types : PackedStringArray
|
@export var types : Array[TypeData] = []
|
||||||
@export var abilities : Array[PokemonAbility] = [] # remplace l'ancien PackedStringArray
|
@export var abilities : Array[PokemonAbility] = [] # remplace l'ancien PackedStringArray
|
||||||
@export var evolution_chain : EvolutionNode
|
@export var evolution_chain : EvolutionNode
|
||||||
@export var base_stats : Dictionary = {}
|
@export var base_stats : Dictionary = {}
|
||||||
|
|
@ -18,6 +18,8 @@ extends Resource
|
||||||
@export var model_scene : PackedScene
|
@export var model_scene : PackedScene
|
||||||
@export var shiny_albedo : Texture2D
|
@export var shiny_albedo : Texture2D
|
||||||
@export var learnset : Array[LearnedMove] = []
|
@export var learnset : Array[LearnedMove] = []
|
||||||
|
@export var cry_latest : AudioStream
|
||||||
|
@export var forms : Array[PokemonForm] = []
|
||||||
|
|
||||||
func get_display_name() -> String:
|
func get_display_name() -> String:
|
||||||
return L10n.pick(names, api_name.capitalize())
|
return L10n.pick(names, api_name.capitalize())
|
||||||
|
|
|
||||||
8
data/pokemon_form.gd
Normal file
8
data/pokemon_form.gd
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# data/pokemon_form.gd
|
||||||
|
@tool
|
||||||
|
class_name PokemonForm
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
@export var kind : String
|
||||||
|
@export var required_item : String
|
||||||
|
@export var variant : PokemonData
|
||||||
1
data/pokemon_form.gd.uid
Normal file
1
data/pokemon_form.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://fmgdjhptqo0d
|
||||||
|
|
@ -22,12 +22,13 @@ func _init(client : PokeApiClient, fs : EditorFileSystem, overwrite : bool) -> v
|
||||||
func run(tokens : Array) -> void:
|
func run(tokens : Array) -> void:
|
||||||
DirAccess.make_dir_recursive_absolute(PokeApiSettings.pokemon_dir())
|
DirAccess.make_dir_recursive_absolute(PokeApiSettings.pokemon_dir())
|
||||||
DirAccess.make_dir_recursive_absolute(PokeApiSettings.sprites_dir())
|
DirAccess.make_dir_recursive_absolute(PokeApiSettings.sprites_dir())
|
||||||
if !DirAccess.dir_exists_absolute(PokeApiSettings.moves_dir()):
|
DirAccess.make_dir_recursive_absolute(PokeApiSettings.cries_dir())
|
||||||
message.emit("[color=orange]Aucune capacité importée : les learnsets seront vides.[/color]")
|
|
||||||
if !DirAccess.dir_exists_absolute(PokeApiSettings.moves_dir()):
|
if !DirAccess.dir_exists_absolute(PokeApiSettings.moves_dir()):
|
||||||
message.emit("[color=orange]Aucune capacité importée : les learnsets seront vides.[/color]")
|
message.emit("[color=orange]Aucune capacité importée : les learnsets seront vides.[/color]")
|
||||||
if !DirAccess.dir_exists_absolute(PokeApiSettings.abilities_dir()):
|
if !DirAccess.dir_exists_absolute(PokeApiSettings.abilities_dir()):
|
||||||
message.emit("[color=orange]Aucun talent importé : les talents des pokémon seront vides.[/color]")
|
message.emit("[color=orange]Aucun talent importé : les talents des pokémon seront vides.[/color]")
|
||||||
|
if !DirAccess.dir_exists_absolute(PokeApiSettings.types_dir()):
|
||||||
|
message.emit("[color=orange]Aucun type importé : les types des pokémon seront vides.[/color]")
|
||||||
|
|
||||||
_pending.clear()
|
_pending.clear()
|
||||||
await _client.run_parallel(tokens, _fetch_pokemon) # phase 1 : téléchargement
|
await _client.run_parallel(tokens, _fetch_pokemon) # phase 1 : téléchargement
|
||||||
|
|
@ -45,24 +46,57 @@ func _fetch_pokemon(token : Variant) -> void:
|
||||||
var stem := PokeApiSettings.pokemon_stem(int(j["id"]), poke_name)
|
var stem := PokeApiSettings.pokemon_stem(int(j["id"]), poke_name)
|
||||||
var path : String = PokeApiSettings.pokemon_dir() + stem + ".tres"
|
var path : String = PokeApiSettings.pokemon_dir() + stem + ".tres"
|
||||||
if !_overwrite and FileAccess.file_exists(path):
|
if !_overwrite and FileAccess.file_exists(path):
|
||||||
message.emit("Déjà présent : %s" % poke_name)
|
message.emit("Déjà présent : %s (coche « Écraser » pour rafraîchir aussi ses formes méga/gigamax)" % poke_name)
|
||||||
return
|
return
|
||||||
|
|
||||||
var species = await _client.get_json(j["species"]["url"])
|
var species = await _client.get_json(j["species"]["url"])
|
||||||
|
var base_index : int = _pending.size()
|
||||||
|
_pending.append(await _build_entry(j, species, stem, path))
|
||||||
|
if species == null: return
|
||||||
|
|
||||||
|
for v in species.get("varieties", []):
|
||||||
|
var variety_name : String = v["pokemon"]["name"]
|
||||||
|
var kind := _form_kind(variety_name)
|
||||||
|
if kind == "": continue # formes régionales etc. : importe-les directement par leur nom (ex. "raichu-alola")
|
||||||
|
|
||||||
|
var jv = await _client.get_json(v["pokemon"]["url"])
|
||||||
|
if jv == null:
|
||||||
|
message.emit("[color=red]Forme introuvable : %s[/color]" % variety_name)
|
||||||
|
continue
|
||||||
|
|
||||||
|
var v_stem := PokeApiSettings.pokemon_stem(int(jv["id"]), variety_name)
|
||||||
|
var v_path := PokeApiSettings.pokemon_dir() + v_stem + ".tres"
|
||||||
|
var entry := await _build_entry(jv, species, v_stem, v_path)
|
||||||
|
entry["form_of"] = base_index
|
||||||
|
entry["form_kind"] = kind
|
||||||
|
entry["form_item_guess"] = _guess_item(variety_name, kind)
|
||||||
|
_pending.append(entry)
|
||||||
|
|
||||||
|
func _form_kind(variety_name : String) -> String:
|
||||||
|
if variety_name.ends_with("-mega-x"): return "mega-x"
|
||||||
|
if variety_name.ends_with("-mega-y"): return "mega-y"
|
||||||
|
if variety_name.ends_with("-mega"): return "mega"
|
||||||
|
if variety_name.ends_with("-gmax"): return "gmax"
|
||||||
|
return ""
|
||||||
|
|
||||||
|
func _guess_item(variety_name : String, kind : String) -> String:
|
||||||
|
if kind == "gmax": return "" # le gigamax ne consomme pas d'objet
|
||||||
|
var suffix := "-x" if kind == "mega-x" else ("-y" if kind == "mega-y" else "")
|
||||||
|
return variety_name.trim_suffix("-" + kind) + "ite" + suffix # convention Bulbapedia, approximative
|
||||||
|
|
||||||
|
## Construit une entrée _pending (utilisée pour l'espèce de base ET pour chaque forme)
|
||||||
|
func _build_entry(j : Dictionary, species : Variant, stem : String, path : String) -> Dictionary:
|
||||||
var d := PokemonData.new()
|
var d := PokemonData.new()
|
||||||
d.id = j["id"]
|
d.id = j["id"]
|
||||||
d.api_name = poke_name
|
d.api_name = j["name"]
|
||||||
d.height = j["height"] / 10.0
|
d.height = j["height"] / 10.0
|
||||||
d.weight = j["weight"] / 10.0
|
d.weight = j["weight"] / 10.0
|
||||||
for t in j["types"]:
|
d.types = _resolve_types(j["types"])
|
||||||
d.types.append(t["type"]["name"])
|
|
||||||
for a in j["abilities"]:
|
|
||||||
d.abilities = _build_abilities(j["abilities"])
|
d.abilities = _build_abilities(j["abilities"])
|
||||||
for s in j["stats"]:
|
for s in j["stats"]:
|
||||||
d.base_stats[s["stat"]["name"]] = s["base_stat"]
|
d.base_stats[s["stat"]["name"]] = s["base_stat"]
|
||||||
|
|
||||||
d.names = {"en": poke_name.capitalize()} # repli si l'espèce est indisponible
|
d.names = {"en": String(j["name"]).capitalize()}
|
||||||
if species != null:
|
if species != null:
|
||||||
d.names = PokeApiText.names(species["names"], _languages)
|
d.names = PokeApiText.names(species["names"], _languages)
|
||||||
d.descriptions = PokeApiText.flavors(species["flavor_text_entries"], _languages)
|
d.descriptions = PokeApiText.flavors(species["flavor_text_entries"], _languages)
|
||||||
|
|
@ -73,40 +107,78 @@ func _fetch_pokemon(token : Variant) -> void:
|
||||||
var art : Dictionary = sprites.get("other", {}).get("official-artwork", {})
|
var art : Dictionary = sprites.get("other", {}).get("official-artwork", {})
|
||||||
var sprite_url = art.get("front_default", sprites.get("front_default"))
|
var sprite_url = art.get("front_default", sprites.get("front_default"))
|
||||||
var shiny_url = art.get("front_shiny", sprites.get("front_shiny"))
|
var shiny_url = art.get("front_shiny", sprites.get("front_shiny"))
|
||||||
var dir := PokeApiSettings.sprites_dir()
|
var sdir := PokeApiSettings.sprites_dir()
|
||||||
|
var cries : Dictionary = j.get("cries", {})
|
||||||
|
|
||||||
_pending.append({
|
return {
|
||||||
"data": d, "path": path, "moves": j["moves"],
|
"data": d, "path": path, "moves": j["moves"],
|
||||||
"png": await _client.download_file(sprite_url, dir + stem + ".png"),
|
"png": await _client.download_file(sprite_url, sdir + stem + ".png"),
|
||||||
"shiny_png": await _client.download_file(shiny_url, dir + stem + "_shiny.png"),
|
"shiny_png": await _client.download_file(shiny_url, sdir + stem + "_shiny.png"),
|
||||||
})
|
"cry": await _client.download_file(cries.get("latest"), PokeApiSettings.cries_dir() + stem + ".ogg"),
|
||||||
|
}
|
||||||
|
|
||||||
func _save_all() -> void:
|
func _save_all() -> void:
|
||||||
var pngs := PackedStringArray()
|
var to_reimport := PackedStringArray()
|
||||||
for p in _pending:
|
for p in _pending:
|
||||||
for key in ["png", "shiny_png"]:
|
for key in ["png", "shiny_png", "cry"]:
|
||||||
if p[key] != "": pngs.append(p[key])
|
if p[key] != "": to_reimport.append(p[key])
|
||||||
if !pngs.is_empty():
|
if !to_reimport.is_empty():
|
||||||
_fs.scan()
|
_fs.scan()
|
||||||
while _fs.is_scanning():
|
while _fs.is_scanning():
|
||||||
await _client.get_tree().process_frame
|
await _client.get_tree().process_frame
|
||||||
_fs.reimport_files(pngs)
|
_fs.reimport_files(to_reimport)
|
||||||
|
|
||||||
|
# étape 1 : sprite/cri/modèle/learnset pour toutes les entrées (bases et formes)
|
||||||
for p in _pending:
|
for p in _pending:
|
||||||
var d : PokemonData = p["data"]
|
var d : PokemonData = p["data"]
|
||||||
d.menu_sprite = _load_texture(p["png"])
|
d.menu_sprite = _load_texture(p["png"])
|
||||||
d.shiny_menu_sprite = _load_texture(p["shiny_png"])
|
d.shiny_menu_sprite = _load_texture(p["shiny_png"])
|
||||||
|
d.cry_latest = _load_audio(p["cry"])
|
||||||
_link_models(d)
|
_link_models(d)
|
||||||
d.learnset = _build_learnset(p["moves"])
|
d.learnset = _build_learnset(p["moves"])
|
||||||
|
|
||||||
|
# étape 2 : formes d'abord, pour obtenir une référence externe (pas embarquée) depuis la base
|
||||||
|
for p in _pending:
|
||||||
|
if !p.has("form_of"): continue
|
||||||
|
var variant : PokemonData = p["data"]
|
||||||
|
ResourceSaver.save(variant, p["path"])
|
||||||
|
var base_d : PokemonData = _pending[p["form_of"]]["data"]
|
||||||
|
base_d.forms.append(_make_form(base_d, variant, p["form_kind"], p["form_item_guess"]))
|
||||||
|
|
||||||
|
# étape 3 : bases (et pokémon sans formes)
|
||||||
|
for p in _pending:
|
||||||
|
if p.has("form_of"): continue
|
||||||
|
var d : PokemonData = p["data"]
|
||||||
ResourceSaver.save(d, p["path"])
|
ResourceSaver.save(d, p["path"])
|
||||||
message.emit("OK : %s (%d capacités)" % [d.get_display_name(), d.learnset.size()])
|
message.emit("OK : %s (%d capacités, %d formes)" % [d.get_display_name(), d.learnset.size(), d.forms.size()])
|
||||||
|
|
||||||
_fs.scan()
|
_fs.scan()
|
||||||
|
|
||||||
|
## Préserve une correction manuelle de required_item faite lors d'un import précédent.
|
||||||
|
func _make_form(base_d : PokemonData, variant : PokemonData, kind : String, item_guess : String) -> PokemonForm:
|
||||||
|
var form := PokemonForm.new()
|
||||||
|
form.kind = kind
|
||||||
|
form.variant = variant
|
||||||
|
form.required_item = item_guess
|
||||||
|
|
||||||
|
var old_path := PokeApiSettings.pokemon_dir() + PokeApiSettings.pokemon_stem(base_d.id, base_d.api_name) + ".tres"
|
||||||
|
if FileAccess.file_exists(old_path):
|
||||||
|
var old := ResourceLoader.load(old_path, "", ResourceLoader.CACHE_MODE_REPLACE) as PokemonData
|
||||||
|
if old:
|
||||||
|
for f in old.forms:
|
||||||
|
if f.kind == kind and f.required_item != "" and f.required_item != item_guess:
|
||||||
|
form.required_item = f.required_item
|
||||||
|
break
|
||||||
|
return form
|
||||||
|
|
||||||
func _load_texture(path : String) -> Texture2D:
|
func _load_texture(path : String) -> Texture2D:
|
||||||
if path.is_empty(): return null
|
if path.is_empty(): return null
|
||||||
return ResourceLoader.load(path, "Texture2D", ResourceLoader.CACHE_MODE_REPLACE) as Texture2D
|
return ResourceLoader.load(path, "Texture2D", ResourceLoader.CACHE_MODE_REPLACE) as Texture2D
|
||||||
|
|
||||||
|
func _load_audio(path : String) -> AudioStream:
|
||||||
|
if path.is_empty(): return null
|
||||||
|
return ResourceLoader.load(path, "AudioStream", ResourceLoader.CACHE_MODE_REPLACE) as AudioStream
|
||||||
|
|
||||||
func _link_models(d : PokemonData) -> void:
|
func _link_models(d : PokemonData) -> void:
|
||||||
var dir := PokeApiSettings.models_dir()
|
var dir := PokeApiSettings.models_dir()
|
||||||
if dir.is_empty(): return
|
if dir.is_empty(): return
|
||||||
|
|
@ -142,3 +214,14 @@ func _build_abilities(raw_abilities : Array) -> Array[PokemonAbility]:
|
||||||
pa.is_hidden = a["is_hidden"]
|
pa.is_hidden = a["is_hidden"]
|
||||||
result.append(pa)
|
result.append(pa)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
func _resolve_types(raw_types : Array) -> Array[TypeData]:
|
||||||
|
var result : Array[TypeData] = []
|
||||||
|
for t in raw_types:
|
||||||
|
var name : String = t["type"]["name"]
|
||||||
|
var path : String = PokeApiSettings.types_dir() + name + ".tres"
|
||||||
|
if !FileAccess.file_exists(path):
|
||||||
|
message.emit("[color=orange]Type introuvable : %s (importe les types d'abord)[/color]" % name)
|
||||||
|
continue
|
||||||
|
result.append(load(path) as TypeData)
|
||||||
|
return result
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ static func max_concurrent() -> int:
|
||||||
static func moves_dir() -> String: return data_dir() + "/moves/"
|
static func moves_dir() -> String: return data_dir() + "/moves/"
|
||||||
static func pokemon_dir() -> String: return data_dir() + "/pokemon/"
|
static func pokemon_dir() -> String: return data_dir() + "/pokemon/"
|
||||||
static func sprites_dir() -> String: return data_dir() + "/sprites/"
|
static func sprites_dir() -> String: return data_dir() + "/sprites/"
|
||||||
|
static func cries_dir() -> String: return data_dir() + "/cries/"
|
||||||
static func types_dir() -> String: return data_dir() + "/types/"
|
static func types_dir() -> String: return data_dir() + "/types/"
|
||||||
static func abilities_dir() -> String: return data_dir() + "/abilities/"
|
static func abilities_dir() -> String: return data_dir() + "/abilities/"
|
||||||
static func evolution_dir() -> String: return data_dir() + "/evolution/"
|
static func evolution_dir() -> String: return data_dir() + "/evolution/"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue