fix: min/max level definitions for monsters
authorxangelo <me@xangelo.ca>
Tue, 5 Sep 2023 18:12:51 +0000 (14:12 -0400)
committerxangelo <me@xangelo.ca>
Tue, 5 Sep 2023 18:12:51 +0000 (14:12 -0400)
There was some confusion over types and whether or not we needed to
included faction data with monsters (We don't). This should sort out
that mess and give us a clearer definition for monsters.

src/server/api.ts
src/server/fight.ts
src/server/monster.ts
src/server/views/fight.ts
src/server/views/monster-selector.ts
src/shared/fight.ts
src/shared/monsters.ts

index 355bd04a72f60ca9639f2d84217a97b0d09974b9..7428e79ddaebd1d50ddf380ec7f2a6408b19eae0 100644 (file)
@@ -166,24 +166,29 @@ app.post('/chat', authEndpoint, async (req: Request, res: Response) => {
 
   let message: Message;
   if(msg.startsWith('/server lmnop')) {
-    if(msg === '/server lmnop refresh-monsters') {
-      await createMonsters();
-      message = broadcastMessage('server', 'Monster refresh!');
-    }
-    else if(msg === '/server lmnop refresh-cities') {
-      await createAllCitiesAndLocations();
-      message = broadcastMessage('server', 'Cities, Locations, and Paths refreshed!');
-    }
-    else if(msg === '/server lmnop refresh-shops') {
-      await createShopItems();
-      await createShopEquipment();
-      message = broadcastMessage('server', 'Refresh shop items');
-    }
-    else {
-      const str = msg.split('/server lmnop ')[1];
-      if(str) {
-        message = broadcastMessage('server', str);
+    try {
+      if(msg === '/server lmnop refresh-monsters') {
+        await createMonsters();
+        message = broadcastMessage('server', 'Monster refresh!');
+      }
+      else if(msg === '/server lmnop refresh-cities') {
+        await createAllCitiesAndLocations();
+        message = broadcastMessage('server', 'Cities, Locations, and Paths refreshed!');
+      }
+      else if(msg === '/server lmnop refresh-shops') {
+        await createShopItems();
+        await createShopEquipment();
+        message = broadcastMessage('server', 'Refresh shop items');
       }
+      else {
+        const str = msg.split('/server lmnop ')[1];
+        if(str) {
+          message = broadcastMessage('server', str);
+        }
+      }
+    }
+    catch(e) {
+      io.to(cache.get(`socket:${req.player.id}`)).emit('chat', renderChatMessage(broadcastMessage('server', e.message)));
     }
   }
   else if(msg === '/online') {
@@ -326,18 +331,9 @@ app.get('/player/explore', authEndpoint, async (req: Request, res: Response) =>
   }
 
   if(fight) {
-    const data: MonsterForFight = {
-      id: fight.id,
-      hp: fight.hp,
-      maxHp: fight.maxHp,
-      name: fight.name,
-      level: fight.level,
-      fight_trigger: fight.fight_trigger
-    };
     const location = await getMonsterLocation(fight.ref_id);
 
-
-    res.send(renderPlayerBar(req.player) + renderFightPreRound(data, true, location, closestTown));
+    res.send(renderPlayerBar(req.player) + renderFightPreRound(fight, true, location, closestTown));
   }
   else {
     if(travelPlan) {
@@ -605,7 +601,7 @@ app.post('/fight/turn', authEndpoint, async (req: Request, res: Response) => {
   }
 
   cache[fightBlockKey] = Date.now() + CONSTANT.FIGHT_ATTACK_DELAY;
-  const monster = await loadMonsterWithFaction(req.player.id);
+  const monster = await loadMonsterFromFight(req.player.id);
 
   if(!monster) {
     res.send(Alert.ErrorAlert('Not in a fight'));
@@ -675,17 +671,7 @@ app.post('/fight', fightRateLimiter, authEndpoint, async (req: Request, res: Res
   const fight = await createFight(req.player.id, monster, fightTrigger);
   const location = await getService(monster.location_id);
 
-
-  const data: MonsterForFight = {
-    id: fight.id,
-    hp: fight.hp,
-    maxHp: fight.maxHp,
-    name: fight.name,
-    level: fight.level,
-    fight_trigger: fight.fight_trigger
-  };
-
-  res.send(renderFightPreRound(data, true, location, location.city_id));
+  res.send(renderFightPreRound(fight, true, location, location.city_id));
 });
 
 app.post('/travel/step', authEndpoint, async (req: Request, res: Response) => {
@@ -764,17 +750,9 @@ app.post('/travel/return-to-source', authEndpoint, async (req: Request, res: Res
   const fight = await loadMonsterFromFight(req.player.id);
   if(fight) {
     // go to the fight screen
-    const data: MonsterForFight = {
-      id: fight.id,
-      hp: fight.hp,
-      maxHp: fight.maxHp,
-      name: fight.name,
-      level: fight.level,
-      fight_trigger: fight.fight_trigger
-    };
     const location = await getMonsterLocation(fight.ref_id);
 
-    res.send(renderPlayerBar(req.player) + renderFightPreRound(data, true, location, req.player.city_id));
+    res.send(renderPlayerBar(req.player) + renderFightPreRound(fight, true, location, req.player.city_id));
   }
   else {
     const [city, locations, paths] = await Promise.all([
index c1bdc453d37d1082422252459201cdac2ca12fce..ab7b2c6b497b9bdf9c485912c100719efc3b5c9e 100644 (file)
@@ -6,7 +6,7 @@ import { updatePlayer } from './player';
 import { getEquippedItems, updateAp } from './inventory';
 import { EquippedItemDetails } from '../shared/equipped';
 import { EquipmentSlot } from '../shared/inventory';
-import { MonsterWithFaction, MonsterForFight } from '../shared/monsters';
+import { MonsterWithFaction, MonsterForFight, Fight } from '../shared/monsters';
 import { getPlayerSkillsAsObject, updatePlayerSkills } from './skills';
 import { SkillID, Skills } from '../shared/skills';
 import { Request, Response } from 'express';
@@ -35,7 +35,7 @@ function exponentialExp(exp: number, monsterLevel: number, playerLevel: number):
   return Math.floor(finalExp);
 }
 
-export async function fightRound(player: Player, monster: MonsterWithFaction,  data: {action: 'attack' | 'cast' | 'flee', target: 'head' | 'body' | 'arms' | 'legs'}) {
+export async function fightRound(player: Player, monster: Fight,  data: {action: 'attack' | 'cast' | 'flee', target: 'head' | 'body' | 'arms' | 'legs'}) {
   const playerSkills = await getPlayerSkillsAsObject(player.id);
   const roundData: FightRound = {
     monster,
@@ -195,7 +195,8 @@ export async function fightRound(player: Player, monster: MonsterWithFaction,  d
         return {
           id: monster.id,
           name: monster.name,
-          level: monster.minLevel,
+          minLevel: monster.minLevel,
+          maxLevel: monster.maxLevel,
           hp: monster.hp,
           maxHp: monster.maxHp,
           fight_trigger: 'explore'
index 18c12435660fdc389054fd922b1992ff1552d34b..54a49dbfc2c76fc4365ac5b36b3b4bdbd34647e4 100644 (file)
@@ -42,7 +42,8 @@ export async function loadMonsterFromFight(player_id: string): Promise<Fight> {
 export async function loadMonsterWithFaction(player_id: string): Promise<MonsterWithFaction> {
   const res = await db.raw(`
                       select 
-                        f.*, fa.id as faction_id, fa.name as faction_name
+                        f.*, fa.id as faction_id, fa.name as faction_name,
+                        m.minLevel, m.maxLevel
                       from fight f
                       join monsters m on f.ref_id = m.id
                       left outer join factions fa on m.faction_id = fa.id
index f09ab41ce244efc199813cadeac077f8ddac3c93..b3ba986f9df286ff02f0272c4d0b814a3f7dcd47 100644 (file)
@@ -1,6 +1,6 @@
 import { FightRound } from "shared/fight";
 import { LocationWithCity } from "shared/map";
-import { MonsterForFight } from "../../shared/monsters";
+import { Fight, MonsterForFight } from "../../shared/monsters";
 import { Button, ButtonWithBlock } from "./components/button";
 
 export function renderRoundDetails(roundData: FightRound): string {
@@ -69,7 +69,7 @@ function AttackButton(blockTime?: number): string {
   }
 }
 
-export function renderFight(monster: MonsterForFight, results: string = '', displayFightActions: boolean = true, blockTime: number = 0) {
+export function renderFight(monster: Fight, results: string = '', displayFightActions: boolean = true, blockTime: number = 0) {
   const hpPercent = Math.floor((monster.hp / monster.maxHp) * 100);
 
   let html = `
@@ -105,7 +105,7 @@ export function renderFight(monster: MonsterForFight, results: string = '', disp
   return html;
 }
 
-export function renderFightPreRound(monster: MonsterForFight,  displayFightActions: boolean = true, location: LocationWithCity, closestTown: number) {
+export function renderFightPreRound(monster: Fight,  displayFightActions: boolean = true, location: LocationWithCity, closestTown: number) {
   const hpPercent = Math.floor((monster.hp / monster.maxHp) * 100);
 
   let html = `
index 03d61979d1eef92ac1437b4829f2d41dff90cac0..0fc5e5b3afa634e62e2cf415f5b25f619f059ec6 100644 (file)
@@ -23,7 +23,7 @@ export function renderMonsterSelector(monsters: Monster[] | MonsterForFight[], a
   <input type="hidden" name="fightTrigger" value="explore">
   <select id="monsterId" name="monsterId">
   ${monsters.map((monster: (any)) => {
-      const range = [monster?.minLevel ?? monster.level, monster?.maxLevel ?? monster.level + 3];
+      const range = [monster?.minLevel, monster?.maxLevel];
       return `<option value="${monster.id}" ${monster.id === activeMonsterId ? 'selected': ''}>${monster.name} (LVL ${range[0]} - ${range[1]})</option>`;
   }).join("\n")}
   </select> <button type="submit" class="red">Fight</button></form>
index d0f7b97e226977c44c3b13fd7cea8756a2545856..22f0ed9b04c81bd64af6b95fd999cfc85af4535b 100644 (file)
@@ -1,4 +1,4 @@
-import {FightTrigger, MonsterWithFaction} from "./monsters"
+import {Fight, FightTrigger, MonsterWithFaction} from "./monsters"
 import {Player} from "./player"
 
 export type FightReward = {
@@ -8,7 +8,7 @@ export type FightReward = {
 }
 
 export type FightRound = {
-  monster: MonsterWithFaction,
+  monster: Fight,
   player: Player,
   fightTrigger: FightTrigger,
   winner: 'player' | 'monster' | 'in-progress',
index 91c0dfade191e42c3736471bce41b9a9ca1d5c40..f5147ff8a8f41c048659fc1143f8b5c656a8b93d 100644 (file)
@@ -45,6 +45,7 @@ export type MonsterForFight = {
   hp: number;
   maxHp: number;
   name: string;
-  level: number;
+  minLevel: number;
+  maxLevel: number;
   fight_trigger: FightTrigger;
 }