UNPKG

osrs-tools

Version:

A comprehensive TypeScript library for Old School RuneScape (OSRS) data and utilities, including quest data, skill requirements, and game item information

81 lines (80 loc) 4.69 kB
import { COMBAT_ACHIEVEMENT_TIERS, CombatAchievementTier, } from "./CombatAchievement.model"; const COMBAT_ACHIEVEMENTS_SOURCE = "https://oldschool.runescape.wiki/w/Combat_Achievements"; const task = (id, name, tier, activity, description, requirements) => ({ id, name, tier, activity, description, wikiUrl: COMBAT_ACHIEVEMENTS_SOURCE, requirements, }); export const COMBAT_ACHIEVEMENTS_DATASET = { seasonLabel: "OSRS Permanent", source: COMBAT_ACHIEVEMENTS_SOURCE, tasks: [ task("ca-easy-barrows-brothers", "Barrows Novice", CombatAchievementTier.Easy, "Barrows", "Defeat all six Barrows brothers at least once."), task("ca-easy-zulrah-kill", "Snaketamer", CombatAchievementTier.Easy, "Zulrah", "Defeat Zulrah once."), task("ca-medium-vorkath-5", "Dragon Hunter", CombatAchievementTier.Medium, "Vorkath", "Defeat Vorkath 5 times."), task("ca-medium-gauntlet-complete", "Crystalline Combat", CombatAchievementTier.Medium, "The Gauntlet", "Complete the Gauntlet once."), task("ca-hard-cg-complete", "Corrupted Challenger", CombatAchievementTier.Hard, "The Corrupted Gauntlet", "Complete the Corrupted Gauntlet once."), task("ca-hard-zulrah-50", "Zulrah Veteran", CombatAchievementTier.Hard, "Zulrah", "Defeat Zulrah 50 times."), task("ca-elite-cox-complete", "Xeric's Recruit", CombatAchievementTier.Elite, "Chambers of Xeric", "Complete a Chambers of Xeric raid.", ["Xeric's Talisman or team access"]), task("ca-elite-tob-complete", "Theatre Initiate", CombatAchievementTier.Elite, "Theatre of Blood", "Complete a Theatre of Blood raid."), task("ca-master-toa-expert", "Expert Invader", CombatAchievementTier.Master, "Tombs of Amascut", "Complete an Expert mode Tombs of Amascut raid.", ["Configured invocation level for Expert mode"]), task("ca-master-inferno-complete", "Infernal Conqueror", CombatAchievementTier.Master, "The Inferno", "Complete the Inferno."), task("ca-gm-colosseum-sol", "Sunfire Victor", CombatAchievementTier.Grandmaster, "Fortis Colosseum", "Defeat Sol Heredit in the Fortis Colosseum."), task("ca-gm-speedrun-toa", "Desert Blitz", CombatAchievementTier.Grandmaster, "Tombs of Amascut", "Complete Tombs of Amascut under a strict speed target.", ["High-end gear and optimized raid route"]), ], }; function normalizeIdSet(taskIds) { return new Set(taskIds.map((taskId) => taskId.trim().toLowerCase())); } function percent(completed, total) { if (total === 0) return 0; return Number(((completed / total) * 100).toFixed(2)); } export function getAllCombatAchievementTasks(dataset = COMBAT_ACHIEVEMENTS_DATASET) { return [...dataset.tasks]; } export function getCombatAchievementTaskById(taskId, dataset = COMBAT_ACHIEVEMENTS_DATASET) { const normalizedTaskId = taskId.trim().toLowerCase(); return dataset.tasks.find((combatTask) => combatTask.id.toLowerCase() === normalizedTaskId); } export function getCombatAchievementTasksByTier(tier, dataset = COMBAT_ACHIEVEMENTS_DATASET) { return dataset.tasks.filter((combatTask) => combatTask.tier === tier); } export function getMissingCombatAchievementTasks(completedTaskIds, dataset = COMBAT_ACHIEVEMENTS_DATASET) { const completedIds = normalizeIdSet(completedTaskIds); return dataset.tasks.filter((combatTask) => !completedIds.has(combatTask.id.toLowerCase())); } export function calculateCombatAchievementProgress(completedTaskIds, dataset = COMBAT_ACHIEVEMENTS_DATASET) { const completedIds = normalizeIdSet(completedTaskIds); const byTier = COMBAT_ACHIEVEMENT_TIERS.map((tier) => { const tierTasks = getCombatAchievementTasksByTier(tier, dataset); const completed = tierTasks.filter((combatTask) => completedIds.has(combatTask.id.toLowerCase())).length; const missingTaskIds = tierTasks .filter((combatTask) => !completedIds.has(combatTask.id.toLowerCase())) .map((combatTask) => combatTask.id); return { tier, total: tierTasks.length, completed, completionPercent: percent(completed, tierTasks.length), missingTaskIds, }; }); const total = dataset.tasks.length; const completed = dataset.tasks.filter((combatTask) => completedIds.has(combatTask.id.toLowerCase())).length; const missingTaskIds = dataset.tasks .filter((combatTask) => !completedIds.has(combatTask.id.toLowerCase())) .map((combatTask) => combatTask.id); return { total, completed, completionPercent: percent(completed, total), byTier, missingTaskIds, }; }