src / beginning / chapters / menu / menu.tscn

Diagram

Diagram

Assets

200
200
200
200
200
200
200
200
200
200
200

Overridden virtual functions

_ready

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: return
	if event.is_action_pressed(&'ui_back'):
		match state:
			State.UNSELECTED: ui_backed.emit()
			State.SELECTED:
				state = State.UNSELECTED
				%AnimationPlayer.play(&'climb_unselected')
$SideSelection/SideButtonContainer/ClimbBookmark, $SideSelection/SideButtonContainer/CassetteBookmark, $StageSelection/StageButtonContainer/Stage1Button, $StageSelection/StageButtonContainer/Stage2Button, $StageSelection/StageButtonContainer/Stage3Button, $StageSelection/StageButtonContainer/Stage4Button, $StageSelection/StageButtonContainer/Stage5Button
func _input(event: InputEvent) -> void:
	if event.is_action_pressed("ui_accept") && focused:
		pressed.emit()

Scene Tree

Signal Connections

$.:[get_started]⇒$.
func _on_get_started(stage_number: int) -> void:
	var stage = stage_resources.filter(func(r):
		return r.number == stage_number)
	if not (stage && stage[0].scene): return
	%ClosingCurtain.play(stage[0].scene)
$.:[ui_backed]⇒$.
func _on_ui_backed() -> void:
	if shown: %AnimationPlayer.play(&'hide')
$SideSelection/SideButtonContainer/ClimbBookmark:[pressed]⇒$.
func _on_climb_button_pressed() -> void:
	if stages_count() > 1:
		state = State.SELECTED
		%AnimationPlayer.play(&'climb_selected')
	else:
		get_started.emit(1)
$StageSelection/StageButtonContainer/Stage1Button:[focus_entered]⇒$., $StageSelection/StageButtonContainer/Stage2Button:[focus_entered]⇒$., $StageSelection/StageButtonContainer/Stage3Button:[focus_entered]⇒$., $StageSelection/StageButtonContainer/Stage4Button:[focus_entered]⇒$., $StageSelection/StageButtonContainer/Stage5Button:[focus_entered]⇒$.
func _on_stage_button_focus_entered(number: int) -> void:
	var photos = %PhotoInstances.get_children()
	var button = get_stage_button(number - 1)
	%StageLabel.text = str(button.get_meta(&'name'))
	for i in photos.size():
		var photo = photos.pop_back()
		if i+1 < number: photo.flick()
		else: photo.pull()
$StageSelection/StageButtonContainer/Stage1Button:[pressed]⇒$., $StageSelection/StageButtonContainer/Stage2Button:[pressed]⇒$., $StageSelection/StageButtonContainer/Stage3Button:[pressed]⇒$., $StageSelection/StageButtonContainer/Stage4Button:[pressed]⇒$., $StageSelection/StageButtonContainer/Stage5Button:[pressed]⇒$.
func _on_stage_button_pressed(stage_number: int) -> void:
	get_started.emit(stage_number)

Animations

Animation_m3sah

Diagram

climb_selected

Diagram

climb_unselected

Diagram

hide

Diagram

show

Diagram

Properties

Table 1. Root properties
Name Value

layout_mode

3

anchors_preset

15

anchor_right

1.0

anchor_bottom

1.0

offset_left

960.0

offset_right

960.0

grow_horizontal

2

grow_vertical

2

theme

script

chapter_resource

Table 2. $BannerBox properties
Name Value

z_index

4

layout_mode

1

anchor_left

1.0

anchor_top

0.162

anchor_right

1.0

anchor_bottom

0.162

offset_left

-721.0

offset_top

-70.96

offset_right

4.0

offset_bottom

72.04

grow_horizontal

0

Table 3. $BannerBox/ChapterNumber properties
Name Value

unique_name_in_owner

true

layout_mode

1

anchors_preset

-1

anchor_left

0.709

anchor_top

0.276

anchor_right

0.709

anchor_bottom

0.276

offset_left

-590.189

offset_top

-27.468

offset_right

-0.189026

offset_bottom

27.532

theme_override_colors/font_color

Color(0.242966, 0.242966, 0.242966, 1)

theme_override_colors/font_outline_color

Color(0.239, 0.239, 0.239, 0)

theme_override_font_sizes/font_size

36

text

Chapter 1

horizontal_alignment

2

Table 4. $BannerBox/ChapterName properties
Name Value

unique_name_in_owner

true

layout_mode

1

anchors_preset

-1

anchor_left

0.709

anchor_top

0.64

anchor_right

0.709

anchor_bottom

0.64

offset_left

-590.189

offset_top

-33.52

offset_right

-0.189026

offset_bottom

33.48

text

Ghost town

horizontal_alignment

2

Table 5. $Box properties
Name Value

