diff --git a/MainWindow.gd b/MainWindow.gd index cf2ce1b..a3c3a62 100644 --- a/MainWindow.gd +++ b/MainWindow.gd @@ -140,6 +140,9 @@ var songs: Array= [] var soundtracks: Array = [] var current_player: Node +## True while statistics are off because a player won, until points are reset. +var stats_paused_by_win: bool = false + ## Seconds to wait before retrying a song download step that failed. var song_fetch_retry_seconds: float = 5.0 @@ -368,6 +371,10 @@ func reset_points() -> void: for player_objects: PlayerObject in Settings.player_array: player_objects.reset_points() load_players() + # A new game starts, so turn statistics back on if winning turned them off + if stats_paused_by_win: + Settings.add_to_stats = true + stats_paused_by_win = false func show_about() -> void: print("show_about") @@ -487,7 +494,10 @@ func _on_player_won(player_object: PlayerObject) -> void: print("_on_player_won") winner_window.show_winner(player_object) music_player_container.play_song(preload("res://sounds/winning.mp3")) - Settings.add_to_stats = false + # Songs played after the game is won don't count towards the statistics + if Settings.add_to_stats: + Settings.add_to_stats = false + stats_paused_by_win = true func _on_player_removed(player_object: PlayerObject) -> void: print("_on_player_removed ", player_object.player_name) diff --git a/PlayerObject.gd b/PlayerObject.gd index 2267b00..5e9d146 100644 --- a/PlayerObject.gd +++ b/PlayerObject.gd @@ -37,13 +37,17 @@ func add_point() -> void: if player_score < Settings.winning_score: player_score += 1 player_point_given.emit() - if player_score == 1 && is_first_point: + var first_point: bool = player_score == 1 && is_first_point + if player_score == 1: is_first_point = false - first_point_triggerd.emit() + # With a low winning score the first point can also be match point or the win, + # so the more important event is checked first + if player_score == Settings.winning_score: + winner_triggerd.emit() elif player_score == Settings.winning_score - 1: match_point_triggerd.emit() - elif player_score == Settings.winning_score: - winner_triggerd.emit() + elif first_point: + first_point_triggerd.emit() else: point_given_sound.emit() diff --git a/SettingsWindow.gd b/SettingsWindow.gd index 6cf69f7..9eb8daa 100644 --- a/SettingsWindow.gd +++ b/SettingsWindow.gd @@ -109,6 +109,12 @@ func _ready() -> void: update_hide_for_seconds_enabled() select_server_button.select(Settings.selected_server) select_server_button.item_selected.connect(select_server) + visibility_changed.connect(_on_visibility_changed) + +# Settings can change outside this window, e.g. winning turns statistics off +func _on_visibility_changed() -> void: + if visible: + add_to_database_button.button_pressed = Settings.add_to_stats func _input(event: InputEvent) -> void: if self.visible == true: @@ -154,7 +160,7 @@ func hide_ticks() -> void: Settings.hide_ticks = !Settings.hide_ticks func lower_winning_score() -> void: - Settings.winning_score -= 1 + Settings.winning_score = max(Settings.winning_score - 1, 1) score_label.text = str(Settings.winning_score) func increase_winning_score() -> void: diff --git a/tests/integration/test_stats_after_win.gd b/tests/integration/test_stats_after_win.gd new file mode 100644 index 0000000..7c6b864 --- /dev/null +++ b/tests/integration/test_stats_after_win.gd @@ -0,0 +1,65 @@ +extends MainWindowTestSuite +## Winning turns statistics off until a new game starts. + +var _crono: PlayerObject + + +func before_test() -> void: + super() + _crono = _add_player("Crono") + await _play_first_song() + Settings.winning_score = 1 + + +func _stats_checkbox() -> CheckButton: + return _window.get_node("SettingsWindow").get_node("%AddToDatabaseCheckButton") + + +func test_winning_turns_statistics_off() -> void: + await _give_point_with_keybind(1) + + assert_bool(Settings.add_to_stats).is_false() + + +func test_resetting_points_turns_statistics_back_on() -> void: + await _give_point_with_keybind(1) + + _press("ResetPointsButton") + + assert_bool(Settings.add_to_stats).is_true() + + +func test_statistics_turned_off_by_hand_stay_off_after_reset() -> void: + Settings.add_to_stats = false + await _give_point_with_keybind(1) + + _press("ResetPointsButton") + + assert_bool(Settings.add_to_stats).is_false() + + +func test_settings_checkbox_shows_statistics_off_after_win() -> void: + await _give_point_with_keybind(1) + + _press("SettingsButton") + + assert_bool(_stats_checkbox().button_pressed).is_false() + + +func test_songs_after_a_win_are_not_counted() -> void: + await _give_point_with_keybind(1) + var played_before: int = _server.count("/music/played?song=0") + + _press("ShowAnswerButton") + + assert_int(_server.count("/music/played?song=0")).is_equal(played_before) + + +func test_winning_score_cannot_go_below_one() -> void: + _press("SettingsButton") + var lower_button: Button = _window.get_node("SettingsWindow").get_node("%LowerButton") + + for i: int in 3: + lower_button.pressed.emit() + + assert_int(Settings.winning_score).is_equal(1) diff --git a/tests/integration/test_stats_after_win.gd.uid b/tests/integration/test_stats_after_win.gd.uid new file mode 100644 index 0000000..793d2ef --- /dev/null +++ b/tests/integration/test_stats_after_win.gd.uid @@ -0,0 +1 @@ +uid://d20y2gtespbou diff --git a/tests/unit/test_player_object.gd b/tests/unit/test_player_object.gd index 2ca400b..ec3834f 100644 --- a/tests/unit/test_player_object.gd +++ b/tests/unit/test_player_object.gd @@ -117,3 +117,22 @@ func test_every_player_gets_a_different_id() -> void: ids[PlayerObject.new("Player %d" % i).id] = true assert_int(ids.size()).is_equal(100) + + +func test_winning_score_of_one_is_won_with_first_point() -> void: + Settings.winning_score = 1 + monitor_signals(_player, false) + + _player.add_point() + + await assert_signal(_player).is_emitted("winner_triggerd") + + +func test_first_point_is_match_point_when_winning_score_is_two() -> void: + Settings.winning_score = 2 + monitor_signals(_player, false) + + _player.add_point() + + await assert_signal(_player).is_emitted("match_point_triggerd") + assert_bool(_player.is_first_point).is_false()