chore(release): 0.4.0
[risinglegends.git] / src / server / player.ts
1 import { db } from './lib/db';
2 import {Player, maxHp} from "../shared/player";
3 import { random } from 'lodash';
4 import { Skills } from '../shared/skills';
5 import {Profession} from 'shared/profession';
6 import {logger} from './lib/logger';
7
8 export async function loadPlayer(authToken: string): Promise<Player> {
9   const res = await db.first()
10             .select(
11               'players.*',
12               'profession_levels.level',
13               'profession_levels.exp',
14               db.raw(`coalesce(pp.permissions, '[]'::json) as permissions`)
15             )
16             .from<Player>('players')
17             .join('profession_levels', function() {
18               this.on(function() {
19                 this.on('profession_levels.player_id', '=', 'players.id')
20                 this.andOn('profession_levels.profession', '=', 'players.profession')
21               })
22             })
23             .leftJoin(
24               db.raw(`(select json_agg(pp.permission) as permissions, pp.player_id from player_permissions pp group by pp.player_id) pp`),
25               'pp.player_id','=', 'players.id'
26             )
27             .where({
28               'players.id': authToken
29             });
30
31   return res;
32 }
33
34 export async function findPlayerByUsername(username: string): Promise<Player> {
35   const res = await db.first()
36             .select(
37               'players.*',
38               'profession_levels.level',
39               'profession_levels.exp',
40               db.raw(`coalesce(pp.permissions, '[]'::json) as permissions`)
41             )
42             .from<Player>('players')
43             .join('profession_levels', function() {
44               this.on(function() {
45                 this.on('profession_levels.player_id', '=', 'players.id')
46                 this.andOn('profession_levels.profession', '=', 'players.profession')
47               })
48             })
49             .leftJoin(
50               db.raw(`(select json_agg(pp.permission) as permissions, pp.player_id from player_permissions pp group by pp.player_id) pp`),
51               'pp.player_id','=', 'players.id'
52             )
53             .where({
54               'players.username': username
55             });
56
57   return res;
58 }
59
60 export async function createPlayer(): Promise<Player> {
61   const raw: Partial<Player> = {
62     username: `Player${Date.now().toString().substr(-7)}`,
63     strength: random(3, 5),
64     constitution: random(3, 5),
65     dexterity: random(3, 5),
66     intelligence: random(3, 5),
67   };
68
69   raw.hp = maxHp(raw.constitution, 1);
70
71   const res  = await db('players').insert(raw).returning<Player[]>('*');
72   const player = res.pop();
73
74   logger.log(`Created player [${player.id}]`);
75
76   // await skills!
77   const pairs = [];
78   const values = [];
79   const sql = `insert into player_skills (id, player_id) values `;
80
81   logger.log(`Inserted base skills for [${player.id}]`)
82
83   Skills.forEach(skill => {
84     pairs.push('(?,?)');
85     values.push(skill.id, player.id);
86   });
87
88   await db.raw(sql + pairs.join(','), values);
89
90   // create the profession level
91   await db('profession_levels').insert({
92     player_id: player.id,
93     profession: 'Wanderer',
94     level: 1,
95     exp: 0
96   });
97
98   logger.log(`Inserted base profession level [${player.id}]`);
99
100   return player;
101 }
102
103
104 export async function updatePlayer(player: Player) {
105   return Promise.all([
106     db('players').where({
107       id: player.id
108     }).update({
109       hp: player.hp,
110       vigor: player.vigor,
111       strength: player.strength,
112       constitution: player.constitution,
113       dexterity: player.dexterity,
114       intelligence: player.intelligence,
115       stat_points: player.stat_points,
116       gold: player.gold
117     }),
118     db('profession_levels').where({
119       player_id: player.id,
120       profession: player.profession
121     }).update({
122       exp: player.exp,
123       level: player.level
124     })
125   ]);
126 }
127
128 export async function movePlayer(cityId: number, playerId: string) {
129   return db('players').where({
130     id: playerId
131   }).update({city_id: cityId})
132 }
133
134 export async function changeProfession(player_id: string, newProfession: Profession): Promise<{level: number, exp: number}> {
135   let level = 1;
136   let exp = 0;
137   try {
138     await db('profession_levels').insert({
139       player_id,
140       profession: newProfession,
141       level,
142       exp
143     });
144   }
145   catch(e) {
146     console.log(e);
147     const res = await db.first().select('*').from('profession_levels').where({
148       player_id,
149       profession: newProfession
150     })
151
152     level = res.level;
153     exp = res.exp;
154     // profession already exists, wahtever yo!
155   }
156
157   await db('players').where({
158     id: player_id
159   }).update({ profession: newProfession });
160
161   return {
162     level,
163     exp
164   };
165 }