osrs-tools 2.5.2 → 2.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runescape/model/diaries/Diary.d.ts.map +1 -1
- package/dist/runescape/model/diaries/Diary.js +0 -7
- package/dist/runescape/model/quest/QuestTool.d.ts +31 -2
- package/dist/runescape/model/quest/QuestTool.d.ts.map +1 -1
- package/dist/runescape/model/quest/QuestTool.js +377 -26
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Diary.d.ts","sourceRoot":"","sources":["../../../../source/runescape/model/diaries/Diary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,eAAe,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Diary.d.ts","sourceRoot":"","sources":["../../../../source/runescape/model/diaries/Diary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,eAAe,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAYlG,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;CACnB;AAiFD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAM9D;AAED,wBAAgB,aAAa,IAAI,KAAK,EAAE,CAEvC;AAGD,QAAA,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAWlC,CAAC;AAEF,eAAe,OAAO,CAAC;AAGvB,eAAO,MAAM,aAAa,OAA4B,CAAC;AACvD,eAAO,MAAM,WAAW,OAA0B,CAAC;AACnD,eAAO,MAAM,YAAY,OAA2B,CAAC;AACrD,eAAO,MAAM,cAAc,OAA6B,CAAC;AACzD,eAAO,MAAM,aAAa,OAA4B,CAAC;AACvD,eAAO,MAAM,YAAY,OAA2B,CAAC;AACrD,eAAO,MAAM,iBAAiB,OAAmC,CAAC;AAClE,eAAO,MAAM,qBAAqB,OAAuC,CAAC;AAC1E,eAAO,MAAM,cAAc,OAA6B,CAAC;AACzD,eAAO,MAAM,YAAY,OAA2B,CAAC;AACrD,eAAO,MAAM,qBAAqB,OAAqC,CAAC;AACxE,eAAO,MAAM,eAAe,OAA8B,CAAC"}
|
|
@@ -9,8 +9,6 @@ import { KourendKebosDiary as typedKourendKebosDiary } from "./kourend-kebos/Kou
|
|
|
9
9
|
import { LumbridgeDraynorDiary as typedLumbridgeDraynorDiary } from "./lumbridge-draynor/LumbridgeDraynor";
|
|
10
10
|
import { MorytaniaDiary as typedMorytaniaDiary } from "./morytania/Morytania";
|
|
11
11
|
import { WildernessDiary as typedWildernessDiary } from "./wilderness/Wilderness";
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
13
|
-
const diariesData = require("../../resources/diary/diaries.json");
|
|
14
12
|
function mapSkillReq(skillReq) {
|
|
15
13
|
// skillReq: { skill: string, level: number, boostable: boolean }
|
|
16
14
|
if (!skillReq || !skillReq.skill)
|
|
@@ -111,11 +109,6 @@ const diaries = {
|
|
|
111
109
|
"Morytania Diary": typedMorytaniaDiary,
|
|
112
110
|
"Wilderness Diary": typedWildernessDiary,
|
|
113
111
|
};
|
|
114
|
-
for (const k of Object.keys(diariesData)) {
|
|
115
|
-
if (!diaries[k]) {
|
|
116
|
-
diaries[k] = buildDiary(k, diariesData[k]);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
112
|
export default diaries;
|
|
120
113
|
// Named exports for convenient imports
|
|
121
114
|
export const ArdougneDiary = diaries["Ardougne Diary"];
|
|
@@ -28,12 +28,41 @@ declare class QuestTool {
|
|
|
28
28
|
static getAllQuests(): Quest[];
|
|
29
29
|
static getAllMiniQuests(): Quest[];
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* Build the quest registry mapping canonical names to quest objects.
|
|
32
|
+
* Uses QuestList as the source of truth for quest names.
|
|
33
|
+
* @returns Map of normalized quest names to Quest objects
|
|
34
|
+
*/
|
|
35
|
+
private static buildQuestRegistry;
|
|
36
|
+
/**
|
|
37
|
+
* Find the quest object matching a canonical quest name from QuestList.
|
|
38
|
+
* Uses the quest's name property to match against the canonical name.
|
|
39
|
+
* @param canonicalName The canonical name from QuestList
|
|
40
|
+
* @param questMap Map of available quest objects
|
|
41
|
+
* @returns The matching Quest object or undefined
|
|
42
|
+
*/
|
|
43
|
+
private static findQuestByCanonicalName;
|
|
44
|
+
/**
|
|
45
|
+
* Normalize a quest name for comparison purposes.
|
|
46
|
+
* Removes punctuation, extra spaces, and converts to lowercase.
|
|
47
|
+
* @param questName The quest name to normalize
|
|
48
|
+
* @returns Normalized quest name
|
|
49
|
+
*/
|
|
50
|
+
private static normalizeQuestName;
|
|
51
|
+
/**
|
|
52
|
+
* Calculate Levenshtein distance between two strings for fuzzy matching.
|
|
53
|
+
* @param str1 First string
|
|
54
|
+
* @param str2 Second string
|
|
55
|
+
* @returns Levenshtein distance
|
|
56
|
+
*/
|
|
57
|
+
private static levenshteinDistance;
|
|
58
|
+
/**
|
|
59
|
+
* Get a quest by name with support for fuzzy matching and common variations.
|
|
60
|
+
* Supports exact matches, case-insensitive matches, and approximate matches.
|
|
33
61
|
* @param questName The name of the quest to retrieve
|
|
34
62
|
* @returns Quest instance or undefined if not found
|
|
35
63
|
*/
|
|
36
64
|
static getQuestByName(questName: string): Quest | undefined;
|
|
65
|
+
private static questCache;
|
|
37
66
|
/**
|
|
38
67
|
* Get the maximum boost for a given skill, based on OSRS Wiki data.
|
|
39
68
|
* @param skillName The name of the skill (case-insensitive, e.g. 'Attack', 'Herblore')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuestTool.d.ts","sourceRoot":"","sources":["../../../../source/runescape/model/quest/QuestTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"QuestTool.d.ts","sourceRoot":"","sources":["../../../../source/runescape/model/quest/QuestTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AA+IhC;;;;;GAKG;AACH,cAAM,SAAS;IACb,OAAO,CAAC,WAAW,CAA0B;gBAEjC,OAAO,CAAC,EAAE,WAAW;IAIjC;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;IAQ1C;;;OAGG;IACH,cAAc,IAAI,WAAW,GAAG,SAAS;IAIzC;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,OAAO,GAAE,GAAG,CAAC,MAAM,CAAa,GAAG,OAAO;WAmCvE,YAAY,IAAI,KAAK,EAAE;WAIvB,gBAAgB,IAAI,KAAK,EAAE;IAIzC;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IA6JjC;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAUvC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAQjC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IA4BlC;;;;;OAKG;IACH,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAiC3D,OAAO,CAAC,MAAM,CAAC,UAAU,CAAiC;IAE1D;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CA2EnD;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -1,6 +1,145 @@
|
|
|
1
1
|
import { RequirementType } from "../Requirement";
|
|
2
2
|
import { QuestList } from "./QuestList";
|
|
3
|
+
// Import all quests for registry
|
|
3
4
|
import AKingdomDivided from "./all/AKingdomDivided";
|
|
5
|
+
import AnimalMagnetism from "./all/AnimalMagnetism";
|
|
6
|
+
import AnotherSliceOfHAM from "./all/AnotherSliceOfHAM";
|
|
7
|
+
import APorcineOfInterest from "./all/APorcineOfInterest";
|
|
8
|
+
import ASoulsBane from "./all/ASoulsBane";
|
|
9
|
+
import ATailOfTwoCats from "./all/ATailOfTwoCats";
|
|
10
|
+
import ATasteOfHope from "./all/ATasteOfHope";
|
|
11
|
+
import ATheatreOfBlood from "./all/ATheatreOfBlood";
|
|
12
|
+
import BelowIceMountain from "./all/BelowIceMountain";
|
|
13
|
+
import BetweenARock from "./all/BetweenARock";
|
|
14
|
+
import BigChompyBirdHunting from "./all/BigChompyBirdHunting";
|
|
15
|
+
import Biohazard from "./all/Biohazard";
|
|
16
|
+
import BlackKnightsFortress from "./all/BlackKnightsFortress";
|
|
17
|
+
import BoneVoyage from "./all/BoneVoyage";
|
|
18
|
+
import CabinFever from "./all/CabinFever";
|
|
19
|
+
import ClientOfKourend from "./all/ClientOfKourend";
|
|
20
|
+
import ClockTower from "./all/ClockTower";
|
|
21
|
+
import ColdWar from "./all/ColdWar";
|
|
22
|
+
import Contact from "./all/Contact";
|
|
23
|
+
import CooksAssistant from "./all/CooksAssistant";
|
|
24
|
+
import CreatureOfFenkenstrain from "./all/CreatureOfFenkenstrain";
|
|
25
|
+
import CurrentAffairs from "./all/CurrentAffairs";
|
|
26
|
+
import DarknessOfHallowvale from "./all/DarknessOfHallowvale";
|
|
27
|
+
import DeathPlateau from "./all/DeathPlateau";
|
|
28
|
+
import DeathToTheDorgeshuun from "./all/DeathToTheDorgeshuun";
|
|
29
|
+
import DemonSlayer from "./all/DemonSlayer";
|
|
30
|
+
import DesertTreasure from "./all/DesertTreasure";
|
|
31
|
+
import DeviousMinds from "./all/DeviousMinds";
|
|
32
|
+
import DoricQuest from "./all/DoricQuest";
|
|
33
|
+
import DoricsQuest from "./all/DoricsQuest";
|
|
34
|
+
import DragonSlayerI from "./all/DragonSlayerI";
|
|
35
|
+
import DragonSlayerII from "./all/DragonSlayerII";
|
|
36
|
+
import DreamMentor from "./all/DreamMentor";
|
|
37
|
+
import DruidicRitual from "./all/DruidicRitual";
|
|
38
|
+
import DwarfCannon from "./all/DwarfCannon";
|
|
39
|
+
import EadgarsRuse from "./all/EadgarsRuse";
|
|
40
|
+
import EaglesPeak from "./all/EaglesPeak";
|
|
41
|
+
import ElementalWorkshopI from "./all/ElementalWorkshopI";
|
|
42
|
+
import ElementalWorkshopII from "./all/ElementalWorkshopII";
|
|
43
|
+
import EnakhrasLament from "./all/EnakhrasLament";
|
|
44
|
+
import EnlightenedJourney from "./all/EnlightenedJourney";
|
|
45
|
+
import FairytaleIGrowingPains from "./all/FairytaleIGrowingPains";
|
|
46
|
+
import FairytaleIICureAQueen from "./all/FairytaleIICureAQueen";
|
|
47
|
+
import FamilyCrest from "./all/FamilyCrest";
|
|
48
|
+
import FightArena from "./all/FightArena";
|
|
49
|
+
import FishingContest from "./all/FishingContest";
|
|
50
|
+
import ForgettableTale from "./all/ForgettableTale";
|
|
51
|
+
import GardenOfTranquillity from "./all/GardenOfTranquillity";
|
|
52
|
+
import GertrudesCat from "./all/GertrudesCat";
|
|
53
|
+
import GettingAhead from "./all/GettingAhead";
|
|
54
|
+
import GhostsAhoy from "./all/GhostsAhoy";
|
|
55
|
+
import GoblinDiplomacy from "./all/GoblinDiplomacy";
|
|
56
|
+
import GrimTales from "./all/GrimTales";
|
|
57
|
+
import HauntedMine from "./all/HauntedMine";
|
|
58
|
+
import HazeelCult from "./all/HazeelCult";
|
|
59
|
+
import HeroesQuest from "./all/HeroesQuest";
|
|
60
|
+
import HolyGrail from "./all/HolyGrail";
|
|
61
|
+
import HorrorFromTheDeep from "./all/HorrorFromTheDeep";
|
|
62
|
+
import IcthlarinsLittleHelper from "./all/IcthlarinsLittleHelper";
|
|
63
|
+
import ImpCatcher from "./all/ImpCatcher";
|
|
64
|
+
import InAidOfTheMyreque from "./all/InAidOfTheMyreque";
|
|
65
|
+
import InSearchOfTheMyreque from "./all/InSearchOfTheMyreque";
|
|
66
|
+
import JunglePotion from "./all/JunglePotion";
|
|
67
|
+
import KingsRansom from "./all/KingsRansom";
|
|
68
|
+
import LegendsQuest from "./all/LegendsQuest";
|
|
69
|
+
import LostCity from "./all/LostCity";
|
|
70
|
+
import LunarDiplomacy from "./all/LunarDiplomacy";
|
|
71
|
+
import MakingHistory from "./all/MakingHistory";
|
|
72
|
+
import MeatAndGreet from "./all/MeatAndGreet";
|
|
73
|
+
import MerlinsCrystal from "./all/MerlinsCrystal";
|
|
74
|
+
import MonkeyMadness from "./all/MonkeyMadness";
|
|
75
|
+
import MonkeyMadnessII from "./all/MonkeyMadnessII";
|
|
76
|
+
import MonksFriend from "./all/MonksFriend";
|
|
77
|
+
import MurderMystery from "./all/MurderMystery";
|
|
78
|
+
import MyArmsBigAdventure from "./all/MyArmsBigAdventure";
|
|
79
|
+
import NatureSpirit from "./all/NatureSpirit";
|
|
80
|
+
import ObservatoryQuest from "./all/ObservatoryQuest";
|
|
81
|
+
import OlafsQuest from "./all/OlafsQuest";
|
|
82
|
+
import OneSmallFavour from "./all/OneSmallFavour";
|
|
83
|
+
import Pandemonium from "./all/Pandemonium";
|
|
84
|
+
import PlagueCity from "./all/PlagueCity";
|
|
85
|
+
import PriestInPeril from "./all/PriestInPeril";
|
|
86
|
+
import PryingTimes from "./all/PryingTimes";
|
|
87
|
+
import RagAndBoneMan from "./all/RagAndBoneMan";
|
|
88
|
+
import Ratcatchers from "./all/Ratcatchers";
|
|
89
|
+
import RecipeForDisaster from "./all/RecipeForDisaster";
|
|
90
|
+
import RecruitmentDrive from "./all/RecruitmentDrive";
|
|
91
|
+
import Regicide from "./all/Regicide";
|
|
92
|
+
import RovingElves from "./all/RovingElves";
|
|
93
|
+
import RoyalTrouble from "./all/RoyalTrouble";
|
|
94
|
+
import RumDeal from "./all/RumDeal";
|
|
95
|
+
import ScorpionCatcher from "./all/ScorpionCatcher";
|
|
96
|
+
import Scrambled from "./all/Scrambled";
|
|
97
|
+
import SeaSlug from "./all/SeaSlug";
|
|
98
|
+
import ShadesOfMortton from "./all/ShadesOfMortton";
|
|
99
|
+
import ShadowOfTheStorm from "./all/ShadowOfTheStorm";
|
|
100
|
+
import ShadowsOfCustodia from "./all/ShadowsOfCustodia";
|
|
101
|
+
import SheepHerder from "./all/SheepHerder";
|
|
102
|
+
import ShiloVillage from "./all/ShiloVillage";
|
|
103
|
+
import SlugMenace from "./all/SlugMenace";
|
|
104
|
+
import SongOfTheElves from "./all/SongOfTheElves";
|
|
105
|
+
import SpiritsOfTheElid from "./all/SpiritsOfTheElid";
|
|
106
|
+
import SwanSong from "./all/SwanSong";
|
|
107
|
+
import TaiBwoWannaiTrio from "./all/TaiBwoWannaiTrio";
|
|
108
|
+
import TheAscentOfArceuus from "./all/TheAscentOfArceuus";
|
|
109
|
+
import TheDepthsOfDespair from "./all/TheDepthsOfDespair";
|
|
110
|
+
import TheFinalDawn from "./all/TheFinalDawn";
|
|
111
|
+
import TheForsakenTower from "./all/TheForsakenTower";
|
|
112
|
+
import TheFremennikExiles from "./all/TheFremennikExiles";
|
|
113
|
+
import TheFremennikIsles from "./all/TheFremennikIsles";
|
|
114
|
+
import TheFremennikTrials from "./all/TheFremennikTrials";
|
|
115
|
+
import TheGiantDwarf from "./all/TheGiantDwarf";
|
|
116
|
+
import TheGolem from "./all/TheGolem";
|
|
117
|
+
import TheGrandTree from "./all/TheGrandTree";
|
|
118
|
+
import TheGreatBrainRobbery from "./all/TheGreatBrainRobbery";
|
|
119
|
+
import TheHandInTheSand from "./all/TheHandInTheSand";
|
|
120
|
+
import TheKnightsSword from "./all/TheKnightsSword";
|
|
121
|
+
import TheLostTribe from "./all/TheLostTribe";
|
|
122
|
+
import TheQueenOfThieves from "./all/TheQueenOfThieves";
|
|
123
|
+
import TheSlugMenace from "./all/TheSlugMenace";
|
|
124
|
+
import TheTaleOfTheRighteous from "./all/TheTaleOfTheRighteous";
|
|
125
|
+
import TheTempleOfIkov from "./all/TheTempleOfIkov";
|
|
126
|
+
import TheTouristTrap from "./all/TheTouristTrap";
|
|
127
|
+
import ThroneOfMiscellania from "./all/ThroneOfMiscellania";
|
|
128
|
+
import TowerOfLife from "./all/TowerOfLife";
|
|
129
|
+
import TreeGnomeVillage from "./all/TreeGnomeVillage";
|
|
130
|
+
import TribalTotem from "./all/TribalTotem";
|
|
131
|
+
import TrollRomance from "./all/TrollRomance";
|
|
132
|
+
import TrollStronghold from "./all/TrollStronghold";
|
|
133
|
+
import TroubledTortugans from "./all/TroubledTortugans";
|
|
134
|
+
import UndergroundPass from "./all/UndergroundPass";
|
|
135
|
+
import VampyreSlayer from "./all/VampyreSlayer";
|
|
136
|
+
import Wanted from "./all/Wanted";
|
|
137
|
+
import Watchtower from "./all/Watchtower";
|
|
138
|
+
import WaterfallQuest from "./all/WaterfallQuest";
|
|
139
|
+
import WhatLiesBelow from "./all/WhatLiesBelow";
|
|
140
|
+
import WitchesPotion from "./all/WitchesPotion";
|
|
141
|
+
import WitchsHouse from "./all/WitchsHouse";
|
|
142
|
+
import ZogreFleshEaters from "./all/ZogreFleshEaters";
|
|
4
143
|
/**
|
|
5
144
|
* OSRS Quest utility tool
|
|
6
145
|
*
|
|
@@ -81,41 +220,253 @@ class QuestTool {
|
|
|
81
220
|
return QuestList.map((name) => QuestTool.getQuestByName(name)).filter((q) => q !== undefined && q.miniquest);
|
|
82
221
|
}
|
|
83
222
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* @
|
|
87
|
-
* @returns Quest instance or undefined if not found
|
|
223
|
+
* Build the quest registry mapping canonical names to quest objects.
|
|
224
|
+
* Uses QuestList as the source of truth for quest names.
|
|
225
|
+
* @returns Map of normalized quest names to Quest objects
|
|
88
226
|
*/
|
|
89
|
-
static
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
227
|
+
static buildQuestRegistry() {
|
|
228
|
+
const registry = new Map();
|
|
229
|
+
// All available quests imported above
|
|
230
|
+
const allQuests = {
|
|
231
|
+
AKingdomDivided,
|
|
232
|
+
AnimalMagnetism,
|
|
233
|
+
AnotherSliceOfHAM,
|
|
234
|
+
APorcineOfInterest,
|
|
235
|
+
ASoulsBane,
|
|
236
|
+
ATailOfTwoCats,
|
|
237
|
+
ATasteOfHope,
|
|
238
|
+
ATheatreOfBlood,
|
|
239
|
+
BelowIceMountain,
|
|
240
|
+
BetweenARock,
|
|
241
|
+
BigChompyBirdHunting,
|
|
242
|
+
Biohazard,
|
|
243
|
+
BlackKnightsFortress,
|
|
244
|
+
BoneVoyage,
|
|
245
|
+
CabinFever,
|
|
246
|
+
ClientOfKourend,
|
|
247
|
+
ClockTower,
|
|
248
|
+
ColdWar,
|
|
249
|
+
Contact,
|
|
250
|
+
CooksAssistant,
|
|
251
|
+
CreatureOfFenkenstrain,
|
|
252
|
+
CurrentAffairs,
|
|
253
|
+
DarknessOfHallowvale,
|
|
254
|
+
DeathPlateau,
|
|
255
|
+
DeathToTheDorgeshuun,
|
|
256
|
+
DemonSlayer,
|
|
257
|
+
DesertTreasure,
|
|
258
|
+
DeviousMinds,
|
|
259
|
+
DoricQuest,
|
|
260
|
+
DoricsQuest,
|
|
261
|
+
DragonSlayerI,
|
|
262
|
+
DragonSlayerII,
|
|
263
|
+
DreamMentor,
|
|
264
|
+
DruidicRitual,
|
|
265
|
+
DwarfCannon,
|
|
266
|
+
EadgarsRuse,
|
|
267
|
+
EaglesPeak,
|
|
268
|
+
ElementalWorkshopI,
|
|
269
|
+
ElementalWorkshopII,
|
|
270
|
+
EnakhrasLament,
|
|
271
|
+
EnlightenedJourney,
|
|
272
|
+
FairytaleIGrowingPains,
|
|
273
|
+
FairytaleIICureAQueen,
|
|
274
|
+
FamilyCrest,
|
|
275
|
+
FightArena,
|
|
276
|
+
FishingContest,
|
|
277
|
+
ForgettableTale,
|
|
278
|
+
GardenOfTranquillity,
|
|
279
|
+
GertrudesCat,
|
|
280
|
+
GettingAhead,
|
|
281
|
+
GhostsAhoy,
|
|
282
|
+
GoblinDiplomacy,
|
|
283
|
+
GrimTales,
|
|
284
|
+
HauntedMine,
|
|
285
|
+
HazeelCult,
|
|
286
|
+
HeroesQuest,
|
|
287
|
+
HolyGrail,
|
|
288
|
+
HorrorFromTheDeep,
|
|
289
|
+
IcthlarinsLittleHelper,
|
|
290
|
+
ImpCatcher,
|
|
291
|
+
InAidOfTheMyreque,
|
|
292
|
+
InSearchOfTheMyreque,
|
|
293
|
+
JunglePotion,
|
|
294
|
+
KingsRansom,
|
|
295
|
+
LegendsQuest,
|
|
296
|
+
LostCity,
|
|
297
|
+
LunarDiplomacy,
|
|
298
|
+
MakingHistory,
|
|
299
|
+
MeatAndGreet,
|
|
300
|
+
MerlinsCrystal,
|
|
301
|
+
MonkeyMadness,
|
|
302
|
+
MonkeyMadnessII,
|
|
303
|
+
MonksFriend,
|
|
304
|
+
MurderMystery,
|
|
305
|
+
MyArmsBigAdventure,
|
|
306
|
+
NatureSpirit,
|
|
307
|
+
ObservatoryQuest,
|
|
308
|
+
OlafsQuest,
|
|
309
|
+
OneSmallFavour,
|
|
310
|
+
Pandemonium,
|
|
311
|
+
PlagueCity,
|
|
312
|
+
PriestInPeril,
|
|
313
|
+
PryingTimes,
|
|
314
|
+
RagAndBoneMan,
|
|
315
|
+
Ratcatchers,
|
|
316
|
+
RecipeForDisaster,
|
|
317
|
+
RecruitmentDrive,
|
|
318
|
+
Regicide,
|
|
319
|
+
RovingElves,
|
|
320
|
+
RoyalTrouble,
|
|
321
|
+
RumDeal,
|
|
322
|
+
ScorpionCatcher,
|
|
323
|
+
Scrambled,
|
|
324
|
+
SeaSlug,
|
|
325
|
+
ShadesOfMortton,
|
|
326
|
+
ShadowOfTheStorm,
|
|
327
|
+
ShadowsOfCustodia,
|
|
328
|
+
SheepHerder,
|
|
329
|
+
ShiloVillage,
|
|
330
|
+
SlugMenace,
|
|
331
|
+
SongOfTheElves,
|
|
332
|
+
SpiritsOfTheElid,
|
|
333
|
+
SwanSong,
|
|
334
|
+
TaiBwoWannaiTrio,
|
|
335
|
+
TheAscentOfArceuus,
|
|
336
|
+
TheDepthsOfDespair,
|
|
337
|
+
TheFinalDawn,
|
|
338
|
+
TheForsakenTower,
|
|
339
|
+
TheFremennikExiles,
|
|
340
|
+
TheFremennikIsles,
|
|
341
|
+
TheFremennikTrials,
|
|
342
|
+
TheGiantDwarf,
|
|
343
|
+
TheGolem,
|
|
344
|
+
TheGrandTree,
|
|
345
|
+
TheGreatBrainRobbery,
|
|
346
|
+
TheHandInTheSand,
|
|
347
|
+
TheKnightsSword,
|
|
348
|
+
TheLostTribe,
|
|
349
|
+
TheQueenOfThieves,
|
|
350
|
+
TheSlugMenace,
|
|
351
|
+
TheTaleOfTheRighteous,
|
|
352
|
+
TheTempleOfIkov,
|
|
353
|
+
TheTouristTrap,
|
|
354
|
+
ThroneOfMiscellania,
|
|
355
|
+
TowerOfLife,
|
|
356
|
+
TreeGnomeVillage,
|
|
357
|
+
TribalTotem,
|
|
358
|
+
TrollRomance,
|
|
359
|
+
TrollStronghold,
|
|
360
|
+
TroubledTortugans,
|
|
361
|
+
UndergroundPass,
|
|
362
|
+
VampyreSlayer,
|
|
363
|
+
Wanted,
|
|
364
|
+
Watchtower,
|
|
365
|
+
WaterfallQuest,
|
|
366
|
+
WhatLiesBelow,
|
|
367
|
+
WitchesPotion,
|
|
368
|
+
WitchsHouse,
|
|
369
|
+
ZogreFleshEaters,
|
|
370
|
+
};
|
|
371
|
+
// Map canonical quest names from QuestList to quest objects
|
|
372
|
+
for (const questName of QuestList) {
|
|
373
|
+
const quest = QuestTool.findQuestByCanonicalName(questName, allQuests);
|
|
103
374
|
if (quest) {
|
|
375
|
+
registry.set(QuestTool.normalizeQuestName(questName), quest);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return registry;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Find the quest object matching a canonical quest name from QuestList.
|
|
382
|
+
* Uses the quest's name property to match against the canonical name.
|
|
383
|
+
* @param canonicalName The canonical name from QuestList
|
|
384
|
+
* @param questMap Map of available quest objects
|
|
385
|
+
* @returns The matching Quest object or undefined
|
|
386
|
+
*/
|
|
387
|
+
static findQuestByCanonicalName(canonicalName, questMap) {
|
|
388
|
+
// Direct match by quest.name property
|
|
389
|
+
for (const quest of Object.values(questMap)) {
|
|
390
|
+
if (quest && typeof quest === "object" && "name" in quest && quest["name"] === canonicalName) {
|
|
104
391
|
return quest;
|
|
105
392
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
393
|
+
}
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Normalize a quest name for comparison purposes.
|
|
398
|
+
* Removes punctuation, extra spaces, and converts to lowercase.
|
|
399
|
+
* @param questName The quest name to normalize
|
|
400
|
+
* @returns Normalized quest name
|
|
401
|
+
*/
|
|
402
|
+
static normalizeQuestName(questName) {
|
|
403
|
+
return questName
|
|
404
|
+
.toLowerCase()
|
|
405
|
+
.replace(/[^\w\s]/g, "") // Remove punctuation (except word chars and spaces)
|
|
406
|
+
.replace(/\s+/g, " ") // Normalize spaces
|
|
407
|
+
.trim();
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Calculate Levenshtein distance between two strings for fuzzy matching.
|
|
411
|
+
* @param str1 First string
|
|
412
|
+
* @param str2 Second string
|
|
413
|
+
* @returns Levenshtein distance
|
|
414
|
+
*/
|
|
415
|
+
static levenshteinDistance(str1, str2) {
|
|
416
|
+
const matrix = [];
|
|
417
|
+
for (let i = 0; i <= str2.length; i++) {
|
|
418
|
+
matrix[i] = [i];
|
|
419
|
+
}
|
|
420
|
+
for (let j = 0; j <= str1.length; j++) {
|
|
421
|
+
matrix[0][j] = j;
|
|
422
|
+
}
|
|
423
|
+
for (let i = 1; i <= str2.length; i++) {
|
|
424
|
+
for (let j = 1; j <= str1.length; j++) {
|
|
425
|
+
if (str2.charAt(i - 1) === str1.charAt(j - 1)) {
|
|
426
|
+
matrix[i][j] = matrix[i - 1][j - 1];
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // Substitution
|
|
430
|
+
matrix[i][j - 1] + 1, // Insertion
|
|
431
|
+
matrix[i - 1][j] + 1);
|
|
432
|
+
}
|
|
113
433
|
}
|
|
114
434
|
}
|
|
115
|
-
|
|
435
|
+
return matrix[str2.length][str1.length];
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Get a quest by name with support for fuzzy matching and common variations.
|
|
439
|
+
* Supports exact matches, case-insensitive matches, and approximate matches.
|
|
440
|
+
* @param questName The name of the quest to retrieve
|
|
441
|
+
* @returns Quest instance or undefined if not found
|
|
442
|
+
*/
|
|
443
|
+
static getQuestByName(questName) {
|
|
444
|
+
if (!questName || questName.trim() === "") {
|
|
116
445
|
return undefined;
|
|
117
446
|
}
|
|
447
|
+
// Initialize cache on first use (lazy initialization)
|
|
448
|
+
if (!QuestTool.questCache) {
|
|
449
|
+
QuestTool.questCache = QuestTool.buildQuestRegistry();
|
|
450
|
+
}
|
|
451
|
+
const normalized = QuestTool.normalizeQuestName(questName);
|
|
452
|
+
// Try exact match first
|
|
453
|
+
if (QuestTool.questCache.has(normalized)) {
|
|
454
|
+
return QuestTool.questCache.get(normalized);
|
|
455
|
+
}
|
|
456
|
+
// Try fuzzy matching if exact match fails
|
|
457
|
+
let bestMatch;
|
|
458
|
+
let bestDistance = 5; // Threshold for fuzzy matching
|
|
459
|
+
for (const [registryKey, quest] of QuestTool.questCache.entries()) {
|
|
460
|
+
const distance = QuestTool.levenshteinDistance(normalized, registryKey);
|
|
461
|
+
if (distance < bestDistance) {
|
|
462
|
+
bestDistance = distance;
|
|
463
|
+
bestMatch = quest;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return bestMatch;
|
|
118
467
|
}
|
|
468
|
+
// Static cache for quest registry (initialized lazily)
|
|
469
|
+
static questCache;
|
|
119
470
|
/**
|
|
120
471
|
* Get the maximum boost for a given skill, based on OSRS Wiki data.
|
|
121
472
|
* @param skillName The name of the skill (case-insensitive, e.g. 'Attack', 'Herblore')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "osrs-tools",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.3",
|
|
4
4
|
"description": "A comprehensive TypeScript library for Old School RuneScape (OSRS) data and utilities, including quest data, skill requirements, and game item information",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"scripts": {
|