diff --git a/core/level_game_state.gd b/core/level_game_state.gd index a1d918d..941435a 100644 --- a/core/level_game_state.gd +++ b/core/level_game_state.gd @@ -550,14 +550,19 @@ func reset_for_prestige(reset_total_currency: bool = false, emit_currency_signal if reset_total_currency: _set_total_currency(currency_id, BigNumber.from_float(0.0)) - generator_states.clear() - generator_buff_levels.clear() - generator_buff_unlocked.clear() - _goal_completed.clear() - for goal_id in _goal_completed.keys(): - _goal_completed[goal_id] = false - research_xp.clear() - research_levels.clear() + generator_states.clear() + generator_buff_levels.clear() + generator_buff_unlocked.clear() + + for goal_id in _goal_definitions.keys(): + _goal_completed[goal_id] = false + + var research_ids: Array = research_xp.keys() + research_xp.clear() + research_levels.clear() + + for research_id in research_ids: + research_xp_changed.emit(research_id, BigNumber.from_float(0.0)) if not emit_currency_signals: return diff --git a/core/prestige/prestige_manager.gd b/core/prestige/prestige_manager.gd index ef3457b..fba756a 100644 --- a/core/prestige/prestige_manager.gd +++ b/core/prestige/prestige_manager.gd @@ -182,7 +182,7 @@ func perform_prestige() -> bool: var prestige_currency_id: StringName = get_prestige_currency_id() if prestige_currency_id != &"": preserve_currencies.append(prestige_currency_id) - game_state.reset_for_prestige(false, false, preserve_currencies) + game_state.reset_for_prestige(true, false, preserve_currencies) _reset_all_buff_levels() _reinitialize_generators_after_prestige_reset() if game_state: diff --git a/tests/test_goals_prestige_reset.gd b/tests/test_goals_prestige_reset.gd new file mode 100644 index 0000000..75a7d64 --- /dev/null +++ b/tests/test_goals_prestige_reset.gd @@ -0,0 +1,146 @@ +@tool +extends Node + +var _game_root: Node = null + +func _ready() -> void: + if not Engine.is_editor_hint(): + test_goals_prestige_reset() + get_tree().quit() + +func test_goals_prestige_reset() -> void: + print("\n=== TEST: Goals Prestige Reset ===\n") + TestUtils.set_test_name("goals_prestige_reset") + + # Load the tiny_sword scene directly + var scene = load("res://docs/gyms/tiny_sword/tiny_sword.tscn") + _game_root = scene.instantiate() + add_child(_game_root) + + print("[TARGET] children_after_load: %d" % get_child_count()) + + var game_state: LevelGameState = _game_root.find_child("LevelGameState") + if game_state == null: + print("[ERROR] LevelGameState not found") + _print_summary(0, 1) + return + + print("[TARGET] game_state_found: true") + + var goals: Array[GoalData] = game_state.get_all_goals() + if goals.is_empty(): + print("[ERROR] No goals found in game state") + _print_summary(0, 1) + return + + var test_goal: GoalData = goals[0] + print("[TARGET] test_goal_id: %s" % String(test_goal.id)) + + var gold: BigNumber = BigNumber.from_float(1000000.0) + game_state.add_currency_by_id(&"gold", gold) + + var is_met_before: bool = game_state.is_goal_met(test_goal) + print("[TARGET] goal_met_before_prestige: %s" % str(is_met_before)) + + TestUtils.assert_true( + is_met_before, + "Goal should be met before prestige (with high currency)" + ) + + var is_completed_before: bool = game_state.is_goal_completed(test_goal.id) + print("[TARGET] goal_completed_before_prestige: %s" % str(is_completed_before)) + + game_state.reset_for_prestige(true, true, []) + + var is_completed_after_reset: bool = game_state.is_goal_completed(test_goal.id) + print("[TARGET] goal_completed_after_prestige: %s" % str(is_completed_after_reset)) + + TestUtils.assert_true( + not is_completed_after_reset, + "Goal should NOT be completed after prestige reset (BUG FIX VERIFICATION)" + ) + + var gold_after: BigNumber = game_state.get_currency_amount_by_id(&"gold") + print("[TARGET] gold_after_prestige: %s" % gold_after.to_string_suffix(2)) + + TestUtils.assert_equals( + 0.0, + gold_after.mantissa, + "Gold should be reset to 0 after prestige" + ) + + var total_gold_after: BigNumber = game_state.get_total_currency_acquired_by_id(&"gold") + print("[TARGET] total_gold_after_prestige: %s" % total_gold_after.to_string_suffix(2)) + + TestUtils.assert_equals( + 0.0, + total_gold_after.mantissa, + "Total gold should be reset to 0 after prestige" + ) + + var is_met_after: bool = game_state.is_goal_met(test_goal) + print("[TARGET] goal_met_after_prestige: %s" % str(is_met_after)) + + TestUtils.assert_true( + not is_met_after, + "Goal should NOT be met after prestige (currency reset to 0)" + ) + + var gold_for_unlock: BigNumber = BigNumber.from_float(1000000.0) + game_state.add_currency_by_id(&"gold", gold_for_unlock) + + var is_met_again: bool = game_state.is_goal_met(test_goal) + print("[TARGET] goal_met_after_reaching_currency: %s" % str(is_met_again)) + + TestUtils.assert_true( + is_met_again, + "Goal should be met again after adding sufficient currency" + ) + + var is_completed_auto: bool = game_state.is_goal_completed(test_goal.id) + print("[TARGET] goal_completed_auto_check: %s" % str(is_completed_auto)) + + # This goal has AUTOMATIC unlock behavior, so it should be auto-completed when met + if test_goal.unlock_behavior == GoalData.UnlockBehavior.AUTOMATIC: + TestUtils.assert_true( + is_completed_auto, + "Goal with AUTOMATIC unlock should be auto-completed when met" + ) + +# Try manual completion (should be a no-op if already auto-completed) + game_state._complete_goal_manually(test_goal.id) + + var is_completed: bool = game_state.is_goal_completed(test_goal.id) + print("[TARGET] goal_completed_after_attempt: %s" % str(is_completed)) + + TestUtils.assert_true( + is_completed, + "Goal should be completed (either auto or manual)" + ) + + game_state.reset_for_prestige(true, true, []) + + var is_completed_after_second_prestige: bool = game_state.is_goal_completed(test_goal.id) + print("[TARGET] goal_completed_after_second_prestige: %s" % str(is_completed_after_second_prestige)) + + TestUtils.assert_true( + not is_completed_after_second_prestige, + "Goal should NOT be completed after second prestige reset" + ) + + var is_met_final: bool = game_state.is_goal_met(test_goal) + print("[TARGET] goal_met_final: %s" % str(is_met_final)) + + TestUtils.assert_true( + not is_met_final, + "Goal should NOT be met after second prestige reset" + ) + + _print_summary(TestUtils.get_passed(), TestUtils.get_failed()) + +func _print_summary(passed_count: int, failed_count: int) -> void: + TestUtils.print_result() + if failed_count == 0: + print("[RESULT] PASS") + else: + print("[RESULT] FAIL") diff --git a/tests/test_goals_prestige_reset.gd.uid b/tests/test_goals_prestige_reset.gd.uid new file mode 100644 index 0000000..88880be --- /dev/null +++ b/tests/test_goals_prestige_reset.gd.uid @@ -0,0 +1 @@ +uid://d23axeulmeeih diff --git a/tests/test_goals_prestige_reset.tscn b/tests/test_goals_prestige_reset.tscn new file mode 100644 index 0000000..d604b14 --- /dev/null +++ b/tests/test_goals_prestige_reset.tscn @@ -0,0 +1,6 @@ +[gd_scene format=3 uid="uid://test_goals_prestige_reset"] + +[ext_resource type="Script" path="res://tests/test_goals_prestige_reset.gd" id="1_test"] + +[node name="TestRoot" type="Node"] +script = ExtResource("1_test") diff --git a/tests/test_research_prestige_reset.gd b/tests/test_research_prestige_reset.gd new file mode 100644 index 0000000..63a6e4a --- /dev/null +++ b/tests/test_research_prestige_reset.gd @@ -0,0 +1,128 @@ +extends SceneTree + +var passed: int = 0 +var failed: int = 0 +var _game_root: Node = null +var _test_complete: bool = false + +func _init(): + print("\n=== TEST: Research Level and XP Reset After Prestige ===\n") + TestUtils.set_test_name("research_prestige_reset") + + var scene = load("res://docs/gyms/tiny_sword/tiny_sword.tscn") + change_scene_to_packed(scene) + + await _wait() + + _game_root = root.get_child(0) + + var game_state: LevelGameState = _game_root.find_child("LevelGameState") + var prestige_manager = _game_root.find_child("PrestigeManager") as PrestigeManager + + if game_state == null: + print("[ERROR] LevelGameState not found") + _print_summary() + _test_complete = true + quit(1) + return + + if prestige_manager == null: + print("[ERROR] PrestigeManager not found") + _print_summary() + _test_complete = true + quit(1) + return + + var research_id: StringName = &"gold_research" + + var initial_xp: BigNumber = game_state.get_research_xp(research_id) + var initial_level: int = game_state.get_research_level(research_id) + print("[TARGET] initial_research_xp: mantissa=%s, exponent=%s" % [initial_xp.mantissa, initial_xp.exponent]) + print("[TARGET] initial_research_level: %d" % initial_level) + + TestUtils.assert_equals( + 0, + initial_xp.mantissa, + "Initial research XP should be 0" + ) + + TestUtils.assert_equals( + 0, + initial_level, + "Initial research level should be 0" + ) + + game_state.add_currency_by_id(&"gold", BigNumber.from_float(100000.0)) + game_state.add_currency_by_id(&"gems", BigNumber.from_float(100.0)) + + await _wait() + + for i in range(10): + game_state.add_research_xp(research_id, BigNumber.from_float(500.0)) + await _wait(0.05) + + var pre_prestige_xp: BigNumber = game_state.get_research_xp(research_id) + var pre_prestige_level: int = game_state.get_research_level(research_id) + print("[TARGET] pre_prestige_research_xp: mantissa=%s, exponent=%s" % [pre_prestige_xp.mantissa, pre_prestige_xp.exponent]) + print("[TARGET] pre_prestige_research_level: %d" % pre_prestige_level) + + TestUtils.assert_true( + pre_prestige_xp.mantissa > 0, + "Research XP should be > 0 before prestige" + ) + + TestUtils.assert_true( + pre_prestige_level > 0, + "Research level should be > 0 before prestige" + ) + + var can_prestige: bool = prestige_manager.can_prestige() + print("[TARGET] can_prestige: %s" % str(can_prestige)) + + TestUtils.assert_true( + can_prestige, + "Should be able to prestige after accumulating currencies" + ) + + if can_prestige: + prestige_manager.perform_prestige() + + await _wait() + + var post_prestige_xp: BigNumber = game_state.get_research_xp(research_id) + var post_prestige_level: int = game_state.get_research_level(research_id) + print("[TARGET] post_prestige_research_xp: mantissa=%s, exponent=%s" % [post_prestige_xp.mantissa, post_prestige_xp.exponent]) + print("[TARGET] post_prestige_research_level: %d" % post_prestige_level) + + TestUtils.assert_equals( + 0, + post_prestige_xp.mantissa, + "Research XP should be reset to 0 after prestige" + ) + + TestUtils.assert_equals( + 0, + post_prestige_level, + "Research level should be reset to 0 after prestige" + ) + + _print_summary() + _test_complete = true + if failed == 0: + quit(0) + else: + quit(1) + +func _wait(seconds: float = 0.1) -> void: + await create_timer(seconds).timeout + +func _print_summary(): + TestUtils.print_result() + passed = TestUtils.get_passed() + failed = TestUtils.get_failed() + +func get_passed() -> int: + return passed + +func get_failed() -> int: + return failed diff --git a/tests/test_research_prestige_reset.gd.uid b/tests/test_research_prestige_reset.gd.uid new file mode 100644 index 0000000..467ed3e --- /dev/null +++ b/tests/test_research_prestige_reset.gd.uid @@ -0,0 +1 @@ +uid://j2a4c8w1qrgj