Skip to content

Commit e8de3ba

Browse files
committed
Refactor combat transition logic into combat state; add trigger and interaction examples
1 parent 31b7486 commit e8de3ba

File tree

17 files changed

+148
-130
lines changed

17 files changed

+148
-130
lines changed
-1.35 MB
Binary file not shown.

assets/music/squashin_bugs_fixed.mp3.import

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
@tool
2+
3+
extends Interaction
4+
5+
@export var pre_combat_timeline: DialogicTimeline
6+
@export var victory_timeline: DialogicTimeline
7+
@export var loss_timeline: DialogicTimeline
8+
9+
@export var combat_arena: PackedScene
10+
11+
12+
func _execute() -> void:
13+
Dialogic.start_timeline(pre_combat_timeline)
14+
15+
# Wait for the timeline to finish before beginning combat.
16+
await Dialogic.timeline_ended
17+
18+
# Let other systems know that a combat has been triggered and then wait for its outcome.
19+
FieldEvents.combat_triggered.emit(combat_arena)
20+
21+
await CombatEvents.combat_finished
22+
23+
# The combat ends with a covered screen, and so we fix that here.
24+
Transition.clear.call_deferred(0.2)
25+
await Transition.finished
26+
27+
# We want to run post-combat events. In some cases, this may not involve much, such as playing a
28+
# game-over screen or removing an AI combat-starting gamepiece from the field.
29+
# In some cases, however, we'll want a dialogue to play or some creative event to occur if, for
30+
# example, the player lost a difficult but non-essential battle.
31+
if CombatEvents.did_player_win_last_combat:
32+
Dialogic.start_timeline(victory_timeline)
33+
34+
else:
35+
Dialogic.start_timeline(loss_timeline)
36+
37+
await Dialogic.timeline_ended
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
join ghost 1
2+
ghost: Your father was a hamster and your mother reeked of elderberry!
3+
ghost: En garde!
4+
[end_timeline]

maps/town/encounter_on_loss.dtl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
join ghost 1
2+
ghost: Ha! Come on, you pansy!
3+
[end_timeline]

maps/town/encounter_on_victory.dtl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
join ghost 1
2+
ghost: Ow...
3+
ghost: Tis but a scratch!
4+
[end_timeline]

project.godot

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ directories/dch_directory={
8080
"wizard": "res://maps/town/wizard.dch"
8181
}
8282
directories/dtl_directory={
83+
"encounter_before_combat": "res://maps/town/encounter_before_combat.dtl",
84+
"encounter_on_loss": "res://maps/town/encounter_on_loss.dtl",
85+
"encounter_on_victory": "res://maps/town/encounter_on_victory.dtl",
8386
"fan_of_four": "res://maps/town/fan_of_four.dtl",
8487
"ghost": "res://maps/grove/ghost.dtl",
8588
"monk": "res://maps/town/monk.dtl",

src/combat/arena_data.gd

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/combat/combat.gd

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,36 @@ extends CanvasLayer
22

33
var _active_arena: CombatArena = null
44

5+
# Keep track of what music track was playing previously, and return to it once combat has finished.
6+
var _previous_music_track: AudioStream = null
7+
58
@onready var _combat_containter: = $CenterContainer as CenterContainer
69

710

811
func _ready() -> void:
9-
CombatEvents.combat_initiated.connect(_on_combat_initiated)
10-
CombatEvents.combat_finished.connect(_on_combat_finished)
12+
FieldEvents.combat_triggered.connect(start)
13+
14+
# TODO: remove with _unhandled input once Battlers have been implemented.
15+
set_process_unhandled_input(false)
1116

1217

13-
func _on_combat_initiated(arena: PackedScene) -> void:
14-
# Don't start a new combat if one is currently ongoing.
15-
if _active_arena:
16-
return
18+
# TODO: This is included to allow leaving the combat state.
19+
# In future releases, these signals will be emitted once battlers from one side have fallen.
20+
func _unhandled_input(event: InputEvent) -> void:
21+
if event.is_action_released("back"):
22+
CombatEvents.did_player_win_last_combat = false
23+
finish()
24+
25+
elif event.is_action_released("interact"):
26+
CombatEvents.did_player_win_last_combat = true
27+
finish()
28+
29+
30+
func start(arena: PackedScene) -> void:
31+
assert(not _active_arena, "Attempting to start a combat when one is ongoing!")
32+
33+
# Cover the screen.
34+
await Transition.cover(0.2)
1735

1836
# Try to setup the combat arena (which comes with AI battlers, etc.).
1937
var new_arena: = arena.instantiate()
@@ -22,11 +40,39 @@ func _on_combat_initiated(arena: PackedScene) -> void:
2240

2341
_active_arena = new_arena
2442
_combat_containter.add_child(_active_arena)
43+
44+
_previous_music_track = Music.get_playing_track()
45+
Music.play(_active_arena.music)
46+
47+
# Let other systems know that the combat state is setup and ready to begin.
48+
CombatEvents.combat_initiated.emit()
49+
50+
# Before starting combat itself, reveal the screen again.
51+
# The Transition.clear() call is deferred since it follows on the heels of cover(), and needs a
52+
# frame to allow everything else to respond to Transition.finished.
53+
Transition.clear.call_deferred(0.2)
54+
await Transition.finished
55+
56+
# TODO: remove with _unhandled input once Battlers have been implemented.
57+
set_process_unhandled_input(true)
2558

2659

27-
func _on_combat_finished() -> void:
60+
func finish() -> void:
61+
# TODO: remove with _unhandled input once Battlers have been implemented.
62+
set_process_unhandled_input(false)
63+
2864
if not _active_arena:
2965
return
3066

67+
# Cover the screen again, transitioning away from the combat game state.
68+
await Transition.cover(0.2)
69+
3170
_active_arena.queue_free()
3271
_active_arena = null
72+
73+
# Signal that the combat has been finished and all combat objects have been dealt with
74+
# accordingly. The field game 'state' will now be in focus.
75+
# Note that whatever object started the combat will now be responsible for flow of the game. In
76+
# particular, the screen is still covered, so the combat-starting object will want to decide
77+
# what to do now that the outcome of the combat is known.
78+
CombatEvents.combat_finished.emit()

src/combat/combat_arena.gd

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,3 @@
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-
12-
elif event.is_action_released("interact"):
13-
CombatEvents.combat_won.emit()

0 commit comments

Comments
 (0)