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