artifacts-dashboard/backend/app/engine/decision/heal_policy.py
Paweł Orzech f845647934
Some checks failed
Release / release (push) Has been cancelled
Initial release: Artifacts MMO Dashboard & Automation Platform
Full-stack dashboard for controlling, automating, and analyzing
Artifacts MMO characters via the game's HTTP API.

Backend (FastAPI):
- Async Artifacts API client with rate limiting and retry
- 6 automation strategies (combat, gathering, crafting, trading, task, leveling)
- Automation engine with runner, manager, cooldown tracker, pathfinder
- WebSocket relay (game server -> frontend)
- Game data cache, character snapshots, price history, analytics
- 9 API routers, 7 database tables, 3 Alembic migrations
- 108 unit tests

Frontend (Next.js 15 + shadcn/ui):
- Live character dashboard with HP/XP bars and cooldowns
- Character detail with stats, equipment, inventory, skills, manual actions
- Automation management with live log streaming
- Interactive canvas map with content-type coloring and zoom/pan
- Bank management, Grand Exchange with price charts
- Events, logs, analytics pages with Recharts
- WebSocket auto-reconnect with query cache invalidation
- Settings page, error boundaries, dark theme

Infrastructure:
- Docker Compose (dev + prod)
- GitHub Actions CI/CD
- Documentation (Architecture, Automation, Deployment, API)
2026-03-01 19:46:45 +01:00

77 lines
2.5 KiB
Python

import logging
from app.engine.strategies.base import ActionPlan, ActionType
from app.schemas.game import CharacterSchema
logger = logging.getLogger(__name__)
class HealPolicy:
"""Encapsulates healing decision logic.
Used by strategies to determine *if* and *how* a character should heal.
"""
@staticmethod
def should_heal(character: CharacterSchema, threshold: int) -> bool:
"""Return ``True`` if the character's HP is below *threshold* percent.
Parameters
----------
character:
The character to evaluate.
threshold:
HP percentage (0-100) below which healing is recommended.
"""
if character.max_hp == 0:
return False
hp_pct = (character.hp / character.max_hp) * 100.0
return hp_pct < threshold
@staticmethod
def is_full_health(character: CharacterSchema) -> bool:
"""Return ``True`` if the character is at maximum HP."""
return character.hp >= character.max_hp
@staticmethod
def choose_heal_method(character: CharacterSchema, config: dict) -> ActionPlan:
"""Decide between resting and using a consumable.
Parameters
----------
character:
Current character state.
config:
Strategy config dict containing ``heal_method``,
``consumable_code``, etc.
Returns
-------
An :class:`ActionPlan` for the chosen healing action.
"""
heal_method = config.get("heal_method", "rest")
consumable_code: str | None = config.get("consumable_code")
if heal_method == "consumable" and consumable_code:
# Verify the character actually has the consumable
has_item = any(
slot.code == consumable_code for slot in character.inventory
)
if has_item:
return ActionPlan(
ActionType.USE_ITEM,
params={"code": consumable_code, "quantity": 1},
reason=f"Using {consumable_code} to heal ({character.hp}/{character.max_hp} HP)",
)
else:
logger.info(
"Consumable %s not in inventory for %s, falling back to rest",
consumable_code,
character.name,
)
# Default / fallback: rest
return ActionPlan(
ActionType.REST,
reason=f"Resting to heal ({character.hp}/{character.max_hp} HP)",
)