proc-gen equipment drops from monsters can be picked up
[sketchy-heroes.git] / src / routes / fight / fight.ts
index 8c3ca0b51d175601dc4638bf2ea1d5601895df5c..038ab97f2bde0e376020c191f711e9938423e8e8 100644 (file)
@@ -2,9 +2,9 @@ import { server } from '../../lib/server';
 import { Static, Type } from '@sinclair/typebox';
 import { prisma } from '../../lib/db';
 import { ForbiddenError } from '../../lib/http-errors';
-import {Fight, Player} from '@prisma/client';
+import {Fight, LootTable, Player, WorldDrop} from '@prisma/client';
 import {maxExp, maxHp} from '../../formulas';
-
+import {weighted} from '../../lib/weighted';
 
 const FightRoundInput = Type.Object({
   params: Type.Object({
@@ -29,7 +29,14 @@ export type FightRoundOutput = {
   monster: Fight,
   winner: 'monster' | 'player' | 'flee',
   roundData: RoundData[],
-  reward: any
+  reward: {
+    exp?: number,
+    currency?: number
+    worldDrop?: {
+      id: string,
+      name: string
+    }
+  }
 }
 
 function round(player: Player, monster: Fight): FightRoundOutput {
@@ -114,6 +121,9 @@ export const fightRound = server.post<FightRoundInputType, FightRoundOutput>('/v
     prisma.player.findUnique({
       where: {
         id: req.params.playerId
+      },
+      include: {
+        zoneBiome: true
       }
     })
   ]);
@@ -175,7 +185,24 @@ export const fightRound = server.post<FightRoundInputType, FightRoundOutput>('/v
           player.hp = maxHp(player.level, player.zest);
         }
 
-        await prisma.$transaction([
+        // we should figure out if you got an item!
+
+        const [monster, ,] = await prisma.$transaction([
+          prisma.monsterBiome.findUnique({
+            where: {
+              monsterId_biome: {
+                monsterId: fight.monsterId,
+                biome: player.zoneBiome.biome
+              }
+            },
+            include: {
+              lootTable: {
+                include: {
+                  item: true
+                }
+              }
+            }
+          }),
           prisma.fight.delete({
             where: {
               id: fight.id
@@ -196,6 +223,29 @@ export const fightRound = server.post<FightRoundInputType, FightRoundOutput>('/v
           })
         ]);
 
+        // since the player won, we can give them an item if they've earned it
+        if(monster && monster.lootTable.length > 0) {
+          const item = weighted(monster.lootTable, (i) => i.dropRate.toNumber());
+
+          if(item) {
+            // we can give the player this item, so lets place it in the "world-drop-table". 
+            // if a player doesn't pick it up, it will remain in the world drop table for 
+            // 24 hours.. after that it's gone forever.
+            // if the player does pick it up then it's moved to their inventory
+            const worldDrop = await prisma.worldDrop.create({
+              data: {
+                itemId: item.itemId,
+                droppedById: player.id
+              }
+            });
+
+            output.reward['worldDrop'] = {
+              id: worldDrop.id,
+              name: item.item.name
+            };
+          }
+        }
+
         // update the player with the new data
         output.player = player;
       }