Replace profiles with regen-focused modes

This commit is contained in:
Jan Bader
2026-06-16 20:35:41 +02:00
parent e12a58ba1f
commit b8b1346f3f
3 changed files with 48 additions and 31 deletions
+32 -23
View File
@@ -15,29 +15,17 @@ const EFFECTS = [
];
const PROFILES = {
balanced: {
label: "Balanced",
weights: { critChance: 8, critDamage: 4, blockChance: 7, healthRegen: 7, lifesteal: 7, doubleChance: 8, damage: 9, meleeDamage: 3, rangedDamage: 5, attackSpeed: 6, skillDamage: 5, skillCooldown: 8, health: 7 },
baseDamage: 1,
baseHealth: 0.75,
},
damage: {
label: "Damage focused",
weights: { critChance: 10, critDamage: 6, blockChance: 3, healthRegen: 3, lifesteal: 6, doubleChance: 10, damage: 10, meleeDamage: 5, rangedDamage: 7, attackSpeed: 8, skillDamage: 7, skillCooldown: 7, health: 3 },
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 },
baseDamage: 1.25,
baseHealth: 0.45,
},
survival: {
label: "Survivability focused",
weights: { critChance: 5, critDamage: 2, blockChance: 10, healthRegen: 10, lifesteal: 9, doubleChance: 5, damage: 5, meleeDamage: 2, rangedDamage: 3, attackSpeed: 4, skillDamage: 3, skillCooldown: 5, health: 10 },
baseDamage: 0.65,
baseHealth: 1.2,
},
skill: {
label: "Skill focused",
weights: { critChance: 7, critDamage: 4, blockChance: 5, healthRegen: 5, lifesteal: 6, doubleChance: 7, damage: 7, meleeDamage: 2, rangedDamage: 4, attackSpeed: 5, skillDamage: 10, skillCooldown: 11, health: 5 },
baseDamage: 0.9,
baseHealth: 0.65,
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 },
baseDamage: 0.45,
baseHealth: 1.35,
},
};
@@ -69,7 +57,7 @@ let state = loadDraft() || createDefaultState();
function createDefaultState() {
return {
profile: "balanced",
profile: "lifesteal",
combatStyle: "melee",
recommendationCount: 8,
pieces: slots.map((slot, index) => createDefaultPiece(slot, index)),
@@ -108,10 +96,11 @@ function enforceFixedPieceFields(piece, index) {
function normalizeState(candidate) {
const fallback = createDefaultState();
const profile = normalizeProfile(candidate?.profile);
return {
...fallback,
...candidate,
profile: PROFILES[candidate?.profile] ? candidate.profile : "balanced",
profile,
combatStyle: ["melee", "ranged", "skill"].includes(candidate?.combatStyle) ? candidate.combatStyle : "melee",
recommendationCount: Math.min(20, Math.max(3, Number(candidate?.recommendationCount || 8))),
pieces: fallback.pieces.map((piece, index) => enforceFixedPieceFields({
@@ -131,6 +120,13 @@ function normalizeState(candidate) {
};
}
function normalizeProfile(profile) {
if (PROFILES[profile]) return profile;
if (["damage", "skill", "balanced"].includes(profile)) return "lifesteal";
if (profile === "survival") return "regen";
return "lifesteal";
}
function clampEffectValue(type, value) {
if (!type) return 1;
const effect = effectById(type);
@@ -223,6 +219,7 @@ function updateAnalysis() {
const totals = calculateTotals();
const damageDetails = calculateDamageDetails(totals, state.combatStyle);
const dps = damageDetails.dps;
const regenDetails = calculateRegenDetails(totals, dps);
const survivability = calculateSurvivability(totals);
const pieceScores = state.pieces.map((piece) => scorePiece(piece, profile, totals));
@@ -230,7 +227,8 @@ function updateAnalysis() {
$("#totalHealth").textContent = fmt(totals.baseHealth);
$("#dpsValue").textContent = fmt(dps);
$("#hitDamageDetails").innerHTML = `Hit ${fmt(damageDetails.singleHit)}<br>Crit ${fmt(damageDetails.critHit)}`;
$("#defenseScore").textContent = fmt(calculateGroupScore(totals, profile, ["defense", "hybrid"], "health"));
$("#regenValue").textContent = fmt(regenDetails.total);
$("#regenDetails").innerHTML = `Health regen ${fmt(regenDetails.healthRegen)}<br>Lifesteal ${fmt(regenDetails.lifesteal)}`;
document.querySelectorAll(".gear-card").forEach((card, index) => {
card.querySelector(".piece-score").textContent = `Score ${fmt(pieceScores[index].score)}`;
@@ -289,6 +287,17 @@ function calculateSurvivability(totals) {
return health * blockMultiplier * regenMultiplier * lifestealMultiplier;
}
function calculateRegenDetails(totals, dps) {
const maxHealth = Math.max(0, totals.baseHealth) * (1 + totals.effects.health / 100);
const healthRegen = maxHealth * (totals.effects.healthRegen / 100);
const lifesteal = Math.max(0, dps) * (totals.effects.lifesteal / 100);
return {
healthRegen,
lifesteal,
total: healthRegen + lifesteal,
};
}
function getStyleDamageBonus(effects, combatStyle) {
if (combatStyle === "ranged") return effects.rangedDamage;
if (combatStyle === "skill") return effects.skillDamage;