chore(release): 0.2.17
[risinglegends.git] / src / server / monster.ts
1 import { db } from './lib/db';
2 import { Fight, Monster, MonsterWithFaction, MonsterForList, FightTrigger } from '../shared/monsters';
3 import { TimePeriod, TimeManager } from '../shared/time';
4 import { LocationWithCity } from 'shared/map';
5
6 const time = new TimeManager();
7
8 /**
9  * return a list of monsters that
10  * - are at the current location
11  * - in the current time period
12  * - in any time period
13  */
14 export async function getMonsterList(location_id: number, timePeriod: TimePeriod[] = []): Promise<Monster[]> {
15   if(timePeriod.length === 0) {
16     timePeriod.push('any');
17     timePeriod.push(time.getTimePeriod());
18   }
19
20   const res: Monster[] = await db.select('*')
21                       .where({ location_id })
22                       .whereIn('time_period', timePeriod)
23                       .from<Monster>('monsters')
24                       .orderBy('level');
25
26   return res;
27 }
28
29 export async function loadMonster(id: number): Promise<Monster> {
30   return db.select('*').from<Monster>('monsters').where({
31     id
32   }).first();
33 }
34
35 export async function loadMonsterFromFight(player_id: string): Promise<Fight> {
36   return await db.first().select('*').from<Fight>('fight').where({
37     player_id,
38   });
39 }
40
41 export async function loadMonsterWithFaction(player_id: string): Promise<MonsterWithFaction> {
42   const res = await db.raw(`
43                       select 
44                         f.*, fa.id as faction_id, fa.name as faction_name
45                       from fight f
46                       join monsters m on f.ref_id = m.id
47                       left outer join factions fa on m.faction_id = fa.id
48                       where f.player_id = ?
49                         limit 1
50                       `, [player_id]);
51
52   return res.rows[0];
53 }
54
55 export async function saveFightState(authToken: string, monster: Fight) {
56   return db('fight').where({
57     player_id: authToken,
58     id: monster.id
59   }).update<Fight>({
60     hp: monster.hp
61   });
62 }
63
64 export async function createFight(playerId: string, monster: Monster, fightTrigger: FightTrigger): Promise<Fight> {
65   const res = await db('fight').insert({
66     player_id: playerId,
67     name: monster.name,
68     strength: monster.strength,
69     constitution: monster.constitution,
70     dexterity: monster.dexterity,
71     intelligence: monster.intelligence,
72     exp: monster.exp,
73     level: monster.level,
74     gold: monster.gold,
75     hp: monster.hp,
76     helmAp: monster.helmAp,
77     chestAp: monster.chestAp,
78     legsAp: monster.legsAp,
79     armsAp: monster.armsAp,
80     maxHp: monster.maxHp,
81     ref_id: monster.id,
82     fight_trigger: fightTrigger
83   }).returning<Fight[]>('*');
84
85   return res.pop();
86 }
87
88 export async function getMonsterLocation(monsterId: number): Promise<LocationWithCity> {
89 return db.select(['locations.*', 'cities.name as city_name'])
90           .from<Monster>('monsters')
91           .join('locations', 'monsters.location_id', '=', 'locations.id')
92           .join('cities', 'cities.id', '=', 'locations.city_id')
93           .where({
94             'monsters.id': monsterId
95           }).first();
96 }
97
98 /**
99  * Given a list of cities, it will return a monster that 
100  * exists in any of the exploration zones with every monster 
101  * having an equal probability of appearing
102  */
103 export async function getRandomMonster(city_id: number[]): Promise<MonsterForList> {
104   const res = await db.raw('select id,name,level from monsters where location_id in (select id from locations where city_id in (?)) order by random() limit 1', [city_id.join(',')])
105
106   return res.rows[0] as MonsterForList;
107 }
108
109 export async function clearFight(authToken: string) {
110   return db('fight').where({
111     player_id: authToken
112   }).delete();
113 }