step 10.9: done

This commit is contained in:
bepis
2026-10-23 01:06:48 +11:00
parent bf0b3867bd
commit 28210ed56c
6 changed files with 464 additions and 15 deletions
+149
View File
@@ -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