128 lines
5.9 KiB
HTML
128 lines
5.9 KiB
HTML
{# Skills Container Partial - For HTMX updates #}
|
|
{# Calculate available skill points: level minus unlocked skills count #}
|
|
{% set skill_points = character.available_skill_points|default(character.level - (character.unlocked_skills|default([])|length), true) %}
|
|
|
|
<div class="skills-container" id="skills-container">
|
|
{# Back Link #}
|
|
<div class="skills-back-link">
|
|
<a href="{{ url_for('character_views.view_character', character_id=character.character_id) }}">
|
|
← Back to {{ character.name }}
|
|
</a>
|
|
</div>
|
|
|
|
{# Header #}
|
|
<div class="skills-header">
|
|
<h1>{{ character.name }}'s Skill Trees</h1>
|
|
<div class="skills-info">
|
|
<div class="skill-points-display">
|
|
<span class="skill-points-label">Skill Points:</span>
|
|
<span class="skill-points-value">{{ skill_points }}</span>
|
|
</div>
|
|
{% set respec_cost = character.level * 100 %}
|
|
<button class="btn-respec"
|
|
hx-post="{{ url_for('character_views.respec_skills', character_id=character.character_id) }}"
|
|
hx-target="#skills-container"
|
|
hx-swap="outerHTML"
|
|
hx-confirm="Respec will reset all skills and cost {{ respec_cost }} gold. Continue?"
|
|
{% if character.gold < respec_cost or not character.unlocked_skills %}disabled{% endif %}>
|
|
Respec ({{ respec_cost }} gold)
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{# Flash Messages #}
|
|
{% if message %}
|
|
<div class="skills-message skills-message--success">{{ message }}</div>
|
|
{% endif %}
|
|
{% if error %}
|
|
<div class="skills-message skills-message--error">{{ error }}</div>
|
|
{% endif %}
|
|
|
|
{# Skill Trees Grid #}
|
|
{% if player_class and player_class.skill_trees %}
|
|
<div class="skill-trees-grid">
|
|
{% for tree in player_class.skill_trees %}
|
|
<div class="skill-tree" data-tree-id="{{ tree.tree_id }}">
|
|
{# Tree Header #}
|
|
<div class="tree-header">
|
|
<h2 class="tree-name">{{ tree.name }}</h2>
|
|
<p class="tree-description">{{ tree.description }}</p>
|
|
</div>
|
|
|
|
{# Tree Diagram (Tiers 5 to 1, top to bottom) #}
|
|
<div class="tree-diagram">
|
|
{% for tier in range(5, 0, -1) %}
|
|
<div class="skill-tier" data-tier="{{ tier }}">
|
|
<span class="tier-label">Tier {{ tier }}</span>
|
|
<div class="skill-nodes">
|
|
{% for node in tree.nodes if node.tier == tier %}
|
|
{# Determine node state #}
|
|
{% set is_unlocked = node.skill_id in character.unlocked_skills %}
|
|
{% set prereqs_met = not node.prerequisites or (node.prerequisites | select('in', character.unlocked_skills) | list | length == node.prerequisites | length) %}
|
|
{% set has_lower_tier = tier == 1 or (tree.nodes | selectattr('tier', 'equalto', tier - 1) | selectattr('skill_id', 'in', character.unlocked_skills) | list | length > 0) %}
|
|
{% set can_unlock = not is_unlocked and prereqs_met and has_lower_tier and skill_points > 0 %}
|
|
{% set has_prereq = node.prerequisites | length > 0 %}
|
|
|
|
<div class="skill-node {% if is_unlocked %}skill-node--unlocked{% elif can_unlock %}skill-node--available{% else %}skill-node--locked{% endif %}{% if has_prereq %} skill-node--has-prereq{% endif %}"
|
|
data-skill-id="{{ node.skill_id }}"
|
|
data-tree-id="{{ tree.tree_id }}"
|
|
onmouseenter="showTooltip(event, '{{ node.skill_id }}')"
|
|
onmouseleave="hideTooltip()">
|
|
|
|
<div class="node-icon">
|
|
{% if is_unlocked %}
|
|
✓
|
|
{% elif can_unlock %}
|
|
◇
|
|
{% else %}
|
|
◆
|
|
{% endif %}
|
|
</div>
|
|
|
|
<span class="node-name">{{ node.name }}</span>
|
|
|
|
{% if can_unlock %}
|
|
<button class="btn-unlock"
|
|
hx-post="{{ url_for('character_views.unlock_skill', character_id=character.character_id) }}"
|
|
hx-vals='{"skill_id": "{{ node.skill_id }}"}'
|
|
hx-target="#skills-container"
|
|
hx-swap="outerHTML"
|
|
onclick="event.stopPropagation()">
|
|
Unlock
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
{# Legend #}
|
|
<div class="skills-legend">
|
|
<div class="legend-item">
|
|
<span class="legend-icon legend-icon--unlocked">✓</span>
|
|
<span>Unlocked</span>
|
|
</div>
|
|
<div class="legend-item">
|
|
<span class="legend-icon legend-icon--available">◇</span>
|
|
<span>Available</span>
|
|
</div>
|
|
<div class="legend-item">
|
|
<span class="legend-icon legend-icon--locked">◆</span>
|
|
<span>Locked</span>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="skills-message skills-message--error">
|
|
Unable to load skill trees for this class.
|
|
</div>
|
|
{% endif %}
|
|
|
|
{# Tooltip Container #}
|
|
<div id="skill-tooltip" class="skill-tooltip"></div>
|
|
</div>
|