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";
11 export const router = Router();
13 type TextSegment = 'intro' | 'insufficient_money' | 'heal_successful';
15 type HealText = Record<TextSegment, string[]>;
19 const defaultTexts: HealText = {
21 `Welcome traveller, I am {{NAME}}, Healer of {{CITY_NAME}}`,
22 "Please come in traveller, I am {{NAME}}, Healer of {{CITY_NAME}}",
25 "Sorry friend, you don't have enough money..",
26 "Sorry, that won't be enough..",
27 "Healing is hard work.. I'm afraid that won't cover it.."
30 "I hope you feel better now",
31 "Good luck on your travels!",
32 "Glad to be of service..."
36 // overrides for specific areas
37 const playerTexts: Record<number, HealText> = {
40 'Welcome to Midfield traveller, I am Casim - healer in these parts',
41 'I am Casim the Healer here... how are you enjoying your stay at Midfield?'
44 'Sorry friend, you don\'t have enough money',
45 'Look.. I\'m sorry.. that won\'t be enough...'
53 'Ah, welcome to Wildegard, one of the few safehavens in the Akari Woods. I am Adovras, healer in these parts.',
54 'Welcome traveller, I am Adovras - healer in these parts'
57 `Sorry friend, you don't have enough money...`
60 "Hope this small healing will be helpful on your journeys"
66 'Ah, welcome traveler - I am Uthar, healer of Davelfell',
67 'Hello, I am Uthar, healer of Davelfell',
68 'Sorry I\'m a bit busy today, I am Uthar, healer of Davelfell'
71 "Bah, don't bother me if you don't have the money",
72 "Look, I'm very busy - come back when you have the money"
75 "*Fizz* *POOF* YOU'RE HEALED!"
80 function getText(type: TextSegment, location: Location, city: City): string {
81 let selected = sample(defaultTexts[type]);
83 if(playerTexts[location.id]) {
84 if(playerTexts[location.id][type].length) {
85 selected = sample(playerTexts[location.id][type]);
89 return selected.replace("{{NAME}}", location.name).replace("{{CITY_NAME}}", city.name);
93 router.get('/city/services/healer/:location_id', authEndpoint, async (req: AuthRequest, res: Response) => {
94 const service = await getService(parseInt(req.params.location_id));
95 const city = await getCityDetails(service.city_id);
97 if(!service || service.city_id !== req.player.city_id) {
98 logger.log(`Invalid location: [${req.params.location_id}]`);
102 const text: string[] = [];
104 text.push(`<p>"${getText('intro', service, city)}"</p>`);
106 if(req.player.hp === maxHp(req.player.constitution, req.player.level) && req.player.vigor === maxVigor(req.player.constitution, req.player.level)) {
107 text.push(`<p>You're already in peak condition!</p>`);
110 if(req.player.gold <= (healCost * 2)) {
111 text.push(`<p>You don't seem to have too much money... I guess I can do it for free this time...</p>`);
112 text.push(`<p><button type="button" hx-post="/city/services/healer/heal/${service.id}" hx-target="#explore">Heal for Free!</button></p>`);
115 text.push(`<p><button type="button" hx-post="/city/services/healer/heal/${service.id}" hx-target="#explore">Heal for ${healCost}g!</button></p>`);
121 <div class="city-title-wrapper"><div class="city-title">${service.city_name}</div></div>
122 <div class="city-details">
123 <h3 class="location-name"><span>${service.name}</span></h3>
124 <div class="service-in-town">
130 //res.send(`<div class="service-in-town">${text.join("\n")}</div>`);
135 router.post('/city/services/healer/heal/:location_id', authEndpoint, async (req: AuthRequest, res: Response) => {
136 const service = await getService(parseInt(req.params.location_id));
137 const city = await getCityDetails(service.city_id);
139 if(!service || service.city_id !== req.player.city_id) {
140 logger.log(`Invalid location: [${req.params.location_id}]`);
144 const text: string[] = [];
145 const cost = req.player.gold <= (healCost * 2) ? 0 : healCost;
147 if(req.player.gold < cost) {
148 text.push(`<p>${getText('insufficient_money', service, city)}</p>`)
151 req.player.hp = maxHp(req.player.constitution, req.player.level);
152 req.player.vigor = maxVigor(req.player.constitution, req.player.level);
153 req.player.gold -= cost;
155 await updatePlayer(req.player);
157 text.push(`<p>${getText('heal_successful', service, city)}</p>`);
158 text.push('<p><button hx-get="/player/explore" hx-target="#explore">Back to Town</button></p>');
162 <div class="city-title-wrapper"><div class="city-title">${service.city_name}</div></div>
163 <div class="city-details">
164 <h3 class="location-name"><span>${service.name}</span></h3>
165 <div class="service-in-town">
169 ${renderPlayerBar(req.player)}