X-Git-Url: https://git.xangelo.ca/?p=sketchy-heroes.git;a=blobdiff_plain;f=src%2Froutes%2Fmove.ts;fp=src%2Froutes%2Fmove.ts;h=b57dd5e931c1f95b8f0e7a786c9bb913bae242b3;hp=8ba79f0f32ab46b8ea81837ec0351a6b6a28d13f;hb=7aa7248bc4f3f59a002beb98fa889a9da3c25866;hpb=9cec2c639563092ed050716db1e7e4657f937bf5 diff --git a/src/routes/move.ts b/src/routes/move.ts index 8ba79f0..b57dd5e 100644 --- a/src/routes/move.ts +++ b/src/routes/move.ts @@ -3,7 +3,15 @@ import { Static, Type } from '@sinclair/typebox'; 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({ @@ -19,7 +27,8 @@ export type MoveOutputType = { id: string; biome: Biome }, - displayText: string + displayText: string, + generatedMonster: Fight | null } const moveStatements = [ @@ -34,6 +43,8 @@ export const move = server.post('/v1/accounts/:pl authenicated: true }, async req => { + let generatedMonster: Fight | null = null; + const player = await prisma.player.findUnique({ where: { id: req.params.playerId @@ -86,12 +97,74 @@ export const move = server.post('/v1/accounts/:pl } }); + + // 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] - } + }; });