step 10.9: done
This commit is contained in:
@@ -167,6 +167,9 @@ async function loadCharacter() {
|
||||
// Update energy bar and start countdown
|
||||
updateEnergyBar(energy.current, energy.max, energy.nextTickInSec);
|
||||
startCountdown();
|
||||
|
||||
// Initialize allocation UI
|
||||
initAllocationUI(character.unspent_points);
|
||||
} catch (err) {
|
||||
// Not authenticated — redirect to login
|
||||
window.location.href = '/login.html';
|
||||
@@ -849,6 +852,146 @@ function startExpeditionSync() {
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// ===== Stat allocation UI =====
|
||||
|
||||
const STAT_KEYS = ['str', 'agi', 'int', 'vit'];
|
||||
const STAT_LABELS = { str: 'STR', agi: 'AGI', int: 'INT', vit: 'VIT' };
|
||||
|
||||
// Temporary allocation state (what the user has clicked, not yet sent)
|
||||
let allocTemp = { str: 0, agi: 0, int: 0, vit: 0 };
|
||||
|
||||
/**
|
||||
* Build the allocation rows (one per stat) with + buttons.
|
||||
*/
|
||||
function buildAllocationRows() {
|
||||
const container = document.getElementById('alloc-rows');
|
||||
if (!container) return;
|
||||
|
||||
container.replaceChildren();
|
||||
|
||||
for (const key of STAT_KEYS) {
|
||||
const row = document.createElement('div');
|
||||
row.className = 'alloc-row';
|
||||
|
||||
const label = document.createElement('span');
|
||||
label.className = 'alloc-label';
|
||||
label.textContent = STAT_LABELS[key];
|
||||
|
||||
const value = document.createElement('span');
|
||||
value.className = 'alloc-value';
|
||||
value.id = 'alloc-val-' + key;
|
||||
value.textContent = '0';
|
||||
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'alloc-btn';
|
||||
btn.type = 'button';
|
||||
btn.textContent = '+';
|
||||
btn.dataset.stat = key;
|
||||
btn.addEventListener('click', handleAllocIncrement);
|
||||
|
||||
row.appendChild(label);
|
||||
row.appendChild(value);
|
||||
row.appendChild(btn);
|
||||
container.appendChild(row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle + button click: increment temp allocation for that stat.
|
||||
*/
|
||||
function handleAllocIncrement(e) {
|
||||
const stat = e.target.dataset.stat;
|
||||
if (!stat) return;
|
||||
|
||||
allocTemp[stat]++;
|
||||
document.getElementById('alloc-val-' + stat).textContent = allocTemp[stat];
|
||||
updateAllocState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update button states and apply button enable/disable.
|
||||
*/
|
||||
function updateAllocState() {
|
||||
const total = STAT_KEYS.reduce((sum, k) => sum + allocTemp[k], 0);
|
||||
const totalEl = document.getElementById('alloc-total');
|
||||
const applyBtn = document.getElementById('alloc-apply-btn');
|
||||
|
||||
if (totalEl) totalEl.textContent = 'Allocated: ' + total;
|
||||
|
||||
// Enable apply only when at least one point allocated and unspent points remain
|
||||
const unspent = parseInt(document.getElementById('unspent-points').textContent, 10) || 0;
|
||||
const canApply = total > 0 && total <= unspent;
|
||||
if (applyBtn) applyBtn.disabled = !canApply;
|
||||
|
||||
// Disable + buttons when total would exceed unspent
|
||||
for (const key of STAT_KEYS) {
|
||||
const btn = document.querySelector('.alloc-btn[data-stat="' + key + '"]');
|
||||
if (btn) {
|
||||
btn.disabled = (total >= unspent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle apply button: send allocation to server, refresh stats.
|
||||
*/
|
||||
async function handleAllocApply() {
|
||||
const applyBtn = document.getElementById('alloc-apply-btn');
|
||||
if (applyBtn.disabled) return;
|
||||
|
||||
// Build allocation object (only stats that were incremented)
|
||||
const allocation = {};
|
||||
let hasPoints = false;
|
||||
for (const key of STAT_KEYS) {
|
||||
if (allocTemp[key] > 0) {
|
||||
allocation[key] = allocTemp[key];
|
||||
hasPoints = true;
|
||||
}
|
||||
}
|
||||
if (!hasPoints) return;
|
||||
|
||||
applyBtn.disabled = true;
|
||||
applyBtn.textContent = 'Applying...';
|
||||
|
||||
try {
|
||||
const data = await api.post('/character/allocate', allocation);
|
||||
if (!data) {
|
||||
showToast('Allocation failed.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
showToast('Stats allocated!', 'success');
|
||||
|
||||
// Reset temp allocation
|
||||
allocTemp = { str: 0, agi: 0, int: 0, vit: 0 };
|
||||
|
||||
// Reload character to get updated stats
|
||||
await loadCharacter();
|
||||
} catch (err) {
|
||||
showToast(err.message || 'Allocation failed.', 'error');
|
||||
// Reload to restore state
|
||||
await loadCharacter();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize or refresh the allocation UI based on current character data.
|
||||
*/
|
||||
function initAllocationUI(unspentPoints) {
|
||||
const section = document.getElementById('allocation-section');
|
||||
if (!section) return;
|
||||
|
||||
if (unspentPoints > 0) {
|
||||
section.style.display = 'block';
|
||||
document.getElementById('unspent-points').textContent = unspentPoints;
|
||||
buildAllocationRows();
|
||||
updateAllocState();
|
||||
} else {
|
||||
section.style.display = 'none';
|
||||
allocTemp = { str: 0, agi: 0, int: 0, vit: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Init =====
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
await loadCharacter();
|
||||
@@ -861,6 +1004,12 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
document.querySelectorAll('.tab').forEach((tab) => {
|
||||
tab.addEventListener('click', () => switchTab(tab.dataset.tab));
|
||||
});
|
||||
|
||||
// Allocation apply button
|
||||
const applyBtn = document.getElementById('alloc-apply-btn');
|
||||
if (applyBtn) {
|
||||
applyBtn.addEventListener('click', handleAllocApply);
|
||||
}
|
||||
});
|
||||
|
||||
// Logout handler
|
||||
|
||||
Reference in New Issue
Block a user