From ed037269314222f86ad6fc79e65623b4ccc92251 Mon Sep 17 00:00:00 2001 From: Bastian Wagner Date: Wed, 19 Aug 2026 13:14:07 +0200 Subject: [PATCH] feat: add hunt API client and models for Playable Slice 0.2 Add to game-api.models.ts: - DangerRating type for hunt encounter danger levels - MonsterSummary interface with key, name, level, artworkPath - HuntEncounter interface for individual hunt encounters - HuntResult interface for hunt completion results, reusing LocationSummary Extend CurrentLocationResponse with possibleMonsters: string[] field. Add to game-api.service.ts: - startHunt(): Observable method posting to /api/hunts Update test fixtures to include possibleMonsters field in mock locations. Co-Authored-By: Claude Haiku 4.5 --- apps/web/src/app/core/api/game-api.models.ts | 22 +++++++++++++++++++ apps/web/src/app/core/api/game-api.service.ts | 6 ++++- .../world/world-page.component.spec.ts | 2 ++ .../app/features/world/world.store.spec.ts | 1 + 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/apps/web/src/app/core/api/game-api.models.ts b/apps/web/src/app/core/api/game-api.models.ts index c5ed58a..cd185f2 100644 --- a/apps/web/src/app/core/api/game-api.models.ts +++ b/apps/web/src/app/core/api/game-api.models.ts @@ -34,6 +34,7 @@ export interface CurrentLocationResponse { huntingEnabled: boolean; artworkPath: string; connections: CurrentLocationConnection[]; + possibleMonsters: string[]; } export type CurrentTravel = @@ -46,3 +47,24 @@ export type CurrentTravel = arrivesAt: string; } | { status: 'COMPLETED'; targetLocation: LocationSummary }; + +export type DangerRating = 'WEAK' | 'MATCH' | 'STRONG' | 'VERY_DANGEROUS' | 'DEADLY'; + +export interface MonsterSummary { + key: string; + name: string; + level: number; + artworkPath: string; +} + +export interface HuntEncounter { + id: string; + monster: MonsterSummary; + dangerRating: DangerRating; +} + +export interface HuntResult { + id: string; + location: LocationSummary; + encounters: HuntEncounter[]; +} diff --git a/apps/web/src/app/core/api/game-api.service.ts b/apps/web/src/app/core/api/game-api.service.ts index 9356b7f..8ae3195 100644 --- a/apps/web/src/app/core/api/game-api.service.ts +++ b/apps/web/src/app/core/api/game-api.service.ts @@ -1,7 +1,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { CharacterResponse, CurrentLocationResponse, CurrentTravel } from './game-api.models'; +import { CharacterResponse, CurrentLocationResponse, CurrentTravel, HuntResult } from './game-api.models'; @Injectable({ providedIn: 'root' }) export class GameApiService { @@ -22,4 +22,8 @@ export class GameApiService { getCurrentTravel(): Observable { return this.http.get('/api/travel/current'); } + + startHunt(): Observable { + return this.http.post('/api/hunts', {}); + } } diff --git a/apps/web/src/app/features/world/world-page.component.spec.ts b/apps/web/src/app/features/world/world-page.component.spec.ts index dba42b2..ae0ce72 100644 --- a/apps/web/src/app/features/world/world-page.component.spec.ts +++ b/apps/web/src/app/features/world/world-page.component.spec.ts @@ -32,6 +32,7 @@ const southGate: CurrentLocationResponse = { huntingEnabled: false, artworkPath: '/images/backgrounds/Suedtor.png', connections: [burnedRoadConnection], + possibleMonsters: [], }; const burnedRoad: CurrentLocationResponse = { @@ -43,6 +44,7 @@ const burnedRoad: CurrentLocationResponse = { isSafe: false, huntingEnabled: true, artworkPath: '/images/backgrounds/Aschestrasse.png', + possibleMonsters: ['goblin', 'skeleton'], connections: [ { targetLocation: { id: 'south-gate-id', key: 'south-gate', name: 'Südtor von Graufurt' }, diff --git a/apps/web/src/app/features/world/world.store.spec.ts b/apps/web/src/app/features/world/world.store.spec.ts index 78eed24..2eb3512 100644 --- a/apps/web/src/app/features/world/world.store.spec.ts +++ b/apps/web/src/app/features/world/world.store.spec.ts @@ -33,6 +33,7 @@ const currentLocation: CurrentLocationResponse = { isSafe: true, huntingEnabled: false, artworkPath: '/images/backgrounds/Suedtor.png', + possibleMonsters: [], connections: [ { targetLocation: {