157 lines
5.8 KiB
HTML
157 lines
5.8 KiB
HTML
<section class="combat" aria-label="Kampf">
|
|
@if (combat(); as combat) {
|
|
<div class="combat__stage">
|
|
<header class="combat__status">
|
|
<div class="fighter fighter--player">
|
|
<img class="fighter__icon" [src]="playerIcon" alt="" />
|
|
<div class="fighter__meter">
|
|
<p class="fighter__name">{{ combat.player.name }}</p>
|
|
<div
|
|
class="bar bar--player"
|
|
role="progressbar"
|
|
[attr.aria-label]="'Lebenspunkte ' + combat.player.name"
|
|
[attr.aria-valuenow]="combat.player.currentHp"
|
|
[attr.aria-valuemin]="0"
|
|
[attr.aria-valuemax]="combat.player.maxHp"
|
|
>
|
|
<span class="bar__fill" [style.inline-size.%]="playerHpPercent()"></span>
|
|
<span class="bar__text">{{ combat.player.currentHp }} / {{ combat.player.maxHp }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<p class="combat__round" data-combat-round>Runde {{ combat.round }}</p>
|
|
|
|
<div class="fighter fighter--monster">
|
|
<div class="fighter__meter">
|
|
<p class="fighter__name">
|
|
{{ combat.monster.name }}
|
|
<span class="fighter__level">Stufe {{ combat.monster.level }}</span>
|
|
</p>
|
|
<div
|
|
class="bar bar--monster"
|
|
role="progressbar"
|
|
[attr.aria-label]="'Lebenspunkte ' + combat.monster.name"
|
|
[attr.aria-valuenow]="combat.monster.currentHp"
|
|
[attr.aria-valuemin]="0"
|
|
[attr.aria-valuemax]="combat.monster.maxHp"
|
|
>
|
|
<span class="bar__fill" [style.inline-size.%]="monsterHpPercent()"></span>
|
|
<span class="bar__text">{{ combat.monster.currentHp }} / {{ combat.monster.maxHp }}</span>
|
|
</div>
|
|
</div>
|
|
<img
|
|
class="fighter__icon"
|
|
[src]="monsterIcon(combat.monster.key, combat.monster.artworkPath)"
|
|
alt=""
|
|
/>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="combat__field">
|
|
<div
|
|
class="sprite sprite--player"
|
|
[class.sprite--attacking]="phase() === 'attacking'"
|
|
[class.sprite--hit]="phase() === 'hit'"
|
|
role="img"
|
|
[attr.aria-label]="combat.player.name"
|
|
></div>
|
|
<img
|
|
class="sprite sprite--monster"
|
|
[style.--sprite-scale]="monsterSpriteScale(combat.monster.key)"
|
|
[src]="monsterSprite(combat.monster.key, combat.monster.artworkPath)"
|
|
[alt]="combat.monster.name"
|
|
/>
|
|
</div>
|
|
|
|
<footer class="combat__actions">
|
|
@if (combat.status === 'ACTIVE') {
|
|
<button
|
|
type="button"
|
|
class="action"
|
|
data-combat-attack
|
|
[disabled]="busy()"
|
|
(click)="attack()"
|
|
>
|
|
<img class="action__icon" src="/images/hud/runtime/AttackIcon-96.png" alt="" />
|
|
<span class="action__label">Angriff</span>
|
|
<span class="action__key">1</span>
|
|
</button>
|
|
}
|
|
</footer>
|
|
|
|
@if (combat.status === 'WON') {
|
|
<div class="outcome outcome--won" data-combat-result="WON">
|
|
<h2 class="outcome__title">Sieg</h2>
|
|
<p>{{ combat.monster.name }} wurde besiegt.</p>
|
|
|
|
@if (combat.rewards; as rewards) {
|
|
<section class="rewards" data-combat-rewards aria-label="Belohnungen">
|
|
<h3 class="rewards__title">Belohnungen</h3>
|
|
|
|
<dl class="rewards__currencies">
|
|
<div class="rewards__currency" data-reward-experience>
|
|
<dt>Erfahrung</dt>
|
|
<dd>+{{ rewards.experience }} XP</dd>
|
|
</div>
|
|
<div class="rewards__currency" data-reward-silver>
|
|
<dt>Silber</dt>
|
|
<dd>+{{ rewards.silver }}</dd>
|
|
</div>
|
|
</dl>
|
|
|
|
@if (rewards.items.length) {
|
|
<h3 class="rewards__title">Beute</h3>
|
|
<ul class="rewards__loot">
|
|
@for (reward of rewards.items; track reward.characterItemId) {
|
|
<li>
|
|
<app-item-card [item]="reward.item" [quantity]="reward.quantity" />
|
|
</li>
|
|
}
|
|
</ul>
|
|
} @else {
|
|
<p class="outcome__hint" data-reward-empty>Keine besondere Beute gefunden.</p>
|
|
}
|
|
</section>
|
|
}
|
|
|
|
<button type="button" class="outcome__button" data-combat-to-hunt (click)="goToHunt()">
|
|
Zur Jagd
|
|
</button>
|
|
</div>
|
|
} @else if (combat.status === 'LOST') {
|
|
<div class="outcome outcome--lost" data-combat-result="LOST">
|
|
<h2 class="outcome__title">Niederlage</h2>
|
|
<p>{{ combat.player.name }} wurde im Kampf besiegt.</p>
|
|
<button type="button" class="outcome__button" data-combat-to-hunt (click)="goToHunt()">
|
|
Zur Jagd
|
|
</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<aside class="combat__log" aria-label="Kampfprotokoll">
|
|
<h2 class="combat__log-title">Kampflog</h2>
|
|
<div class="combat__log-body">
|
|
@for (round of logRounds(); track round.round) {
|
|
<p class="combat__log-round">Runde {{ round.round }}</p>
|
|
@for (event of round.events; track event.sequence) {
|
|
<p class="combat__log-entry" [class.combat__log-entry--player]="event.source === 'PLAYER'">
|
|
{{ formatEvent(event) }}
|
|
</p>
|
|
}
|
|
}
|
|
</div>
|
|
</aside>
|
|
} @else if (combatStore.loading()) {
|
|
<p class="combat__notice" role="status">Kampf wird geladen…</p>
|
|
}
|
|
|
|
@if (combatStore.error(); as error) {
|
|
<section class="combat__notice combat__notice--error" role="alert">
|
|
<p>{{ error }}</p>
|
|
<button type="button" data-combat-retry (click)="retry()">Erneut versuchen</button>
|
|
</section>
|
|
}
|
|
</section>
|