src / beginning / chapters / chapters.tscn

Diagram

Diagram

Assets

200
200
200
200
200
200
200
200
200

Overridden virtual functions

_ready

func _ready() -> void:
	if get_parent() == get_tree().root:
		%AnimationPlayer.play('opening')
	FocusHelper.set_neighbors_h(%ChaptersContainer.get_children())
	for chapter in %ChaptersContainer.get_children():
		chapter.focus_entered.connect(_on_chapater_focused.bind(chapter))
	load_focused_chapter_to_menu()
$Menu
func _ready() -> void:
	if get_parent() == get_tree().root:
		%AnimationPlayer.play(&'show')
	FocusHelper.set_neighbors_h(%SideButtonContainer.get_children())
	FocusHelper.set_neighbors_h(%StageButtonContainer.get_children())

_input

func _input(event: InputEvent) -> void:
	if not (shown && current_plate == Plate.ROOT): return
	if event.is_action_pressed("ui_back"):
		go_back()
	elif event.is_action_pressed("ui_accept"):
		go_foward()
$Menu
func _input(event: InputEvent) -> void:
	if not shown: return
	if event.is_action_pressed(&'ui_back'):
		match state:
			State.UNSELECTED: ui_backed.emit()
			State.SELECTED:
				state = State.UNSELECTED
				%AnimationPlayer.play(&'climb_unselected')

Scene Tree

Signal Connections

$.:[selected]⇒$.
func _on_selected(idx: int) -> void:
	%Menu.grab_focus_first = true
	selected_chapter_idx = idx
	zoom_pin_to(idx)
	get_chapter(idx).selected()
	set_chapters_animation_offset()
	%ChaptersAnimationPlayer.play("selected")
	current_plate = Plate.MENU
$Menu:[ui_backed]⇒$.
func _on_menu_ui_backed() -> void:
	if current_plate == Plate.MENU:
		(func(): current_plate = Plate.ROOT).call_deferred()
		get_chapter(selected_chapter_idx).unselected()
		%ChaptersAnimationPlayer.play("unselected")
		selected_chapter_idx = -1
		force_focus_return()
$AnimationPlayer:[animation_finished]⇒$.
func _on_animation_player_animation_finished(_anim_name: StringName) -> void:
	if current_plate == Plate.ROOT:
		force_focus_return()

Animations

Animation_f7nbf

Diagram

selected

Diagram

unselected

Diagram

Animation_xd314

Diagram

focus_pin_to_chapter_0

Diagram

focus_pin_to_chapter_1

Diagram

focus_pin_to_chapter_2

Diagram

focus_pin_to_chapter_3

Diagram

focus_pin_to_chapter_4

Diagram

focus_pin_to_chapter_5

Diagram

focus_pin_to_chapter_6

Diagram

focus_pin_to_chapter_7

Diagram

focus_pin_to_chapter_8

Diagram

opening

Diagram

zoom_pin_to_chapter_0

Diagram

zoom_pin_to_chapter_1

Diagram

zoom_pin_to_chapter_2

Diagram

zoom_pin_to_chapter_3

Diagram

zoom_pin_to_chapter_4

Diagram

zoom_pin_to_chapter_5

Diagram

zoom_pin_to_chapter_6

Diagram

zoom_pin_to_chapter_7

Diagram

zoom_pin_to_chapter_8

Diagram

Properties

Table 1. Root properties
Name Value

layout_mode

3

anchors_preset

15

anchor_right

1.0

anchor_bottom

1.0

grow_horizontal

2

grow_vertical

2

script

Table 2. $Banner properties
Name Value

layout_mode

1

anchors_preset

-1

anchor_left

0.469

anchor_right

0.469

offset_left

-100.48004

offset_top

-220.0

offset_right

99.51996

offset_bottom

-20.0

Table 3. $ChaptersContainer properties
Name Value

unique_name_in_owner

true

layout_mode

1

anchors_preset

10

anchor_right

1.0

offset_left

815.0

offset_top

-150.0

offset_right

817.0

offset_bottom

18.0

grow_horizontal

2

Table 4. $ChaptersContainer/Chapter_0 properties
Name Value

layout_mode

2

focus_neighbor_left

NodePath(".")

focus_neighbor_top

NodePath(".")

focus_neighbor_right

NodePath("../Chapter_1")

focus_neighbor_bottom

NodePath(".")

focus_next

NodePath("../Chapter_1")

focus_previous

NodePath(".")

resource

Table 5. $ChaptersContainer/Chapter_1 properties
Name Value

layout_mode

2

focus_neighbor_left

NodePath("../Chapter_0")

focus_neighbor_top

NodePath(".")

focus_neighbor_right

NodePath("../Chapter_2")

focus_neighbor_bottom

NodePath(".")

focus_next

NodePath("../Chapter_2")

focus_previous

NodePath("../Chapter_0")

resource

Table 6. $ChaptersContainer/Chapter_1/Sprite2D properties
Name Value

