chore(release): 0.3.2
[risinglegends.git] / src / server / locations / healer / index.ts
1 import { Response, Router } from "express";
2 import { maxHp, maxVigor } from "../../../shared/player";
3 import { authEndpoint, AuthRequest } from '../../auth';
4 import { logger } from "../../lib/logger";
5 import { 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 { BackToTown } from "../../views/components/button";
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/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>"${getText('intro', service, city)}"</p>`);
106
107   if(req.player.hp === maxHp(req.player.constitution, req.player.level) && req.player.vigor === maxVigor(req.player.constitution, req.player.level)) {
108     text.push(`<p>You're already in peak condition!</p>`);
109   }
110   else {
111     if(req.player.gold <= (healCost * 2)) {
112       text.push(`<p>You don't seem to have too much money... I guess I can do it for free this time...</p>`);
113       text.push(`<p><button type="button" hx-post="/city/services/healer/heal/${service.id}" hx-target="#explore">Heal for Free!</button></p>`);
114     }
115     else {
116       text.push(`<p><button type="button" hx-post="/city/services/healer/heal/${service.id}" hx-target="#explore">Heal for ${healCost}g!</button></p>`);
117     }
118
119   }
120
121   res.send(`
122 <div class="city-title-wrapper"><div class="city-title">${service.city_name}</div></div>
123 <div class="city-details">
124 <h3 class="location-name"><span>${service.name}</span></h3>
125 <div class="service-in-town">
126 ${text.join("\n")}
127 ${BackToTown()}
128 </div>
129 </div>
130   `);
131
132   //res.send(`<div class="service-in-town">${text.join("\n")}</div>`);
133 });
134
135
136
137 router.post('/city/services/healer/heal/:location_id', authEndpoint, async (req: AuthRequest, res: Response) => {
138   const service = await getService(parseInt(req.params.location_id));
139   const city = await getCityDetails(service.city_id);
140
141   if(!service || service.city_id !== req.player.city_id) {
142     logger.log(`Invalid location: [${req.params.location_id}]`);
143     res.sendStatus(400);
144   }
145
146   const text: string[] = [];
147   const cost = req.player.gold <= (healCost * 2) ? 0 : healCost;
148
149   if(req.player.gold < cost) {
150     text.push(`<p>${getText('insufficient_money', service, city)}</p>`)
151   }
152   else {
153     req.player.hp = maxHp(req.player.constitution, req.player.level);
154     req.player.vigor = maxVigor(req.player.constitution, req.player.level);
155     req.player.gold -= cost;
156
157     await updatePlayer(req.player);
158
159     text.push(`<p>${getText('heal_successful', service, city)}</p>`);
160   }
161
162   res.send(`
163 <div class="city-title-wrapper"><div class="city-title">${service.city_name}</div></div>
164 <div class="city-details">
165 <h3 class="location-name"><span>${service.name}</span></h3>
166 <div class="service-in-town">
167 ${text.join("\n")}
168 ${BackToTown()}
169 </div>
170 </div>
171 ${renderPlayerBar(req.player)}
172 `);
173 });