8ba79f0f32ab46b8ea81837ec0351a6b6a28d13f
[sketchy-heroes.git] / src / routes / move.ts
1 import { server } from '../lib/server';
2 import { Static, Type } from '@sinclair/typebox';
3 import { prisma } from '../lib/db';
4 import { ForbiddenError } from '../lib/http-errors';
5 import { random, sample } from 'lodash';
6 import {Biome, Player} from '@prisma/client';
7
8 const MoveInput = Type.Object({
9   params: Type.Object({
10     playerId: Type.String()
11   })
12 });
13
14 type MoveInputType = Static<typeof MoveInput>;
15
16 export type MoveOutputType = {
17   player: Player,
18   biome: {
19     id: string;
20     biome: Biome
21   },
22   displayText: string
23 }
24
25 const moveStatements = [
26   "You walk forward",
27   "You take a few steps",
28   "You pause for a second before hurrying along",
29   "You stumble forward..."
30 ];
31
32 export const move = server.post<MoveInputType, MoveOutputType>('/v1/accounts/:playerId/move', {
33   schema: MoveInput,
34   authenicated: true
35 }, async req => {
36
37   const player = await prisma.player.findUnique({
38     where: {
39       id: req.params.playerId
40     },
41     include: {
42       zoneBiome: true
43     }
44   });
45
46   if(!player) {
47     throw new ForbiddenError();
48   }
49
50   if(player.stamina <= 0) {
51     throw new ForbiddenError('Insufficient Stamina');
52   }
53
54
55   player.stamina--;
56   player.steps++;
57
58   if(player.steps > player.zoneBiome.maxSteps) {
59     // ok, move them to a new zone!
60     const chosenBiome = sample(Object.values(Biome)) as Biome;
61     const biome = await prisma.zoneBiomes.create({
62       data: {
63         biome: chosenBiome,
64         maxSteps: random(500, 1500)
65       }
66     });
67
68     await prisma.zoneBiomes.delete({
69       where: {
70         id: player.zoneBiomeId
71       }
72     });
73
74     player.zoneBiome = biome;
75     player.steps = 0;
76   }
77
78
79   await prisma.player.update({
80     where: {
81       id: player.id
82     },
83     data: {
84       steps: player.steps,
85       stamina: player.stamina
86     }
87   });
88
89   return {
90     player,
91     biome: {
92       id: player.zoneBiome.id,
93       biome: player.zoneBiome.biome
94     },
95     displayText: sample(moveStatements) || moveStatements[0]
96   }
97 });