forked from phenom/healer-man
Honor RoM off-hand and ranged equipment slots
This commit is contained in:
1 parent
0206fda9e2
commit
7449abdad2
15 files changed
+150
-29
No files matched your search
+26
-3
@@ -44,6 +44,11 @@ export interface EquipmentChange {
|
||||
readonly reason?: string;
|
||||
}
|
||||
|
||||
export interface EquipmentClassContext {
|
||||
readonly secondaryClassId?: ClassId | null;
|
||||
readonly level?: number;
|
||||
}
|
||||
|
||||
const equipmentSlotSet = new Set<string>(EQUIPMENT_SLOTS);
|
||||
|
||||
const ARMOR_RANK: Readonly<Record<string, number>> = Object.freeze({
|
||||
@@ -62,6 +67,7 @@ const SHIELD_CLASSES = new Set<ClassId>([
|
||||
|
||||
const WEAPON_CLASSES: Readonly<Record<string, ReadonlySet<BaseClassId>>> = Object.freeze({
|
||||
bow: new Set<BaseClassId>(["warrior", "hunter", "rogue"]),
|
||||
crossbow: new Set<BaseClassId>(["warrior", "hunter", "rogue"]),
|
||||
dagger: new Set<BaseClassId>(["warrior", "hunter", "rogue", "priest", "shaman", "mage", "warlock", "druid"]),
|
||||
mace: new Set<BaseClassId>(["warrior", "paladin", "priest", "death-knight", "shaman", "druid"]),
|
||||
staff: new Set<BaseClassId>(["warrior", "hunter", "priest", "shaman", "mage", "warlock", "druid"]),
|
||||
@@ -75,7 +81,23 @@ export function equipmentSlotForItem(item: InventoryItem): EquipmentSlot | null
|
||||
return equipmentSlotSet.has(slot) ? slot as EquipmentSlot : null;
|
||||
}
|
||||
|
||||
export function classCanEquipItem(classId: ClassId, item: InventoryItem): boolean {
|
||||
export function classCanEquipItem(classId: ClassId, item: InventoryItem, context: EquipmentClassContext = {}): boolean {
|
||||
const slot = equipmentSlotForItem(item);
|
||||
if (!slot) return false;
|
||||
const level = context.level ?? Number.POSITIVE_INFINITY;
|
||||
if (classId.startsWith("rom-")) {
|
||||
if (slot === "off-hand" && item.weaponType
|
||||
&& level < 16) return false;
|
||||
if (slot === "off-hand" && item.weaponType
|
||||
&& classId !== "rom-rogue" && context.secondaryClassId !== "rom-rogue") return false;
|
||||
if (slot === "ranged") {
|
||||
if (item.weaponType === "bow" || item.weaponType === "crossbow") return classId === "rom-scout"
|
||||
|| (context.secondaryClassId === "rom-scout" && level >= 10);
|
||||
if (item.weaponType === "projectile" || item.weaponType === "throwing") return (classId === "rom-rogue"
|
||||
|| context.secondaryClassId === "rom-rogue") && level >= 12;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (item.armorType === "shield" && !SHIELD_CLASSES.has(classId)) return false;
|
||||
if (item.armorType && item.armorType !== "shield") {
|
||||
const requiredRank = ARMOR_RANK[item.armorType] ?? Number.POSITIVE_INFINITY;
|
||||
@@ -85,7 +107,7 @@ export function classCanEquipItem(classId: ClassId, item: InventoryItem): boolea
|
||||
const allowedClasses = WEAPON_CLASSES[item.weaponType];
|
||||
if (!allowedClasses?.has(baseClassFor(classId))) return false;
|
||||
}
|
||||
return equipmentSlotForItem(item) !== null;
|
||||
return true;
|
||||
}
|
||||
|
||||
function mutableAssignments(assignments: EquipmentAssignments): Record<string, EquipmentLoadout> {
|
||||
@@ -114,12 +136,13 @@ export function equipInventoryItem(
|
||||
ownerId: string,
|
||||
ownerClassId: ClassId,
|
||||
instanceId: string,
|
||||
classContext: EquipmentClassContext = {},
|
||||
): EquipmentChange {
|
||||
const item = inventory.find((candidate) => candidate.instanceId === instanceId);
|
||||
if (!item) return { ok: false, assignments, reason: "That item is no longer in your inventory." };
|
||||
const slot = equipmentSlotForItem(item);
|
||||
if (!slot) return { ok: false, assignments, reason: `${item.name} does not use an equippable slot.` };
|
||||
if (!classCanEquipItem(ownerClassId, item)) {
|
||||
if (!classCanEquipItem(ownerClassId, item, classContext)) {
|
||||
return { ok: false, assignments, reason: `That class cannot equip ${item.name}.` };
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user