Add skill base stat entry
This commit is contained in:
@@ -7,6 +7,7 @@ Forge Master characters can equip:
|
|||||||
- 8 items
|
- 8 items
|
||||||
- 1 mount
|
- 1 mount
|
||||||
- 3 pets
|
- 3 pets
|
||||||
|
- 1 skill base-stat entry
|
||||||
|
|
||||||
Each equipped piece has:
|
Each equipped piece has:
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ The 8 core item slots are fixed and cannot be renamed or have their base stat ed
|
|||||||
| Item 7 | Boots | 1,850,000 health |
|
| Item 7 | Boots | 1,850,000 health |
|
||||||
| Item 8 | Belt | 1,150,000 health |
|
| Item 8 | Belt | 1,150,000 health |
|
||||||
|
|
||||||
Mount and pet base stats remain editable, and each has separate damage and health base values because they can provide both stats at once.
|
Mount and pet base stats remain editable, and each has separate damage and health base values because they can provide both stats at once. Skill base stats are entered separately as damage and health and do not have effects.
|
||||||
|
|
||||||
## Supported effects
|
## Supported effects
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ const slots = [
|
|||||||
...FIXED_ITEMS.map((item, i) => ({ type: "item", title: `Item ${i + 1}`, fixed: item })),
|
...FIXED_ITEMS.map((item, i) => ({ type: "item", title: `Item ${i + 1}`, fixed: item })),
|
||||||
{ type: "mount", title: "Mount" },
|
{ type: "mount", title: "Mount" },
|
||||||
...Array.from({ length: 3 }, (_, i) => ({ type: "pet", title: `Pet ${i + 1}` })),
|
...Array.from({ length: 3 }, (_, i) => ({ type: "pet", title: `Pet ${i + 1}` })),
|
||||||
|
{ type: "skill", title: "Skill", noEffects: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
const $ = (selector) => document.querySelector(selector);
|
const $ = (selector) => document.querySelector(selector);
|
||||||
@@ -86,7 +87,8 @@ function createDefaultPiece(slot, index) {
|
|||||||
baseDamage: slot.fixed?.baseType === "damage" ? slot.fixed.baseValue : 0,
|
baseDamage: slot.fixed?.baseType === "damage" ? slot.fixed.baseValue : 0,
|
||||||
baseHealth: slot.fixed?.baseType === "health" ? slot.fixed.baseValue : 0,
|
baseHealth: slot.fixed?.baseType === "health" ? slot.fixed.baseValue : 0,
|
||||||
fixedBase: Boolean(slot.fixed),
|
fixedBase: Boolean(slot.fixed),
|
||||||
effects: [{ type: "", value: 1 }, { type: "", value: 1 }],
|
noEffects: Boolean(slot.noEffects),
|
||||||
|
effects: slot.noEffects ? [] : [{ type: "", value: 1 }, { type: "", value: 1 }],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +119,8 @@ function normalizeState(candidate) {
|
|||||||
...(candidate?.pieces?.[index] || {}),
|
...(candidate?.pieces?.[index] || {}),
|
||||||
baseDamage: Number(candidate?.pieces?.[index]?.baseDamage ?? (candidate?.pieces?.[index]?.baseType === "damage" ? candidate?.pieces?.[index]?.baseValue : piece.baseDamage) ?? 0),
|
baseDamage: Number(candidate?.pieces?.[index]?.baseDamage ?? (candidate?.pieces?.[index]?.baseType === "damage" ? candidate?.pieces?.[index]?.baseValue : piece.baseDamage) ?? 0),
|
||||||
baseHealth: Number(candidate?.pieces?.[index]?.baseHealth ?? (candidate?.pieces?.[index]?.baseType === "health" ? candidate?.pieces?.[index]?.baseValue : piece.baseHealth) ?? 0),
|
baseHealth: Number(candidate?.pieces?.[index]?.baseHealth ?? (candidate?.pieces?.[index]?.baseType === "health" ? candidate?.pieces?.[index]?.baseValue : piece.baseHealth) ?? 0),
|
||||||
effects: [0, 1].map((effectIndex) => ({
|
noEffects: piece.noEffects || Boolean(candidate?.pieces?.[index]?.noEffects),
|
||||||
|
effects: piece.noEffects ? [] : [0, 1].map((effectIndex) => ({
|
||||||
type: candidate?.pieces?.[index]?.effects?.[effectIndex]?.type || "",
|
type: candidate?.pieces?.[index]?.effects?.[effectIndex]?.type || "",
|
||||||
value: clampEffectValue(
|
value: clampEffectValue(
|
||||||
candidate?.pieces?.[index]?.effects?.[effectIndex]?.type || "",
|
candidate?.pieces?.[index]?.effects?.[effectIndex]?.type || "",
|
||||||
@@ -187,25 +190,29 @@ function renderGear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const effects = node.querySelector(".effects");
|
const effects = node.querySelector(".effects");
|
||||||
piece.effects.forEach((effect, effectIndex) => {
|
if (piece.noEffects) {
|
||||||
const row = document.createElement("div");
|
effects.innerHTML = '<p class="no-effects-note">Base stats only. No effects.</p>';
|
||||||
row.className = "effect-row";
|
} else {
|
||||||
row.innerHTML = `
|
piece.effects.forEach((effect, effectIndex) => {
|
||||||
<label>Effect ${effectIndex + 1}
|
const row = document.createElement("div");
|
||||||
<select data-effect-type="${effectIndex}">
|
row.className = "effect-row";
|
||||||
<option value="">None</option>
|
row.innerHTML = `
|
||||||
${EFFECTS.map((option) => `<option value="${option.id}">${option.label} (max ${option.cap}%)</option>`).join("")}
|
<label>Effect ${effectIndex + 1}
|
||||||
</select>
|
<select data-effect-type="${effectIndex}">
|
||||||
</label>
|
<option value="">None</option>
|
||||||
<label>Percent
|
${EFFECTS.map((option) => `<option value="${option.id}">${option.label} (max ${option.cap}%)</option>`).join("")}
|
||||||
<input data-effect-value="${effectIndex}" type="number" min="1" step="0.1" value="${effect.value}" />
|
</select>
|
||||||
<span class="cap-hint"></span>
|
</label>
|
||||||
</label>`;
|
<label>Percent
|
||||||
row.querySelector("select").value = effect.type;
|
<input data-effect-value="${effectIndex}" type="number" min="1" step="0.1" value="${effect.value}" />
|
||||||
const hint = row.querySelector(".cap-hint");
|
<span class="cap-hint"></span>
|
||||||
hint.textContent = effect.type ? `Cap: ${effectById(effect.type).cap}%` : "Ignored";
|
</label>`;
|
||||||
effects.appendChild(row);
|
row.querySelector("select").value = effect.type;
|
||||||
});
|
const hint = row.querySelector(".cap-hint");
|
||||||
|
hint.textContent = effect.type ? `Cap: ${effectById(effect.type).cap}%` : "Ignored";
|
||||||
|
effects.appendChild(row);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
grid.appendChild(node);
|
grid.appendChild(node);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ h3 { margin-bottom: 0; }
|
|||||||
.effect-row { display: grid; grid-template-columns: 1fr; gap: 0.45rem; align-items: end; }
|
.effect-row { display: grid; grid-template-columns: 1fr; gap: 0.45rem; align-items: end; }
|
||||||
.gear-card .effect-row input[data-effect-value] { width: 100%; }
|
.gear-card .effect-row input[data-effect-value] { width: 100%; }
|
||||||
.cap-hint { color: var(--muted); font-size: 0.8rem; margin-top: 0.2rem; }
|
.cap-hint { color: var(--muted); font-size: 0.8rem; margin-top: 0.2rem; }
|
||||||
|
.no-effects-note { color: var(--muted); font-size: 0.9rem; margin: 0; }
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 900px) {
|
||||||
.hero, .results { grid-template-columns: 1fr; }
|
.hero, .results { grid-template-columns: 1fr; }
|
||||||
|
|||||||
Reference in New Issue
Block a user