piclets / src /lib /db /encounterService.ts
Fraser's picture
BIG CHANGE
c703ea3
import { db } from './index';
import type { Encounter, PicletInstance } from './schema';
import { EncounterType } from './schema';
import { getOrCreateGameState, markEncountersRefreshed } from './gameState';
import { getCaughtPiclets } from './piclets';
// Configuration
const ENCOUNTER_REFRESH_HOURS = 2;
const MIN_WILD_ENCOUNTERS = 2;
const MAX_WILD_ENCOUNTERS = 4;
export class EncounterService {
// Check if encounters should be refreshed
static async shouldRefreshEncounters(): Promise<boolean> {
const state = await getOrCreateGameState();
const hoursSinceRefresh = (Date.now() - state.lastEncounterRefresh.getTime()) / (1000 * 60 * 60);
return hoursSinceRefresh >= ENCOUNTER_REFRESH_HOURS;
}
// Force encounter refresh
static async forceEncounterRefresh(): Promise<void> {
await db.encounters.clear();
await markEncountersRefreshed();
}
// Get current encounters
static async getCurrentEncounters(): Promise<Encounter[]> {
return await db.encounters
.orderBy('createdAt')
.reverse()
.toArray();
}
// Clear all encounters
static async clearEncounters(): Promise<void> {
await db.encounters.clear();
}
// Generate new encounters - simplified to only wild battles
static async generateEncounters(): Promise<Encounter[]> {
const encounters: Omit<Encounter, 'id'>[] = [];
// Check if player has any Piclets
const caughtPiclets = await getCaughtPiclets();
if (caughtPiclets.length === 0) {
// No Piclets yet - show empty state, they need to scan first
console.log('Player has no caught piclets - returning empty encounters');
await db.encounters.clear();
await markEncountersRefreshed();
return [];
}
// Player has Piclets - generate wild battle encounters
console.log('Generating wild battle encounters');
const wildEncounters = await this.generateWildBattleEncounters();
encounters.push(...wildEncounters);
// Clear existing encounters and add new ones
await db.encounters.clear();
for (const encounter of encounters) {
await db.encounters.add(encounter);
}
await markEncountersRefreshed();
return await this.getCurrentEncounters();
}
// Generate wild battle encounters using existing caught Piclets
private static async generateWildBattleEncounters(): Promise<Omit<Encounter, 'id'>[]> {
const encounters: Omit<Encounter, 'id'>[] = [];
// Get all caught piclets to use as potential opponents
const caughtPiclets = await getCaughtPiclets();
if (caughtPiclets.length === 0) {
return encounters;
}
// Generate 2-4 random wild encounters
const numEncounters = Math.floor(Math.random() * (MAX_WILD_ENCOUNTERS - MIN_WILD_ENCOUNTERS + 1)) + MIN_WILD_ENCOUNTERS;
for (let i = 0; i < numEncounters; i++) {
// Pick a random Piclet from caught ones to use as opponent
const randomPiclet = caughtPiclets[Math.floor(Math.random() * caughtPiclets.length)];
// Use the piclet's name for display
const displayName = randomPiclet.typeId.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
const encounter: Omit<Encounter, 'id'> = {
type: EncounterType.WILD_PICLET,
title: `Wild ${displayName}`,
description: `A wild ${displayName} appears! Ready for battle?`,
picletInstanceId: randomPiclet.id,
picletTypeId: randomPiclet.typeId,
enemyLevel: 5, // Simplified - no level variance needed
createdAt: new Date()
};
encounters.push(encounter);
}
return encounters;
}
// Get a specific encounter by ID
static async getEncounter(id: number): Promise<Encounter | undefined> {
return await db.encounters.get(id);
}
// Delete an encounter (after it's been completed)
static async deleteEncounter(id: number): Promise<void> {
await db.encounters.delete(id);
}
}