feat(web): run quest steps from the NPC screen

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Bastian Wagner
2026-08-22 23:19:16 +02:00
parent bc0d910190
commit ff8b7c8b78
6 changed files with 667 additions and 10 deletions

View File

@@ -41,6 +41,7 @@
[class.merchant__button--active]="
(action.type === 'OPEN_EXCHANGE' && isPanel('EXCHANGE')) ||
(action.type === 'OPEN_SHOP' && isPanel('SHOP')) ||
(action.type === 'VIEW_QUESTS' && isPanel('QUESTS')) ||
(action.type === 'TALK' && isPanel('DIALOGUE'))
"
[attr.data-action]="action.type"
@@ -58,6 +59,71 @@
<p class="merchant__error" role="alert">{{ store.actionError() }}</p>
}
@if (store.questLine(); as line) {
<blockquote class="merchant__dialogue" data-quest-line aria-live="polite">
{{ line }}
</blockquote>
}
@if (store.grantedBag(); as bag) {
<section class="bag-granted" data-granted-bag aria-live="polite">
<h2 class="bag-granted__heading">New Loot Bag</h2>
<p class="bag-granted__name">{{ bag.name }}</p>
<p class="bag-granted__capacity">{{ capacityLabel(bag) }}</p>
<button
type="button"
class="merchant__link"
(click)="store.dismissGrantedBag()"
>
Dismiss
</button>
</section>
}
@if (isPanel('QUESTS')) {
<section class="merchant__panel" aria-label="Quests">
<h2 class="merchant__panel-title">Matters at Hand</h2>
@for (quest of store.quests(); track quest.key) {
<article class="npc-quest" [attr.data-quest]="quest.key">
<h3 class="npc-quest__title">{{ quest.title }}</h3>
<p class="npc-quest__description">{{ quest.description }}</p>
@if (currentObjective(quest); as objective) {
<app-quest-objective-line
[objective]="objective"
[hint]="quest.hint"
/>
}
@if (quest.status === 'AVAILABLE') {
<button
type="button"
class="merchant__button"
data-quest-accept
[disabled]="store.pending() !== null"
(click)="store.acceptQuest(quest.key)"
>
Accept
</button>
} @else if (quest.status === 'ACTIVE' && isCurrentStepHere(quest)) {
<button
type="button"
class="merchant__button"
data-quest-advance
[disabled]="store.pending() !== null"
(click)="store.advanceQuest(quest.key)"
>
Continue
</button>
}
</article>
} @empty {
<p class="merchant__empty">There is nothing to discuss.</p>
}
</section>
}
@if (isPanel('EXCHANGE') && store.exchange(); as exchange) {
<section class="merchant__panel" aria-label="Trade in goods">
<h2 class="merchant__panel-title">{{ exchange.profileName }}</h2>