{# ══════════════════════════════════════════════════════════════════════ Fragment dynamique du match (swap AJAX) Contient : flashes, topbar, board, main du joueur actif, log. Le modal et le contexte JS sont dans match.html.twig hors du wrapper. ══════════════════════════════════════════════════════════════════════ #} {% import 'admin/tcg/_macros.html.twig' as helpers %} {# ── Flashes ── #} {% for label, msgs in app.flashes(['error', 'warning', 'success']) %} {% for m in msgs %}
{{ m }}
{% endfor %} {% endfor %} {# ── Bandeau infos + actions globales ── #}
Tour {{ state.turn ?? 1 }} Joueur actif #{{ state.activePlayer ?? '?' }} Statut {{ match.status }}
{% if match.status != 'finished' %}
{% endif %} ← Retour
{% if match.status == 'finished' %}

Partie terminée

Vainqueur : Joueur #{{ state.activePlayer ?? '?' }} {% if match.winner %} ({{ match.winner.username }}){% endif %}

{% endif %} {# ── Board principal ── #}
{# ═════════════ Joueur 2 (haut, miroir) ═════════════ #}
{{ helpers.renderCamp(state.players[p2Id] ?? {}, p2Id, cardMap, elementsMap, match.id, state.activePlayer, match.status, energyBudgets[p2Id] ?? {}) }}
{# ═════════════ Joueur 1 (bas, orienté normalement) ═════════════ #} {{ helpers.renderCamp(state.players[p1Id] ?? {}, p1Id, cardMap, elementsMap, match.id, state.activePlayer, match.status, energyBudgets[p1Id] ?? {}) }}
{# ── Main du joueur actif ── #} {% set activeP = state.players[state.activePlayer] ?? null %} {% if activeP %} {# Budget par type précalculé côté controller (cf. AdminTcgController::buildMatchViewData). #} {% set typeBudget = energyBudgets[state.activePlayer] ?? {} %}
Main du Joueur #{{ state.activePlayer }} ({{ (activeP.hand ?? [])|length }} carte{{ (activeP.hand ?? [])|length > 1 ? 's' : '' }})
{% if (activeP.hand ?? [])|length == 0 %}
Main vide.
{% else %} {% for cid in activeP.hand %} {% set card = cardMap[cid] ?? null %} {% set handIdx = loop.index0 %}
{{ helpers.renderCard(card, elementsMap, handIdx) }} {% if match.status != 'finished' %}
{# ── Placer en énergie ── #}
{# ── Invoquer (form avec zone + slot + énergie). Pour un Sort : zone forcée à 'spell', slot auto-déterminé côté moteur, et libellé « Activer » à la place de « Invoquer ». #} {% set isSpellCard = card and card.cardType == 'spell' %}
{{ isSpellCard ? 'Activer' : 'Invoquer' }}
{% if isSpellCard %} {% else %} {% endif %}
{% endif %}
{% endfor %} {% endif %}
{% endif %} {# ── Log ── #}
Log ({{ (state.log ?? [])|length }})
{% if (state.log ?? [])|length == 0 %}
Aucune action enregistrée.
{% else %} {% for entry in (state.log|slice(-20)|reverse) %}
T{{ entry.turn }} · P{{ entry.player }} · {{ entry.action }} {% for k, v in entry %} {% if k not in ['turn', 'player', 'action'] %} {{ k }}={{ v is iterable ? v|json_encode : v }} {% endif %} {% endfor %}
{% endfor %} {% endif %}