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
JavaScript
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,
};
}