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";
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: AuthRequest, res: Response) => {
95 const service = await getService(parseInt(req.params.location_id));
96 const city = await getCityDetails(service.city_id);
98 if(!service || service.city_id !== req.player.city_id) {
99 logger.log(`Invalid location: [${req.params.location_id}]`);
103 const text: string[] = [];
105 text.push(`<p><b>${service.name}</b></p>`);
106 text.push(`<p>"${getText('intro', service, city)}"</p>`);
109 if(req.player.hp === maxHp(req.player.constitution, req.player.level)) {
110 text.push(`<p>You're already at full health?</p>`);
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>`);
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>`);
123 res.send(`<div>${text.join("\n")}</div>`);
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);
132 if(!service || service.city_id !== req.player.city_id) {
133 logger.log(`Invalid location: [${req.params.location_id}]`);
137 const text: string[] = [];
138 text.push(`<p><b>${service.name}</b></p>`);
140 const cost = req.player.gold <= (healCost * 2) ? 0 : healCost;
142 if(req.player.gold < cost) {
143 text.push(`<p>${getText('insufficient_money', service, city)}</p>`)
144 res.send(`<div>${text.join("\n")}</div>`);
147 req.player.hp = maxHp(req.player.constitution, req.player.level);
148 req.player.gold -= cost;
150 await updatePlayer(req.player);
151 const inventory = await getEquippedItems(req.player.id);
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));