Files
step3/scripts/autoload/profile_service.gd
T

106 lines
3.0 KiB
GDScript

extends Node
signal profile_changed
const SAVE_PATH := "user://profile.json"
var profile: Dictionary = {
"xp": 0,
"level": 1,
"current_streak": 0,
"best_streak": 0,
"badges": [],
"completed_question_ids": [],
"system_stats": {},
"block_history": []
}
func _ready() -> void:
load_profile()
func load_profile() -> void:
if not FileAccess.file_exists(SAVE_PATH):
save_profile()
return
var file := FileAccess.open(SAVE_PATH, FileAccess.READ)
if file == null:
push_error("Unable to open profile save.")
return
var parsed = JSON.parse_string(file.get_as_text())
if typeof(parsed) == TYPE_DICTIONARY:
for key in profile.keys():
if parsed.has(key):
profile[key] = parsed[key]
profile_changed.emit()
func save_profile() -> void:
var file := FileAccess.open(SAVE_PATH, FileAccess.WRITE)
if file == null:
push_error("Unable to write profile save.")
return
file.store_string(JSON.stringify(profile, "\t"))
func get_profile() -> Dictionary:
return profile.duplicate(true)
func apply_block_results(results: Dictionary) -> void:
profile["xp"] = int(profile["xp"]) + int(results.get("xp_earned", 0))
profile["level"] = ProgressionService.level_for_xp(int(profile["xp"]))
profile["current_streak"] = int(results.get("ending_streak", profile["current_streak"]))
profile["best_streak"] = max(int(profile["best_streak"]), int(profile["current_streak"]))
var unlocked_badges: Array = results.get("badges_unlocked", [])
for badge in unlocked_badges:
if not profile["badges"].has(badge):
profile["badges"].append(badge)
var answers: Array = results.get("answers", [])
for answer in answers:
var question: Dictionary = answer.get("question", {})
var question_id := str(question.get("id", ""))
if question_id != "" and not profile["completed_question_ids"].has(question_id):
profile["completed_question_ids"].append(question_id)
var system_name := str(question.get("system", "General"))
if not profile["system_stats"].has(system_name):
profile["system_stats"][system_name] = {"seen": 0, "correct": 0}
profile["system_stats"][system_name]["seen"] = int(profile["system_stats"][system_name]["seen"]) + 1
if bool(answer.get("is_correct", false)):
profile["system_stats"][system_name]["correct"] = int(profile["system_stats"][system_name]["correct"]) + 1
var summary: Dictionary = {
"timestamp": Time.get_datetime_string_from_system(),
"mode": results.get("mode", "Tutor"),
"system": results.get("system", "All Systems"),
"correct": results.get("correct", 0),
"total": results.get("total", 0),
"xp_earned": results.get("xp_earned", 0)
}
profile["block_history"].push_front(summary)
if profile["block_history"].size() > 12:
profile["block_history"].resize(12)
save_profile()
profile_changed.emit()
func reset_profile() -> void:
profile = {
"xp": 0,
"level": 1,
"current_streak": 0,
"best_streak": 0,
"badges": [],
"completed_question_ids": [],
"system_stats": {},
"block_history": []
}
save_profile()
profile_changed.emit()