Compare commits
6 commits
fc1f024fdd
...
aab0c841fe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aab0c841fe | ||
|
|
0933d9b71d | ||
|
|
bc57c99331 | ||
|
|
a923c1319b | ||
|
|
b4edeff685 | ||
|
|
47d2630a54 |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "addons/pokeapi_importer"]
|
||||||
|
path = addons/pokeapi_importer
|
||||||
|
url = https://git.thethomaas.net/TheThomaas/pokeapi_importer.git
|
||||||
1
addons/pokeapi_importer
Submodule
1
addons/pokeapi_importer
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 4a1f82dd02bd7dc443f7b4038af6c5089bff3bb5
|
||||||
10
data/mounts/charizard.tres
Normal file
10
data/mounts/charizard.tres
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[gd_resource type="Resource" script_class="MountProfile" format=3 uid="uid://did0vw42e8fex"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://dsgbmr2jqjata" path="res://scripts/mount/mount_profile.gd" id="1_aoce8"]
|
||||||
|
[ext_resource type="Resource" uid="uid://hogb1068ywfe" path="res://data/pokeapi/pokemon/0006_charizard.tres" id="2_onvr1"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1_aoce8")
|
||||||
|
species = ExtResource("2_onvr1")
|
||||||
|
surfaces = 5
|
||||||
|
metadata/_custom_type_script = "uid://dsgbmr2jqjata"
|
||||||
16
game/player/StateMachine/MountedState.gd
Normal file
16
game/player/StateMachine/MountedState.gd
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# MountedState.gd
|
||||||
|
extends State
|
||||||
|
|
||||||
|
class_name MountedState
|
||||||
|
|
||||||
|
var state_name : String = "Mounted"
|
||||||
|
var play_char : CharacterBody3D
|
||||||
|
var profile : MountProfile # assigné par qui déclenche la monte, avant transitioned.emit(..., "MountedState")
|
||||||
|
|
||||||
|
func enter(play_char_ref : CharacterBody3D) -> void:
|
||||||
|
play_char = play_char_ref
|
||||||
|
play_char.move_speed = profile.mount_speed
|
||||||
|
play_char.move_accel = profile.mount_accel
|
||||||
|
play_char.move_deccel = profile.mount_deccel
|
||||||
|
# instancier profile.mount_scene_override ou profile.species.model_scene,
|
||||||
|
# le positionner, y attacher play_char selon seat_offset...
|
||||||
|
|
@ -64,3 +64,10 @@ func set_locked(value : bool) -> void:
|
||||||
is_locked = value
|
is_locked = value
|
||||||
if indicator: indicator.visible = value
|
if indicator: indicator.visible = value
|
||||||
locked_changed.emit(value)
|
locked_changed.emit(value)
|
||||||
|
|
||||||
|
func try_mount(target_pokemon : PokemonData) -> bool:
|
||||||
|
if !MountRegistry.can_mount_on(target_pokemon, MountProfile.Surface.GROUND):
|
||||||
|
return false
|
||||||
|
play_char.current_mount = target_pokemon
|
||||||
|
transitioned.emit(self, "MountedState")
|
||||||
|
return true
|
||||||
27
scripts/mount/mount_profile.gd
Normal file
27
scripts/mount/mount_profile.gd
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
# res://scripts/mount/mount_profile.gd
|
||||||
|
@tool
|
||||||
|
class_name MountProfile
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
enum Surface {
|
||||||
|
GROUND = 1,
|
||||||
|
WATER = 2,
|
||||||
|
AIR = 4,
|
||||||
|
LAVA = 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
@export var species : PokemonData
|
||||||
|
@export_flags("Terre:1", "Eau:2", "Ciel:4", "Lave:8") var surfaces : int = Surface.GROUND
|
||||||
|
|
||||||
|
@export_group("Mouvement")
|
||||||
|
@export var mount_speed : float = 8.0
|
||||||
|
@export var mount_accel : float = 6.0
|
||||||
|
@export var mount_deccel : float = 7.0
|
||||||
|
@export var mount_jump_height : float = 2.5 # ignoré si AIR est actif (vol libre plutôt que saut)
|
||||||
|
|
||||||
|
@export_group("Attache")
|
||||||
|
@export var seat_offset : Vector3 = Vector3(0, 1.2, -0.3)
|
||||||
|
@export var mount_scene_override : PackedScene # sinon utilise species.model_scene
|
||||||
|
|
||||||
|
func can_use_surface(surface : Surface) -> bool:
|
||||||
|
return (surfaces & surface) != 0
|
||||||
25
scripts/mount/mount_registry.gd
Normal file
25
scripts/mount/mount_registry.gd
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# res://scripts/mount/mount_registry.gd (autoload)
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
const MOUNTS_DIR := "res://data/mounts/"
|
||||||
|
|
||||||
|
var _by_species : Dictionary = {} # nom d'API -> MountProfile
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
for file in ResourceLoader.list_directory(MOUNTS_DIR):
|
||||||
|
if file.ends_with("/"): continue
|
||||||
|
var profile := load(MOUNTS_DIR + file) as MountProfile
|
||||||
|
if profile and profile.species:
|
||||||
|
_by_species[profile.species.api_name] = profile
|
||||||
|
|
||||||
|
func get_profile(d : PokemonData) -> MountProfile:
|
||||||
|
if d == null: return null
|
||||||
|
return _by_species.get(d.api_name)
|
||||||
|
|
||||||
|
func is_mountable(d : PokemonData) -> bool:
|
||||||
|
return get_profile(d) != null
|
||||||
|
|
||||||
|
## Le pokémon peut-il être monté sur CETTE surface précisément ?
|
||||||
|
func can_mount_on(d : PokemonData, surface : MountProfile.Surface) -> bool:
|
||||||
|
var p := get_profile(d)
|
||||||
|
return p != null and p.can_use_surface(surface)
|
||||||
88
scripts/pokedex.gd
Normal file
88
scripts/pokedex.gd
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
# res://scripts/pokedex.gd (dans le jeu, pas dans l'addon)
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
var _paths : Dictionary = {} # nom d'API -> chemin du .tres
|
||||||
|
var _id_to_name : Dictionary = {} # id -> nom d'API
|
||||||
|
var _cache : Dictionary = {} # nom -> PokemonData
|
||||||
|
|
||||||
|
var _moves : Dictionary = {} # nom -> MoveData
|
||||||
|
var _types : Dictionary = {} # nom -> TypeData
|
||||||
|
var _abilities : Dictionary = {} # nom -> AbilityData
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
var dir := PokeApiSettings.pokemon_dir()
|
||||||
|
for file in ResourceLoader.list_directory(dir):
|
||||||
|
if file.ends_with("/"): continue # sous-dossier
|
||||||
|
var info := PokeApiSettings.parse_pokemon_stem(file.get_basename())
|
||||||
|
if info.is_empty(): continue
|
||||||
|
_paths[info["name"]] = dir + file
|
||||||
|
_id_to_name[info["id"]] = info["name"]
|
||||||
|
|
||||||
|
#---------- pokémon ----------
|
||||||
|
|
||||||
|
## key : un id (int) ou un nom d'API (String, ex. "pikachu")
|
||||||
|
## Renvoie aussi bien une espèce de base qu'une forme (méga, gigamax, régionale),
|
||||||
|
## puisque toutes sont sauvegardées comme des .tres indépendants dans le même dossier.
|
||||||
|
func get_pokemon(key : Variant) -> PokemonData:
|
||||||
|
var poke_name : String
|
||||||
|
if key is int:
|
||||||
|
poke_name = _id_to_name.get(key, "")
|
||||||
|
else:
|
||||||
|
poke_name = String(key).to_lower()
|
||||||
|
if !_paths.has(poke_name): return null
|
||||||
|
if !_cache.has(poke_name):
|
||||||
|
_cache[poke_name] = load(_paths[poke_name]) as PokemonData
|
||||||
|
return _cache[poke_name]
|
||||||
|
|
||||||
|
func has_pokemon(key : Variant) -> bool:
|
||||||
|
if key is int: return _id_to_name.has(key)
|
||||||
|
return _paths.has(String(key).to_lower())
|
||||||
|
|
||||||
|
## Une forme méga/gmax précise d'un pokémon, ex. get_form(charizard, "mega-x").
|
||||||
|
func get_form(d : PokemonData, kind : String) -> PokemonData:
|
||||||
|
if d == null: return null
|
||||||
|
for f in d.forms:
|
||||||
|
if f.kind == kind: return f.variant
|
||||||
|
return null
|
||||||
|
|
||||||
|
func all_ids() -> Array:
|
||||||
|
var ids : Array = _id_to_name.keys()
|
||||||
|
ids.sort()
|
||||||
|
return ids
|
||||||
|
|
||||||
|
func all_names() -> Array:
|
||||||
|
return _paths.keys()
|
||||||
|
|
||||||
|
#---------- capacités / types / talents ----------
|
||||||
|
|
||||||
|
func get_move(move_name : String) -> MoveData:
|
||||||
|
move_name = move_name.to_lower()
|
||||||
|
if !_moves.has(move_name):
|
||||||
|
var path := PokeApiSettings.moves_dir() + move_name + ".tres"
|
||||||
|
if !ResourceLoader.exists(path): return null
|
||||||
|
_moves[move_name] = load(path) as MoveData
|
||||||
|
return _moves[move_name]
|
||||||
|
|
||||||
|
func get_type(type_name : String) -> TypeData:
|
||||||
|
type_name = type_name.to_lower()
|
||||||
|
if !_types.has(type_name):
|
||||||
|
var path := PokeApiSettings.types_dir() + type_name + ".tres"
|
||||||
|
if !ResourceLoader.exists(path): return null
|
||||||
|
_types[type_name] = load(path) as TypeData
|
||||||
|
return _types[type_name]
|
||||||
|
|
||||||
|
func get_ability(ability_name : String) -> AbilityData:
|
||||||
|
ability_name = ability_name.to_lower()
|
||||||
|
if !_abilities.has(ability_name):
|
||||||
|
var path := PokeApiSettings.abilities_dir() + ability_name + ".tres"
|
||||||
|
if !ResourceLoader.exists(path): return null
|
||||||
|
_abilities[ability_name] = load(path) as AbilityData
|
||||||
|
return _abilities[ability_name]
|
||||||
|
|
||||||
|
#---------- cache ----------
|
||||||
|
|
||||||
|
func clear_cache() -> void:
|
||||||
|
_cache.clear()
|
||||||
|
_moves.clear()
|
||||||
|
_types.clear()
|
||||||
|
_abilities.clear()
|
||||||
Loading…
Reference in a new issue