aboutsummaryrefslogtreecommitdiff
path: root/game/src/CreditsMenu/CreditsMenu.gd
blob: 52c1711df8ad5e2019590bbf4509fdc6c6c7ec53 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
extends Control

signal back_button_pressed

###############
# Credits CSV format
# The project title row is the only requirement within the csv file, however
# it can be on any row, so long as it exists.
# ----------------------
# title,project-title
# role-name,person-name
# role-name,person-name
# role-name,person-name
# ...
###############

@export_file("*.csv")
var core_credits_path : String

@export_group("Label Variants", "label_variants_")
@export
var label_variants_project : StringName

@export
var label_variants_role : StringName

@export
var label_variants_person : StringName

@export
var credits_list: VBoxContainer

const title_key : String = "TITLE"

# REQUIREMENTS:
# * 1.5 Credits Menu
# * SS-17

# REQUIREMENTS
# * FS-4
func _load_credit_file(path : String) -> Dictionary:
   var roles := {}
   var core_credits = FileAccess.open(path, FileAccess.READ)
   if core_credits == null:
      push_error("Failed to open credits file %s (error code %d)" % [path, FileAccess.get_open_error()])
      return roles

   while not core_credits.eof_reached():
      var line := core_credits.get_csv_line()
      var role := line[0].strip_edges().to_upper()

      # If the line does not have an identifiable role or is empty then skip it
      if role.is_empty() or line.size() < 2:
         if not (role.is_empty() and line.size() < 2):
            push_warning("Incorrectly formatted credit line %s in %s" % [line, path])
         continue

      var person := line[1].strip_edges()

      if person.is_empty():
         push_warning("Incorrectly formatted credit line %s in %s" % [line, path])
         continue
      if line.size() > 2:
         push_warning("Extra entries ignored in credit line %s in %s" % [line, path])

      if role not in roles:
         roles[role] = [person]
      else:
         if person in roles[role]:
            push_warning("Duplicate person %s for role %s in %s" % [person, role, path])
         else:
            roles[role].push_back(person)
   if title_key in roles:
      if roles[title_key].size() > 1:
         push_warning("More than one %s: %s in %s" % [title_key, roles[title_key], path])
         roles[title_key] = [roles[title_key][0]]
   else:
      push_warning("Credits file %s missing %s" % [path, title_key])
   for role_list in roles.values():
      role_list.sort_custom(func(a : String, b : String) -> bool: return a.naturalnocasecmp_to(b) < 0)
   return roles

func _add_label(node : Node, text : String, type_variation : StringName) -> void:
   var label := Label.new()
   label.name = 'Label' + text
   label.text = text
   label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
   label.theme_type_variation = type_variation
   node.add_child(label)

# REQUIREMENTS:
# * UI-34, UI-35
func _add_project_credits(project : Dictionary) -> void:
   var project_credits_list = VBoxContainer.new()
   project_credits_list.name = 'Credits'
   if title_key in project:
      var title : String = project[title_key][0]
      project_credits_list.name += title
      _add_label(project_credits_list, title, label_variants_project)
      project_credits_list.add_child(HSeparator.new())

   for role in project:
      if role == title_key:
         continue

      var role_parent = VBoxContainer.new()

      for person in project[role]:
         _add_label(role_parent, person, label_variants_person)

      _add_label(project_credits_list, role, label_variants_role)
      project_credits_list.add_child(role_parent)
      project_credits_list.add_child(HSeparator.new())

   credits_list.add_child(project_credits_list)

# REQUIREMENTS:
# * SS-17
func _ready():
   _add_project_credits(_load_credit_file(core_credits_path))

# REQUIREMENTS:
# * UI-38
# * UIFUN-37
func _on_back_button_pressed() -> void:
   back_button_pressed.emit()