1 import { FightRound } from "shared/fight";
2 import { LocationWithCity } from "shared/map";
3 import { MonsterForFight } from "../../shared/monsters";
5 export function renderRoundDetails(roundData: FightRound): string {
6 let html: string[] = roundData.roundDetails.map(d => `<div>${d}</div>`);
8 switch(roundData.winner) {
10 html.push(`<div>You defeated the ${roundData.monster.name}!</div>`);
11 if(roundData.rewards.gold) {
12 html.push(`<div>You gained ${roundData.rewards.gold} gold</div>`);
14 if(roundData.rewards.exp) {
15 html.push(`<div>You gained ${roundData.rewards.exp} exp</div>`);
17 if(roundData.rewards.levelIncrease) {
18 html.push(`<div>You gained a level! ${roundData.player.level}</div>`);
22 if(roundData.player.hp === 0) {
23 html.push(`<p>You were killed...</p>`);
25 html.push('<p><button hx-get="/player/explore" hx-target="#explore">Back to Town</button></p>');
28 // fight still in progress, so we don't send any final actions back
33 return html.join("\n");
36 export function renderFight(monster: MonsterForFight, results: string = '', displayFightActions: boolean = true) {
37 const hpPercent = Math.floor((monster.hp / monster.maxHp) * 100);
40 <div id="fight-container">
41 <div id="defender-info">
42 <div class="avatar-container">
43 <img id="avatar" src="https://via.placeholder.com/64x64">
45 <div id="defender-stat-bars">
46 <div id="defender-name">${monster.name}</div>
47 <div class="progress-bar" id="defender-hp-bar" style="background: linear-gradient(to right, red, red ${hpPercent}%, transparent ${hpPercent}%, transparent)" title="${hpPercent}% - ${monster.hp}/${monster.maxHp}">${hpPercent}% - ${monster.hp} / ${monster.maxHp}</div>
50 <div id="fight-actions">
51 ${displayFightActions ? `
52 <form hx-post="/fight/turn" hx-target="#fight-container">
53 <select id="fight-target" name="fightTarget">
54 <option value="head">Head</option>
55 <option value="body">Body</option>
56 <option value="arms">Arms</option>
57 <option value="legs">Legs</option>
59 <button type="submit" class="fight-action red" name="action" value="attack">Attack</button>
60 <button type="submit" class="fight-action red" name="action" value="cast">Cast</button>
61 <button type="submit" class="fight-action" name="action" value="flee">Flee</button>
65 <div id="fight-results">${results}</div>
72 export function renderFightPreRound(monster: MonsterForFight, displayFightActions: boolean = true, location: LocationWithCity, closestTown: number) {
73 const hpPercent = Math.floor((monster.hp / monster.maxHp) * 100);
76 <section id="explore" class="tab active" style="background-image: url('/assets/img/map/${closestTown}.jpeg')" hx-swap-oob="true">
77 <div class="city-title-wrapper">
78 <div class="city-title">${location.city_name}</div>
80 <div class="city-details">
81 <h3 class="location-name"><span>${location.name}</span></h3>
83 <div id="fight-container">
84 <div id="defender-info">
85 <div class="avatar-container">
86 <img id="avatar" src="https://via.placeholder.com/64x64">
88 <div id="defender-stat-bars">
89 <div id="defender-name">${monster.name}</div>
90 <div class="progress-bar" id="defender-hp-bar" style="background: linear-gradient(to right, red, red ${hpPercent}%, transparent ${hpPercent}%, transparent)" title="${hpPercent}% - ${monster.hp}/${monster.maxHp}">${hpPercent}% - ${monster.hp} / ${monster.maxHp}</div>
93 <div id="fight-actions">
94 ${displayFightActions ? `
95 <form hx-post="/fight/turn" hx-target="#fight-container">
96 <select id="fight-target" name="fightTarget">
97 <option value="head">Head</option>
98 <option value="body">Body</option>
99 <option value="arms">Arms</option>
100 <option value="legs">Legs</option>
102 <button type="submit" class="fight-action red" name="action" value="attack">Attack</button>
103 <button type="submit" class="fight-action red" name="action" value="cast">Cast</button>
104 <button type="submit" class="fight-action" name="action" value="flee">Flee</button>
108 <div id="fight-results"></div>