Introduce constants for repeated ids
This commit is contained in:
@@ -18,14 +18,19 @@ const EFFECTS = [
|
|||||||
{ id: "health", label: "Health", cap: 15, group: "defense" },
|
{ id: "health", label: "Health", cap: 15, group: "defense" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const PROFILE_IDS = Object.freeze({ LIFESTEAL: "lifesteal", REGEN: "regen" });
|
||||||
|
const COMBAT_STYLES = Object.freeze({ MELEE: "melee", RANGED: "ranged", SKILL: "skill" });
|
||||||
|
const PIECE_TYPES = Object.freeze({ ITEM: "item", MOUNT: "mount", PET: "pet", SKILL: "skill" });
|
||||||
|
const REPLACEMENT_TARGETS = Object.freeze({ MOUNT: "mount", PET: "pet" });
|
||||||
|
|
||||||
const PROFILES = {
|
const PROFILES = {
|
||||||
lifesteal: {
|
[PROFILE_IDS.LIFESTEAL]: {
|
||||||
label: "Lifesteal (DPS + Lifesteal)",
|
label: "Lifesteal (DPS + Lifesteal)",
|
||||||
weights: { critChance: 10, critDamage: 6, blockChance: 2, healthRegen: 2, lifesteal: 10, doubleChance: 10, damage: 10, meleeDamage: 6, rangedDamage: 6, attackSpeed: 9, skillDamage: 7, skillCooldown: 7, health: 3 },
|
weights: { critChance: 10, critDamage: 6, blockChance: 2, healthRegen: 2, lifesteal: 10, doubleChance: 10, damage: 10, meleeDamage: 6, rangedDamage: 6, attackSpeed: 9, skillDamage: 7, skillCooldown: 7, health: 3 },
|
||||||
baseDamage: 1.25,
|
baseDamage: 1.25,
|
||||||
baseHealth: 0.45,
|
baseHealth: 0.45,
|
||||||
},
|
},
|
||||||
regen: {
|
[PROFILE_IDS.REGEN]: {
|
||||||
label: "Regen (Health + Regen)",
|
label: "Regen (Health + Regen)",
|
||||||
weights: { critChance: 4, critDamage: 2, blockChance: 7, healthRegen: 12, lifesteal: 5, doubleChance: 4, damage: 4, meleeDamage: 2, rangedDamage: 2, attackSpeed: 3, skillDamage: 3, skillCooldown: 3, health: 12 },
|
weights: { critChance: 4, critDamage: 2, blockChance: 7, healthRegen: 12, lifesteal: 5, doubleChance: 4, damage: 4, meleeDamage: 2, rangedDamage: 2, attackSpeed: 3, skillDamage: 3, skillCooldown: 3, health: 12 },
|
||||||
baseDamage: 0.45,
|
baseDamage: 0.45,
|
||||||
@@ -47,10 +52,10 @@ const FIXED_ITEMS = [
|
|||||||
{ name: "Belt", baseType: "health", baseValue: 1150000 },
|
{ name: "Belt", baseType: "health", baseValue: 1150000 },
|
||||||
];
|
];
|
||||||
const slots = [
|
const slots = [
|
||||||
...FIXED_ITEMS.map((item, i) => ({ type: "item", title: `Item ${i + 1}`, fixed: item })),
|
...FIXED_ITEMS.map((item, i) => ({ type: PIECE_TYPES.ITEM, title: `Item ${i + 1}`, fixed: item })),
|
||||||
{ type: "mount", title: "Mount" },
|
{ type: PIECE_TYPES.MOUNT, title: "Mount" },
|
||||||
...Array.from({ length: 3 }, (_, i) => ({ type: "pet", title: `Pet ${i + 1}` })),
|
...Array.from({ length: 3 }, (_, i) => ({ type: PIECE_TYPES.PET, title: `Pet ${i + 1}` })),
|
||||||
{ type: "skill", title: "Skill", noEffects: true },
|
{ type: PIECE_TYPES.SKILL, title: "Skill", noEffects: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
const $ = (selector) => document.querySelector(selector);
|
const $ = (selector) => document.querySelector(selector);
|
||||||
@@ -65,8 +70,8 @@ let state = loadDraft() || createDefaultState();
|
|||||||
|
|
||||||
function createDefaultState() {
|
function createDefaultState() {
|
||||||
return {
|
return {
|
||||||
profile: "lifesteal",
|
profile: PROFILE_IDS.LIFESTEAL,
|
||||||
combatStyle: "melee",
|
combatStyle: COMBAT_STYLES.MELEE,
|
||||||
recommendationCount: 8,
|
recommendationCount: 8,
|
||||||
pieces: slots.map((slot, index) => createDefaultPiece(slot, index)),
|
pieces: slots.map((slot, index) => createDefaultPiece(slot, index)),
|
||||||
newItem: createDefaultNewItem(),
|
newItem: createDefaultNewItem(),
|
||||||
@@ -101,7 +106,7 @@ function createDefaultPiece(slot, index) {
|
|||||||
|
|
||||||
function enforceFixedPieceFields(piece, index) {
|
function enforceFixedPieceFields(piece, index) {
|
||||||
const fixed = FIXED_ITEMS[index];
|
const fixed = FIXED_ITEMS[index];
|
||||||
if (!fixed || piece.type !== "item") return piece;
|
if (!fixed || piece.type !== PIECE_TYPES.ITEM) return piece;
|
||||||
const baseValue = Number(piece.baseValue || (fixed.baseType === "damage" ? piece.baseDamage : piece.baseHealth) || fixed.baseValue);
|
const baseValue = Number(piece.baseValue || (fixed.baseType === "damage" ? piece.baseDamage : piece.baseHealth) || fixed.baseValue);
|
||||||
return {
|
return {
|
||||||
...piece,
|
...piece,
|
||||||
@@ -121,7 +126,7 @@ function normalizeState(candidate) {
|
|||||||
...fallback,
|
...fallback,
|
||||||
...candidate,
|
...candidate,
|
||||||
profile,
|
profile,
|
||||||
combatStyle: ["melee", "ranged", "skill"].includes(candidate?.combatStyle) ? candidate.combatStyle : "melee",
|
combatStyle: Object.values(COMBAT_STYLES).includes(candidate?.combatStyle) ? candidate.combatStyle : COMBAT_STYLES.MELEE,
|
||||||
recommendationCount: Math.min(20, Math.max(3, Number(candidate?.recommendationCount || 8))),
|
recommendationCount: Math.min(20, Math.max(3, Number(candidate?.recommendationCount || 8))),
|
||||||
newItem: normalizeNewItem(candidate?.newItem),
|
newItem: normalizeNewItem(candidate?.newItem),
|
||||||
pieces: fallback.pieces.map((piece, index) => normalizePiece(piece, candidate?.pieces?.[index], index)),
|
pieces: fallback.pieces.map((piece, index) => normalizePiece(piece, candidate?.pieces?.[index], index)),
|
||||||
@@ -167,9 +172,9 @@ function normalizeEffects(candidateEffects) {
|
|||||||
|
|
||||||
function normalizeProfile(profile) {
|
function normalizeProfile(profile) {
|
||||||
if (PROFILES[profile]) return profile;
|
if (PROFILES[profile]) return profile;
|
||||||
if (["damage", "skill", "balanced"].includes(profile)) return "lifesteal";
|
if (["damage", "skill", "balanced"].includes(profile)) return PROFILE_IDS.LIFESTEAL;
|
||||||
if (profile === "survival") return "regen";
|
if (profile === "survival") return PROFILE_IDS.REGEN;
|
||||||
return "lifesteal";
|
return PROFILE_IDS.LIFESTEAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
function clampEffectValue(type, value) {
|
function clampEffectValue(type, value) {
|
||||||
@@ -193,8 +198,8 @@ function render() {
|
|||||||
function getReplacementOptions() {
|
function getReplacementOptions() {
|
||||||
return [
|
return [
|
||||||
...FIXED_ITEMS.map((item, index) => ({ value: `item-${index}`, label: item.name })),
|
...FIXED_ITEMS.map((item, index) => ({ value: `item-${index}`, label: item.name })),
|
||||||
{ value: "mount", label: "Mount" },
|
{ value: REPLACEMENT_TARGETS.MOUNT, label: "Mount" },
|
||||||
{ value: "pet", label: "Pet (worst current pet)" },
|
{ value: REPLACEMENT_TARGETS.PET, label: "Pet (worst current pet)" },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,10 +435,10 @@ function getReplacementTargetPiece(target, pieceScores) {
|
|||||||
const pinned = state.pieces.find((piece) => piece.id === state.newItem.targetPieceId);
|
const pinned = state.pieces.find((piece) => piece.id === state.newItem.targetPieceId);
|
||||||
if (pinned) return pinned;
|
if (pinned) return pinned;
|
||||||
}
|
}
|
||||||
if (target === "mount") return state.pieces.find((piece) => piece.type === "mount") || null;
|
if (target === REPLACEMENT_TARGETS.MOUNT) return state.pieces.find((piece) => piece.type === PIECE_TYPES.MOUNT) || null;
|
||||||
if (target === "pet") {
|
if (target === REPLACEMENT_TARGETS.PET) {
|
||||||
return [...pieceScores]
|
return [...pieceScores]
|
||||||
.filter(({ piece }) => piece.type === "pet")
|
.filter(({ piece }) => piece.type === PIECE_TYPES.PET)
|
||||||
.sort((a, b) => a.score - b.score)[0]?.piece || null;
|
.sort((a, b) => a.score - b.score)[0]?.piece || null;
|
||||||
}
|
}
|
||||||
const fixed = /^item-(\d+)$/.exec(target || "");
|
const fixed = /^item-(\d+)$/.exec(target || "");
|
||||||
@@ -446,7 +451,7 @@ function createNewItemCandidate(target) {
|
|||||||
const fixedBaseHealth = fixed?.baseType === "health" ? Number(state.newItem.baseHealth || fixed.baseValue) : 0;
|
const fixedBaseHealth = fixed?.baseType === "health" ? Number(state.newItem.baseHealth || fixed.baseValue) : 0;
|
||||||
return {
|
return {
|
||||||
id: "new-item",
|
id: "new-item",
|
||||||
type: target === "mount" ? "mount" : target === "pet" ? "pet" : "item",
|
type: target === REPLACEMENT_TARGETS.MOUNT ? PIECE_TYPES.MOUNT : target === REPLACEMENT_TARGETS.PET ? PIECE_TYPES.PET : PIECE_TYPES.ITEM,
|
||||||
name: "New item",
|
name: "New item",
|
||||||
baseDamage: fixed ? fixedBaseDamage : Number(state.newItem.baseDamage || 0),
|
baseDamage: fixed ? fixedBaseDamage : Number(state.newItem.baseDamage || 0),
|
||||||
baseHealth: fixed ? fixedBaseHealth : Number(state.newItem.baseHealth || 0),
|
baseHealth: fixed ? fixedBaseHealth : Number(state.newItem.baseHealth || 0),
|
||||||
@@ -524,11 +529,11 @@ function deltaClass(value) {
|
|||||||
return "delta-neutral";
|
return "delta-neutral";
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateDps(totals, combatStyle = "melee") {
|
function calculateDps(totals, combatStyle = COMBAT_STYLES.MELEE) {
|
||||||
return calculateDamageDetails(totals, combatStyle).dps;
|
return calculateDamageDetails(totals, combatStyle).dps;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateDamageDetails(totals, combatStyle = "melee") {
|
function calculateDamageDetails(totals, combatStyle = COMBAT_STYLES.MELEE) {
|
||||||
const effects = totals.effects;
|
const effects = totals.effects;
|
||||||
const baseDamage = Math.max(0, totals.baseDamage);
|
const baseDamage = Math.max(0, totals.baseDamage);
|
||||||
const globalDamage = 1 + effects.damage / 100;
|
const globalDamage = 1 + effects.damage / 100;
|
||||||
@@ -540,7 +545,7 @@ function calculateDamageDetails(totals, combatStyle = "melee") {
|
|||||||
const critDamage = effects.critDamage / 100;
|
const critDamage = effects.critDamage / 100;
|
||||||
const crit = 1 + critChance * critDamage;
|
const crit = 1 + critChance * critDamage;
|
||||||
const critHit = singleHit * (1 + critDamage);
|
const critHit = singleHit * (1 + critDamage);
|
||||||
const cooldown = combatStyle === "skill" ? 1 / Math.max(0.05, 1 - effects.skillCooldown / 100) : 1;
|
const cooldown = combatStyle === COMBAT_STYLES.SKILL ? 1 / Math.max(0.05, 1 - effects.skillCooldown / 100) : 1;
|
||||||
return {
|
return {
|
||||||
singleHit,
|
singleHit,
|
||||||
critHit,
|
critHit,
|
||||||
@@ -570,8 +575,8 @@ function calculateRegenDetails(totals, dps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getStyleDamageBonus(effects, combatStyle) {
|
function getStyleDamageBonus(effects, combatStyle) {
|
||||||
if (combatStyle === "ranged") return effects.rangedDamage;
|
if (combatStyle === COMBAT_STYLES.RANGED) return effects.rangedDamage;
|
||||||
if (combatStyle === "skill") return effects.skillDamage;
|
if (combatStyle === COMBAT_STYLES.SKILL) return effects.skillDamage;
|
||||||
return effects.meleeDamage;
|
return effects.meleeDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user