Module:GameData/doc: Difference between revisions

Support data modifications, alter equipmentSlots data structure, remove milestoneCount (logic for mastery token drop rates have changed), and include bankSortOrder for sorting various tables
(Correct mastery checkpoint data for Summoning)
(Support data modifications, alter equipmentSlots data structure, remove milestoneCount (logic for mastery token drop rates have changed), and include bankSortOrder for sorting various tables)
Line 7: Line 7:
# Copy the game data & update [[Module:GameData/data]] accordingly
# Copy the game data & update [[Module:GameData/data]] accordingly


{{SpoilerBox|color=default|title=Code|text=<syntaxhighlight lang="javascript" line>// TODO:
{{SpoilerBox|color=default|title=Code|text=<syntaxhighlight lang="javascript" line>class Wiki {
// Handle modifications portion of data packages
class Wiki {
constructor() {
constructor() {
this.debugMode = false;
this.debugMode = false;
Line 58: Line 56:
}
}
return gameVersion + ' (' + fileVer + ')';
return gameVersion + ' (' + fileVer + ')';
}
getObjectByID(data, objectID, idKey = 'id') {
if ((data !== undefined) && (objectID !== undefined)) {
return data.find((obj) => obj[idKey] === objectID);
}
}
}
async printWikiData() {
async printWikiData() {
Line 114: Line 117:
Object.keys(packData).forEach((categoryName) => {
Object.keys(packData).forEach((categoryName) => {
switch(categoryName) {
switch(categoryName) {
case 'bankSortOrder':
case 'pages':
case 'pages':
case 'steamAchievements':
case 'steamAchievements':
Line 185: Line 187:
if (!this.skillDataInit[dataNode.skillID]) {
if (!this.skillDataInit[dataNode.skillID]) {
if (gameSkill !== undefined) {
if (gameSkill !== undefined) {
if (gameSkill.milestones !== undefined && dataNode.data.milestoneCount === undefined) {
dataNode.data.milestoneCount = gameSkill.milestones.length;
}
// Import other attributes varying by skill
// Import other attributes varying by skill
let importKeys = [];
let importKeys = [];
Line 372: Line 370:
}
}
break;
break;
case 'bankSortOrder':
case 'combatAreaDisplayOrder':
case 'combatAreaDisplayOrder':
case 'dungeonDisplayOrder':
case 'dungeonDisplayOrder':
Line 438: Line 437:
}
}
});
});
// If the data package contains modifications, apply these also
const modificationData = this.packData[namespace].modifications;
if (modificationData !== undefined) {
this.applyDataModifications(modificationData);
}
}
applyDataModifications(modData) {
const modDataKeys = Object.keys(modData)
for (const modCatID in modDataKeys) {
const modCat = modDataKeys[modCatID];
const catData = modData[modCat];
if (modCat === 'shopUpgradeChains') {
// Modify the root upgrade ID of shop upgrade chains
catData.forEach((modItem) => {
const modObjID = modItem.id;
if (modObjID === undefined) {
console.warn(`Could not apply data modification: ID of object to be modified not found, category "${ modCat }"`);
}
else {
const modObj = this.getObjectByID(this.gameData[modCat], modObjID);
if (modObj === undefined) {
console.warn(`Could not apply data modification: Object with ID "${ modObjID }" not found for category "${ modCat }"`);
}
else {
Object.keys(modItem).filter((k) => k !== 'id').forEach((k) => {
modObj[k] = modItem[k];
});
}
}
});
}
else if (modCat === 'cookingCategories') {
// Append to the list of shop upgrade IDs for cooking utilities/categories
catData.forEach((modItem) => {
const modObjID = modItem.id;
const cookingSkill = this.getObjectByID(this.gameData.skillData, 'melvorD:Cooking', 'skillID');
if (modObjID === undefined) {
console.warn(`Could not apply data modification: ID of object to be modified not found, category "${ modCat }"`);
}
else if (cookingSkill === undefined) {
console.warn('Could not apply data modification: Data for skill "melvorD:Cooking" not found');
}
else {
const modObj = this.getObjectByID(cookingSkill.data.categories, modObjID);
if (modObj === undefined) {
console.warn(`Could not apply data modification: Object with ID "${ modObjID }" not found for category "${ modCat }"`);
}
else {
Object.keys(modItem).filter((k) => k !== 'id').forEach((k) => {
if (k === 'shopUpgradeIDs') {
if (modObj[k] === undefined) {
modObj[k] = modItem[k];
}
else {
modObj[k].push(...modItem[k]);
}
}
else {
console.warn(`Could not apply data modification: Unhandled key "${ k }" for category "${ modCat }", object "${ mobObjID }"`);
}
});
}
}
});
}
else if (modCat === 'fletchingRecipes') {
// Append to alternativeCosts property of recipes (e.g. Arrow shafts)
catData.forEach((modItem) => {
const modObjID = modItem.id;
const fletchingSkill = this.getObjectByID(this.gameData.skillData, 'melvorD:Fletching', 'skillID');
if (modObjID === undefined) {
console.warn(`Could not apply data modification: ID of object to be modified not found, category "${ modCat }"`);
}
else if (fletchingSkill === undefined) {
console.warn('Could not apply data modification: Data for skill "melvorD:Fletching" not found');
}
else {
const modObj = this.getObjectByID(fletchingSkill.data.recipes, modObjID);
if (modObj === undefined) {
console.warn(`Could not apply data modification: Object with ID "${ modObjID }" not found for category "${ modCat }"`);
}
else {
Object.keys(modItem).filter((k) => k !== 'id').forEach((k) => {
if (k === 'alternativeCosts') {
if (modObj[k] === undefined) {
modObj[k] = modItem[k];
}
else {
modObj[k].push(...modItem[k]);
}
}
else {
console.warn(`Could not apply data modification: Unhandled key "${ k }" for category "${ modCat }", object "${ mobObjID }"`);
}
});
}
}
});
}
else {
console.warn(`Could not apply data modification: Unhandled category "${ modCat }"`);
}
}
}
}
registerNonPackData() {
registerNonPackData() {
Line 469: Line 571:
}
}
if (this.gameData.equipmentSlots === undefined) {
if (this.gameData.equipmentSlots === undefined) {
//TODO: Amend to follow { id: ..., name: ... } structure. Obtain name from getLangString('EQUIP_SLOT', numID)
const slotIDs = Object.keys(EquipmentSlots).filter((slotID) => !isNaN(parseInt(slotID)));
this.gameData.equipmentSlots = EquipmentSlots;
this.gameData.equipmentSlots = slotIDs.map((slotID) => ({id: EquipmentSlots[slotID], name: getLangString('EQUIP_SLOT', slotID)}));
}
}
if (this.gameData.attackTypes === undefined) {
if (this.gameData.attackTypes === undefined) {
Line 479: Line 581:
newData.forEach((tier) => delete tier.engDisplay);
newData.forEach((tier) => delete tier.engDisplay);
this.gameData.slayerTiers = newData;
this.gameData.slayerTiers = newData;
}
if (this.gameData.modifierData === undefined && modifierData !== undefined) {
var wikiModData = {};
Object.keys(modifierData).forEach((modK) => {
const mod = modifierData[modK];
wikiModData[modK] = {};
Object.keys(mod).forEach((k) => {
if (k === 'modifyValue') {
// Convert function into function name
// If the function is inline and has no name, then use the function definition instead
var funcName = mod[k].name;
if (funcName === 'modifyValue') {
funcName = mod[k].toString();
}
wikiModData[modK][k] = funcName;
}
else if (k === 'langDescription') {
wikiModData[modK]['description'] = mod[k];
}
else if (k !== 'description') {
wikiModData[modK][k] = mod[k];
}
});
});
this.gameData.modifierData = wikiModData;
}
}
}
}