adding abilities, created skill tree template and unlock mechanics

This commit is contained in:
2025-11-28 21:41:46 -06:00
parent d9bc46adc1
commit a8767b34e2
96 changed files with 3331 additions and 13 deletions

View File

@@ -714,22 +714,18 @@ def view_skills(character_id: str):
api_client = get_api_client()
try:
# Get character data
# Get character data (includes full player_class with skill_trees)
response = api_client.get(f"/api/v1/characters/{character_id}")
character = response.get('result')
# Load class data to get skill trees
class_id = character.get('class_id')
player_class = None
if class_id:
response = api_client.get(f"/api/v1/classes/{class_id}")
player_class = response.get('result')
# Player class is already embedded in character response
player_class = character.get('player_class')
logger.info(
"Skill tree viewed",
user_id=user.get('id'),
character_id=character_id
character_id=character_id,
class_id=player_class.get('class_id') if player_class else None
)
return render_template(
@@ -752,3 +748,145 @@ def view_skills(character_id: str):
)
flash('An error occurred while loading the skill tree.', 'error')
return redirect(url_for('character_views.list_characters'))
@character_bp.route('/<character_id>/skills/unlock', methods=['POST'])
@require_auth_web
def unlock_skill(character_id: str):
"""
Unlock a skill for a character (HTMX endpoint).
Args:
character_id: ID of the character
Returns:
Re-rendered skills container partial
"""
user = get_current_user()
api_client = get_api_client()
skill_id = request.form.get('skill_id')
if not skill_id:
return _render_skills_page(
api_client, character_id, user,
error="No skill specified"
)
try:
# Call API to unlock skill
api_client.post(
f"/api/v1/characters/{character_id}/skills/unlock",
data={'skill_id': skill_id}
)
logger.info(
"Skill unlocked",
user_id=user.get('id'),
character_id=character_id,
skill_id=skill_id
)
return _render_skills_page(
api_client, character_id, user,
message=f"Skill unlocked!"
)
except APIError as e:
logger.error(
"Failed to unlock skill",
user_id=user.get('id'),
character_id=character_id,
skill_id=skill_id,
error=str(e)
)
return _render_skills_page(
api_client, character_id, user,
error=str(e.message) if hasattr(e, 'message') else "Failed to unlock skill"
)
@character_bp.route('/<character_id>/skills/respec', methods=['POST'])
@require_auth_web
def respec_skills(character_id: str):
"""
Respec all skills for a character (HTMX endpoint).
Args:
character_id: ID of the character
Returns:
Re-rendered skills container partial
"""
user = get_current_user()
api_client = get_api_client()
try:
# Call API to respec skills
response = api_client.post(f"/api/v1/characters/{character_id}/skills/respec")
result = response.get('result', {})
logger.info(
"Skills respec",
user_id=user.get('id'),
character_id=character_id,
cost=result.get('cost')
)
return _render_skills_page(
api_client, character_id, user,
message=f"Skills reset! {result.get('available_points', 0)} skill points refunded."
)
except APIError as e:
logger.error(
"Failed to respec skills",
user_id=user.get('id'),
character_id=character_id,
error=str(e)
)
return _render_skills_page(
api_client, character_id, user,
error=str(e.message) if hasattr(e, 'message') else "Failed to respec skills"
)
def _render_skills_page(api_client, character_id: str, user: dict,
message: str = None, error: str = None):
"""
Helper to render the skills container partial for HTMX updates.
Args:
api_client: API client instance
character_id: Character ID
user: Current user dict
message: Optional success message
error: Optional error message
Returns:
Rendered skills container HTML (partial, no base template)
"""
try:
# Get fresh character data (includes full player_class with skill_trees)
response = api_client.get(f"/api/v1/characters/{character_id}")
character = response.get('result')
# Player class is already embedded in character response
player_class = character.get('player_class')
# Use partial template for HTMX responses (no base.html wrapper)
return render_template(
'character/partials/skills_container.html',
character=character,
player_class=player_class,
message=message,
error=error
)
except APIError as e:
logger.error("Failed to render skills page", error=str(e))
return render_template(
'character/partials/skills_container.html',
character={'character_id': character_id, 'name': 'Unknown', 'unlocked_skills': [], 'available_skill_points': 0, 'level': 1, 'gold': 0},
player_class=None,
error="Failed to load character data"
)