diff --git a/GAME.md b/GAME.md index ac95fe9..48a900d 100644 --- a/GAME.md +++ b/GAME.md @@ -130,7 +130,7 @@ The app models this with the New item comparison panel: - Enter the new roll's base stat and effects. - The app shows DPS and Regen change separately. - If `Pet` is selected, the app chooses the current worst pet by piece score as the replacement target. -- Swapping in the new roll stores the replaced piece and prior New item fields so the user can swap back. +- Pressing `Swap` exchanges the new roll with the current target. The replaced target becomes the New item candidate, so pressing `Swap` again restores the previous state. ## Profiles diff --git a/README.md b/README.md index 7ec6ad3..fe41e85 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ For the game rules, stat caps, formulas, assumptions, and known limitations used - choose what it would replace, - enter the new roll's value and effects, - compare DPS and Regen changes before swapping. - - use **Swap in new item** to apply it, with **Swap back** available if you want to undo. + - press **Swap** to exchange the new roll with the current target; pressing **Swap** again exchanges them back. 7. Use **Best sacrifice candidates** as a quick shortlist of low-value pieces. When comparing a new pet, choose `Pet`; the app automatically compares against your currently weakest pet. diff --git a/app.js b/app.js index 0221a7a..80d5f7b 100644 --- a/app.js +++ b/app.js @@ -68,10 +68,10 @@ function createDefaultState() { function createDefaultNewItem() { return { target: "item-0", + targetPieceId: null, baseDamage: 0, baseHealth: 0, effects: [{ type: "", value: 1 }, { type: "", value: 1 }], - lastSwap: null, }; } @@ -146,10 +146,10 @@ function normalizeNewItem(candidate) { ...fallback, ...candidate, target: getReplacementOptions().some((option) => option.value === candidate?.target) ? candidate.target : fallback.target, + targetPieceId: candidate?.targetPieceId || null, baseDamage: Math.max(0, Number(candidate?.baseDamage || 0)), baseHealth: Math.max(0, Number(candidate?.baseHealth || 0)), effects, - lastSwap: candidate?.lastSwap || null, }; } @@ -367,9 +367,7 @@ function updateNewItemImpactHints(replacementTotals, replacementDps) { } function updateSwapControls() { - const hasSwap = Boolean(state.newItem.lastSwap); - $("#swapBackNewItem").disabled = !hasSwap; - $("#swapStatus").textContent = hasSwap ? `Can swap back ${state.newItem.lastSwap.piece?.name || "previous item"}.` : ""; + $("#swapStatus").textContent = "Press Swap again to exchange back."; } function calculateTotals() { @@ -407,6 +405,10 @@ function getFixedReplacementTarget(target) { } function getReplacementTargetPiece(target, pieceScores) { + if (state.newItem.targetPieceId) { + const pinned = state.pieces.find((piece) => piece.id === state.newItem.targetPieceId); + if (pinned) return pinned; + } if (target === "mount") return state.pieces.find((piece) => piece.type === "mount") || null; if (target === "pet") { return [...pieceScores] @@ -457,7 +459,6 @@ function cloneNewItem(newItem) { return { ...newItem, effects: newItem.effects.map((effect) => ({ ...effect })), - lastSwap: null, }; } @@ -472,25 +473,21 @@ function swapInNewItem() { const previousPiece = clonePiece(targetPiece); const previousNewItem = cloneNewItem(state.newItem); state.pieces[index] = createPieceFromCandidate(targetPiece, candidate); - state.newItem = { - ...previousNewItem, - lastSwap: { - index, - target: previousNewItem.target, - piece: previousPiece, - newItem: previousNewItem, - swappedAt: new Date().toISOString(), - }, - }; + state.newItem = createNewItemFromPiece(previousPiece, previousNewItem.target, targetPiece.id); render(); } -function swapBackNewItem() { - const lastSwap = state.newItem.lastSwap; - if (!lastSwap || !state.pieces[lastSwap.index]) return; - state.pieces[lastSwap.index] = clonePiece(lastSwap.piece); - state.newItem = cloneNewItem(lastSwap.newItem); - render(); +function createNewItemFromPiece(piece, target, targetPieceId = null) { + return { + target, + targetPieceId, + baseDamage: Number(piece.baseDamage || 0), + baseHealth: Number(piece.baseHealth || 0), + effects: [0, 1].map((index) => ({ + type: piece.effects?.[index]?.type || "", + value: piece.effects?.[index]?.value || 1, + })), + }; } function formatDelta(value, suffix = "") { @@ -833,11 +830,11 @@ function bindEvents() { $("#importFile").addEventListener("change", importUploadedJson); $("#newItemTarget").addEventListener("change", (event) => { state.newItem.target = event.target.value; + state.newItem.targetPieceId = null; renderNewItemComparison(); updateAnalysis(); }); $("#swapNewItem").addEventListener("click", swapInNewItem); - $("#swapBackNewItem").addEventListener("click", swapBackNewItem); $(".new-item-card").addEventListener("input", handleNewItemInput); $(".new-item-card").addEventListener("change", handleNewItemInput); } diff --git a/index.html b/index.html index f5fecd0..1c1fadb 100644 --- a/index.html +++ b/index.html @@ -105,8 +105,7 @@