Update debug_pokemon_panel.gd
This commit is contained in:
parent
e666c8a34d
commit
ce4aa6b30e
|
|
@ -1,21 +1,43 @@
|
|||
extends CanvasLayer
|
||||
# Autoload : DebugPokemonPanel
|
||||
#panneau de test (build de debug uniquement) : liste des pokemon du Pokedex, un clic ajoute a l'equipe
|
||||
#panneau de test (build de debug uniquement) :
|
||||
# - onglet "Ajouter" : liste des pokemon du Pokedex, un clic ajoute a l'equipe
|
||||
# - onglet "Capacites" : on choisit un pokemon de l'equipe, puis on remplace ses capacites
|
||||
# par n'importe quelle capacite importee (recherche par nom, type, categorie ou statut)
|
||||
|
||||
enum Mode { ADD, MOVES }
|
||||
|
||||
const TOGGLE_ACTION : StringName = &"debug_pokemon_panel"
|
||||
const DEFAULT_LEVEL : int = 10
|
||||
|
||||
var _root : Control
|
||||
var _mode : Mode = Mode.ADD
|
||||
var _message : Label
|
||||
var _was_paused : bool = false
|
||||
var _prev_mouse_mode : Input.MouseMode = Input.MOUSE_MODE_VISIBLE
|
||||
|
||||
#onglet "Ajouter"
|
||||
var _add_view : Control
|
||||
var _filter : LineEdit
|
||||
var _level_spin : SpinBox
|
||||
var _team_label : Label
|
||||
var _scroll : ScrollContainer
|
||||
var _list : VBoxContainer
|
||||
var _message : Label
|
||||
var _buttons : Array[Button] = []
|
||||
var _populated : bool = false
|
||||
var _was_paused : bool = false
|
||||
var _prev_mouse_mode : Input.MouseMode = Input.MOUSE_MODE_VISIBLE
|
||||
|
||||
#onglet "Capacites"
|
||||
var _moves_view : Control
|
||||
var _moves_team_box : HFlowContainer
|
||||
var _slots_box : VBoxContainer
|
||||
var _picker_box : VBoxContainer
|
||||
var _picker_title : Label
|
||||
var _move_filter : LineEdit
|
||||
var _move_list : VBoxContainer
|
||||
var _move_buttons : Array[Button] = []
|
||||
var _moves_populated : bool = false
|
||||
var _edit_pokemon : PokemonInstance = null
|
||||
var _edit_slot : int = -1
|
||||
|
||||
func _ready() -> void:
|
||||
if !OS.is_debug_build():
|
||||
|
|
@ -44,13 +66,15 @@ func _unhandled_input(event : InputEvent) -> void:
|
|||
else: _open()
|
||||
get_viewport().set_input_as_handled()
|
||||
elif _root.visible and event.is_action_pressed(&"ui_cancel"):
|
||||
_close()
|
||||
#Echap / B : ferme d'abord la liste des capacites, puis le panneau
|
||||
if _mode == Mode.MOVES and _picker_box.visible: _close_picker()
|
||||
else: _close()
|
||||
get_viewport().set_input_as_handled()
|
||||
|
||||
#---------- ouverture / fermeture ----------
|
||||
|
||||
func _open() -> void:
|
||||
if !_populated: _populate()
|
||||
if _mode == Mode.ADD and !_populated: _populate()
|
||||
_was_paused = get_tree().paused
|
||||
_prev_mouse_mode = Input.mouse_mode
|
||||
get_tree().paused = true
|
||||
|
|
@ -58,6 +82,7 @@ func _open() -> void:
|
|||
_root.visible = true
|
||||
_message.text = ""
|
||||
_refresh_team()
|
||||
if _mode == Mode.MOVES: _refresh_moves_team()
|
||||
_focus_first.call_deferred()
|
||||
|
||||
func _close() -> void:
|
||||
|
|
@ -66,10 +91,29 @@ func _close() -> void:
|
|||
Input.mouse_mode = _prev_mouse_mode
|
||||
|
||||
func _focus_first() -> void:
|
||||
for b in _buttons:
|
||||
if b.is_visible_in_tree():
|
||||
b.grab_focus()
|
||||
return
|
||||
if _mode == Mode.ADD:
|
||||
for b in _buttons:
|
||||
if b.is_visible_in_tree():
|
||||
b.grab_focus()
|
||||
return
|
||||
else:
|
||||
for child in _moves_team_box.get_children():
|
||||
if child is Button:
|
||||
child.grab_focus()
|
||||
return
|
||||
|
||||
func _set_mode(mode : Mode) -> void:
|
||||
_mode = mode
|
||||
_add_view.visible = mode == Mode.ADD
|
||||
_moves_view.visible = mode == Mode.MOVES
|
||||
_message.text = ""
|
||||
if mode == Mode.ADD:
|
||||
if !_populated: _populate()
|
||||
_refresh_team()
|
||||
else:
|
||||
_close_picker()
|
||||
_refresh_moves_team()
|
||||
_focus_first.call_deferred()
|
||||
|
||||
#---------- interface ----------
|
||||
|
||||
|
|
@ -88,7 +132,7 @@ func _build_ui() -> void:
|
|||
_root.add_child(center)
|
||||
|
||||
var panel := PanelContainer.new()
|
||||
panel.custom_minimum_size = Vector2(580, 640)
|
||||
panel.custom_minimum_size = Vector2(620, 680)
|
||||
center.add_child(panel)
|
||||
|
||||
var margin := MarginContainer.new()
|
||||
|
|
@ -101,12 +145,64 @@ func _build_ui() -> void:
|
|||
margin.add_child(box)
|
||||
|
||||
var title := Label.new()
|
||||
title.text = "Debug : ajouter un Pokémon à l'équipe"
|
||||
title.text = "Debug : Pokémon"
|
||||
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(title)
|
||||
|
||||
#onglets
|
||||
var tabs := HBoxContainer.new()
|
||||
tabs.add_theme_constant_override("separation", 8)
|
||||
box.add_child(tabs)
|
||||
var group := ButtonGroup.new()
|
||||
tabs.add_child(_make_tab_button("Ajouter un Pokémon", Mode.ADD, group, true))
|
||||
tabs.add_child(_make_tab_button("Modifier les capacités", Mode.MOVES, group, false))
|
||||
|
||||
_build_add_view(box)
|
||||
_build_moves_view(box)
|
||||
|
||||
_message = Label.new()
|
||||
_message.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
box.add_child(_message)
|
||||
|
||||
var actions := HBoxContainer.new()
|
||||
actions.add_theme_constant_override("separation", 8)
|
||||
box.add_child(actions)
|
||||
actions.add_child(_make_action_button("Soigner l'équipe", _on_heal_pressed))
|
||||
actions.add_child(_make_action_button("Vider l'équipe", _on_clear_pressed))
|
||||
actions.add_child(_make_action_button("Fermer", _close))
|
||||
|
||||
var hint := Label.new()
|
||||
hint.text = "F3 / Select : ouvrir-fermer | Échap / B : retour, puis fermer"
|
||||
hint.modulate = Color(1.0, 1.0, 1.0, 0.5)
|
||||
hint.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(hint)
|
||||
|
||||
func _make_tab_button(label : String, mode : Mode, group : ButtonGroup, pressed : bool) -> Button:
|
||||
var button := Button.new()
|
||||
button.text = label
|
||||
button.toggle_mode = true
|
||||
button.button_group = group
|
||||
button.button_pressed = pressed
|
||||
button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
button.pressed.connect(_set_mode.bind(mode))
|
||||
return button
|
||||
|
||||
func _make_action_button(label : String, callback : Callable) -> Button:
|
||||
var button := Button.new()
|
||||
button.text = label
|
||||
button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
button.pressed.connect(callback)
|
||||
return button
|
||||
|
||||
func _build_add_view(parent : Control) -> void:
|
||||
var view := VBoxContainer.new()
|
||||
view.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
view.add_theme_constant_override("separation", 8)
|
||||
parent.add_child(view)
|
||||
_add_view = view
|
||||
|
||||
var level_row := HBoxContainer.new()
|
||||
box.add_child(level_row)
|
||||
view.add_child(level_row)
|
||||
var level_label := Label.new()
|
||||
level_label.text = "Niveau"
|
||||
level_row.add_child(level_label)
|
||||
|
|
@ -125,40 +221,68 @@ func _build_ui() -> void:
|
|||
|
||||
_team_label = Label.new()
|
||||
_team_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
box.add_child(_team_label)
|
||||
view.add_child(_team_label)
|
||||
|
||||
_scroll = ScrollContainer.new()
|
||||
_scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
_scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
_scroll.follow_focus = true
|
||||
box.add_child(_scroll)
|
||||
view.add_child(_scroll)
|
||||
|
||||
_list = VBoxContainer.new()
|
||||
_list.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
_scroll.add_child(_list)
|
||||
|
||||
_message = Label.new()
|
||||
box.add_child(_message)
|
||||
func _build_moves_view(parent : Control) -> void:
|
||||
var view := VBoxContainer.new()
|
||||
view.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
view.add_theme_constant_override("separation", 8)
|
||||
view.visible = false
|
||||
parent.add_child(view)
|
||||
_moves_view = view
|
||||
|
||||
var actions := HBoxContainer.new()
|
||||
actions.add_theme_constant_override("separation", 8)
|
||||
box.add_child(actions)
|
||||
actions.add_child(_make_action_button("Soigner l'équipe", _on_heal_pressed))
|
||||
actions.add_child(_make_action_button("Vider l'équipe", _on_clear_pressed))
|
||||
actions.add_child(_make_action_button("Fermer", _close))
|
||||
var team_title := Label.new()
|
||||
team_title.text = "Pokémon à modifier"
|
||||
view.add_child(team_title)
|
||||
_moves_team_box = HFlowContainer.new()
|
||||
view.add_child(_moves_team_box)
|
||||
|
||||
var hint := Label.new()
|
||||
hint.text = "F3 / Select : ouvrir-fermer | Échap / B : fermer"
|
||||
hint.modulate = Color(1.0, 1.0, 1.0, 0.5)
|
||||
hint.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(hint)
|
||||
var slots_title := Label.new()
|
||||
slots_title.text = "Capacités : clique sur un emplacement pour le remplacer"
|
||||
view.add_child(slots_title)
|
||||
_slots_box = VBoxContainer.new()
|
||||
view.add_child(_slots_box)
|
||||
|
||||
func _make_action_button(label : String, callback : Callable) -> Button:
|
||||
var button := Button.new()
|
||||
button.text = label
|
||||
button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
button.pressed.connect(callback)
|
||||
return button
|
||||
#liste de toutes les capacites (affichee quand un emplacement est choisi)
|
||||
_picker_box = VBoxContainer.new()
|
||||
_picker_box.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
_picker_box.add_theme_constant_override("separation", 6)
|
||||
_picker_box.visible = false
|
||||
view.add_child(_picker_box)
|
||||
|
||||
_picker_title = Label.new()
|
||||
_picker_box.add_child(_picker_title)
|
||||
|
||||
var search_row := HBoxContainer.new()
|
||||
_picker_box.add_child(search_row)
|
||||
_move_filter = LineEdit.new()
|
||||
_move_filter.placeholder_text = "Rechercher (nom, type, physical/special/status, statut)..."
|
||||
_move_filter.clear_button_enabled = true
|
||||
_move_filter.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
_move_filter.text_changed.connect(_on_move_filter_changed)
|
||||
search_row.add_child(_move_filter)
|
||||
search_row.add_child(_make_action_button("Retirer cette capacité", _on_remove_move_pressed))
|
||||
|
||||
var move_scroll := ScrollContainer.new()
|
||||
move_scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
move_scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
move_scroll.follow_focus = true
|
||||
_picker_box.add_child(move_scroll)
|
||||
_move_list = VBoxContainer.new()
|
||||
_move_list.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
move_scroll.add_child(_move_list)
|
||||
|
||||
#---------- onglet "Ajouter" ----------
|
||||
|
||||
func _populate() -> void:
|
||||
_populated = true
|
||||
|
|
@ -181,8 +305,6 @@ func _populate() -> void:
|
|||
if _buttons.is_empty():
|
||||
_message.text = "Aucun Pokémon dans le Pokedex."
|
||||
|
||||
#---------- actions ----------
|
||||
|
||||
func _on_pokemon_pressed(data : PokemonData) -> void:
|
||||
var team : PokemonTeam = GameData.player_team
|
||||
if team.is_full():
|
||||
|
|
@ -194,18 +316,6 @@ func _on_pokemon_pressed(data : PokemonData) -> void:
|
|||
_message.text = "%s Lv.%d ajouté (%d/%d)" % [pokemon.get_display_name(), pokemon.level, team.size(), PokemonTeam.MAX_SIZE]
|
||||
_refresh_team()
|
||||
|
||||
func _on_clear_pressed() -> void:
|
||||
var team : PokemonTeam = GameData.player_team
|
||||
while !team.is_empty():
|
||||
team.remove_at(team.size() - 1)
|
||||
GameData.validate_selection()
|
||||
_message.text = "Équipe vidée"
|
||||
_refresh_team()
|
||||
|
||||
func _on_heal_pressed() -> void:
|
||||
GameData.player_team.heal_all()
|
||||
_message.text = "Équipe soignée"
|
||||
|
||||
func _on_filter_changed(text : String) -> void:
|
||||
var needle : String = text.strip_edges().to_lower()
|
||||
for b in _buttons:
|
||||
|
|
@ -220,3 +330,148 @@ func _refresh_team() -> void:
|
|||
for p in team.members:
|
||||
names.append("%s Lv.%d" % [p.get_display_name(), p.level])
|
||||
_team_label.text = "Équipe (%d/%d) : %s" % [team.size(), PokemonTeam.MAX_SIZE, ", ".join(names)]
|
||||
|
||||
#---------- onglet "Capacites" ----------
|
||||
|
||||
func _refresh_moves_team() -> void:
|
||||
for child in _moves_team_box.get_children():
|
||||
_moves_team_box.remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
var team : PokemonTeam = GameData.player_team
|
||||
if !team.members.has(_edit_pokemon):
|
||||
_edit_pokemon = team.members[0] if !team.is_empty() else null
|
||||
|
||||
var group := ButtonGroup.new()
|
||||
for p in team.members:
|
||||
var button := Button.new()
|
||||
button.text = "%s Lv.%d" % [p.get_display_name(), p.level]
|
||||
button.toggle_mode = true
|
||||
button.button_group = group
|
||||
button.button_pressed = p == _edit_pokemon
|
||||
button.pressed.connect(_select_pokemon.bind(p))
|
||||
_moves_team_box.add_child(button)
|
||||
|
||||
if team.is_empty():
|
||||
var empty := Label.new()
|
||||
empty.text = "L'équipe est vide : ajoute d'abord un Pokémon (onglet « Ajouter »)."
|
||||
_moves_team_box.add_child(empty)
|
||||
_refresh_slots()
|
||||
|
||||
func _select_pokemon(pokemon : PokemonInstance) -> void:
|
||||
_edit_pokemon = pokemon
|
||||
_close_picker()
|
||||
_refresh_slots()
|
||||
|
||||
func _refresh_slots() -> void:
|
||||
for child in _slots_box.get_children():
|
||||
_slots_box.remove_child(child)
|
||||
child.queue_free()
|
||||
if _edit_pokemon == null: return
|
||||
|
||||
for i in PokemonInstance.MAX_ACTIVE_MOVES:
|
||||
var button := Button.new()
|
||||
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
var prefix : String = "▶ " if i == _edit_slot else ""
|
||||
if i < _edit_pokemon.active_moves.size():
|
||||
var ms : MoveSlot = _edit_pokemon.active_moves[i]
|
||||
button.text = "%s%d. %s PP %d/%d" % [prefix, i + 1, ms.move.get_display_name(), ms.current_pp, ms.max_pp]
|
||||
else:
|
||||
button.text = "%s%d. (vide)" % [prefix, i + 1]
|
||||
button.pressed.connect(_on_slot_pressed.bind(i))
|
||||
_slots_box.add_child(button)
|
||||
|
||||
func _on_slot_pressed(index : int) -> void:
|
||||
if _edit_pokemon == null: return
|
||||
_edit_slot = index
|
||||
_picker_title.text = "Capacité n°%d de %s : choisis un remplacement" % [index + 1, _edit_pokemon.get_display_name()]
|
||||
_picker_box.visible = true
|
||||
_refresh_slots()
|
||||
if !_moves_populated: await _populate_moves()
|
||||
_move_filter.text = ""
|
||||
_on_move_filter_changed("")
|
||||
_focus_first_move.call_deferred()
|
||||
|
||||
func _close_picker() -> void:
|
||||
_edit_slot = -1
|
||||
if _picker_box != null: _picker_box.visible = false
|
||||
if _slots_box != null: _refresh_slots()
|
||||
|
||||
func _populate_moves() -> void:
|
||||
#charge toutes les capacites importees (une seule fois) ; "Pokedex" les garde ensuite en cache
|
||||
_moves_populated = true
|
||||
var names : PackedStringArray = PackedStringArray()
|
||||
for file in ResourceLoader.list_directory(PokeApiSettings.moves_dir()):
|
||||
if file.ends_with(".tres"): names.append(file.get_basename())
|
||||
names.sort()
|
||||
|
||||
var loaded : int = 0
|
||||
for move_name in names:
|
||||
var move : MoveData = Pokedex.get_move(move_name)
|
||||
if move == null: continue
|
||||
|
||||
var power_text : String = str(move.power) if move.power > 0 else "-"
|
||||
var button := Button.new()
|
||||
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
button.text = "%s [%s · %s · puiss. %s]" % [move.get_display_name(), move.type, move.category, power_text]
|
||||
button.set_meta("search", ("%s %s %s %s %s" % [move_name, move.get_display_name(), move.type, move.category, move.ailment]).to_lower())
|
||||
button.pressed.connect(_on_move_pressed.bind(move))
|
||||
_move_list.add_child(button)
|
||||
_move_buttons.append(button)
|
||||
|
||||
loaded += 1
|
||||
if loaded % 40 == 0:
|
||||
_message.text = "Chargement des capacités... %d/%d" % [loaded, names.size()]
|
||||
await get_tree().process_frame
|
||||
_message.text = "%d capacités disponibles." % loaded
|
||||
if loaded == 0:
|
||||
_message.text = "Aucune capacité trouvée : importe d'abord les capacités avec le plugin."
|
||||
|
||||
func _on_move_filter_changed(text : String) -> void:
|
||||
var needle : String = text.strip_edges().to_lower()
|
||||
for b in _move_buttons:
|
||||
b.visible = needle == "" or needle in String(b.get_meta("search"))
|
||||
|
||||
func _focus_first_move() -> void:
|
||||
for b in _move_buttons:
|
||||
if b.is_visible_in_tree():
|
||||
b.grab_focus()
|
||||
return
|
||||
|
||||
func _on_move_pressed(move : MoveData) -> void:
|
||||
if _edit_pokemon == null or _edit_slot < 0: return
|
||||
var pokemon : PokemonInstance = _edit_pokemon
|
||||
|
||||
#la capacite devient aussi "apprise" (coherence avec le reste du jeu)
|
||||
if !pokemon.learned_moves.has(move): pokemon.learned_moves.append(move)
|
||||
var move_slot := MoveSlot.new(move)
|
||||
if _edit_slot < pokemon.active_moves.size():
|
||||
pokemon.active_moves[_edit_slot] = move_slot
|
||||
else:
|
||||
pokemon.active_moves.append(move_slot)
|
||||
|
||||
_message.text = "%s : %s en position %d" % [pokemon.get_display_name(), move.get_display_name(), _edit_slot + 1]
|
||||
_close_picker()
|
||||
|
||||
func _on_remove_move_pressed() -> void:
|
||||
if _edit_pokemon == null or _edit_slot < 0: return
|
||||
if _edit_slot < _edit_pokemon.active_moves.size():
|
||||
_edit_pokemon.active_moves.remove_at(_edit_slot)
|
||||
_message.text = "Capacité n°%d retirée" % (_edit_slot + 1)
|
||||
_close_picker()
|
||||
|
||||
#---------- actions communes ----------
|
||||
|
||||
func _on_clear_pressed() -> void:
|
||||
var team : PokemonTeam = GameData.player_team
|
||||
while !team.is_empty():
|
||||
team.remove_at(team.size() - 1)
|
||||
GameData.validate_selection()
|
||||
_message.text = "Équipe vidée"
|
||||
_refresh_team()
|
||||
if _mode == Mode.MOVES: _refresh_moves_team()
|
||||
|
||||
func _on_heal_pressed() -> void:
|
||||
GameData.player_team.heal_all() #rend aussi tous les PP
|
||||
_message.text = "Équipe soignée (PV et PP)"
|
||||
if _mode == Mode.MOVES: _refresh_slots()
|
||||
Loading…
Reference in a new issue