z_index

2

layout_mode

1

anchors_preset

-1

anchor_left

1.0

anchor_top

0.069

anchor_right

1.0

anchor_bottom

0.069

offset_left

-721.0

offset_top

0.47999573

offset_right

4.0

offset_bottom

678.48

texture

Box
Figure 1. res://assets/images/ui/Chapters/menu/Box.svg

region_rect

Rect2(235, 116, 725, 760)

patch_margin_bottom

300

Table 6. $Banner properties
Name Value

unique_name_in_owner

true

z_index

3

texture_filter

2

position

Vector2(1639, 175)

texture

Banner
Figure 2. res://assets/images/ui/Chapters/menu/Banner.png
Table 7. $SideSelection properties
Name Value

texture_filter

2

Table 8. $SideSelection/CenterBox properties
Name Value

z_index

2

layout_mode

3

anchors_preset

0

offset_left

1256.0

offset_top

247.0

offset_right

1884.0

offset_bottom

517.0

theme

Table 9. $SideSelection/CenterBox/BlueHeartIcon properties
Name Value

unique_name_in_owner

true

position

Vector2(150.5, 133.5)

scale

Vector2(1.38281, 1.38281)

texture

BlueHeart
Figure 3. res://assets/images/ui/BlueHeart.svg
Table 10. $SideSelection/CenterBox/StrawberryIcon properties
Name Value

position

Vector2(303, 92.5)

scale

Vector2(0.269531, 0.269531)

texture

Strawberry
Figure 4. res://assets/images/ui/Strawberry.png
Table 11. $SideSelection/CenterBox/MultiplicationStrawberry properties
Name Value

position

Vector2(353, 94.5)

scale

Vector2(0.145145, 0.145145)

texture

Multiplication
Figure 5. res://assets/images/ui/Multiplication.svg
Table 12. $SideSelection/CenterBox/StrawberryCountContainer properties
Name Value

layout_mode

1

anchors_preset

-1

anchor_left

0.637

anchor_top

0.322

anchor_right

0.637

anchor_bottom

0.322

offset_left

-10.036

offset_top

-28.94

offset_right

126.964

offset_bottom

38.06

Table 13. $SideSelection/CenterBox/StrawberryCountContainer/ObtainedStrawberryCount properties
Name Value

unique_name_in_owner

true

layout_mode

2

text

0

Table 14. $SideSelection/CenterBox/StrawberryCountContainer/Slash properties
Name Value

layout_mode

2

text

/

Table 15. $SideSelection/CenterBox/StrawberryCountContainer/MaxStrawberryCount properties
Name Value

unique_name_in_owner

true

layout_mode

2

text

20

Table 16. $SideSelection/CenterBox/FailureIcon properties
Name Value

position

Vector2(327, 187.5)

scale

Vector2(0.392578, 0.392578)

texture

Skull
Figure 6. res://assets/images/ui/Skull.svg
Table 17. $SideSelection/CenterBox/MultiplicationStrawberry2 properties
Name Value

position

Vector2(383, 188.5)

scale

Vector2(0.145, 0.145)

texture

Multiplication
Figure 7. res://assets/images/ui/Multiplication.svg
Table 18. $SideSelection/CenterBox/FailureCount properties
Name Value

unique_name_in_owner

true

layout_mode

0

offset_left

413.0

offset_top

151.5

offset_right

541.0

offset_bottom

218.5

text

0

Table 19. $SideSelection/BottomBox properties
Name Value

z_index

2

layout_mode

3

anchor_left

1.0

anchor_top

0.713

anchor_right

1.0

anchor_bottom

0.713

offset_left

1199.0

offset_top

517.0

offset_right

1920.0

offset_bottom

753.0

grow_horizontal

0

theme

Table 20. $SideSelection/BottomBox/Label properties
Name Value

layout_mode

1

anchors_preset

-1

anchor_right

1.0

anchor_bottom

0.913

offset_bottom

-61.468

grow_horizontal

2

grow_vertical

2

theme_override_colors/font_color

Color(0.508731, 0.408952, 0.432275, 1)

theme_override_colors/font_outline_color

Color(0, 0, 0, 0)

text

Climb

horizontal_alignment

1

vertical_alignment

1

Table 21. $SideSelection/SideButtonContainer properties
Name Value

unique_name_in_owner

true

z_index

1

offset_left

1402.0

offset_top

648.0

offset_right

1739.0

offset_bottom

875.0

size_flags_horizontal

6

Table 22. $SideSelection/SideButtonContainer/ClimbBookmark properties
Name Value

layout_mode

2

Table 23. $SideSelection/SideButtonContainer/CassetteBookmark properties
Name Value

unique_name_in_owner

true

layout_mode

2

