import { sample } from 'lodash';
import { City, Location } from "../../../shared/map";
import { renderPlayerBar } from "../../views/player-bar";
+import { BackToTown } from "../../views/components/button";
export const router = Router();
<h3 class="location-name"><span>${service.name}</span></h3>
<div class="service-in-town">
${text.join("\n")}
+${BackToTown()}
</div>
</div>
`);
await updatePlayer(req.player);
text.push(`<p>${getText('heal_successful', service, city)}</p>`);
- text.push('<p><button hx-get="/player/explore" hx-target="#explore">Back to Town</button></p>');
}
res.send(`
<h3 class="location-name"><span>${service.name}</span></h3>
<div class="service-in-town">
${text.join("\n")}
+${BackToTown()}
</div>
</div>
${renderPlayerBar(req.player)}
import * as Alert from "../views/alert";
import { changeProfession } from "../player";
import { renderPlayerBar } from "../views/player-bar";
+import { BackToTown } from "../views/components/button";
function p(str: string) {
return `<p>${str}</p>`;
html.push(`<p>However, you should visit the ${place} in ${town} that can probably provide some guidance!</p>`);
}
+ html.push(BackToTown());
res.send(`
<div class="city-title-wrapper"><div class="city-title">${service.city_name}</div></div>
<div class="city-details">
import { EquippedItemDetails } from "../../shared/equipped";
import { PlayerItem } from "../../shared/items";
import { capitalize } from "lodash";
+import { ProgressBar } from "./components/progress-bar";
function icon(icon_name?: string): string {
const placeholder = 'https://placehold.co/64x64/af936c/6d5f4d';
return `<span class="requirement-title">${name}</span>: <span class="requirement-value ${typeof val === 'number' ? (val > 0 ? "success": "error") : ""}">${valSign}${val}</span>`;
}
-function generateProgressBar(current: number, max: number, color: string, displayPercent: boolean = true): string {
- let percent = 0;
- if(max > 0) {
- percent = Math.floor((current / max) * 100);
- }
- const display = `${displayPercent? `${percent}% - `: ''}`;
- return `<div class="progress-bar" style="background: linear-gradient(to right, ${color}, ${color} ${percent}%, transparent ${percent}%, transparent)" title="${display}${current}/${max}">${display}${current}/${max}</div>`;
-}
-
function renderInventoryItem(item: EquippedItemDetails , action: (item: EquippedItemDetails) => string): string {
return `<div class="store-list">
<div class="inventory-icon" style="background-image: url('${icon(item.icon)}')">
${item.boosts.intelligence ? renderStatBoost('INT', item.boosts.intelligence) : ''}
${item.boosts.damage ? renderStatBoost('DMG', item.boosts.damage) : ''}
${item.boosts.damage_mitigation ? renderStatBoost('MIT', item.boosts.damage_mitigation.toString())+'%' : ''}
- ${['SPELL'].includes(item.type) ? '': generateProgressBar(item.currentAp, item.maxAp, '#7be67b')}
+ ${ProgressBar(item.currentAp, item.maxAp, `dur-${item.item_id}`, {
+ startingColor: '#7be67b',
+ endingColor: '#7be67b',
+ displayPercent: false,
+ title: item.type === 'SPELL' ? 'Uses' : 'Durability'
+ })}
</div>
${item.hasOwnProperty('id') ? `<div>${item.cost.toLocaleString()}G</div>` : ''}
</div>
import { max } from "lodash";
import { LocationWithCity } from "../../shared/map";
import { Monster, MonsterForFight } from "../../shared/monsters";
+import { BackToTown } from "./components/button";
export function renderOnlyMonsterSelector(monsters: Monster[] | MonsterForFight[], activeMonsterId: number = 0, location?: LocationWithCity): string {
let html = `
const range = [monster.level, monster.level + 3];
return `<option value="${monster.id}" ${monster.id === activeMonsterId ? 'selected': ''}>${monster.name} (${range[0]} - ${range[1]})</option>`;
}).join("\n")}
- </select> <button type="submit" class="red">Fight</button></form></div>
+ </select> <button type="submit" class="red">Fight</button></form>
+<br><br>
+${BackToTown()}
+
+</div>
`;
return html;
import { EquippedItemDetails } from "../../shared/equipped";
import { ProgressBar } from "./components/progress-bar";
import * as City from './components/city';
+import { BackToTown } from "./components/button";
function renderStatBoost(name: string, val: number | string): string {
let valSign: string = '';
${item.boosts.intelligence ? renderStatBoost('INT', item.boosts.intelligence) : ''}
${item.boosts.damage ? renderStatBoost(item.affectedSkills.includes('restoration_magic') ? 'HP' : 'DMG', item.boosts.damage) : ''}
${item.boosts.damage_mitigation ? renderStatBoost('MIT', item.boosts.damage_mitigation.toString())+'%' : ''}
- ${['WEAPON','SPELL'].includes(item.type) ? '' : ProgressBar(item.currentAp, item.maxAp, `${item.item_id}-ap`, {
+ ${ProgressBar(item.currentAp, item.maxAp, `${item.item_id}-ap`, {
displayPercent: false,
-title: 'Durability',
+title: item.type === 'SPELL' ? 'Uses' : 'Durability',
startingColor: '#7be67b',
endingColor: '#7be67b'
})}
}
equipment.forEach(item => {
+ if(item.maxAp <= 0) {
+ return;
+ }
const filter = item.type === 'ARMOUR' ? item.equipment_slot : item.type;
listingTypes.add(filter);
${finalListing.join("\n")}
</div>
</div>
+ ${BackToTown()}
`)}`;
return html;
import { Player } from "../../shared/player";
import { LocationWithCity } from "shared/map";
import { ProgressBar } from "./components/progress-bar";
+import { BackToTown } from "./components/button";
type RenderStatOptions = {
unsigned: boolean
}
export function renderEquipmentDetails(item: ShopEquipment, player: Player): string {
+ const isSpell = item.type === 'SPELL';
+
return `
<div class="details">
<div class="name">${item.name}${item.equipment_slot === 'TWO_HANDED' ? ' (2H)': ''}</div>
${item.boosts.intelligence ? renderStatBoost('INT', item.boosts.intelligence) : ''}
${item.boosts.damage ? renderStatBoost(item.affectedSkills.includes('restoration_magic') ? 'HP' : 'DMG', item.boosts.damage) : ''}
${item.boosts.damage_mitigation ? renderStatBoost('MIT', item.boosts.damage_mitigation.toString())+'%' : ''}
- ${['SPELL'].includes(item.type) ? '' : renderStat('Durability', 'DUR', item.maxAp, { unsigned: true })}
+ ${renderStat(isSpell ? 'Uses': 'Durability', isSpell ? 'Uses': 'DUR', item.maxAp, { unsigned: true })}
</div>
${item.hasOwnProperty('id') ? `<div class="store-cost">${item.cost.toLocaleString()}G</div>` : ''}
</div>
${finalListing.join("\n")}
</div>
</div>
+${BackToTown()}
</div>`;
return html;
import {Profession} from "./profession";
import {SkillID} from "./skills";
+import { max } from 'lodash';
export type InventoryType = 'ARMOUR' | 'WEAPON' | 'SPELL';
const damageRatio = 1 - (item.currentAp / item.maxAp);
- return Math.floor(totalCost * damageRatio);
+ return max([Math.floor(totalCost * damageRatio), 1]);
}