Files
step3/scripts/autoload/progression_service.gd
T

101 lines
3.2 KiB
GDScript

extends Node
const XP_PER_LEVEL := 500
var badge_catalog := {
"First Block": "Complete your first question block.",
"First Run": "Answer your first core mode question.",
"Hot Streak": "Answer 5 questions correctly in a row.",
"Tenacious": "Complete 10 total questions.",
"Sharp Shooter": "Score at least 80% on a block.",
"Clock Ready": "Complete a timed block."
}
func level_for_xp(xp: int) -> int:
return int(floor(float(xp) / float(XP_PER_LEVEL))) + 1
func xp_into_level(xp: int) -> int:
return xp % XP_PER_LEVEL
func calculate_block_rewards(answers: Array, mode: String, system_name: String) -> Dictionary:
var correct := 0
var longest_streak := 0
var running_streak := int(ProfileService.get_profile().get("current_streak", 0))
var ending_streak := running_streak
for answer in answers:
if bool(answer.get("is_correct", false)):
correct += 1
ending_streak += 1
longest_streak = max(longest_streak, ending_streak)
else:
ending_streak = 0
var total: int = max(answers.size(), 1)
var accuracy := float(correct) / float(total)
var xp := answers.size() * 25 + correct * 35 + longest_streak * 10
if accuracy >= 0.8:
xp += 100
if mode == "Timed":
xp += 50
var profile: Dictionary = ProfileService.get_profile()
var badges: Array[String] = []
_add_badge_if_needed(badges, profile, "First Block", true)
_add_badge_if_needed(badges, profile, "Hot Streak", longest_streak >= 5)
_add_badge_if_needed(badges, profile, "Tenacious", profile.get("completed_question_ids", []).size() + answers.size() >= 10)
_add_badge_if_needed(badges, profile, "Sharp Shooter", accuracy >= 0.8)
_add_badge_if_needed(badges, profile, "Clock Ready", mode == "Timed")
return {
"mode": mode,
"system": system_name,
"correct": correct,
"total": answers.size(),
"accuracy": accuracy,
"xp_earned": xp,
"ending_streak": ending_streak,
"longest_streak": longest_streak,
"badges_unlocked": badges,
"answers": answers
}
func calculate_question_rewards(answer: Dictionary, elapsed_seconds: float, target_seconds: float, score_delta: int) -> Dictionary:
var is_correct := bool(answer.get("is_correct", false))
var profile: Dictionary = ProfileService.get_profile()
var ending_streak := int(profile.get("current_streak", 0)) + 1 if is_correct else 0
var xp := 20
if is_correct:
xp += 35
if elapsed_seconds <= target_seconds:
xp += 10
elif elapsed_seconds > target_seconds * 1.5:
xp = max(10, xp - 10)
var badges: Array[String] = []
_add_badge_if_needed(badges, profile, "First Run", true)
_add_badge_if_needed(badges, profile, "Hot Streak", ending_streak >= 5)
_add_badge_if_needed(badges, profile, "Tenacious", profile.get("completed_question_ids", []).size() + 1 >= 10)
return {
"mode": "Core",
"system": str(answer.get("question", {}).get("system", "All Systems")),
"correct": 1 if is_correct else 0,
"total": 1,
"accuracy": 1.0 if is_correct else 0.0,
"xp_earned": xp,
"score_delta": score_delta,
"ending_streak": ending_streak,
"longest_streak": ending_streak,
"badges_unlocked": badges,
"answers": [answer]
}
func _add_badge_if_needed(badges: Array[String], profile: Dictionary, badge_name: String, condition: bool) -> void:
if condition and not profile.get("badges", []).has(badge_name):
badges.append(badge_name)