Add killerName to Mission model and enhance overlay components

- Introduced killerName field in the Mission model within the Prisma schema and created a corresponding migration.
- Updated mission management logic to assign a killerName during mission creation.
- Enhanced overlay components to display killer information, including avatar and name, in both expanded and minimized panels.
- Added new CSS styles for killer display in the overlay.
- Included new avatar images for various killers in the overlay assets.
This commit is contained in:
Maurycy
2026-05-11 17:39:22 +00:00
parent 0031ef0a8f
commit 0517202412
60 changed files with 372 additions and 127 deletions

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "missions" ADD COLUMN "killer_name" TEXT;

View File

@@ -39,6 +39,7 @@ model Mission {
difficulty Int @db.SmallInt
durationMinutes Int @default(20) @map("duration_minutes") @db.SmallInt
status String @default("active")
killerName String? @map("killer_name")
encounterLibraryVersion String @map("encounter_library_version")
startedAt DateTime @default(now()) @map("started_at")
endedAt DateTime? @map("ended_at")

View File

@@ -79,7 +79,7 @@ export class EncounterService {
const libEncounter = getEncounterById(encounter.key);
const flavor = libEncounter
? pickFlavor(libEncounter, { success: result.success }, rng)
? pickFlavor(libEncounter, { success: result.success, killerName: mission.killerName }, rng)
: result.logText;
newLog.push({ ...result, logText: flavor });

View File

@@ -10,7 +10,8 @@ import type {
Survivor,
SurvivorStats,
} from '@fog-explorer/api-interfaces';
import { getLibraryVersion } from '@fog-explorer/encounter-library';
import { getLibraryVersion, KILLER_NAMES } from '@fog-explorer/encounter-library';
import seedrandom = require('seedrandom');
import { TwitchJwtPayload } from '../auth/twitch-jwt.guard';
import { PrismaService } from '../prisma/prisma.service';
import { MissionStoreService } from './mission-store.service';
@@ -38,6 +39,7 @@ export class MissionsService {
const nextTickAt = new Date(now.getTime() + TICK_BASE_INTERVAL_MS + jitter);
const stats: SurvivorStats = { objectives: 5, survival: 5, altruism: 5 };
const survivorName = characterName ?? defaultName(claims.opaque_user_id);
const killerName = pickKiller(missionId);
// Upsert user and create survivor + mission in one transaction.
await this.prisma.$transaction(async (tx) => {
@@ -66,6 +68,7 @@ export class MissionsService {
difficulty,
durationMinutes,
status: 'active',
killerName,
encounterLibraryVersion: getLibraryVersion(),
nextTickAt,
participants: {
@@ -98,6 +101,7 @@ export class MissionsService {
difficulty,
durationMinutes,
status: 'active',
killerName,
encounterLibraryVersion: getLibraryVersion(),
nextTickAt: nextTickAt.toISOString(),
tickIndex: 0,
@@ -154,3 +158,8 @@ export class MissionsService {
function defaultName(opaqueUserId: string): string {
return `Survivor ${opaqueUserId.slice(-4)}`;
}
function pickKiller(missionId: string): string {
const rng = seedrandom(`killer:${missionId}`);
return KILLER_NAMES[Math.floor(rng() * KILLER_NAMES.length)];
}