Catalog RoM leveling gear package milestones
This commit is contained in:
1 parent
189b94d6b7
commit
d3cc27a54a
7 files changed
+134
-24
No files matched your search
@@ -3764,3 +3764,17 @@ Vite's existing large-chunk advisory remains informational.
|
|||||||
assignments, including Durnik as a dwarf, are covered by
|
assignments, including Durnik as a dwarf, are covered by
|
||||||
`src/game/romFiveValidation.test.ts`; this level-1 scene does not exercise
|
`src/game/romFiveValidation.test.ts`; this level-1 scene does not exercise
|
||||||
the level-10 secondary-class unlock or elite-skill mechanics.
|
the level-10 secondary-class unlock or elite-skill mechanics.
|
||||||
|
|
||||||
|
## RoM leveling loot and package catalog (2026-09-23)
|
||||||
|
|
||||||
|
- Rebuilt the client and reran `node scripts/playtest-rom-five.cjs` after the
|
||||||
|
leveling boss-loot rule and source package catalog changes. The live Rogue
|
||||||
|
roster preview showed the complete body and starter blade silhouette;
|
||||||
|
the in-dungeon scene showed the player and companion bodies with weapon,
|
||||||
|
shield, and staff silhouettes. No browser page errors occurred. Evidence:
|
||||||
|
`artifacts/playtest/rom-five/roster-preview.png` and
|
||||||
|
`artifacts/playtest/rom-five/dungeon-rogue.png`.
|
||||||
|
- This level-1 scene checks rendering. Focused boss-card, SQL loot, RuneWaker
|
||||||
|
loot, and RoM class tests check that leveling boss item drops are empty,
|
||||||
|
cards remain granted, and secondary stat growth uses the primary level.
|
||||||
|
Source package contents are cataloged as unverified and were not granted.
|
||||||
@@ -4,7 +4,7 @@ Status: **Needs Testing**. This is a targeted diagnostic for Priest healer, Knig
|
|||||||
|
|
||||||
## Cohort and rules
|
## Cohort and rules
|
||||||
|
|
||||||
The five named builds and live NPCs use these race-legal pairings. Their secondary classes activate at level 10. RoM has no talent allocation; ordinary skills unlock by level, and the generated source's internal level variants do not create a player-facing spell-rank choice.
|
The five named builds and live NPCs use these race-legal pairings. Their secondary classes activate at level 10 and always share their primary class's level. RoM has no talent allocation; ordinary skills unlock by level, and the generated source's internal level variants do not create a player-facing spell-rank choice.
|
||||||
|
|
||||||
| Role | Class pair | NPC name | Race |
|
| Role | Class pair | NPC name | Race |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
@@ -55,4 +55,4 @@ After the mechanics corrections, the targeted Shadoj run at level 60 with the sa
|
|||||||
|
|
||||||
The RoM source catalog and generated data remain authoritative for ability descriptions and components. The recorded combat results cover primary-only builds; rerun targeted diagnostics before drawing conclusions about the new pairings. Elite skill validation is deferred.
|
The RoM source catalog and generated data remain authoritative for ability descriptions and components. The recorded combat results cover primary-only builds; rerun targeted diagnostics before drawing conclusions about the new pairings. Elite skill validation is deferred.
|
||||||
|
|
||||||
RoM stat and equipment fidelity is a separate prerequisite for balance certification. `docs/ROM_STATS_AND_GEARING.md` records the source conversion coefficients, current WoW-shaped gear adapter, native item import gaps, and the players-only RoM online group boundary.
|
RoM stat and equipment fidelity is a separate prerequisite for balance certification. `docs/ROM_STATS_AND_GEARING.md` records the source conversion coefficients, current WoW-shaped gear adapter, native item import gaps, and the players-only RoM online group boundary. Leveling bosses award cards but no items. `docs/ROM_LEVELING_GEAR_PACKAGES.md` records the source-confirmed level-50/55/60/65 four-choice quest packages, a level-5 three-choice quest, and an optional level-30 battlefield family; the actual package contents and native equip stats still need decoding before these become playable gear.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# RoM leveling gear package catalog
|
||||||
|
|
||||||
|
Status: **quest choices verified; package contents and equipment stats unverified**. This is source evidence for a RoM leveling route, not a runtime gear grant. The generated inventory is `src/game/generated/romLevelingGearPackages.json`, owned by `scripts/runewaker-pipeline/export-leveling-gear-packages.mjs`. Refresh it with `node scripts/runewaker-pipeline/export-leveling-gear-packages.mjs` against the sibling RuneWaker client snapshot, or set `RUNEWAKER_ROOT` to another snapshot.
|
||||||
|
|
||||||
|
## Confirmed quest milestones
|
||||||
|
|
||||||
|
The client `Resource/data/questdetailobject.db` links each quest to the armor-category reward packages in the order below. `itemobject.db` confirms that the later parent packages and their similarly named weapons and armor subpackages exist. The client strings describe each later parent choice as giving one weapons package and one armor package; their exact item links have not been decoded. The inner package expansion into individual items is also unverified, so the seven-piece suits listed for levels 50–65 are **matching source sets**, not proven package contents. Their member IDs and required levels are recorded in the generated JSON from `suitobject.db` and `armorobject.db`.
|
||||||
|
|
||||||
|
| Quest level and name | Quest ID | Plate package | Chain package | Leather package | Cloth package |
|
||||||
|
| --- | ---: | ---: | ---: | ---: | ---: |
|
||||||
|
| 5 Equip Yourself | 423783 | — | 209025 | 209024 | 209015 |
|
||||||
|
| 30 Key to Victory | 423771 | 208802* | 208803 | 208804 | 208805 |
|
||||||
|
| 50 Appropriate Support | 424596 | 240384 | 240387 | 240390 | 240393 |
|
||||||
|
| 55 Rewards for Students | 424597 | 240353 | 240356 | 240359 | 240362 |
|
||||||
|
| 60 Lance's Support | 424598 | 240341 | 240344 | 240347 | 240350 |
|
||||||
|
| 65 Return to Dalanis | 424213 | 240304 | 240307 | 240310 | 240313 |
|
||||||
|
|
||||||
|
*The level-30 source name is **World Battlefield Bonus Armor Package**, without the word “Plate.” Its plate classification is only a likely reading of its position beside chain, leather, and cloth; the generated catalog uses `armor` until verified. This is a battlefield reward, so it is an optional source candidate rather than a guaranteed leveling grant. The level-5 quest has only three choices, and its chain choice is named **Chainmail Armor Box**. Neither early tier has confirmed individual package contents. The level-65 rewards are the Redhill Mountains Pioneer packages. The source-linked subpackage IDs, source names, matching suit IDs, seven armor member IDs, and their actual required levels for levels 50–65 are in the JSON catalog. Some level-50 suit members have required levels below 50; the quest reward level is the milestone, not an assertion that every item requires that level.
|
||||||
|
|
||||||
|
## Applying these to the five classes
|
||||||
|
|
||||||
|
The current game marks Knight as plate, Priest and Mage as cloth, and Rogue and Scout as leather in `src/app/characterCatalog.ts`. This suggests one plate, one leather, and one cloth choice for the five-class cohort; chain remains in the catalog because it is one of the source quest choices. Before grants are enabled, confirm native RoM class permissions and individual weapon choices, especially the Scout. A secondary class shares the primary's level and does not require a second package progression.
|
||||||
|
|
||||||
|
During leveling, `src/game/lootPolicy.ts` suppresses all boss item drops. Boss cards are awarded separately. Package gear should come from a level or quest milestone, never from a dungeon boss loot table. A fallback starter kit can cover levels for which no verified source package exists.
|
||||||
|
|
||||||
|
## Gaps before playable package gear
|
||||||
|
|
||||||
|
1. Locate and verify package expansion records or scripts for every parent and subpackage, including weapon selections, accessories, exact armor items, and quantities. Matching a suit by name, category, and required level is not enough to grant its pieces as historical package contents.
|
||||||
|
2. Decode native equipment slots, weapon and armor type, base stats, and item-instance bonuses. The current RoM gear path uses WoW-shaped synthetic heirlooms and cannot represent the source items faithfully.
|
||||||
|
3. Find a complete, generally available source-backed route from 1–49 and above level 65. Level 5 has only cloth, leather, and chain choices; level 30 has four battlefield choices. Logar/Hope package names exist in the item table, but their acquisition route and contents are not confirmed. Avoid inventing missing plate or weapon contents.
|
||||||
|
4. Make the milestone grant idempotent and persistent, then verify class eligibility, package selection, leveling through each milestone, and native-stat combat outcomes for all five builds.
|
||||||
@@ -45,7 +45,7 @@ RoM equipment has base item properties plus additional attribute sources. [Gamef
|
|||||||
1. Decode `armorobject.db` and `weaponobject.db` into native slot, armor/weapon type, base defense/damage, attribute, and level fields. Preserve source object IDs and validate the binary layout against source structures and known items before allowing package equipment to equip.
|
1. Decode `armorobject.db` and `weaponobject.db` into native slot, armor/weapon type, base defense/damage, attribute, and level fields. Preserve source object IDs and validate the binary layout against source structures and known items before allowing package equipment to equip.
|
||||||
2. Add a RoM item-instance bonus layer for native flat stats, transferred attributes, rune sockets, and later enhancement/tier data. Sum those bonuses into a native stat block. Keep WoW `ItemStats` and heirloom scoring unchanged for WoW characters.
|
2. Add a RoM item-instance bonus layer for native flat stats, transferred attributes, rune sockets, and later enhancement/tier data. Sum those bonuses into a native stat block. Keep WoW `ItemStats` and heirloom scoring unchanged for WoW characters.
|
||||||
3. Extend the generated class data with race and sex arguments and the vocation conversion coefficients. Keep secondary growth tied to the primary's level, including after the level-10 secondary unlock. Convert the complete RoM stat block to combat inputs through a RoM-specific adapter, including ATK, MATK, DEF, MDEF, and separate healing inputs.
|
3. Extend the generated class data with race and sex arguments and the vocation conversion coefficients. Keep secondary growth tied to the primary's level, including after the level-10 secondary unlock. Convert the complete RoM stat block to combat inputs through a RoM-specific adapter, including ATK, MATK, DEF, MDEF, and separate healing inputs.
|
||||||
4. Use legal starter equipment as a temporary bridge, then source-backed quest or item-shop equipment packages for leveling. The client snapshot confirms four armor-choice quest reward families at levels 50, 55, 60, and 65; see `docs/ROM_LEVELING_GEAR_PACKAGES.md`. Resolve the package expansion data and missing earlier/later tiers before granting source items. Dungeon bosses award cards during leveling, not equipment or miscellaneous items. Do not tune a RoM heirloom to a WoW drop score or apply WoW rating conversions to it.
|
4. Use legal starter equipment as a temporary bridge, then source-backed quest or item-shop equipment packages for leveling. The client snapshot confirms four armor-choice quest reward families at levels 50, 55, 60, and 65, a three-choice quest at level 5, and a battlefield reward at level 30; see `docs/ROM_LEVELING_GEAR_PACKAGES.md`. Resolve the package expansion data and missing general-route tiers before granting source items. Dungeon bosses award cards during leveling, not equipment or miscellaneous items. Do not tune a RoM heirloom to a WoW drop score or apply WoW rating conversions to it.
|
||||||
5. Derive role-specific *upgrade scores* from the marginal combat effect of each native stat at the current level and gear state. Measure Knight survival/threat, Priest effective HPS and sustain, and each DPS build's damage on the same targeted encounter set. Source coefficients seed that model; targeted combat measurements establish practical weights and catch caps or nonlinear effects.
|
5. Derive role-specific *upgrade scores* from the marginal combat effect of each native stat at the current level and gear state. Measure Knight survival/threat, Priest effective HPS and sustain, and each DPS build's damage on the same targeted encounter set. Source coefficients seed that model; targeted combat measurements establish practical weights and catch caps or nonlinear effects.
|
||||||
|
|
||||||
## Online and validation boundary
|
## Online and validation boundary
|
||||||
|
|||||||
@@ -70,25 +70,36 @@ function sourceName(id) {
|
|||||||
// source's armor category, required levels, names, and suit membership. Package
|
// source's armor category, required levels, names, and suit membership. Package
|
||||||
// expansion itself is not present in these DB records and remains unverified.
|
// expansion itself is not present in these DB records and remains unverified.
|
||||||
const milestones = [
|
const milestones = [
|
||||||
{ level: 50, questId: 424596, choices: [
|
{ level: 5, questId: 423783, packageStructure: "single-package-contents-unverified", choices: [
|
||||||
|
["cloth", 209015],
|
||||||
|
["leather", 209024],
|
||||||
|
["chain", 209025],
|
||||||
|
] },
|
||||||
|
{ level: 30, questId: 423771, packageStructure: "battlefield-package-contents-unverified", choices: [
|
||||||
|
["armor", 208802],
|
||||||
|
["chain", 208803],
|
||||||
|
["leather", 208804],
|
||||||
|
["cloth", 208805],
|
||||||
|
] },
|
||||||
|
{ level: 50, questId: 424596, packageStructure: "named-subpackages-links-unverified", choices: [
|
||||||
["plate", 240384, 240385, 240386, 610363],
|
["plate", 240384, 240385, 240386, 610363],
|
||||||
["chain", 240387, 240388, 240389, 610364],
|
["chain", 240387, 240388, 240389, 610364],
|
||||||
["leather", 240390, 240391, 240392, 610365],
|
["leather", 240390, 240391, 240392, 610365],
|
||||||
["cloth", 240393, 240394, 240395, 610366],
|
["cloth", 240393, 240394, 240395, 610366],
|
||||||
] },
|
] },
|
||||||
{ level: 55, questId: 424597, choices: [
|
{ level: 55, questId: 424597, packageStructure: "named-subpackages-links-unverified", choices: [
|
||||||
["plate", 240353, 240354, 240355, 610395],
|
["plate", 240353, 240354, 240355, 610395],
|
||||||
["chain", 240356, 240357, 240358, 610396],
|
["chain", 240356, 240357, 240358, 610396],
|
||||||
["leather", 240359, 240360, 240361, 610397],
|
["leather", 240359, 240360, 240361, 610397],
|
||||||
["cloth", 240362, 240363, 240364, 610398],
|
["cloth", 240362, 240363, 240364, 610398],
|
||||||
] },
|
] },
|
||||||
{ level: 60, questId: 424598, choices: [
|
{ level: 60, questId: 424598, packageStructure: "named-subpackages-links-unverified", choices: [
|
||||||
["plate", 240341, 240342, 240343, 610391],
|
["plate", 240341, 240342, 240343, 610391],
|
||||||
["chain", 240344, 240345, 240346, 610392],
|
["chain", 240344, 240345, 240346, 610392],
|
||||||
["leather", 240347, 240348, 240349, 610393],
|
["leather", 240347, 240348, 240349, 610393],
|
||||||
["cloth", 240350, 240351, 240352, 610394],
|
["cloth", 240350, 240351, 240352, 610394],
|
||||||
] },
|
] },
|
||||||
{ level: 65, questId: 424213, choices: [
|
{ level: 65, questId: 424213, packageStructure: "named-subpackages-links-unverified", choices: [
|
||||||
["plate", 240304, 240302, 240303, 610387],
|
["plate", 240304, 240302, 240303, 610387],
|
||||||
["chain", 240307, 240305, 240306, 610388],
|
["chain", 240307, 240305, 240306, 610388],
|
||||||
["leather", 240310, 240308, 240309, 610389],
|
["leather", 240310, 240308, 240309, 610389],
|
||||||
@@ -96,15 +107,18 @@ const milestones = [
|
|||||||
] },
|
] },
|
||||||
];
|
];
|
||||||
|
|
||||||
const extracted = milestones.map(({ level, questId, choices }) => {
|
const extracted = milestones.map(({ level, questId, packageStructure, choices }) => {
|
||||||
const quest = record("questdetailobject.db", questId);
|
const quest = record("questdetailobject.db", questId);
|
||||||
if (quest.readInt32LE(0xc0) !== level) throw new Error(`Quest ${questId} level drifted.`);
|
if (quest.readInt32LE(0xc0) !== level) throw new Error(`Quest ${questId} level drifted.`);
|
||||||
const rewardIds = Array.from({ length: 4 }, (_, index) => quest.readInt32LE(0x34c + index * 4));
|
const rewardIds = Array.from({ length: 4 }, (_, index) => quest.readInt32LE(0x34c + index * 4));
|
||||||
|
if (rewardIds.slice(choices.length).some((id) => id !== 0)) {
|
||||||
|
throw new Error(`Quest ${questId} has an unrecorded reward choice.`);
|
||||||
|
}
|
||||||
const packages = choices.map(([armorCategory, packageId, weaponPackageId, armorPackageId, matchingSuitId], index) => {
|
const packages = choices.map(([armorCategory, packageId, weaponPackageId, armorPackageId, matchingSuitId], index) => {
|
||||||
if (rewardIds[index] !== packageId) throw new Error(`Quest ${questId} reward order drifted.`);
|
if (rewardIds[index] !== packageId) throw new Error(`Quest ${questId} reward order drifted.`);
|
||||||
for (const id of [packageId, weaponPackageId, armorPackageId]) record("itemobject.db", id);
|
for (const id of [packageId, weaponPackageId, armorPackageId].filter(Boolean)) record("itemobject.db", id);
|
||||||
const suit = record("suitobject.db", matchingSuitId);
|
const suit = matchingSuitId ? record("suitobject.db", matchingSuitId) : null;
|
||||||
const matchingArmorItems = Array.from({ length: 10 }, (_, member) => suit.readInt32LE(1224 + member * 4))
|
const matchingArmorItems = suit ? Array.from({ length: 10 }, (_, member) => suit.readInt32LE(1224 + member * 4))
|
||||||
.filter((id) => id > 0)
|
.filter((id) => id > 0)
|
||||||
.map((itemId) => {
|
.map((itemId) => {
|
||||||
const item = record("armorobject.db", itemId);
|
const item = record("armorobject.db", itemId);
|
||||||
@@ -116,26 +130,22 @@ const extracted = milestones.map(({ level, questId, choices }) => {
|
|||||||
throw new Error(`Armor ${itemId} has unexpected required level ${requiredLevel}.`);
|
throw new Error(`Armor ${itemId} has unexpected required level ${requiredLevel}.`);
|
||||||
}
|
}
|
||||||
return { itemId, name: sourceName(itemId), requiredLevel };
|
return { itemId, name: sourceName(itemId), requiredLevel };
|
||||||
});
|
}) : [];
|
||||||
if (matchingArmorItems.length !== 7) throw new Error(`Suit ${matchingSuitId} should have seven armor pieces.`);
|
if (suit && matchingArmorItems.length !== 7) throw new Error(`Suit ${matchingSuitId} should have seven armor pieces.`);
|
||||||
return {
|
return {
|
||||||
armorCategory,
|
armorCategory,
|
||||||
packageId,
|
packageId,
|
||||||
packageName: sourceName(packageId),
|
packageName: sourceName(packageId),
|
||||||
weaponPackageId,
|
...(weaponPackageId ? { weaponPackageId, weaponPackageName: sourceName(weaponPackageId) } : {}),
|
||||||
weaponPackageName: sourceName(weaponPackageId),
|
...(armorPackageId ? { armorPackageId, armorPackageName: sourceName(armorPackageId) } : {}),
|
||||||
armorPackageId,
|
...(suit ? { matchingSuitId, matchingSuitName: sourceName(matchingSuitId), matchingArmorItems } : {}),
|
||||||
armorPackageName: sourceName(armorPackageId),
|
|
||||||
matchingSuitId,
|
|
||||||
matchingSuitName: sourceName(matchingSuitId),
|
|
||||||
matchingArmorItems,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return { level, questId, questName: sourceName(questId), packages };
|
return { level, questId, questName: sourceName(questId), packageStructure, packages };
|
||||||
});
|
});
|
||||||
|
|
||||||
const output = {
|
const output = {
|
||||||
schemaVersion: 1,
|
schemaVersion: 2,
|
||||||
contentStatus: "quest-rewards-confirmed-package-expansion-unverified",
|
contentStatus: "quest-rewards-confirmed-package-expansion-unverified",
|
||||||
sourceFiles: Object.fromEntries(files.map((name) => [name, createHash("sha256").update(buffers[name]).digest("hex")])),
|
sourceFiles: Object.fromEntries(files.map((name) => [name, createHash("sha256").update(buffers[name]).digest("hex")])),
|
||||||
milestones: extracted,
|
milestones: extracted,
|
||||||
|
|||||||
@@ -950,7 +950,7 @@ describe("combat store", () => {
|
|||||||
expect(useCombatStore.getState().lootMob("lootable", 30_000)).toBe(false);
|
expect(useCombatStore.getState().lootMob("lootable", 30_000)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("suppresses leveling equipment while granting boss cards automatically exactly once", () => {
|
it("suppresses leveling boss items while granting boss cards automatically exactly once", () => {
|
||||||
useCombatStore.getState().initializeCharacter({
|
useCombatStore.getState().initializeCharacter({
|
||||||
classId: "priest",
|
classId: "priest",
|
||||||
level: 1,
|
level: 1,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 2,
|
||||||
"contentStatus": "quest-rewards-confirmed-package-expansion-unverified",
|
"contentStatus": "quest-rewards-confirmed-package-expansion-unverified",
|
||||||
"sourceFiles": {
|
"sourceFiles": {
|
||||||
"questdetailobject.db": "52950d1df2e0094144064298ab36554b2db424acfb23d142cce7d3087e4cfa7f",
|
"questdetailobject.db": "52950d1df2e0094144064298ab36554b2db424acfb23d142cce7d3087e4cfa7f",
|
||||||
@@ -9,10 +9,62 @@
|
|||||||
"string_enus.db": "4fce021ba9ed110a213e08d3228b2de57cec66ddbbc8cdcf5753204874d9ab75"
|
"string_enus.db": "4fce021ba9ed110a213e08d3228b2de57cec66ddbbc8cdcf5753204874d9ab75"
|
||||||
},
|
},
|
||||||
"milestones": [
|
"milestones": [
|
||||||
|
{
|
||||||
|
"level": 5,
|
||||||
|
"questId": 423783,
|
||||||
|
"questName": "Equip Yourself",
|
||||||
|
"packageStructure": "single-package-contents-unverified",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"armorCategory": "cloth",
|
||||||
|
"packageId": 209015,
|
||||||
|
"packageName": "Cloth Armor Package"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"armorCategory": "leather",
|
||||||
|
"packageId": 209024,
|
||||||
|
"packageName": "Leather Armor Package"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"armorCategory": "chain",
|
||||||
|
"packageId": 209025,
|
||||||
|
"packageName": "Chainmail Armor Box"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 30,
|
||||||
|
"questId": 423771,
|
||||||
|
"questName": "Key to Victory",
|
||||||
|
"packageStructure": "battlefield-package-contents-unverified",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"armorCategory": "armor",
|
||||||
|
"packageId": 208802,
|
||||||
|
"packageName": "World Battlefield Bonus Armor Package"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"armorCategory": "chain",
|
||||||
|
"packageId": 208803,
|
||||||
|
"packageName": "World Battlefield Bonus Chain Package"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"armorCategory": "leather",
|
||||||
|
"packageId": 208804,
|
||||||
|
"packageName": "World Battlefield Bonus Leather Package"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"armorCategory": "cloth",
|
||||||
|
"packageId": 208805,
|
||||||
|
"packageName": "World Battlefield Bonus Cloth Package"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"level": 50,
|
"level": 50,
|
||||||
"questId": 424596,
|
"questId": 424596,
|
||||||
"questName": "Appropriate Support",
|
"questName": "Appropriate Support",
|
||||||
|
"packageStructure": "named-subpackages-links-unverified",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"armorCategory": "plate",
|
"armorCategory": "plate",
|
||||||
@@ -212,6 +264,7 @@
|
|||||||
"level": 55,
|
"level": 55,
|
||||||
"questId": 424597,
|
"questId": 424597,
|
||||||
"questName": "Rewards for Students",
|
"questName": "Rewards for Students",
|
||||||
|
"packageStructure": "named-subpackages-links-unverified",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"armorCategory": "plate",
|
"armorCategory": "plate",
|
||||||
@@ -411,6 +464,7 @@
|
|||||||
"level": 60,
|
"level": 60,
|
||||||
"questId": 424598,
|
"questId": 424598,
|
||||||
"questName": "Lance's Support",
|
"questName": "Lance's Support",
|
||||||
|
"packageStructure": "named-subpackages-links-unverified",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"armorCategory": "plate",
|
"armorCategory": "plate",
|
||||||
@@ -610,6 +664,7 @@
|
|||||||
"level": 65,
|
"level": 65,
|
||||||
"questId": 424213,
|
"questId": 424213,
|
||||||
"questName": "Return to Dalanis",
|
"questName": "Return to Dalanis",
|
||||||
|
"packageStructure": "named-subpackages-links-unverified",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"armorCategory": "plate",
|
"armorCategory": "plate",
|
||||||
|
|||||||
Reference in new issue
Block a user