Use hybrid WoW-stat gear for five RoM builds

This commit is contained in:
phenom committed 2026-09-23 18:23:31 -04:00
1 parent f4a7d33f74
commit 8e95480d4f
10 files changed
+134 -29

No files matched your search

+17 -8
View File
@@ -24,6 +24,7 @@ import type { InventoryItem } from "./lootTypes";
import type { PartyRole } from "./partyRoles";
import {
gearProfileFor,
isRomHybridGearClass,
specializationScore,
type GearArchetype,
type SpecializationDefinition,
@@ -119,6 +120,8 @@ function weaponTypeFor(classId: ClassId, slot: EquipmentSlot, profile: Specializ
if (slot === "off-hand" && profile.weaponLayout === "dual-wield") return "dagger";
if (slot === "ranged") return profile.gearArchetype === "spell-dps" || profile.gearArchetype === "healer" ? "wand" : "bow";
if (slot !== "main-hand") return null;
if (classId === "rom-scout" && profile.weaponLayout === "ranged") return "dagger";
if (classId === "rom-mage") return profile.weaponLayout === "two-hand" ? "staff" : "dagger";
if (profile.weaponLayout === "caster") {
return ["priest", "shaman", "druid", "witch-doctor", "chronomancer", "primalist", "venomancer"].includes(classId)
? "mace"
@@ -129,8 +132,8 @@ function weaponTypeFor(classId: ClassId, slot: EquipmentSlot, profile: Specializ
return "mace";
}
function inventorySlotFor(slot: EquipmentSlot, layout: WeaponLayout): string {
if (slot === "main-hand") return layout === "two-hand" || layout === "ranged" ? "two-hand" : "one-hand";
function inventorySlotFor(classId: ClassId, slot: EquipmentSlot, layout: WeaponLayout): string {
if (slot === "main-hand") return layout === "two-hand" || (layout === "ranged" && classId !== "rom-scout") ? "two-hand" : "one-hand";
return slot;
}
@@ -212,13 +215,16 @@ function heirloomItem(
if (cached) return cached;
const armorType = armorTypeForSlot(context.classId, slot, layout);
const weaponType = weaponTypeFor(context.classId, slot, { ...profile, weaponLayout: layout });
const inventorySlot = inventorySlotFor(slot, layout);
const inventorySlot = inventorySlotFor(context.classId, slot, layout);
const weight = SLOT_WEIGHT[slot];
const budget = Math.max(2, level * weight * 1.18);
const armor = armorType && armorType !== "shield"
? Math.max(1, Math.round(level * weight * ({ cloth: 1, leather: 1.35, mail: 1.7, chain: 1.7, plate: 2.1 }[armorType] ?? 1)))
: armorType === "shield" ? Math.max(2, Math.round(level * weight * 3.2)) : 0;
const sourceStats = statDistribution(profile.gearArchetype, budget, armor);
const distributedStats = statDistribution(profile.gearArchetype, budget, armor);
const sourceStats = armorType === "shield" && isRomHybridGearClass(context.classId)
? { ...distributedStats, blockValue: Math.max(1, Math.round(level * weight * 0.45)) }
: distributedStats;
const sourceWeapon = weaponStats(slot, inventorySlot, weaponType, budget);
let stats = itemStatsFor({
itemId: 9_000_000,
@@ -232,11 +238,11 @@ function heirloomItem(
sourceWeapon,
});
const currentScore = specializationScore(stats, profile);
const catalogScore = highestCatalogScore(context.classId, slot, level, profile)
+ (slot === "main-hand" && ["two-hand", "ranged"].includes(layout)
const catalogScore = isRomHybridGearClass(context.classId) ? 0 : highestCatalogScore(context.classId, slot, level, profile)
+ (slot === "main-hand" && inventorySlot === "two-hand"
? highestCatalogScore(context.classId, "off-hand", level, profile)
: 0);
const conflictSafety = slot === "main-hand" && ["two-hand", "ranged"].includes(layout) ? 1.05 : 1.02;
const conflictSafety = slot === "main-hand" && inventorySlot === "two-hand" ? 1.05 : 1.02;
const targetScore = catalogScore > 0 ? catalogScore * conflictSafety : currentScore;
if (currentScore > 0 && Math.abs(targetScore - currentScore) > 0.01) stats = scaleStats(stats, targetScore / currentScore);
const normalizedScore = specializationScore(stats, profile);
@@ -277,7 +283,10 @@ export function resolvedEquipmentLoadout(
): Readonly<Partial<Record<EquipmentSlot, InventoryItem>>> {
const profile = gearProfileFor(context.classId, context.specializationId, context.role);
const result: Partial<Record<EquipmentSlot, InventoryItem>> = {};
for (const slot of [...BASE_SLOTS, ...weaponSlots(profile.weaponLayout)]) result[slot] = heirloomItem(context, profile, slot);
for (const slot of [...BASE_SLOTS, ...weaponSlots(profile.weaponLayout)]) {
if (isRomHybridGearClass(context.classId) && slot === "wrist") continue;
result[slot] = heirloomItem(context, profile, slot);
}
const itemById = new Map(inventory.map((item) => [item.instanceId, item]));
const earned = assignments[context.ownerId] ?? {};
for (const slot of EQUIPMENT_SLOTS) {