feat: expose current world location
This commit is contained in:
93
apps/api/src/world/world.service.ts
Normal file
93
apps/api/src/world/world.service.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Character } from '../characters/entities/character.entity';
|
||||
import { TravelService } from '../travel/travel.service';
|
||||
import { LocationConnection } from './entities/location-connection.entity';
|
||||
|
||||
export interface LocationSummary {
|
||||
id: string;
|
||||
key: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface CurrentLocationConnection {
|
||||
targetLocation: LocationSummary;
|
||||
travelDurationSeconds: number;
|
||||
danger: 'LOW' | 'HIGH';
|
||||
}
|
||||
|
||||
export interface CurrentLocationResponse {
|
||||
id: string;
|
||||
key: string;
|
||||
name: string;
|
||||
description: string;
|
||||
regionKey: string;
|
||||
minRecommendedLevel: number;
|
||||
maxRecommendedLevel: number;
|
||||
dangerLevel: number;
|
||||
isSafe: boolean;
|
||||
huntingEnabled: boolean;
|
||||
artworkPath: string;
|
||||
connections: CurrentLocationConnection[];
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class WorldService {
|
||||
constructor(
|
||||
private readonly travelService: TravelService,
|
||||
@InjectRepository(Character)
|
||||
private readonly characters: Repository<Character>,
|
||||
@InjectRepository(LocationConnection)
|
||||
private readonly connections: Repository<LocationConnection>,
|
||||
) {}
|
||||
|
||||
async getCurrentLocation(
|
||||
characterId: string,
|
||||
): Promise<CurrentLocationResponse> {
|
||||
await this.travelService.completeTravelIfDue(characterId);
|
||||
|
||||
const character = await this.characters.findOne({
|
||||
where: { id: characterId },
|
||||
relations: { currentLocation: true },
|
||||
});
|
||||
if (!character) {
|
||||
throw new NotFoundException('Character not found.');
|
||||
}
|
||||
|
||||
const connections = await this.connections.find({
|
||||
where: { fromLocationId: character.currentLocationId, enabled: true },
|
||||
relations: { toLocation: true },
|
||||
});
|
||||
const location = character.currentLocation;
|
||||
|
||||
return {
|
||||
id: location.id,
|
||||
key: location.key,
|
||||
name: location.name,
|
||||
description: location.description,
|
||||
regionKey: location.regionKey,
|
||||
minRecommendedLevel: location.minRecommendedLevel,
|
||||
maxRecommendedLevel: location.maxRecommendedLevel,
|
||||
dangerLevel: location.dangerLevel,
|
||||
isSafe: location.isSafe,
|
||||
huntingEnabled: location.huntingEnabled,
|
||||
artworkPath: location.artworkPath,
|
||||
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),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
private toDangerRating(ambushChance: string): 'LOW' | 'HIGH' {
|
||||
return Number(ambushChance) <= 0.05 ? 'LOW' : 'HIGH';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user