Table 24. $SideSelection/SideButtonContainer/CassetteBookmark/Bookmark/Sprite2D properties
Name Value

scale

Vector2(0.8, 0.8)

texture

Cassette
Figure 8. res://assets/images/ui/Chapters/menu/Cassette.svg
Table 25. $StageSelection/BottomBox properties
Name Value

z_index

2

layout_mode

3

anchor_left

1.0

anchor_top

0.713

anchor_right

1.0

anchor_bottom

0.713

offset_left

1199.0

offset_top

648.269

offset_right

1920.0

offset_bottom

791.269

grow_horizontal

0

theme

Table 26. $StageSelection/BottomBox/StageLabel properties
Name Value

unique_name_in_owner

true

layout_mode

1

anchors_preset

14

anchor_top

0.5

anchor_right

1.0

anchor_bottom

0.5

offset_top

-45.5

offset_bottom

33.5

grow_horizontal

2

grow_vertical

2

theme_override_colors/font_color

Color(0.508731, 0.408952, 0.432275, 1)

theme_override_colors/font_outline_color

Color(0, 0, 0, 0)

text

Get started

horizontal_alignment

1

Table 27. $StageSelection/Photos properties
Name Value

unique_name_in_owner

true

z_index

2

position

Vector2(1545, 451)

Table 28. $StageSelection/Photos/PhotoInstances properties
Name Value

unique_name_in_owner

true

Table 29. $StageSelection/StageButtonContainer properties
Name Value

unique_name_in_owner

true

z_index

1

offset_left

1293.0

offset_top

755.0

offset_right

1843.0

offset_bottom

951.0

size_flags_horizontal

4

alignment

1

Table 30. $StageSelection/StageButtonContainer/Stage1Button properties
Name Value

layout_mode

2

Table 31. $StageSelection/StageButtonContainer/Stage1Button/Bookmark properties
Name Value

texture

bookmark yellow
Figure 9. res://assets/images/ui/Chapters/menu/bookmark_yellow.png
Table 32. $StageSelection/StageButtonContainer/Stage1Button/Bookmark/Sprite2D properties
Name Value

scale

Vector2(0.7, 0.7)

texture

Star
Figure 10. res://assets/images/ui/Chapters/menu/Star.svg
Table 33. $StageSelection/StageButtonContainer/Stage2Button properties
Name Value

layout_mode

2

Table 34. $StageSelection/StageButtonContainer/Stage2Button/Bookmark properties
Name Value

texture

bookmark navy
Figure 11. res://assets/images/ui/Chapters/menu/bookmark_navy.png
Table 35. $StageSelection/StageButtonContainer/Stage2Button/Bookmark/Sprite2D properties
Name Value

scale

Vector2(0.7, 0.7)

texture

Mountain
Figure 12. res://assets/images/ui/Chapters/menu/Mountain.svg
Table 36. $StageSelection/StageButtonContainer/Stage3Button properties
Name Value

layout_mode

2

Table 37. $StageSelection/StageButtonContainer/Stage3Button/Bookmark properties
Name Value

texture

bookmark navy
Figure 13. res://assets/images/ui/Chapters/menu/bookmark_navy.png
Table 38. $StageSelection/StageButtonContainer/Stage3Button/Bookmark/Sprite2D properties
Name Value

scale

Vector2(0.7, 0.7)

texture

Mountain
Figure 14. res://assets/images/ui/Chapters/menu/Mountain.svg
Table 39. $StageSelection/StageButtonContainer/Stage4Button properties
Name Value

layout_mode

2

Table 40. $StageSelection/StageButtonContainer/Stage4Button/Bookmark properties
Name Value

texture

bookmark navy
Figure 15. res://assets/images/ui/Chapters/menu/bookmark_navy.png
Table 41. $StageSelection/StageButtonContainer/Stage4Button/Bookmark/Sprite2D properties
Name Value

scale

Vector2(0.7, 0.7)

texture

Mountain
Figure 16. res://assets/images/ui/Chapters/menu/Mountain.svg
Table 42. $StageSelection/StageButtonContainer/Stage5Button properties
Name Value

layout_mode

2

Table 43. $StageSelection/StageButtonContainer/Stage5Button/Bookmark properties
Name Value

texture

bookmark navy
Figure 17. res://assets/images/ui/Chapters/menu/bookmark_navy.png
Table 44. $StageSelection/StageButtonContainer/Stage5Button/Bookmark/Sprite2D properties
Name Value

scale

Vector2(0.7, 0.7)

texture

Mountain
Figure 18. res://assets/images/ui/Chapters/menu/Mountain.svg
Table 45. $ClosingCurtain properties
Name Value

unique_name_in_owner

true

layout_mode

1

offset_top

-1.0

offset_bottom

-1.0

Table 46. $AnimationPlayer properties
Name Value

