Skip to content

Commit fff10fe

Browse files
committed
Enter and exit combat state
1 parent 7f0317e commit fff10fe

File tree

8 files changed

+103
-4
lines changed

8 files changed

+103
-4
lines changed

project.godot

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ interact={
142142
"events": [null, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"echo":false,"script":null)
143143
]
144144
}
145+
back={
146+
"deadzone": 0.5,
147+
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"echo":false,"script":null)
148+
]
149+
}
145150

146151
[layer_names]
147152

src/combat/combat.gd

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ extends CanvasLayer
22

33
var _active_arena: CombatArena = null
44

5+
@onready var _combat_containter: = $CenterContainer as CenterContainer
6+
7+
8+
func _ready() -> void:
9+
CombatEvents.combat_initiated.connect(_on_combat_initiated)
10+
CombatEvents.combat_finished.connect(_on_combat_finished)
11+
512

613
func _on_combat_initiated(arena: PackedScene) -> void:
714
# Don't start a new combat if one is currently ongoing.
@@ -12,4 +19,14 @@ func _on_combat_initiated(arena: PackedScene) -> void:
1219
var new_arena: = arena.instantiate()
1320
assert(new_arena is CombatArena,
1421
"Failed to initiate combat. Provided 'arena' arugment is not a CombatArena.")
15-
add_child(new_arena)
22+
23+
_active_arena = new_arena
24+
_combat_containter.add_child(_active_arena)
25+
26+
27+
func _on_combat_finished() -> void:
28+
if not _active_arena:
29+
return
30+
31+
_active_arena.queue_free()
32+
_active_arena = null

src/combat/combat_arena.gd

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
class_name CombatArena extends Control
22

33
@export var music: AudioStream
4+
5+
6+
# TODO: This is included to allow leaving the combat state.
7+
# In future releases, these signals will be emitted once battlers from one side have fallen.
8+
func _unhandled_input(event: InputEvent) -> void:
9+
if event.is_action_released("back"):
10+
CombatEvents.combat_lost.emit()
11+
CombatEvents.combat_finished.emit()
12+
13+
elif event.is_action_released("interact"):
14+
CombatEvents.combat_won.emit()
15+
CombatEvents.combat_finished.emit()

src/combat/combat_arena.tscn

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,12 @@ y_sort_enabled = true
2424
anchors_preset = 0
2525
offset_right = 40.0
2626
offset_bottom = 40.0
27+
28+
[node name="InstructionsLabel" type="Label" parent="Foreground"]
29+
layout_mode = 0
30+
offset_left = 890.0
31+
offset_top = 823.0
32+
offset_right = 1808.0
33+
offset_bottom = 970.0
34+
text = "Press 'ESCAPE' to lose combat.
35+
Press 'SPACE' to win combat."

src/common/combat_events.gd

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,20 @@ extends Node
33

44
## Emitted whenever a combat is triggered. Technically, this event occurs within the field state.
55
signal combat_initiated(arena: PackedScene)
6+
7+
## Emitted immediately after the player has won combat and all animations have finished.
8+
## This is used to transition to the combat results screen and notify the combat-starting-trigger
9+
## of the combat result.
10+
signal combat_won
11+
12+
## Emitted immediately after the player has lost combat and all animations have finished.
13+
## This is used to fade the screen post-combat and notify the combat-starting-trigger of the result.
14+
signal combat_lost
15+
16+
## Emitted whenever the player has finished with the combat state regardless of whether or not the
17+
## combat was won by the player.
18+
## If the player won the combat, the battle results screen has been displayed and dismissed and the
19+
## screen has faded to black.
20+
## If the player lost combat, the screen has faded to black. In most places, the "gameover" screen
21+
## will be displayed next.
22+
signal combat_finished

src/field/cutscenes/templates/combat_trigger.gd

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,42 @@ class_name CombatTrigger extends Trigger
33

44
@export var combat_arena: PackedScene
55

6+
# An internal flag that tracks the outcome of a given combat instance. It is reset every time this
7+
# trigger is run.
8+
var _is_victory: = false
9+
610

711
func _execute() -> void:
8-
print("FIGHT!")
912
CombatEvents.combat_initiated.emit(combat_arena)
13+
14+
# The trigger wants to know if the player wins or loses combat, so we'll listen in for win/lose
15+
# signals. We only want the trigger to know about THIS combat, so we need to track the method
16+
# reference in order to disconnect it, since the callback will not be called on a loss.
17+
_is_victory = false
18+
CombatEvents.combat_won.connect(_on_combat_won)
19+
await CombatEvents.combat_finished
20+
CombatEvents.combat_won.disconnect(_on_combat_won)
21+
22+
# We want to run post-combat events. In some cases, this may not involve much, such as playing a
23+
# game-over screen or removing an AI combat-starting gamepiece from the field.
24+
# In some cases, however, we'll want a dialogue to play or some creative event to occur if, for
25+
# example, the player lost a difficult but non-essential battle.
26+
if _is_victory:
27+
await _run_victory_cutscene()
28+
29+
else:
30+
await _run_loss_cutscene()
31+
32+
33+
func _on_combat_won() -> void:
34+
_is_victory = true
35+
36+
37+
func _run_victory_cutscene() -> void:
38+
await get_tree().process_frame
39+
print("Player won")
40+
41+
42+
func _run_loss_cutscene() -> void:
43+
await get_tree().process_frame
44+
print("Player lost")

src/field/field.gd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ func _ready() -> void:
1414
assert(gameboard)
1515
randomize()
1616

17+
# The field state must pause/unpause with combat accordingly.
18+
# Note that pausing/unpausing input is already wrapped up in triggers, which are what will
19+
# initiate combat.
20+
CombatEvents.combat_initiated.connect(func(_arena): hide())
21+
CombatEvents.combat_finished.connect(func(): show())
22+
1723
Camera.scale = scale
1824
Camera.gameboard = gameboard
1925
Camera.make_current()

src/main.tscn

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,6 @@ emote = 1
492492

493493
[node name="Combat1" type="Node2D" parent="Field/Terrain/Gamepieces/Town"]
494494
position = Vector2(56, 216)
495-
scale = Vector2(1, 1)
496495
metadata/_edit_group_ = true
497496

498497
[node name="Sprite2D" type="Sprite2D" parent="Field/Terrain/Gamepieces/Town/Combat1"]
@@ -507,7 +506,6 @@ emote = 0
507506

508507
[node name="Combat2" type="Node2D" parent="Field/Terrain/Gamepieces/Town"]
509508
position = Vector2(70.4, 184)
510-
scale = Vector2(1, 1)
511509
metadata/_edit_group_ = true
512510

513511
[node name="Sprite2D" type="Sprite2D" parent="Field/Terrain/Gamepieces/Town/Combat2"]

0 commit comments

Comments
 (0)