achievements
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
use rusqlite::Connection;
|
||||
use crate::db;
|
||||
|
||||
pub fn check_achievements(db: &Connection, token: &str) -> Vec<String> {
|
||||
let mut newly_unlocked = Vec::new();
|
||||
let total = db::get_solve_count(db, token);
|
||||
let (streak_current, streak_best, _) = db::get_streak(db, token);
|
||||
let no_hint = db::get_no_hint_count(db, token);
|
||||
|
||||
let best = streak_current.max(streak_best);
|
||||
|
||||
for (count, id) in [(1, "first_solve"), (10, "solver_10"), (25, "solver_25"),
|
||||
(50, "solver_50"), (100, "centurion"), (250, "dedicated"),
|
||||
(500, "obsessed"), (1000, "grandmaster")] {
|
||||
if total >= count && db::unlock_achievement(db, token, id) {
|
||||
newly_unlocked.push(id.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
for (count, id) in [(3, "streak_3"), (7, "streak_7"), (14, "streak_14"),
|
||||
(30, "streak_30"), (60, "streak_60"), (100, "streak_100"),
|
||||
(365, "streak_365")] {
|
||||
if best >= count && db::unlock_achievement(db, token, id) {
|
||||
newly_unlocked.push(id.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
for (count, id) in [(1, "purist"), (10, "purist_10"), (50, "purist_50")] {
|
||||
if no_hint >= count && db::unlock_achievement(db, token, id) {
|
||||
newly_unlocked.push(id.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
for (preset, id) in [("glyph", "glyph_first"), ("rune", "rune_first"),
|
||||
("scroll", "scroll_first"), ("codex", "codex_first"),
|
||||
("grimoire", "grimoire_first")] {
|
||||
if db::get_solve_count_by_preset(db, token, preset) >= 1 {
|
||||
if db::unlock_achievement(db, token, id) { newly_unlocked.push(id.to_string()); }
|
||||
}
|
||||
}
|
||||
|
||||
let gly = db::get_solve_count_by_preset(db, token, "glyph");
|
||||
let run = db::get_solve_count_by_preset(db, token, "rune");
|
||||
let scr = db::get_solve_count_by_preset(db, token, "scroll");
|
||||
let cod = db::get_solve_count_by_preset(db, token, "codex");
|
||||
let gri = db::get_solve_count_by_preset(db, token, "grimoire");
|
||||
if gly >= 1 && run >= 1 && scr >= 1 && cod >= 1 && gri >= 1 {
|
||||
if db::unlock_achievement(db, token, "explorer") { newly_unlocked.push("explorer".to_string()); }
|
||||
}
|
||||
if gly >= 10 && run >= 10 && scr >= 10 && cod >= 10 && gri >= 10 {
|
||||
if db::unlock_achievement(db, token, "true_master") { newly_unlocked.push("true_master".to_string()); }
|
||||
}
|
||||
|
||||
if let Some(t) = db::get_fastest_solve(db, token, "glyph") {
|
||||
if t <= 30 { if db::unlock_achievement(db, token, "speed_glyph") { newly_unlocked.push("speed_glyph".to_string()); } }
|
||||
}
|
||||
if let Some(t) = db::get_fastest_solve(db, token, "rune") {
|
||||
if t <= 60 { if db::unlock_achievement(db, token, "speed_rune") { newly_unlocked.push("speed_rune".to_string()); } }
|
||||
if t <= 30 { if db::unlock_achievement(db, token, "lightning_rune") { newly_unlocked.push("lightning_rune".to_string()); } }
|
||||
}
|
||||
if let Some(t) = db::get_fastest_solve(db, token, "scroll") {
|
||||
if t <= 180 { if db::unlock_achievement(db, token, "speed_scroll") { newly_unlocked.push("speed_scroll".to_string()); } }
|
||||
}
|
||||
if let Some(t) = db::get_fastest_solve(db, token, "codex") {
|
||||
if t <= 600 { if db::unlock_achievement(db, token, "speed_codex") { newly_unlocked.push("speed_codex".to_string()); } }
|
||||
}
|
||||
|
||||
newly_unlocked
|
||||
}
|
||||
|
||||
/// (id, name, description, icon, color1, color2)
|
||||
/// Each achievement has a UNIQUE filled icon.
|
||||
pub fn all_achievements() -> Vec<(&'static str, &'static str, &'static str, &'static str, &'static str, &'static str)> {
|
||||
vec![
|
||||
// milestones - progression through puzzle counts
|
||||
("first_solve", "First Steps", "Complete your first puzzle", "puzzle-filled", "#4ade80", "#22c55e"),
|
||||
("solver_10", "Getting Started", "Complete 10 puzzles", "star-filled", "#60a5fa", "#3b82f6"),
|
||||
("solver_25", "Quarter Century", "Complete 25 puzzles", "badge-filled", "#a78bfa", "#8b5cf6"),
|
||||
("solver_50", "Half Century", "Complete 50 puzzles", "award-filled", "#f472b6", "#ec4899"),
|
||||
("centurion", "Centurion", "Complete 100 puzzles", "trophy-filled", "#fbbf24", "#f59e0b"),
|
||||
("dedicated", "Dedicated", "Complete 250 puzzles", "diamond-filled", "#fb923c", "#f97316"),
|
||||
("obsessed", "Obsessed", "Complete 500 puzzles", "heart-filled", "#f87171", "#ef4444"),
|
||||
("grandmaster", "Grandmaster", "Complete 1000 puzzles", "crown-filled", "#e879f9", "#d946ef"),
|
||||
|
||||
// streaks - consecutive days
|
||||
("streak_3", "Hat Trick", "3-day streak", "flame-filled", "#4ade80", "#22c55e"),
|
||||
("streak_7", "Full Week", "7-day streak", "sunrise-filled", "#60a5fa", "#3b82f6"),
|
||||
("streak_14", "Fortnight", "14-day streak", "calendar-filled", "#a78bfa", "#8b5cf6"),
|
||||
("streak_30", "Monthly", "30-day streak", "moon-filled", "#fbbf24", "#f59e0b"),
|
||||
("streak_60", "Iron Will", "60-day streak", "shield-filled", "#fb923c", "#f97316"),
|
||||
("streak_100", "Unstoppable", "100-day streak", "meteor-filled", "#f87171", "#ef4444"),
|
||||
("streak_365", "Year Strong", "365-day streak", "globe-filled", "#e879f9", "#d946ef"),
|
||||
|
||||
// purist - no hints
|
||||
("purist", "Purist", "Solve without hints", "shield-check-filled", "#4ade80", "#22c55e"),
|
||||
("purist_10", "True Purist", "10 solves without hints", "eye-filled", "#60a5fa", "#3b82f6"),
|
||||
("purist_50", "Unassisted", "50 solves without hints", "atom-filled", "#fbbf24", "#f59e0b"),
|
||||
|
||||
// presets - difficulty levels
|
||||
("glyph_first", "First Glyph", "Complete a Glyph puzzle", "circle-filled", "#d9f99d", "#bef264"),
|
||||
("rune_first", "Rune Reader", "Complete a Rune puzzle", "circle-filled", "#86efac", "#4ade80"),
|
||||
("scroll_first", "Scroll Keeper", "Complete a Scroll puzzle", "square-filled", "#93c5fd", "#60a5fa"),
|
||||
("codex_first", "Codex Breaker", "Complete a Codex puzzle", "hexagon-filled", "#c4b5fd", "#a78bfa"),
|
||||
("grimoire_first", "Grimoire Master", "Complete a Grimoire puzzle", "octagon-filled", "#fde68a", "#fbbf24"),
|
||||
("explorer", "Explorer", "One of each difficulty", "compass-filled", "#f0abfc", "#e879f9"),
|
||||
("true_master", "True Master", "10 of each difficulty", "rosette-filled", "#fbbf24", "#f59e0b"),
|
||||
|
||||
// speed - fast solves
|
||||
("speed_glyph", "Quick Sketch", "Glyph under 30s", "bolt-filled", "#d9f99d", "#bef264"),
|
||||
("speed_rune", "Speed Demon", "Rune under 60s", "bolt-filled", "#fbbf24", "#f59e0b"),
|
||||
("lightning_rune", "Lightning", "Rune under 30s", "sparkles-filled", "#f87171", "#ef4444"),
|
||||
("speed_scroll", "Quick Thinker", "Scroll under 3 min", "clock-filled", "#fb923c", "#f97316"),
|
||||
("speed_codex", "Sharp Mind", "Codex under 10 min", "bulb-filled", "#a78bfa", "#8b5cf6"),
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user