broken_seals/game/ui/trainer/TrainerWindow.gd

256 lines
6.3 KiB
GDScript

extends Control
# Copyright (c) 2019-2021 Péter Magyar
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
export(NodePath) var spell_entry_container_path : NodePath
export(NodePath) var learn_button_path : NodePath
export(NodePath) var cost_label_path : NodePath
export(NodePath) var spell_icon_path : NodePath
export(NodePath) var spell_name_label_path : NodePath
export(NodePath) var spell_description_label_path : NodePath
export(NodePath) var spell_requirements_label_path : NodePath
var _spell_entry_container : Node
var _spell_entries : Array
var _learn_button : Button
var _cost_label : Label
var _spell_icon : TextureRect
var _spell_name_label : Label
var _spell_description_label : Label
var _spell_requirements_label : Label
var _player : Entity
var _trainer : Entity
var _entity_data : EntityData
var _character_class : EntityClassData
var _spells : Array
var _spell_button_group : ButtonGroup
var _timer : float = 0
func _ready() -> void:
_spell_button_group = ButtonGroup.new()
_spell_entry_container = get_node(spell_entry_container_path)
_spell_icon = get_node(spell_icon_path) as TextureRect
_spell_name_label = get_node(spell_name_label_path) as Label
_spell_description_label = get_node(spell_description_label_path) as Label
_spell_requirements_label = get_node(spell_requirements_label_path) as Label
_learn_button = get_node(learn_button_path)
_cost_label = get_node(cost_label_path)
_learn_button.connect("pressed", self, "learn")
connect("visibility_changed", self, "_visibility_changed")
set_process(false)
func _process(delta):
_timer += delta
if _timer > 1:
_timer = 0
if _player == null:
return
var target : Entity = _player.getc_target()
if target != _trainer:
hide()
if !_player.isc_target_in_interact_range():
hide()
func learn() -> void:
if _character_class == null:
return
if _player == null:
return
var b : Button = _spell_button_group.get_pressed_button()
if b:
var spell : Spell = b.get_meta("spell")
_player.spell_learn_requestc(spell.id)
refresh_entries()
func refresh_entries() -> void:
if _character_class == null or _player == null:
return
for c in _spell_entry_container.get_children():
c.queue_free()
_spell_entries.clear()
for s in _spells:
var spell : Spell = s
if !spell:
continue
if _player.spell_hasc(spell):
continue
var b : Button = Button.new()
b.text = spell.text_name + " (rank " + str(spell.rank) + ")"
b.set_meta("spell", spell)
b.group = _spell_button_group
b.toggle_mode = true
b.connect("pressed", self, "_button_pressed")
_spell_entries.append(b)
_spell_entry_container.add_child(b)
if _spell_entries.size() > 0:
_spell_entries[0].pressed = true
_button_pressed()
func refresh_all() -> void:
if _player == null:
return
if _character_class == null:
return
refresh_entries()
func _visibility_changed() -> void:
if visible:
refresh_all()
else:
_trainer = null
set_process(visible)
func set_player(p_player: Entity) -> void:
if _player != null:
_player.disconnect("centity_data_changed", self, "centity_data_changed")
_player.disconnect("onc_open_winow_request", self, "onc_open_winow_request")
_player = p_player
_player.connect("centity_data_changed", self, "centity_data_changed")
_player.connect("onc_open_winow_request", self, "onc_open_winow_request")
if _player != null:
centity_data_changed(_player.centity_data)
else:
centity_data_changed(null)
func centity_data_changed(data: EntityData):
_spells.clear()
_entity_data = null
_character_class = null
if data == null:
return
_entity_data = _player.centity_data
_character_class = _entity_data.entity_class_data
if _character_class == null:
return
for i in range(_character_class.get_num_spells()):
_spells.append(_character_class.get_spell(i))
_spells.sort_custom(CustomSpellSorter, "sort")
refresh_all()
func _button_pressed():
var b : Button = _spell_button_group.get_pressed_button()
if b && b.has_meta("spell"):
var spell : Spell = b.get_meta("spell")
_spell_icon.texture = spell.icon
_spell_name_label.text = spell.text_name
_spell_description_label.text = spell.text_description
var req_str = "Required: "
if spell.training_required_spell:
req_str += spell.training_required_spell.text_name + " (rank " + str(spell.training_required_spell.rank) + ") "
if spell.level > 0:
req_str += "level " + str(spell.level)
_spell_requirements_label.text = req_str
_cost_label.text = str(spell.get_training_cost())
else:
_spell_icon.texture = null
_spell_name_label.text = ""
_spell_description_label.text = ""
_spell_requirements_label.text = ""
_cost_label.text = "0"
class CustomSpellSorter:
static func sort(a, b):
if a.level < b.level:
return true
elif a.level > b.level:
return false
else:
var res = a.text_name.casecmp_to(b.text_name)
if res == 0:
if a.rank < b.rank:
return true
return false
elif res == 1:
return false
return true
func onc_open_winow_request(window_id : int) -> void:
if window_id != EntityEnums.ENTITY_WINDOW_TRAINER:
return
_trainer = _player.getc_target()
show()
# if player.has_signal("player_moved") && !player.is_connected("player_moved", self, "on_player_moved"):
# player.connect("player_moved", self, "on_player_moved", [], CONNECT_ONESHOT)