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";
13 export const router = Router();
15 type TextSegment = 'intro' | 'insufficient_money' | 'heal_successful';
17 type HealText = Record<TextSegment, string[]>;
21 const defaultTexts: HealText = {
23 `Welcome traveller, I am {{NAME}}, Healer of {{CITY_NAME}}`,
24 "Please come in traveller, I am {{NAME}}, Healer of {{CITY_NAME}}",
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.."
32 "I hope you feel better now",
33 "Good luck on your travels!",
34 "Glad to be of service..."
38 // overrides for specific areas
39 const playerTexts: Record<number, HealText> = {
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?'
46 'Sorry friend, you don\'t have enough money',
47 'Look.. I\'m sorry.. that won\'t be enough...'
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'
59 `Sorry friend, you don't have enough money...`
62 "Hope this small healing will be helpful on your journeys"
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'
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"
77 "*Fizz* *POOF* YOU'RE HEALED!"
82 function getText(type: TextSegment, location: Location, city: City): string {
83 let selected = sample(defaultTexts[type]);
85 if(playerTexts[location.id]) {
86 if(playerTexts[location.id][type].length) {
87 selected = sample(playerTexts[location.id][type]);
91 return selected.replace("{{NAME}}", location.name).replace("{{CITY_NAME}}", city.name);
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);
99 if(!service || service.city_id !== req.player.city_id) {
100 logger.log(`Invalid location: [${req.params.location_id}]`);
104 const text: string[] = [];
106 text.push(`<p>"${getText('intro', service, city)}"</p>`);
108 if(req.player.hp === maxHp(req.player.constitution, req.player.level)) {
109 text.push(`<p>You're already at full health?</p>`);
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>`);
117 text.push(`<p><button type="button" hx-post="/city/services/healer/heal/${service.id}" hx-target="#explore">Heal for ${healCost}g!</button></p>`);
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">
132 //res.send(`<div class="service-in-town">${text.join("\n")}</div>`);
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);
141 if(!service || service.city_id !== req.player.city_id) {
142 logger.log(`Invalid location: [${req.params.location_id}]`);
146 const text: string[] = [];
147 const cost = req.player.gold <= (healCost * 2) ? 0 : healCost;
148 let inventory: EquippedItemDetails[];
150 if(req.player.gold < cost) {
151 text.push(`<p>${getText('insufficient_money', service, city)}</p>`)
154 req.player.hp = maxHp(req.player.constitution, req.player.level);
155 req.player.gold -= cost;
157 await updatePlayer(req.player);
158 inventory = await getEquippedItems(req.player.id);
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>');
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">
172 ${inventory ? renderPlayerBar(req.player, inventory) : ''}