texture

Chapter 1
Figure 1. res://assets/images/ui/Chapters/Chapter_1.png
Table 7. $ChaptersContainer/Chapter_2 properties
Name Value

layout_mode

2

focus_neighbor_left

NodePath("../Chapter_1")

focus_neighbor_top

NodePath(".")

focus_neighbor_right

NodePath("../Chapter_3")

focus_neighbor_bottom

NodePath(".")

focus_next

NodePath("../Chapter_3")

focus_previous

NodePath("../Chapter_1")

resource

Table 8. $ChaptersContainer/Chapter_2/Sprite2D properties
Name Value

texture

Chapter 2
Figure 2. res://assets/images/ui/Chapters/Chapter_2.png
Table 9. $ChaptersContainer/Chapter_3 properties
Name Value

layout_mode

2

focus_neighbor_left

NodePath("../Chapter_2")

focus_neighbor_top

NodePath(".")

focus_neighbor_right

NodePath("../Chapter_4")

focus_neighbor_bottom

NodePath(".")

focus_next

NodePath("../Chapter_4")

focus_previous

NodePath("../Chapter_2")

resource

Table 10. $ChaptersContainer/Chapter_3/Sprite2D properties
Name Value

texture

Chapter 3
Figure 3. res://assets/images/ui/Chapters/Chapter_3.png
Table 11. $ChaptersContainer/Chapter_4 properties
Name Value

layout_mode

2

focus_neighbor_left

NodePath("../Chapter_3")

focus_neighbor_top

NodePath(".")

focus_neighbor_right

NodePath("../Chapter_5")

focus_neighbor_bottom

NodePath(".")

focus_next

NodePath("../Chapter_5")

focus_previous

NodePath("../Chapter_3")

resource

Table 12. $ChaptersContainer/Chapter_4/Sprite2D properties
Name Value

texture

Chapter 4
Figure 4. res://assets/images/ui/Chapters/Chapter_4.png
Table 13. $ChaptersContainer/Chapter_5 properties
Name Value

layout_mode

2

focus_neighbor_left

NodePath("../Chapter_4")

focus_neighbor_top

NodePath(".")

focus_neighbor_right

NodePath("../Chapter_6")

focus_neighbor_bottom

NodePath(".")

focus_next

NodePath("../Chapter_6")

focus_previous

NodePath("../Chapter_4")

resource

Table 14. $ChaptersContainer/Chapter_5/Sprite2D properties
Name Value

texture

Chapter 5
Figure 5. res://assets/images/ui/Chapters/Chapter_5.png
Table 15. $ChaptersContainer/Chapter_6 properties
Name Value

layout_mode

2

focus_neighbor_left

NodePath("../Chapter_5")

focus_neighbor_top

NodePath(".")

focus_neighbor_right

NodePath("../Chapter_7")

focus_neighbor_bottom

NodePath(".")

focus_next

NodePath("../Chapter_7")

focus_previous

NodePath("../Chapter_5")

resource

Table 16. $ChaptersContainer/Chapter_6/Sprite2D properties
Name Value

texture

Chapter 6
Figure 6. res://assets/images/ui/Chapters/Chapter_6.png
Table 17. $ChaptersContainer/Chapter_7 properties
Name Value

layout_mode

2

focus_neighbor_left

NodePath("../Chapter_6")

focus_neighbor_top

NodePath(".")

focus_neighbor_right

NodePath("../Chapter_8")

focus_neighbor_bottom

NodePath(".")

focus_next

NodePath("../Chapter_8")

focus_previous

NodePath("../Chapter_6")

resource

Table 18. $ChaptersContainer/Chapter_7/Sprite2D properties
Name Value

texture

Chapter 7
Figure 7. res://assets/images/ui/Chapters/Chapter_7.png
Table 19. $ChaptersContainer/Chapter_8 properties
Name Value

layout_mode

2

focus_neighbor_left

NodePath("../Chapter_7")

focus_neighbor_top

NodePath(".")

focus_neighbor_right

NodePath(".")

focus_neighbor_bottom

NodePath(".")

focus_next

NodePath(".")

focus_previous

NodePath("../Chapter_7")

resource

Table 20. $ChaptersContainer/Chapter_8/Sprite2D properties
Name Value

texture

Chapter 8
Figure 8. res://assets/images/ui/Chapters/Chapter_8.png
Table 21. $Grid1920x1080 properties
Name Value

visible

false

position

Vector2(960, 540)

texture

grid 1920x1080
Figure 9. res://assets/guide/grid_1920x1080.png
Table 22. $Pin properties
Name Value

visible

false

position

Vector2(903, 554)

scale

Vector2(0.5, 0.5)

Table 23. $Menu properties
Name Value

unique_name_in_owner

true

layout_mode

1

Table 24. $ChaptersAnimationPlayer properties
Name Value

unique_name_in_owner

true

root_node

