Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save work #384

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
},
"devDependencies": {
"@biomejs/biome": "^1.8.3",
"@oldschoolgg/toolkit": "git+https://github.com/oldschoolgg/toolkit.git#62f9f71274c6d36db6c56a2228ae3df9ab090dbd",
"@types/node": "^20.14.9",
"@types/node-fetch": "^2.6.1",
"@vitest/coverage-v8": "^1.6.0",
Expand Down
92 changes: 52 additions & 40 deletions scripts/enum.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,62 @@
import { writeFileSync } from "node:fs";

import { Items } from "../src";
import type { Item } from "../src/meta/types";
import { USELESS_ITEMS } from "../src/structures/Items";
import { moidLink } from "./prepareItems";

const exitingKeys = new Set<string>();
const duplicates = new Set<number>();
let str = "export enum EItem {";
outer: for (const item of Items.values()) {
if (!item.tradeable_on_ge && !item.equipment) continue;
for (const str of [
"Xeric's aid",
"Overload",
"Revitalisation",
"Sigil",
"10th",
"4th",
"Prayer enh",
"'24",
"20",
]) {
if (item.name.startsWith(str)) {
continue outer;
function doesWikiNameMatch(item: Item) {
if (!item.wiki_name) return false;
const wikiName = item.wiki_name.toLowerCase();
const name = item.name.toLowerCase();
if (wikiName.slice(0, 2) === name.slice(0, 2)) return true;
if (JSON.stringify(wikiName.split(" ").sort()) === JSON.stringify(name.split(" ").sort())) return true;
return false;
}

export function makeEnum() {
const exitingKeys = new Set<string>();
const duplicates = new Set<number>();
let str = "export enum EItem {";
outer: for (const item of Items.values()) {
if (!item.tradeable_on_ge && !item.equipment) continue;
for (const str of [
"Xeric's aid",
"Overload",
"Revitalisation",
"Sigil",
"10th",
"4th",
"Prayer enh",
"'24",
"20",
]) {
if (item.name.startsWith(str)) {
continue outer;
}
}
}
for (const str of ["+", "Twisted ("]) {
if (item.name.includes(str)) {
continue outer;
for (const str of ["+", "Twisted ("]) {
if (item.name.includes(str)) {
continue outer;
}
}
if (USELESS_ITEMS.includes(item.id)) {
continue;
}
let key = doesWikiNameMatch(item) ? item.wiki_name! : item.name;
key = key.replace("3rd", "third");
key = key.replace(/[^\w\s]|_/g, "");
key = key.replace(/\s+/g, "_");
key = key.toUpperCase();
if (exitingKeys.has(key)) {
duplicates.add(item.id);
continue;
}
exitingKeys.add(key);
str += `\n\t${key} = ${item.id},`;
}
if (USELESS_ITEMS.includes(item.id)) {
continue;
}
let key = item.wiki_name ?? item.name;
key = key.replace("3rd", "third");
key = key.replace(/[^\w\s]|_/g, "");
key = key.replace(/\s+/g, "_");
key = key.toUpperCase();
if (exitingKeys.has(key)) {
duplicates.add(item.id);
continue;
}
exitingKeys.add(key);
str += `\n\t${key} = ${item.id},`;
str += "\n}";
str += "\n";
writeFileSync("./src/EItem.ts", str);
console.log(`Duplicates: ${moidLink(Array.from(duplicates))}`);
}
str += "\n}";
str += "\n";
writeFileSync("./src/EItem.ts", str);
console.log(`Duplicates: ${moidLink(Array.from(duplicates))}`);
7 changes: 1 addition & 6 deletions scripts/manualItemChanges.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import type { Item } from "../src/meta/types";

type DeepPartial<T> = T extends object
? {
[P in keyof T]?: DeepPartial<T[P]>;
}
: T;
import type { DeepPartial } from "./scriptUtil";

export const itemChanges: Record<number, DeepPartial<Item>> = {
27665: {
Expand Down
124 changes: 113 additions & 11 deletions scripts/prepareItems.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { readFileSync, writeFileSync } from "node:fs";
import { Stopwatch } from "@oldschoolgg/toolkit/dist/lib/Stopwatch";
import { diff } from "deep-object-diff";
import deepMerge from "deepmerge";
import { deepClone, increaseNumByPercent, notEmpty, objectEntries, reduceNumByPercent } from "e";
Expand All @@ -8,12 +9,93 @@ import { EquipmentSlot, type Item } from "../src/meta/types";
import Items, { CLUE_SCROLLS, CLUE_SCROLL_NAMES, USELESS_ITEMS } from "../src/structures/Items";
import itemID from "../src/util/itemID";
import { getItemOrThrow } from "../src/util/util";
import { makeEnum } from "./enum";
import { itemChanges } from "./manualItemChanges";
import type { DeepPartial } from "./scriptUtil";

const ITEM_UPDATE_CONFIG = {
SHOULD_UPDATE_PRICES: false,
};

export interface RLItem {
name: string;
weight?: number;
ge_limit?: number;
equipable?: boolean;
equipment?: {
slot?: number;
amagic?: number;
mdmg?: number;
arange?: number;
str?: number;
prayer?: number;
aspeed?: number;
dstab?: number;
dslash?: number;
dcrush?: number;
dmagic?: number;
drange?: number;
astab?: number;
aslash?: number;
acrush?: number;
is2h?: boolean;
rstr?: number;
};
}

type StatsJson = Record<string, RLItem>;
const rlItemSlotMap = {
3: "weapon",
4: "body",
0: "head",
13: "ammo",
7: "legs",
10: "feet",
9: "hands",
1: "cape",
2: "neck",
12: "ring",
5: "shield",
};

function convertRoot2ToItem(rlItem: RLItem, currentItem: Item): DeepPartial<Item> {
let slot: any = null;
if (rlItem.equipment) {
if (rlItem.equipment.is2h) {
slot = EquipmentSlot.TwoHanded;
} else {
// @ts-ignore
slot = rlItemSlotMap[rlItem.equipment.slot];
}
}

return {
name: rlItem.name,
weight: rlItem.weight,
buy_limit: rlItem.ge_limit,
equipment:
rlItem.equipment && rlItem.equipable && currentItem.equipable_by_player
? {
attack_stab: rlItem.equipment.astab || 0,
attack_slash: rlItem.equipment.aslash || 0,
attack_crush: rlItem.equipment.acrush || 0,
attack_magic: rlItem.equipment.amagic || 0,
attack_ranged: rlItem.equipment.arange || 0,
defence_stab: rlItem.equipment.dstab || 0,
defence_slash: rlItem.equipment.dslash || 0,
defence_crush: rlItem.equipment.dcrush || 0,
defence_magic: rlItem.equipment.dmagic || 0,
defence_ranged: rlItem.equipment.drange || 0,
melee_strength: rlItem.equipment.str || 0,
ranged_strength: rlItem.equipment.rstr || 0,
magic_damage: rlItem.equipment.mdmg || 0,
prayer: rlItem.equipment.prayer || 0,
slot,
}
: undefined,
};
}

const previousItems = JSON.parse(readFileSync("./src/data/items/item_data.json", "utf-8"));

const equipmentModifications = new Map();
Expand Down Expand Up @@ -260,19 +342,27 @@ const itemsToIgnorePrices = [
const keysToWarnIfRemovedOrAdded: (keyof Item)[] = ["equipable", "equipment", "weapon"];

export default async function prepareItems(): Promise<void> {
const stopwatch = new Stopwatch();
const messages: string[] = [];
const allItemsRaw: RawItemCollection = await fetch(
"https://raw.githubusercontent.com/0xNeffarion/osrsreboxed-db/master/docs/items-complete.json",
).then((res): Promise<any> => res.json());
const allItems = deepClone(allItemsRaw);

const allPrices = await fetch("https://prices.runescape.wiki/api/v1/osrs/latest", {
headers: {
"User-Agent": "oldschooljs - @magnaboy",
},
})
.then((res): Promise<any> => res.json())
.then(res => res.data);
const [allItemsRaw, rlItems, allPrices]: [RawItemCollection, StatsJson, any] = await Promise.all([
fetch("https://raw.githubusercontent.com/0xNeffarion/osrsreboxed-db/master/docs/items-complete.json").then(
(res): Promise<any> => res.json(),
),
fetch("https://raw.githubusercontent.com/runelite/static.runelite.net/gh-pages/item/stats.json").then(
(res): Promise<any> => res.json(),
),
fetch("https://prices.runescape.wiki/api/v1/osrs/latest", {
headers: {
"User-Agent": "oldschooljs - @magnaboy",
},
})
.then((res): Promise<any> => res.json())
.then(res => res.data),
]);
stopwatch.check("Fetched data");

const allItems = deepClone(allItemsRaw);

if (!allPrices[20_997]) {
throw new Error("Failed to fetch prices");
Expand All @@ -291,6 +381,14 @@ export default async function prepareItems(): Promise<void> {
};
}

const rlItem = rlItems[item.id];
if (rlItem) {
if (rlItem.name !== item.name) {
console.log(`Name mismatch for ${item.id} - ${item.name} - ${rlItem.name}`);
}
item = deepMerge(item, convertRoot2ToItem(rlItem, item)) as any;
}

for (const delKey of [
"quest_item",
"placeholder",
Expand Down Expand Up @@ -461,6 +559,7 @@ export default async function prepareItems(): Promise<void> {
newItemJSON[item.id] = item;
}
}
stopwatch.check("Processed all items.");

if (nameChanges.length > 0) {
messages.push(`Name Changes:\n ${nameChanges.join("\n ")}`);
Expand Down Expand Up @@ -514,4 +613,7 @@ ${messages.join("\n")}`,
);
writeFileSync(`./update-history/${baseFilename}.json`, `${JSON.stringify(diffOutput, null, " ")}`);
writeFileSync("./src/data/items/item_data.json", `${JSON.stringify(newItemJSON, null, " ")}\n`);
stopwatch.check("Wrote files.");
makeEnum();
stopwatch.check("Made enum.");
}
5 changes: 5 additions & 0 deletions scripts/scriptUtil.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type DeepPartial<T> = T extends object
? {
[P in keyof T]?: DeepPartial<T[P]>;
}
: T;
Loading