hero-mark-2/menus/scoreboards_scholar.gd

113 lines
3.1 KiB
GDScript

extends Node
const PAGE_SIZE: int = 8
var loaded_scores: Dictionary = {}
var selected_level: int = 0
var _page: int = 0
onready var scores: VBoxContainer = $"%Scores"
onready var level_title: Button = $"%LevelTitle"
func _ready() -> void:
yield(_refresh_scores(), "completed")
Fade.fade_in(Options.transition_speed_secs)
func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_right"):
selected_level = posmod(selected_level + 1, LevelData.levels.size())
while not LevelData.levels[selected_level].has_scoreboard:
selected_level = posmod(selected_level + 1, LevelData.levels.size())
_refresh_scores()
elif event.is_action_pressed("ui_left"):
selected_level = posmod(selected_level - 1, LevelData.levels.size())
while not LevelData.levels[selected_level].has_scoreboard:
selected_level = posmod(selected_level - 1, LevelData.levels.size())
_refresh_scores()
elif event.is_action_pressed("ui_down"):
_page += 1
_refresh_scores()
elif event.is_action_pressed("ui_up"):
_page = int(max(_page - 1, 0))
_refresh_scores()
elif event.is_action_pressed("ui_cancel"):
Fade.fade_out(Options.transition_speed_secs)
yield(Fade, "fade_finished")
SceneManager.current_scene = preload("res://menus/main_menu.tscn").instance()
func _refresh_scores() -> void:
level_title.text = LevelData.levels[selected_level].title
var level = LevelData.levels[selected_level].save_id
if not level in loaded_scores:
yield(_load_scores(level), "completed")
if ScoreBoard.errored:
push_error("Scoreboard could not be loaded.")
var entries = loaded_scores.get(level, {})
while _page * PAGE_SIZE > entries.size():
_page -= 1
var offset = _page * PAGE_SIZE
$"%PrevScores".visible = _page > 0
$"%NextScores".visible = entries.size() - offset > PAGE_SIZE
for i in 8:
var entry_node = scores.get_node("ScoreEntry%d" % i)
if i >= entries.size() - offset:
entry_node.visible = false
else:
var player = entries.keys()[offset + i]
var entry = entries[player]
entry_node.visible = true
entry_node.place = offset + i + 1
entry_node.player = player
entry_node.score = entry.score
entry_node.time = float(entry.time) * 0.001 # convert from ms
entry_node.difficulty = entry.difficulty
func _load_scores(level: String) -> void:
loaded_scores[level] = {}
if ScoreBoard.server_host.empty():
yield(get_tree(), "idle_frame")
return
var result: Dictionary = yield(ScoreBoard.get_scores(level), "completed")
if ScoreBoard.errored:
#TODO: failure indication
return
var players = result.keys().duplicate()
_sorting_dict = result
players.sort_custom(self, "_sort_scores")
for p in players:
loaded_scores[level][p] = result[p]
var _sorting_dict: Dictionary = {}
func _sort_scores(a, b) -> bool:
var score_a = _sorting_dict[a]
var score_b = _sorting_dict[b]
if score_b.score < score_a.score:
return true
elif score_b.score == score_a.score:
if score_b.difficulty < score_a.difficulty:
return true
elif score_b.difficulty == score_a.difficulty:
if score_b.time > score_a.time:
return true
return false