1 import { Request, Response, Router } from "express";
2 import { maxHp, Player } from "../../../shared/player";
3 import { authEndpoint } 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";
12 export const router = Router();
14 type TextSegment = 'intro' | 'insufficient_money' | 'heal_successful';
16 type HealText = Record<TextSegment, string[]>;
20 const defaultTexts: HealText = {
22 `Welcome traveller, I am {{NAME}}, Healer of {{CITY_NAME}}`,
23 "Please come in traveller, I am {{NAME}}, Healer of {{CITY_NAME}}",
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.."
31 "I hope you feel better now",
32 "Good luck on your travels!",
33 "Glad to be of service..."
37 // overrides for specific areas
38 const playerTexts: Record<number, HealText> = {
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?'
45 'Sorry friend, you don\'t have enough money',
46 'Look.. I\'m sorry.. that won\'t be enough...'
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'
58 `Sorry friend, you don't have enough money...`
61 "Hope this small healing will be helpful on your journeys"
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'
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"
76 "*Fizz* *POOF* YOU'RE HEALED!"
81 function getText(type: TextSegment, location: Location, city: City): string {
82 let selected = sample(defaultTexts[type]);
84 if(playerTexts[location.id]) {
85 if(playerTexts[location.id][type].length) {
86 selected = sample(playerTexts[location.id][type]);
90 return selected.replace("{{NAME}}", location.name).replace("{{CITY_NAME}}", city.name);
94 router.get('/city/services/city:services:healer/:location_id', authEndpoint, async (req: Request, res: Response) => {
95 const authToken = req.headers['x-authtoken']!.toString();
96 const player: Player = await loadPlayer(authToken)
98 logger.log(`Couldnt find player with id ${authToken}`);
99 return res.sendStatus(400);
102 const service = await getService(parseInt(req.params.location_id));
103 const city = await getCityDetails(service.city_id);
105 if(!service || service.city_id !== player.city_id) {
106 logger.log(`Invalid location: [${req.params.location_id}]`);
110 const text: string[] = [];
112 text.push(`<p><b>${service.name}</b></p>`);
113 text.push(`<p>"${getText('intro', service, city)}"</p>`);
116 if(player.hp === maxHp(player.constitution, player.level)) {
117 text.push(`<p>You're already at full health?</p>`);
120 if(player.gold <= (healCost * 2)) {
121 text.push(`<p>You don't seem to have too much money... I guess I can do it for free this time...</p>`);
122 text.push(`<p><button type="button" hx-post="/city/services/city:services:healer:heal/${service.id}" hx-target="#explore">Heal for Free!</button></p>`);
125 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>`);
130 res.send(`<div>${text.join("\n")}</div>`);
135 router.post('/city/services/city:services:healer:heal/:location_id', authEndpoint, async (req: Request, res: Response) => {
136 const authToken = req.headers['x-authtoken']!.toString();
137 const player: Player = await loadPlayer(authToken)
139 logger.log(`Couldnt find player with id ${authToken}`);
140 return res.sendStatus(400);
143 const service = await getService(parseInt(req.params.location_id));
144 const city = await getCityDetails(service.city_id);
146 if(!service || service.city_id !== player.city_id) {
147 logger.log(`Invalid location: [${req.params.location_id}]`);
151 const text: string[] = [];
152 text.push(`<p><b>${service.name}</b></p>`);
154 const cost = player.gold <= (healCost * 2) ? 0 : healCost;
156 if(player.gold < cost) {
157 text.push(`<p>${getText('insufficient_money', service, city)}</p>`)
158 res.send(`<div>${text.join("\n")}</div>`);
161 player.hp = maxHp(player.constitution, player.level);
164 await updatePlayer(player);
165 const inventory = await getEquippedItems(player.id);
167 text.push(`<p>${getText('heal_successful', service, city)}</p>`);
168 text.push('<p><button hx-get="/player/explore" hx-target="#explore">Back to Town</button></p>');
169 res.send(`<div>${text.join("\n")}</div>` + renderPlayerBar(player, inventory));