diff --git a/src/engine/dbc.ts b/src/engine/dbc.ts index f16ef497e..e83253809 100644 --- a/src/engine/dbc.ts +++ b/src/engine/dbc.ts @@ -1,7 +1,9 @@ import { LuaArray } from "@wowts/lua"; + interface ConduitData { ranks: LuaArray; } + export const conduits: LuaArray = { [5]: { ranks: { @@ -5248,3 +5250,254 @@ export const conduits: LuaArray = { }, }, }; + +export const runeforgeBonusId: LuaArray = { + [327508]: 6823, + [327284]: 6828, + [327364]: 6829, + [327492]: 6830, + [327489]: 6831, + [327365]: 6832, + [327351]: 6834, + [332769]: 6926, + [332892]: 6927, + [332928]: 6928, + [333030]: 6931, + [333097]: 6932, + [333167]: 6933, + [333313]: 6934, + [333373]: 6936, + [333393]: 6937, + [334501]: 6940, + [334525]: 6941, + [334547]: 6942, + [334580]: 6943, + [334583]: 6944, + [334678]: 6945, + [334692]: 6946, + [334728]: 6947, + [334724]: 6948, + [334836]: 6949, + [334888]: 6950, + [334898]: 6951, + [334949]: 6952, + [334974]: 6953, + [335177]: 6954, + [335214]: 6955, + [335229]: 6956, + [335239]: 6957, + [335253]: 6958, + [335266]: 6959, + [335274]: 6960, + [335451]: 6961, + [335458]: 6962, + [335555]: 6963, + [335567]: 6964, + [335582]: 6965, + [335594]: 6966, + [335629]: 6967, + [335718]: 6969, + [335282]: 6970, + [335758]: 6971, + [336470]: 6972, + [336400]: 6973, + [336266]: 6974, + [336370]: 6975, + [336011]: 6976, + [336314]: 6977, + [336507]: 6978, + [336133]: 6979, + [336067]: 6980, + [336165]: 6981, + [336143]: 6982, + [336214]: 6983, + [337477]: 6984, + [336741]: 6985, + [336739]: 6986, + [336738]: 6987, + [336735]: 6988, + [336734]: 6989, + [336730]: 6990, + [336215]: 6991, + [336063]: 6992, + [335902]: 6993, + [335899]: 6994, + [335897]: 6995, + [335895]: 6996, + [335893]: 6997, + [335891]: 6998, + [335889]: 6999, + [335886]: 7000, + [336897]: 7002, + [336742]: 7003, + [336743]: 7004, + [336745]: 7005, + [336747]: 7006, + [336819]: 7007, + [336822]: 7008, + [336830]: 7009, + [336844]: 7010, + [336849]: 7011, + [336867]: 7012, + [336870]: 7013, + [336878]: 7014, + [336895]: 7015, + [336901]: 7016, + [336902]: 7017, + [336907]: 7018, + [337020]: 7025, + [337038]: 7026, + [337057]: 7027, + [337065]: 7028, + [337106]: 7029, + [337111]: 7030, + [337122]: 7031, + [337128]: 7032, + [337135]: 7033, + [337141]: 7034, + [337146]: 7035, + [337159]: 7036, + [337163]: 7037, + [337166]: 7038, + [337169]: 7039, + [337272]: 7040, + [337504]: 7041, + [337534]: 7043, + [337539]: 7044, + [337541]: 7045, + [337544]: 7046, + [337545]: 7047, + [337547]: 7048, + [337551]: 7050, + [337685]: 7051, + [337775]: 7052, + [337600]: 7053, + [337594]: 7054, + [337746]: 7055, + [337681]: 7056, + [337812]: 7057, + [337777]: 7058, + [337825]: 7059, + [337831]: 7060, + [337838]: 7061, + [337847]: 7062, + [337850]: 7063, + [337247]: 7064, + [337638]: 7065, + [337297]: 7066, + [337257]: 7067, + [337334]: 7068, + [337292]: 7069, + [337481]: 7070, + [337483]: 7071, + [337473]: 7072, + [337225]: 7073, + [337343]: 7074, + [337172]: 7075, + [338138]: 7076, + [337288]: 7077, + [337290]: 7078, + [337570]: 7079, + [337294]: 7080, + [337296]: 7081, + [337298]: 7082, + [338608]: 7084, + [338657]: 7085, + [338658]: 7086, + [338661]: 7087, + [338668]: 7088, + [339144]: 7089, + [339141]: 7090, + [339139]: 7091, + [339060]: 7092, + [339063]: 7093, + [339056]: 7094, + [339062]: 7095, + [339064]: 7096, + [338831]: 7097, + [338829]: 7098, + [338832]: 7099, + [338477]: 7100, + [339344]: 7101, + [339340]: 7102, + [339348]: 7103, + [339351]: 7104, + [339058]: 7105, + [338743]: 7106, + [339942]: 7107, + [339949]: 7108, + [340053]: 7109, + [340059]: 7110, + [340076]: 7111, + [340078]: 7112, + [340079]: 7113, + [340080]: 7114, + [340081]: 7115, + [340082]: 7116, + [340083]: 7117, + [340084]: 7118, + [340085]: 7119, + [340086]: 7120, + [340087]: 7121, + [340088]: 7122, + [340089]: 7123, + [340090]: 7124, + [340091]: 7125, + [340092]: 7126, + [340458]: 7128, + [340197]: 7159, + [341724]: 7160, + [341804]: 7161, + [342415]: 7162, + [343250]: 7184, + [346264]: 7218, + [346279]: 7219, + [353447]: 7458, + [353882]: 7466, + [353822]: 7467, + [353699]: 7468, + [353577]: 7469, + [354131]: 7470, + [354161]: 7471, + [354123]: 7472, + [354186]: 7473, + [354109]: 7474, + [354294]: 7475, + [354333]: 7476, + [354115]: 7477, + [354473]: 7478, + [354647]: 7570, + [354118]: 7571, + [354703]: 7572, + [354731]: 7573, + [354837]: 7577, + [355098]: 7679, + [355099]: 7680, + [355886]: 7681, + [355890]: 7698, + [355893]: 7699, + [355996]: 7700, + [355447]: 7701, + [355100]: 7702, + [356391]: 7703, + [356392]: 7704, + [356592]: 7707, + [356218]: 7708, + [356250]: 7709, + [356254]: 7710, + [356344]: 7711, + [356362]: 7712, + [356259]: 7713, + [356262]: 7714, + [356264]: 7715, + [356375]: 7716, + [356618]: 7717, + [356684]: 7718, + [356705]: 7721, + [356789]: 7722, + [356818]: 7726, + [356877]: 7727, + [356395]: 7728, + [356390]: 7729, + [357996]: 7730, +}; diff --git a/src/states/runeforge.ts b/src/states/runeforge.ts index b0e0529a1..807249244 100644 --- a/src/states/runeforge.ts +++ b/src/states/runeforge.ts @@ -1,6 +1,6 @@ import aceEvent, { AceEvent } from "@wowts/ace_event-3.0"; -import { LuaArray, kpairs, lualength, pairs, tonumber } from "@wowts/lua"; -import { concat, insert } from "@wowts/table"; +import { LuaArray, ipairs, pairs } from "@wowts/lua"; +import { concat, insert, sort } from "@wowts/table"; import { AceModule } from "@wowts/tsaddon"; import { C_LegendaryCrafting, Enum } from "@wowts/wow-mock"; import { OvaleClass } from "../Ovale"; @@ -9,13 +9,15 @@ import { OvaleConditionClass, returnBoolean, } from "../engine/condition"; -import { DebugTools } from "../engine/debug"; +import { runeforgeBonusId } from "../engine/dbc"; +import { DebugTools, Tracer } from "../engine/debug"; import { OptionUiGroup } from "../ui/acegui-helpers"; import { OvaleEquipmentClass, SlotName } from "./Equipment"; export class Runeforge { private module: AceModule & AceEvent; - private equippedLegendaryById: LuaArray = {}; + private tracer: Tracer; + private equippedRuneforgeById: LuaArray = {}; private debugRuneforges: OptionUiGroup = { @@ -28,42 +30,26 @@ export class Runeforge { multiline: 25, width: "full", get: () => { - const ids = + const powers = C_LegendaryCrafting.GetRuneforgePowers(undefined); const output: LuaArray = {}; - for (const [, id] of pairs(ids)) { - const runeforgePower = - C_LegendaryCrafting.GetRuneforgePowerInfo(id); - if (runeforgePower != undefined) { - insert(output, `${id}: ${runeforgePower.name}`); + for (const [, id] of pairs(powers)) { + const [spellId, name] = this.getRuneforgePowerInfo(id); + const bonusId = + (spellId && runeforgeBonusId[spellId]) || 0; + if (bonusId !== 0) { + const slot = this.equippedRuneforgeById[bonusId]; + if (slot) { + insert( + output, + `* ${name}: ${bonusId} (${slot})` + ); + } else { + insert(output, ` ${name}: ${bonusId}`); + } } } - insert(output, ""); - insert(output, "Equipped:"); - for (const [id] of kpairs(this.equippedRuneforgeById)) { - insert(output, ` ${id}`); - } - return concat(output, "\n"); - }, - }, - }, - }; - - private debugLegendaries: OptionUiGroup = { - type: "group", - name: "Legendaries", - args: { - legendaries: { - type: "input", - name: "Legendaries", - multiline: 25, - width: "full", - get: () => { - const output: LuaArray = {}; - insert(output, "Legendary bonus IDs:"); - for (const [id] of kpairs(this.equippedLegendaryById)) { - insert(output, ` ${id}`); - } + sort(output); return concat(output, "\n"); }, }, @@ -76,14 +62,13 @@ export class Runeforge { private equipment: OvaleEquipmentClass ) { debug.defaultOptions.args["runeforge"] = this.debugRuneforges; - debug.defaultOptions.args["legendaries"] = this.debugLegendaries; - this.module = ovale.createModule( "OvaleRuneforge", this.handleInitialize, this.handleDisable, aceEvent ); + this.tracer = debug.create(this.module.GetName()); } private handleInitialize = () => { @@ -98,40 +83,65 @@ export class Runeforge { }; private handleOvaleEquipmentChanged = (event: string, slot: SlotName) => { - // Update bonus IDs list in equippedLegendaryById. - for (const [id, slotName] of pairs(this.equippedLegendaryById)) { + for (const [id, slotName] of pairs(this.equippedRuneforgeById)) { if (slotName == slot) { - delete this.equippedLegendaryById[id]; + delete this.equippedRuneforgeById[id]; } } const quality = this.equipment.getEquippedItemQuality(slot); if (quality == Enum.ItemQuality.Legendary) { - // XXX Assume the first bonus ID is the legendary bonus ID. - const bonusIds = this.equipment.getEquippedItemBonusIds(slot); - if (lualength(bonusIds) > 0) { - const id = bonusIds[1]; - this.equippedLegendaryById[id] = slot; - } - } - // Update power IDs list in equippedRuneforgeById. - for (const [id, slotName] of pairs(this.equippedRuneforgeById)) { - if (slotName == slot) { - delete this.equippedRuneforgeById[id]; + const powerId = this.getRuneforgePowerId(slot); + if (powerId) { + const [spellId] = this.getRuneforgePowerInfo(powerId); + if (spellId) { + const bonusId = runeforgeBonusId[spellId]; + const bonusIds = + this.equipment.getEquippedItemBonusIds(slot); + for (const [, id] of ipairs(bonusIds)) { + if (bonusId === id) { + this.tracer.debug( + event, + `Slot ${slot} has runeforge bonus ID ${bonusId}` + ); + this.equippedRuneforgeById[id] = slot; + break; + } + } + } } } + }; + + private getRuneforgePowerId = (slot: SlotName): number | undefined => { const location = this.equipment.getEquippedItemLocation(slot); - if (location != undefined) { + if (location) { if (C_LegendaryCrafting.IsRuneforgeLegendary(location)) { const componentInfo = C_LegendaryCrafting.GetRuneforgeLegendaryComponentInfo( location ); - const id = tonumber(componentInfo.powerID); - this.equippedRuneforgeById[id] = slot; + return componentInfo.powerID; } } + return undefined; + }; + + private getRuneforgePowerInfo = ( + powerId: number + ): [number | undefined, string | undefined] => { + const powerInfo = C_LegendaryCrafting.GetRuneforgePowerInfo(powerId); + if (powerInfo) { + const spellId = powerInfo.descriptionSpellID; + const name = powerInfo.name; + return [spellId, name]; + } + return [undefined, undefined]; }; + hasRuneforge(id: number) { + return this.equippedRuneforgeById[id] !== undefined; + } + registerConditions(condition: OvaleConditionClass) { condition.registerCondition( "equippedruneforge", @@ -143,12 +153,6 @@ export class Runeforge { private equippedRuneforge: ConditionFunction = (positionalParameters) => { const id = positionalParameters[1] as number; - /* Check both lists and return true if the ID is in either of them. - * Technically could be incorrect, but chance of collision is very low. - */ - if (this.equippedLegendaryById[id] || this.equippedRuneforgeById[id]) { - return returnBoolean(true); - } - return returnBoolean(false); + return returnBoolean(this.hasRuneforge(id)); }; } diff --git a/src/utils/importsimc/export-data.ts b/src/utils/importsimc/export-data.ts index f5707745f..2765ea1f4 100644 --- a/src/utils/importsimc/export-data.ts +++ b/src/utils/importsimc/export-data.ts @@ -4,9 +4,11 @@ import { DbcData } from "./importspells"; export function exportData(dbc: DbcData) { const lines = [ `import { LuaArray } from "@wowts/lua"; + interface ConduitData { ranks: LuaArray; -}`, +} +`, ]; lines.push("export const conduits: LuaArray = {"); for (const [id, conduit] of dbc.conduitById.entries()) { @@ -18,6 +20,11 @@ interface ConduitData { lines.push(` },`); lines.push(`},`); } + lines.push("};\n"); + lines.push("export const runeforgeBonusId: LuaArray = {"); + for (const [id, runeforge] of dbc.runeforgeById.entries()) { + lines.push(`[${runeforge.spell_id}]: ${id},`); + } lines.push("};"); writeFileSync("src/engine/dbc.ts", lines.join("\n"), { encoding: "utf8" }); }