chore(release): 0.2.6
[risinglegends.git] / src / server / locations / healer / index.ts
1 import { Request, Response, Router } from "express";
2 import { maxHp, Player } from "../../../shared/player";
3 import { authEndpoint, AuthRequest } from '../../auth';
4 import { logger } from "../../lib/logger";
5 import { loadPlayer, updatePlayer } from "../../player";
6 import { getCityDetails, getService } from '../../map';
7 import { sample } from 'lodash';
8 import { City, Location } from "../../../shared/map";
9 import { renderPlayerBar } from "../../views/player-bar";
10 import { getEquippedItems } from "../../inventory";
11
12 export const router = Router();
13
14 type TextSegment = 'intro' | 'insufficient_money' | 'heal_successful';
15
16 type HealText = Record<TextSegment, string[]>;
17
18 const healCost = 10;
19
20 const defaultTexts: HealText = {
21   intro: [
22     `Welcome traveller, I am {{NAME}}, Healer of {{CITY_NAME}}`,
23     "Please come in traveller, I am {{NAME}}, Healer of {{CITY_NAME}}",
24   ],
25   insufficient_money: [
26     "Sorry friend, you don't have enough money..",
27     "Sorry, that won't be enough..",
28     "Healing is hard work.. I'm afraid that won't cover it.."
29   ],
30   heal_successful: [
31     "I hope you feel better now",
32     "Good luck on your travels!",
33     "Glad to be of service..."
34   ]
35 };
36
37 // overrides for specific areas
38 const playerTexts: Record<number, HealText> = {
39   [8]: {
40     intro: [
41       'Welcome to Midfield traveller, I am Casim - healer in these parts',
42       'I am Casim the Healer here... how are you enjoying your stay at Midfield?'
43     ],
44     insufficient_money: [
45       'Sorry friend, you don\'t have enough money',
46       'Look.. I\'m sorry.. that won\'t be enough...'
47     ],
48     heal_successful: [
49       'Glad to help!'
50     ]
51   },
52   [16]: {
53     intro: [
54       'Ah, welcome to Wildegard, one of the few safehavens in the Akari Woods. I am Adovras, healer in these parts.',
55       'Welcome traveller, I am Adovras - healer in these parts'
56     ],
57     insufficient_money: [
58       `Sorry friend, you don't have enough money...`
59     ],
60     heal_successful: [
61       "Hope this small healing will be helpful on your journeys"
62     ]
63
64   },
65   [11]: {
66     intro: [
67       'Ah, welcome traveler - I am Uthar, healer of Davelfell',
68       'Hello, I am Uthar, healer of Davelfell',
69       'Sorry I\'m a bit busy today, I am Uthar, healer of Davelfell'
70     ],
71     insufficient_money: [
72       "Bah, don't bother me if you don't have the money",
73       "Look, I'm very busy - come back when you have the money"
74     ],
75     heal_successful: [
76       "*Fizz* *POOF* YOU'RE HEALED!"
77     ]
78   }
79 }
80
81 function getText(type: TextSegment, location: Location, city: City): string {
82   let selected = sample(defaultTexts[type]);
83
84   if(playerTexts[location.id]) {
85     if(playerTexts[location.id][type].length) {
86       selected = sample(playerTexts[location.id][type]);
87     }
88   }
89
90   return selected.replace("{{NAME}}", location.name).replace("{{CITY_NAME}}", city.name);
91
92 }
93
94 router.get('/city/services/city:services:healer/:location_id', authEndpoint, async (req: AuthRequest, res: Response) => {
95   const service = await getService(parseInt(req.params.location_id));
96   const city = await getCityDetails(service.city_id);
97
98   if(!service || service.city_id !== req.player.city_id) {
99     logger.log(`Invalid location: [${req.params.location_id}]`);
100     res.sendStatus(400);
101   }
102
103   const text: string[] = [];
104
105   text.push(`<p><b>${service.name}</b></p>`);
106   text.push(`<p>"${getText('intro', service, city)}"</p>`);
107
108
109   if(req.player.hp === maxHp(req.player.constitution, req.player.level)) {
110     text.push(`<p>You're already at full health?</p>`);
111   }
112   else {
113     if(req.player.gold <= (healCost * 2)) {
114       text.push(`<p>You don't seem to have too much money... I guess I can do it for free this time...</p>`);
115       text.push(`<p><button type="button" hx-post="/city/services/city:services:healer:heal/${service.id}" hx-target="#explore">Heal for Free!</button></p>`);
116     }
117     else {
118       text.push(`<p><button type="button" hx-post="/city/services/city:services:healer:heal/${service.id}" hx-target="#explore">Heal for ${healCost}g!</button></p>`);
119     }
120
121   }
122
123   res.send(`<div>${text.join("\n")}</div>`);
124 });
125
126
127
128 router.post('/city/services/city:services:healer:heal/:location_id', authEndpoint, async (req: AuthRequest, res: Response) => {
129   const service = await getService(parseInt(req.params.location_id));
130   const city = await getCityDetails(service.city_id);
131
132   if(!service || service.city_id !== req.player.city_id) {
133     logger.log(`Invalid location: [${req.params.location_id}]`);
134     res.sendStatus(400);
135   }
136
137   const text: string[] = [];
138   text.push(`<p><b>${service.name}</b></p>`);
139
140   const cost = req.player.gold <= (healCost * 2) ? 0 : healCost;
141
142   if(req.player.gold < cost) {
143     text.push(`<p>${getText('insufficient_money', service, city)}</p>`)
144     res.send(`<div>${text.join("\n")}</div>`);
145   }
146   else {
147     req.player.hp = maxHp(req.player.constitution, req.player.level);
148     req.player.gold -= cost;
149
150     await updatePlayer(req.player);
151     const inventory = await getEquippedItems(req.player.id);
152
153     text.push(`<p>${getText('heal_successful', service, city)}</p>`);
154     text.push('<p><button hx-get="/player/explore" hx-target="#explore">Back to Town</button></p>');
155     res.send(`<div>${text.join("\n")}</div>` + renderPlayerBar(req.player, inventory));
156   }
157 });