Tales-of-PKMN/game/pokemon/sent_pokemon.gd

79 lines
2.5 KiB
GDScript

class_name SentPokemon
extends Node3D
#un pokemon de l'equipe sorti dans le monde (apres un lancer).
#plusieurs peuvent etre sortis en meme temps ; un meme pokemon ne peut l'etre qu'une fois.
signal recalled
const GROUP : StringName = &"sent_pokemon"
const MODEL_FACES_PLUS_Z : bool = true #true si tes modeles regardent vers +Z (cas des glTF) : sinon mets false
static var _counter : int = 0 #ordre d'envoi, pour retrouver le plus recent
var pokemon : PokemonInstance
var model : Node3D
var order : int = 0
static func send(parent : Node, p : PokemonInstance, at : Vector3, look_at_pos : Vector3 = Vector3.INF) -> SentPokemon:
#un pokemon deja sorti est d'abord rappele (il "se deplace" a l'endroit du nouveau lancer)
for existing in parent.get_tree().get_nodes_in_group(GROUP):
if existing is SentPokemon and existing.pokemon == p:
existing.recall()
var sent := SentPokemon.new()
sent.pokemon = p
sent.order = _counter
_counter += 1
parent.add_child(sent)
sent.global_position = at
sent._build_model()
if look_at_pos != Vector3.INF:
var flat : Vector3 = Vector3(look_at_pos.x, at.y, look_at_pos.z)
if flat.distance_to(at) > 0.01:
sent.look_at(flat, Vector3.UP)
if MODEL_FACES_PLUS_Z: sent.rotate_y(PI) #look_at oriente -Z vers la cible
return sent
static func find_for(tree : SceneTree, p : PokemonInstance) -> SentPokemon:
#le SentPokemon de ce pokemon, s'il est actuellement dehors
for n in tree.get_nodes_in_group(GROUP):
if n is SentPokemon and n.pokemon == p and !n.is_queued_for_deletion(): return n
return null
static func get_latest(tree : SceneTree) -> SentPokemon:
#le pokemon sorti le plus recemment
var latest : SentPokemon = null
for n in tree.get_nodes_in_group(GROUP):
if n is SentPokemon and !n.is_queued_for_deletion() and (latest == null or n.order > latest.order):
latest = n
return latest
func _ready() -> void:
add_to_group(GROUP)
func _build_model() -> void:
model = create_model(pokemon)
add_child(model)
static func create_model(p : PokemonInstance) -> Node3D:
#modele 3D de l'espece ; capsule de remplacement s'il n'y en a pas
var result : Node3D = null
var scene : PackedScene = p.species.model_scene
if scene:
result = scene.instantiate() as Node3D
if result == null:
var mesh_instance := MeshInstance3D.new()
var capsule := CapsuleMesh.new()
capsule.radius = 0.3
capsule.height = 1.0
mesh_instance.mesh = capsule
mesh_instance.position.y = 0.5
result = mesh_instance
return result
func recall() -> void:
recalled.emit()
queue_free()