feat(api): reveal the ash pit route from the watchpost hotspot

This commit is contained in:
Bastian Wagner
2026-08-23 11:18:20 +02:00
parent aaa7146c0c
commit 37d025f401
5 changed files with 309 additions and 11 deletions

View File

@@ -5,6 +5,7 @@ import { Character } from '../characters/entities/character.entity';
import { calculateDangerRating, DangerRating } from '../hunting/danger-rating';
import { LocationMonster } from '../monsters/entities/location-monster.entity';
import { TravelService } from '../travel/travel.service';
import { WorldDiscoveryService } from './discovery/world-discovery.service';
import { LocationConnection } from './entities/location-connection.entity';
import { LocationDefinition } from './entities/location-definition.entity';
import {
@@ -68,6 +69,7 @@ export class WorldService {
private readonly connections: Repository<LocationConnection>,
@InjectRepository(LocationMonster)
private readonly locationMonsters: Repository<LocationMonster>,
private readonly worldDiscovery: WorldDiscoveryService,
) {}
async getCurrentLocation(
@@ -85,6 +87,16 @@ export class WorldService {
? await this.getEncounterPool(location.id)
: [];
const visibleConnections: LocationConnection[] = [];
for (const connection of connections) {
if (
connection.enabled &&
(await this.worldDiscovery.isTravelAllowed(characterId, connection))
) {
visibleConnections.push(connection);
}
}
return {
id: location.id,
key: location.key,
@@ -114,17 +126,15 @@ export class WorldService {
iconPath: entry.monster.iconPath,
})),
rewardPreview: location.localRewardPreview,
connections: connections
.filter((connection) => connection.enabled)
.map((connection) => ({
targetLocation: {
id: connection.toLocation.id,
key: connection.toLocation.key,
name: connection.toLocation.name,
},
travelDurationSeconds: connection.travelDurationSeconds,
danger: this.toDangerRating(connection.ambushChance),
})),
connections: visibleConnections.map((connection) => ({
targetLocation: {
id: connection.toLocation.id,
key: connection.toLocation.key,
name: connection.toLocation.name,
},
travelDurationSeconds: connection.travelDurationSeconds,
danger: this.toDangerRating(connection.ambushChance),
})),
possibleMonsters: pool.map((entry) => entry.monster.name),
};
}
@@ -152,11 +162,21 @@ export class WorldService {
throw locationInteractionUnavailable();
}
// A hotspot that reveals a route writes before it speaks. Idempotent by
// the unique pair, so a second click simply reports nothing new.
const discoveredLocation = poi.discoversLocationKey
? await this.worldDiscovery.discover(
characterId,
poi.discoversLocationKey,
)
: null;
return {
interactionKey: poi.key,
title: poi.resultTitle ?? poi.title,
text: poi.resultText,
...(poi.resultImg === undefined ? {} : { img: poi.resultImg }),
discoveredLocation,
};
}