Combat foundation complete

This commit is contained in:
2025-11-27 22:18:58 -06:00
parent dd92cf5991
commit 6d3fb63355
33 changed files with 1870 additions and 85 deletions

View File

@@ -142,7 +142,7 @@
{% endif %}
</span>
<span class="effect-name">{{ effect.name }}</span>
<span class="effect-duration">{{ effect.remaining_duration }} {% if effect.remaining_duration == 1 %}turn{% else %}turns{% endif %}</span>
<span class="effect-duration">{{ effect.duration }} {% if effect.duration == 1 %}turn{% else %}turns{% endif %}</span>
</div>
{% endfor %}
</div>
@@ -206,43 +206,73 @@
}
});
// Guard against duplicate enemy turn requests
// Enemy turn handling with proper chaining for multiple enemies
let enemyTurnPending = false;
let enemyTurnTimeout = null;
function triggerEnemyTurn() {
// Prevent duplicate requests
if (enemyTurnPending) {
return;
}
// Clear any pending timeout
if (enemyTurnTimeout) {
clearTimeout(enemyTurnTimeout);
}
enemyTurnPending = true;
enemyTurnTimeout = setTimeout(function() {
htmx.ajax('POST', '{{ url_for("combat.combat_enemy_turn", session_id=session_id) }}', {
target: '#combat-log',
swap: 'beforeend'
}).then(function() {
setTimeout(function() {
// Use fetch instead of htmx.ajax for better control over response handling
fetch('{{ url_for("combat.combat_enemy_turn", session_id=session_id) }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'HX-Request': 'true'
},
credentials: 'same-origin'
})
.then(function(response) {
const hasMoreEnemies = response.headers.get('HX-Trigger')?.includes('enemyTurn');
return response.text().then(function(html) {
return { html: html, hasMoreEnemies: hasMoreEnemies };
});
})
.then(function(data) {
// Append the log entry
const combatLog = document.getElementById('combat-log');
if (combatLog) {
combatLog.insertAdjacentHTML('beforeend', data.html);
combatLog.scrollTop = combatLog.scrollHeight;
}
enemyTurnPending = false;
}).catch(function() {
if (data.hasMoreEnemies) {
// More enemies to go - trigger next enemy turn
triggerEnemyTurn();
} else {
// All enemies done - refresh page to update UI
setTimeout(function() {
window.location.reload();
}, 800);
}
})
.catch(function(error) {
console.error('Enemy turn failed:', error);
enemyTurnPending = false;
// Refresh anyway to recover from error state
setTimeout(function() {
window.location.reload();
}, 1000);
});
}, 1000);
}
// Handle enemy turn polling
// Handle player action triggering enemy turn
document.body.addEventListener('htmx:afterRequest', function(event) {
// Check if we need to trigger enemy turn
const response = event.detail.xhr;
if (response && response.getResponseHeader('HX-Trigger')) {
const triggers = response.getResponseHeader('HX-Trigger');
if (triggers && triggers.includes('enemyTurn')) {
triggerEnemyTurn();
}
if (!response) return;
const triggers = response.getResponseHeader('HX-Trigger') || '';
// Only trigger enemy turn from player actions (not from our fetch calls)
if (triggers.includes('enemyTurn') && !enemyTurnPending) {
triggerEnemyTurn();
}
});
@@ -254,5 +284,13 @@
// Let the full page swap happen for victory/defeat screen
}
});
// Auto-trigger enemy turn on page load if it's not the player's turn
{% if not is_player_turn %}
document.addEventListener('DOMContentLoaded', function() {
// Small delay to let the page render first
triggerEnemyTurn();
});
{% endif %}
</script>
{% endblock %}