From af7a09cd94c907bf5b9a19c9784fb2931ec76273 Mon Sep 17 00:00:00 2001 From: Paul Gestwicki Date: Thu, 8 Feb 2024 07:34:35 -0500 Subject: [PATCH] Clarify year transition The routing of year information has changed so that it goes through coroutines. This means that, unlike with signals, we can await on a function's completion. The current approach to showing the year transition is simple text with the Continue button. This is not great, but it does solve a lot of problems: the player is already looking there, and they know how to click "continue" to move on. --- project/ui/game_screen.gd | 10 +++++++- project/ui/main_scene.gd | 4 ++- project/ui/year_indicator.gd | 26 ++++++++++---------- project/ui/year_progress_circle.gd | 2 +- project/world/world.gd | 39 ++++++++++++++---------------- 5 files changed, 44 insertions(+), 37 deletions(-) diff --git a/project/ui/game_screen.gd b/project/ui/game_screen.gd index 77d7815..4911a94 100644 --- a/project/ui/game_screen.gd +++ b/project/ui/game_screen.gd @@ -10,7 +10,8 @@ var world : World: set(value): world = value %CharacterDisplay.character = world.character - %YearIndicator.world = world + %YearIndicator.set_year(world.year) + %YearIndicator.presenter = weakref(self) ## This box holds the whole top interaction area. It is the container ## whose content is swapped out by the ending screen at the end of @@ -172,6 +173,13 @@ func show_text(story) -> void: push_error("Unexpected parameter type: " + story.get_class()) +## Advance the year to the given value. +## +## This is a coroutine that completes when the animation is done. +func show_year_advancement(new_year:Year.Name) -> void: + await %YearIndicator.show_advancement(new_year) + + ## Remove all the children from the given container. func _clear(container:Control) -> void: while container.get_child_count() > 0: diff --git a/project/ui/main_scene.gd b/project/ui/main_scene.gd index bae64c7..ec8a7ab 100644 --- a/project/ui/main_scene.gd +++ b/project/ui/main_scene.gd @@ -79,7 +79,9 @@ func _run_next_story() -> void: ## Load the story and start it var story = load(story_path).new() await story.run(_game_screen) - world.turns += 1 + var year_changed := world.end_turn() + if year_changed: + await _game_screen.show_year_advancement(world.year) func _draw_random_story() -> String: diff --git a/project/ui/year_indicator.gd b/project/ui/year_indicator.gd index a1f9d5f..cb9bc38 100644 --- a/project/ui/year_indicator.gd +++ b/project/ui/year_indicator.gd @@ -1,16 +1,8 @@ extends HBoxContainer -var world: World: - set(value): - if world != null: - if world != value: - world.years_changed.disconnect(_year_progressed) +var presenter : WeakRef # Circular dependency - world = value - world.years_changed.connect(_year_progressed) - _update_display(world.year) - -@onready var _year_name: Label = %YearName +@onready var _year_name := %YearName @onready var _year_circles := { Year.Name.FRESHMAN: %Year1, Year.Name.SOPHOMORE: %Year2, @@ -19,10 +11,18 @@ var world: World: } -func _year_progressed(years: int) -> void: - _update_display(years) +## Set the year programatically and instantly +func set_year(year:Year.Name) -> void: + _year_circles[year].year_passed = true + _year_name.text = Year.as_string(year) -func _update_display(new_year: Year.Name) -> void: +## Animate the year transition +## +## This is a coroutine. +func show_advancement(new_year:Year.Name) -> void: _year_circles[new_year].year_passed = true _year_name.text = Year.as_string(new_year) + presenter.get_ref().show_text("%s Year!" % Year.as_string(new_year)) + await presenter.get_ref().show_continue() + diff --git a/project/ui/year_progress_circle.gd b/project/ui/year_progress_circle.gd index acaac31..5f67dcb 100644 --- a/project/ui/year_progress_circle.gd +++ b/project/ui/year_progress_circle.gd @@ -5,7 +5,7 @@ extends Control @export var inner_border := 2 -var year_passed : bool: +@export var year_passed : bool: set(value): year_passed = value queue_redraw() diff --git a/project/world/world.gd b/project/world/world.gd index e1ac7c3..51b3000 100644 --- a/project/world/world.gd +++ b/project/world/world.gd @@ -1,9 +1,6 @@ ## The state of the game world class_name World extends RefCounted -signal turns_changed(new_turn: int) -signal years_changed(new_year: int) - ## The maximum number of turns that can be taken in a year const MAX_TURNS_PER_YEAR := 3 @@ -26,25 +23,10 @@ var game_map := GameMap.new() var turns_per_year := MAX_TURNS_PER_YEAR -## The number of turns the player has taken. -## -## A turn is a complete story, from beginning to end, that consists of one -## logical unit of time. -var turns := 0: - set(value): - turns = value - - if turns >= turns_per_year: - turns = 0 - if Year.has_next(year): - year = Year.next(year) - - turns_changed.emit(turns) +var year := Year.Name.FRESHMAN -var year := Year.Name.FRESHMAN: - set(value): - year = value - years_changed.emit(year) +## The number of turns the player has taken this year. +var _turns_this_year := 0 ## Add all the stories in the given directory to the list @@ -63,6 +45,21 @@ func add_stories(dir:DirAccess) -> Array[String]: return results +## Mark the end of the current turn. +## +## The result is true if the year changed and false otherwise. +## Finishing senior year does not count as the year changing. +func end_turn() -> bool: + _turns_this_year += 1 + + if _turns_this_year >= turns_per_year: + _turns_this_year = 0 + if Year.has_next(year): + year = Year.next(year) + return true + return false + + ## Remove all the stories in the given directory from the list ## of available stories ##