unique_name_in_owner

true

libraries

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

menu.gd

extends Control

signal ui_backed
signal get_started(stage_number: int)

@export var grab_focus_first : bool = false : set = set_grab_focus_first
@export var grab_focus_side  : bool = false : set = set_grab_focus_side
@export var grab_focus_stage : bool = false : set = set_grab_focus_stage
@export var shown : bool = false
@export var chapter_resource : ChapterResource : set = load_chapter
enum State { UNSELECTED, SELECTED }
var state : State = State.UNSELECTED
var chapter_number : int
var stage_resources : Array[StageResource]


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())


func load_chapter(resource: ChapterResource) -> void:
	if not is_node_ready(): await ready
	chapter_number      = resource.number
	%ChapterNumber.text = 'Chapter %s' % resource.number
	%ChapterName.text   = resource.name
	%Banner.modulate    = resource.color
	%BlueHeartIcon.visible = false
	%MaxStrawberryCount.text = str(resource.strawberry_count())
	load_chapter_stages(resource)
	if Current.account: setup_from_account_resource()


func load_chapter_stages(resource: ChapterResource) -> void:
	clear_photos()
	clear_stage_buttons()
	stage_resources = []
	for i in resource.stages.size():
		var stage = resource.stages[i]
		add_photo(stage, i)
		add_stage_button(stage, i)
		stage_resources.push_back(stage)


func setup_from_account_resource() -> void:
	var chapter = Current.account.get_chapter(chapter_number)
	var stage_count = %StageButtonContainer.get_child_count() - 1
	var hidden_numbers = ArrayHelper.build(stage_count, false)
	if chapter:
		%CassetteBookmark.visible = chapter.obtained_cassette
		%BlueHeartIcon.visible    = chapter.obtained_blue_heart
		%ObtainedStrawberryCount.text = str(chapter.obtained_strawberry_count())
		%FailureCount.text = str(chapter.total_failure_count())
		for i in stage_count:
			hidden_numbers[i] = not chapter.has_stage(i+1)
	else:
		%CassetteBookmark.visible = false
	for i in stage_count:
		if hidden_numbers[i]:
			hide_stage_button_and_photo(i + 1)


func set_grab_focus_first(val) -> void:
	if val: %AnimationPlayer.play(&'show')


func set_grab_focus_side(val) -> void:
	FocusHelper.grab_first(%SideButtonContainer, val)


func set_grab_focus_stage(val) -> void:
	FocusHelper.grab_first(%StageButtonContainer, val)


func clear_photos() -> void:
	%Photos.get_node('Template').hide()
	for photo in %PhotoInstances.get_children():
		photo.queue_free()


func add_photo(resource: StageResource, idx: int) -> void:
	var photo = %Photos.get_node('Template/Photo').duplicate()
	photo.rotation = abs(photo.rotation) * (idx%2 * 2 - 1)
	photo.position += Vector2(8, -8) * idx
	photo.image = resource.photo
	photo.set_meta(&'number', idx + 1)
	%PhotoInstances.add_child(photo)
	%PhotoInstances.move_child(photo, 0)


func clear_stage_buttons() -> void:
	for button in %StageButtonContainer.get_children():
		button.hide()


func add_stage_button(resource: StageResource, idx: int) -> void:
	var stage = get_stage_button(idx)
	stage.set_meta(&'name', resource.name)
	stage.show()


func get_stage_button(idx: int) -> Node:
	return %StageButtonContainer.get_child(idx)


func hide_stage_button_and_photo(number: int) -> void:
	var button = %StageButtonContainer.get_child(number)
	if button: button.hide()
	for photo in %PhotoInstances.get_children():
		if photo.get_meta(&'number') == number:
			photo.hide()


func stages_count() -> int:
	return %StageButtonContainer.get_children().filter(func(c):
		return c.visible).size()


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')


func _on_climb_button_pressed() -> void:
	if stages_count() > 1:
		state = State.SELECTED
		%AnimationPlayer.play(&'climb_selected')
	else:
		get_started.emit(1)


func _on_stage_button_focus_entered(number: int) -> void:
	var photos = %PhotoInstances.get_children()
	var button = get_stage_button(number - 1)
	%StageLabel.text = str(button.get_meta(&'name'))
	for i in photos.size():
		var photo = photos.pop_back()
		if i+1 < number: photo.flick()
		else: photo.pull()


func _on_stage_button_pressed(stage_number: int) -> void:
	get_started.emit(stage_number)


func _on_ui_backed() -> void:
	if shown: %AnimationPlayer.play(&'hide')


func _on_get_started(stage_number: int) -> void:
	var stage = stage_resources.filter(func(r):
		return r.number == stage_number)
	if not (stage && stage[0].scene): return
	%ClosingCurtain.play(stage[0].scene)