Visual novel scene progress
This commit is contained in:
5
scripts/battle/camera_controller.gd
Normal file
5
scripts/battle/camera_controller.gd
Normal file
@@ -0,0 +1,5 @@
|
||||
class_name CameraController extends Camera2D
|
||||
|
||||
|
||||
func apply_drag(delta: Vector2) -> void:
|
||||
position += delta / zoom
|
||||
1
scripts/battle/camera_controller.gd.uid
Normal file
1
scripts/battle/camera_controller.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://csdcbi2gtwrly
|
||||
151
scripts/battle/combat_ui.gd
Normal file
151
scripts/battle/combat_ui.gd
Normal file
@@ -0,0 +1,151 @@
|
||||
class_name CombatUI extends CanvasLayer
|
||||
|
||||
signal fight_confirmed(proposal: CombatProposal)
|
||||
signal fight_cancelled
|
||||
|
||||
@onready var unit_panel: PanelContainer = %UnitPanel
|
||||
@onready var name_label: Label = %NameLabel
|
||||
@onready var hp_bar: ProgressBar = %HPBar
|
||||
|
||||
@onready var background_tint: ColorRect = %BackgroundTint
|
||||
@onready var proposal_panel: PanelContainer = %CombatProposalPanel
|
||||
@onready var atk_name_label: Label = %AttackerNameLabel
|
||||
@onready var atk_hp_bar: ProgressBar = %AttackerHPBar
|
||||
@onready var atk_atk_label: Label = %AttackerATKLabel
|
||||
@onready var atk_def_label: Label = %AttackerDEFLabel
|
||||
@onready var atk_hit_label: Label = %AttackerHITLabel
|
||||
@onready var atk_spd_label: Label = %AttackerSPDLabel
|
||||
@onready var def_name_label: Label = %DefenderNameLabel
|
||||
@onready var def_hp_bar: ProgressBar = %DefenderHPBar
|
||||
@onready var def_atk_label: Label = %DefenderATKLabel
|
||||
@onready var def_def_label: Label = %DefenderDEFLabel
|
||||
@onready var def_hit_label: Label = %DefenderHITLabel
|
||||
@onready var def_spd_label: Label = %DefenderSPDLabel
|
||||
@onready var fight_button: Button = %FightButton
|
||||
@onready var cancel_button: Button = %CancelButton
|
||||
@onready var atk_tactic_select: OptionButton = %AttackerTacticSelect
|
||||
@onready var def_tactic_select: OptionButton = %DefenderTacticSelect
|
||||
|
||||
var _selected_unit: Unit
|
||||
var _current_proposal: CombatProposal
|
||||
var combat_system: CombatSystem
|
||||
|
||||
func _ready() -> void:
|
||||
unit_panel.visible = false
|
||||
proposal_panel.visible = false
|
||||
fight_button.pressed.connect(_on_fight_pressed)
|
||||
cancel_button.pressed.connect(_on_cancel_pressed)
|
||||
atk_tactic_select.item_selected.connect(_on_atk_tactic_selected)
|
||||
def_tactic_select.item_selected.connect(_on_def_tactic_selected)
|
||||
for unit: Unit in get_tree().get_nodes_in_group("units"):
|
||||
unit.unit_selected_changed.connect(_on_unit_selected_changed)
|
||||
unit.unit_died.connect(_on_unit_died)
|
||||
get_tree().node_added.connect(_on_node_added)
|
||||
|
||||
func _on_node_added(node: Node) -> void:
|
||||
if node is Unit and node.is_in_group("units"):
|
||||
if not node.unit_selected_changed.is_connected(_on_unit_selected_changed):
|
||||
node.unit_selected_changed.connect(_on_unit_selected_changed)
|
||||
if not node.unit_died.is_connected(_on_unit_died):
|
||||
node.unit_died.connect(_on_unit_died)
|
||||
|
||||
func _on_unit_died(unit: Unit) -> void:
|
||||
if _selected_unit == unit:
|
||||
_selected_unit = null
|
||||
unit_panel.visible = false
|
||||
if _current_proposal:
|
||||
if _current_proposal.attacker.unit == unit or _current_proposal.defender.unit == unit:
|
||||
_hide_proposal()
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _selected_unit and is_instance_valid(_selected_unit):
|
||||
hp_bar.max_value = _selected_unit.current_stats.max_hp
|
||||
hp_bar.value = _selected_unit.current_stats.current_hp
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if proposal_panel.visible and event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_RIGHT:
|
||||
_hide_proposal()
|
||||
fight_cancelled.emit()
|
||||
get_viewport().set_input_as_handled()
|
||||
|
||||
func _on_unit_selected_changed(unit: Unit, selected: bool) -> void:
|
||||
if selected:
|
||||
_selected_unit = unit
|
||||
name_label.text = unit.current_info.name
|
||||
hp_bar.max_value = unit.current_stats.max_hp
|
||||
hp_bar.value = unit.current_stats.current_hp
|
||||
unit_panel.visible = true
|
||||
else:
|
||||
_selected_unit = null
|
||||
unit_panel.visible = false
|
||||
|
||||
func show_proposal(proposal: CombatProposal) -> void:
|
||||
_current_proposal = proposal
|
||||
_populate_tactic_select(atk_tactic_select, proposal.attacker)
|
||||
_populate_tactic_select(def_tactic_select, proposal.defender)
|
||||
_refresh_stats()
|
||||
background_tint.visible = true
|
||||
proposal_panel.visible = true
|
||||
|
||||
func _hide_proposal() -> void:
|
||||
background_tint.visible = false
|
||||
proposal_panel.visible = false
|
||||
_current_proposal = null
|
||||
|
||||
func _on_fight_pressed() -> void:
|
||||
if _current_proposal:
|
||||
var proposal := _current_proposal
|
||||
_hide_proposal()
|
||||
fight_confirmed.emit(proposal)
|
||||
|
||||
func _on_cancel_pressed() -> void:
|
||||
_hide_proposal()
|
||||
fight_cancelled.emit()
|
||||
|
||||
|
||||
func _populate_tactic_select(button: OptionButton, combatant: CombatProposal.CombatantStats) -> void:
|
||||
button.clear()
|
||||
var selected_idx := 0
|
||||
for i in combatant.available_tactics.size():
|
||||
var tactic := combatant.available_tactics[i]
|
||||
button.add_item(tactic.tactic_name)
|
||||
if tactic == combatant.selected_tactic:
|
||||
selected_idx = i
|
||||
button.selected = selected_idx
|
||||
var is_player := combatant.unit.current_allegiance.type == UnitAllegiance.AllegianceType.PLAYER
|
||||
button.disabled = not is_player
|
||||
|
||||
|
||||
func _refresh_stats() -> void:
|
||||
var atk := _current_proposal.attacker
|
||||
var def := _current_proposal.defender
|
||||
atk_name_label.text = atk.unit.current_info.name
|
||||
atk_hp_bar.max_value = atk.max_hp
|
||||
atk_hp_bar.value = atk.hp
|
||||
atk_atk_label.text = "ATK: %d" % atk.atk
|
||||
atk_def_label.text = "DEF: %d" % atk.def
|
||||
atk_hit_label.text = "HIT: %d%%" % atk.hit
|
||||
atk_spd_label.text = "SPD: %d" % atk.spd
|
||||
def_name_label.text = def.unit.current_info.name
|
||||
def_hp_bar.max_value = def.max_hp
|
||||
def_hp_bar.value = def.hp
|
||||
def_atk_label.text = "ATK: %d" % def.atk
|
||||
def_def_label.text = "DEF: %d" % def.def
|
||||
def_hit_label.text = "HIT: %d%%" % def.hit
|
||||
def_spd_label.text = "SPD: %d" % def.spd
|
||||
|
||||
|
||||
func _on_atk_tactic_selected(index: int) -> void:
|
||||
if not _current_proposal or not combat_system:
|
||||
return
|
||||
var tactic := _current_proposal.attacker.available_tactics[index]
|
||||
combat_system.update_tactic(_current_proposal, true, tactic)
|
||||
_refresh_stats()
|
||||
|
||||
|
||||
func _on_def_tactic_selected(index: int) -> void:
|
||||
if not _current_proposal or not combat_system:
|
||||
return
|
||||
var tactic := _current_proposal.defender.available_tactics[index]
|
||||
combat_system.update_tactic(_current_proposal, false, tactic)
|
||||
_refresh_stats()
|
||||
1
scripts/battle/combat_ui.gd.uid
Normal file
1
scripts/battle/combat_ui.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://w2wh6gtv3u2l
|
||||
16
scripts/battle/grid_overlay.gd
Normal file
16
scripts/battle/grid_overlay.gd
Normal file
@@ -0,0 +1,16 @@
|
||||
class_name GridOverlay extends TileMapLayer
|
||||
|
||||
const SOURCE_ID = 0
|
||||
const HIGHLIGHT_SPRITE_ID = Vector2i(0,0)
|
||||
|
||||
@onready var targeting_selector: Sprite2D = $TargetingIndicator
|
||||
|
||||
func highlight_tile(coords: Vector2i) -> void:
|
||||
set_cell(coords, SOURCE_ID, HIGHLIGHT_SPRITE_ID)
|
||||
|
||||
func clear_tile(coords: Vector2i) -> void:
|
||||
set_cell(coords)
|
||||
|
||||
func target_tile(coords: Vector2i) -> void:
|
||||
targeting_selector.position = coords * tile_set.tile_size
|
||||
targeting_selector.visible = true
|
||||
1
scripts/battle/grid_overlay.gd.uid
Normal file
1
scripts/battle/grid_overlay.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cxl38x2m6sj3w
|
||||
Reference in New Issue
Block a user