extends CanvasLayer class_name Tutorial const STEP_SCENE = preload("res://gui/game/tutorial/step_gui/step_gui.tscn") signal succeded var indicators : Array[InGameIndicator] var player : Player var region : Region var game_gui : GameGui var success = false @onready var steps : Array[Step] = [ Step.new( "MOVE_WITH_RIGHT_CLICK_OR_WASD", (func (): return player.global_position.distance_to(region.data.player_spawn) > 30) ), Step.new( "CHANGE_ZOOM_WITH_Z_X", (func (): return GameInfo.settings_data.zoom != 1.), (func (): GameInfo.game_data.player_data.inventory.add_item(Detector.new())) ), Step.new( "SELECT_ITEM_WITH_SCROLL_CLICK_OR_NUMBER", (func (): return player.data.inventory.current_item_ind != player.data.inventory.tools.size()) ), Step.new( "LEFT_CLICK_TO_USE_ITEMS", (func (): return player.instruction is Player.ItemActionInstruction) ), Step.new( "USE_YOUR_DETECTOR_TO_FIND_THE_BATTERY", (func (): return player.position.distance_to(Vector2.ZERO) < 600) ), Step.new( "RECHARGE_IN_THE_RECHARGE_STATION", (func (): return region and region.data and not region.data.in_passing_day_animation and region.data.day != 1), (func (): game_gui.show_energy() game_gui.show_help() game_gui.help.display_energy_tutorial() await game_gui.help.tutorial_passed GameInfo.game_data.player_data.inventory.add_item(Pickaxe.new())) ), Step.new( "DIG_A_TALION_VEIN_WITH_SHOVEL", (func (): for e in region.entity_container.get_children(): if e is ItemObject and e.item is Seed: return true return false) ), Step.new( "TAKE_A_SEED_BY_CLICKING_ON_IT", (func (): return player.data.inventory.seeds.find_custom( func(i:Item): return i is Seed ) != -1) ), Step.new( "DROP_SEED_WITH_KEY", (func (): return ( Input.is_action_pressed("drop")) ) ), Step.new( "PLANT_SEED_IN_FERTILE_ZONE", (func (): for e in region.entity_container.get_children(): if e is Plant: game_gui.help.display_plant_info_tutorial(e.card_info()) return true return false) ), Step.new( "WAIT_FOR_THE_PLANT_MATURATION", (func (): return region and region.data and not region.data.in_passing_day_animation and region.data.get_score() != 0), (func (): GameInfo.game_data.player_data.inventory.add_item(Fork.new())) ), Step.new( "HARVEST_A_MATURE_PLANT", (func (): for e in region.entity_container.get_children(): if e is Plant and e.harvested: return true return false) ), Step.new( "TAKE_HARVESTED_SEEDS", (func (): for s in player.data.inventory.seeds: if s is Seed and len(s.plant_mutations) > 0: game_gui.help.display_mutations_tutorial(s.card_info()) return true return false), (func (): await game_gui.help.tutorial_passed game_gui.show_progress_bar() game_gui.help.display_plant_point_tutorial()) ), Step.new( "HAVE_3_PLANT_POINTS_SIMULTANEOUSLY", (func (): return region.data.get_score() >= 3) ), ] func _ready(): setup_gui() show() game_gui.show_energy(false) game_gui.show_progress_bar(false) game_gui.show_help(false) func setup_gui(): for s in %Steps.get_children(): s.queue_free() for s in steps: var new_step = STEP_SCENE.instantiate() as TutorialStepGui new_step.suceeded = false new_step.text = s.get_text() %Steps.add_child(new_step) func _process(_d): if success: hide() elif region and region.data and not success: var all_success = true for i in len(steps): var step := steps[i] var step_gui := %Steps.get_children()[i] as TutorialStepGui step_gui.visible = i == 0 or steps[i-1].succeeded if step_gui.visible: var old_succeeded = step.succeeded step.update_succeeded() if old_succeeded != step.succeeded: # Put a delay so two state don't collide return step_gui.suceeded = step.succeeded if not step.succeeded: game_gui.objective_text = step.text all_success = false if all_success: finish_tutorial() func finish_tutorial(): region.data.state = RegionData.State.SUCCEEDED region.data.update() succeded.emit() success = true SteamConnection.unlock_achievement(SteamConnection.ACH_FINISH_TUTORIAL) class Step: var text : String : get = get_text var is_step_over_callable : Callable var on_succeeded : Callable var succeeded = false func _init( _text : String = "", _is_step_over_callable : Callable = (func():return false), _on_succeeded : Callable = (func():return false) ): text = _text is_step_over_callable = _is_step_over_callable on_succeeded = _on_succeeded func get_text() -> String: return text func update_succeeded() -> bool: if not succeeded: succeeded = is_step_over_callable.call() if succeeded: on_succeeded.call() return succeeded