import { prisma } from '../lib/db';
import { ForbiddenError } from '../lib/http-errors';
import { random, sample } from 'lodash';
-import {Biome, Player} from '@prisma/client';
+import {Biome, Player, Fight} from '@prisma/client';
+import {now} from '../lib/time';
+import {generateMonster} from '../services/generate-monster';
+
+type RawMonsterSelection = {
+ monsterId: string;
+ biome: Biome,
+ time: {min: number, max:number}[]
+}
const MoveInput = Type.Object({
params: Type.Object({
id: string;
biome: Biome
},
- displayText: string
+ displayText: string,
+ generatedMonster: Fight | null
}
const moveStatements = [
authenicated: true
}, async req => {
+ let generatedMonster: Fight | null = null;
+
const player = await prisma.player.findUnique({
where: {
id: req.params.playerId
}
});
+
+ // now that you have moved, you have 40% chance of fighting a monster
+ if(random(0, 100) < 20) {
+ // ok it's battle time!
+ // retrieve all monsters from the database that are in this biome
+ // that are within the timeframe specified!
+ const monsters = await prisma.$queryRaw`
+ WITH p AS ( -- probability
+ SELECT *,
+ weight::NUMERIC / sum(weight) OVER () AS probability
+ FROM "MonsterBiome"
+ WHERE biome = ${player.zoneBiome.biome}
+ ),
+ cp AS ( -- cumulative probability
+ SELECT *,
+ sum(p.probability) OVER (
+ ORDER BY probability DESC
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+ ) AS cumprobability
+ FROM p
+ ),
+ fp AS (
+ SELECT
+ cp.*,
+ cp.cumprobability - cp.probability AS startprobability,
+ cp.cumprobability AS endprobability
+ FROM cp
+ )
+
+ SELECT "monsterId", biome, time FROM fp
+WHERE random() BETWEEN startprobability AND endprobability;
+ ` as RawMonsterSelection[];
+
+ // now lets filter out the timezones!
+ const moment = now();
+ const availableMonsters = monsters.filter(monster => {
+ return monster.time.filter(time => {
+ return time.min <= moment && time.max >= moment;
+ });
+ })
+
+ if(availableMonsters) {
+ const selectedMonster = sample(availableMonsters);
+ if(selectedMonster) {
+ const monster = await prisma.monster.findUnique({
+ where: {
+ id: selectedMonster.monsterId
+ }
+ });
+
+ if(monster) {
+ generatedMonster = await prisma.fight.create({
+ data: generateMonster(player, monster)
+ });
+ }
+ }
+ }
+
+ }
+
+
return {
player,
biome: {
- id: player.zoneBiome.id,
+ id: player.zoneBiomeId,
biome: player.zoneBiome.biome
},
+ generatedMonster,
displayText: sample(moveStatements) || moveStatements[0]
- }
+ };
});