NodePath("../ChaptersContainer")

libraries

{ &"": SubResource("AnimationLibrary_c4ypt") }

Table 25. $AnimationPlayer properties
Name Value

unique_name_in_owner

true

libraries

{ &"": SubResource("AnimationLibrary_wkduh") }

chapters.gd

extends Control

signal focused(idx: int)
signal selected(idx: int)
signal ui_backed

@export var grab_focus_first : bool : set = set_grab_focus_first
@export var play_opening := false : set = set_play_opening
@export var current_plate : Plate = Plate.ROOT
@export var shown : bool = false
enum Plate { ROOT, MENU }
const ICON_OFFSET := 164
const INITIAL_CHAPTERS_X := 815
var focused_chapter_idx : int = 0
var selected_chapter_idx : int = -1


func _ready() -> void:
	if get_parent() == get_tree().root:
		%AnimationPlayer.play('opening')
	FocusHelper.set_neighbors_h(%ChaptersContainer.get_children())
	for chapter in %ChaptersContainer.get_children():
		chapter.focus_entered.connect(_on_chapater_focused.bind(chapter))
	load_focused_chapter_to_menu()


func setup_from_account_resource() -> void:
	if not Current.account: return
	var numbers = Current.account.chapters.map(func(c): return c.number)
	for chapter in %ChaptersContainer.get_children():
		var number = int(str(chapter.name)[-1])
		if number == 0: continue
		if not numbers.has(number): chapter.hide()


func _input(event: InputEvent) -> void:
	if not (shown && current_plate == Plate.ROOT): return
	if event.is_action_pressed("ui_back"):
		go_back()
	elif event.is_action_pressed("ui_accept"):
		go_foward()


func go_back() -> void:
	shown = false
	%AnimationPlayer.play("RESET")
	ui_backed.emit()


func go_foward() -> void:
	current_plate = Plate.MENU
	selected.emit(focused_chapter_idx)


func set_grab_focus_first(val: bool) -> void:
	FocusHelper.grab_first(%ChaptersContainer, val)


func set_play_opening(val: bool) -> void:
	if val: %AnimationPlayer.play("opening")


func focus_pin_to(idx: int) -> void:
	var anim_name = "focus_pin_to_chapter_%s" % idx
	if shown: %AnimationPlayer.play(anim_name)
	else: %AnimationPlayer.queue(anim_name)


func zoom_pin_to(idx: int) -> void:
	var anim_name = "zoom_pin_to_chapter_%s" % idx
	%AnimationPlayer.play(anim_name)


func force_focus_return():
	var target = get_chapter(focused_chapter_idx)
	if not FocusHelper.is_focuesed(target):
		target.focus_returned()


func load_focused_chapter_to_menu():
	var chapter = get_chapter(focused_chapter_idx)
	%Menu.chapter_resource = chapter.resource


func get_chapter(idx: int) -> Node:
	return %ChaptersContainer.get_child(idx)


func set_chapters_animation_offset() -> void:
	var current_pos = %ChaptersContainer.position
	var anim = %ChaptersAnimationPlayer.get_animation('selected')
	var track_idx = anim.find_track('.:position', Animation.TrackType.TYPE_VALUE)
	anim.track_set_key_value(track_idx, 0, current_pos)
	var pos = anim.track_get_key_value(track_idx, 1)
	pos.x = current_pos.x
	anim.track_set_key_value(track_idx, 1, pos)
	anim = %ChaptersAnimationPlayer.get_animation('unselected')
	track_idx = anim.find_track('.:position', Animation.TrackType.TYPE_VALUE)
	pos = anim.track_get_key_value(track_idx, 0)
	pos.x = current_pos.x
	anim.track_set_key_value(track_idx, 0, pos)
	anim.track_set_key_value(track_idx, 1, current_pos)


func _on_chapater_focused(chapter: Node) -> void:
	var idx = int(str(chapter.name)[-1])
	focused_chapter_idx = idx
	%ChaptersContainer.position.x = INITIAL_CHAPTERS_X - (ICON_OFFSET * idx)
	focus_pin_to(idx)
	load_focused_chapter_to_menu()
	focused.emit(idx)


func _on_animation_player_animation_finished(_anim_name: StringName) -> void:
	if current_plate == Plate.ROOT:
		force_focus_return()


func _on_selected(idx: int) -> void:
	%Menu.grab_focus_first = true
	selected_chapter_idx = idx
	zoom_pin_to(idx)
	get_chapter(idx).selected()
	set_chapters_animation_offset()
	%ChaptersAnimationPlayer.play("selected")
	current_plate = Plate.MENU


func _on_menu_ui_backed() -> void:
	if current_plate == Plate.MENU:
		(func(): current_plate = Plate.ROOT).call_deferred()
		get_chapter(selected_chapter_idx).unselected()
		%ChaptersAnimationPlayer.play("unselected")
		selected_chapter_idx = -1
		force_focus_return()