chore(release): 0.2.9
[risinglegends.git] / src / server / views / fight.ts
1 import { FightRound } from "shared/fight";
2 import { LocationWithCity } from "shared/map";
3 import { MonsterForFight } from "../../shared/monsters";
4
5 export function renderRoundDetails(roundData: FightRound): string {
6   let html: string[] = roundData.roundDetails.map(d => `<div>${d}</div>`);
7
8   switch(roundData.winner) {
9     case 'player':
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>`);
13       }
14       if(roundData.rewards.exp) {
15         html.push(`<div>You gained ${roundData.rewards.exp} exp</div>`);
16       }
17       if(roundData.rewards.levelIncrease) {
18         html.push(`<div>You gained a level! ${roundData.player.level}</div>`);
19       }
20     break;
21     case 'monster':
22       // prompt to return to town and don't let them do anything
23       html.push(`<p>You were killed...</p>`);
24       html.push('<p><button hx-get="/player/explore" hx-target="#explore">Back to Town</button></p>');
25     break;
26     case 'in-progress':
27       // fight still in progress, so we don't send any final actions back
28     break;
29   }
30
31
32   return html.join("\n");
33 }
34
35 export function renderFight(monster: MonsterForFight, results: string = '', displayFightActions: boolean = true) {
36   const hpPercent = Math.floor((monster.hp / monster.maxHp) * 100);
37
38   let html = `
39   <div id="fight-container">
40     <div id="defender-info">
41       <div class="avatar-container">
42         <img id="avatar" src="https://via.placeholder.com/64x64">
43       </div>
44       <div id="defender-stat-bars">
45         <div id="defender-name">${monster.name}</div>
46         <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>
47       </div>
48     </div>
49     <div id="fight-actions">
50       ${displayFightActions ? `
51       <form hx-post="/fight/turn" hx-target="#fight-container">
52         <select id="fight-target" name="fightTarget">
53           <option value="head">Head</option>
54           <option value="body">Body</option>
55           <option value="arms">Arms</option>
56           <option value="legs">Legs</option>
57         </select>
58         <button type="submit" class="fight-action red" name="action" value="attack">Attack</button>
59         <button type="submit" class="fight-action red" name="action" value="cast">Cast</button>
60         <button type="submit" class="fight-action" name="action" value="flee">Flee</button>
61       </form>
62       `: ''}
63       </div>
64     <div id="fight-results">${results}</div>
65   </div>
66 </div>`;
67
68   return html;
69 }
70
71 export function renderFightPreRound(monster: MonsterForFight,  displayFightActions: boolean = true, location: LocationWithCity) {
72   const hpPercent = Math.floor((monster.hp / monster.maxHp) * 100);
73
74   let html = `
75   <div class="city-title-wrapper">
76     <div class="city-title">${location.city_name}</div>
77   </div>
78   <div class="city-details">
79     <h3 class="location-name"><span>${location.name}</span></h3>
80
81   <div id="fight-container">
82     <div id="defender-info">
83       <div class="avatar-container">
84         <img id="avatar" src="https://via.placeholder.com/64x64">
85       </div>
86       <div id="defender-stat-bars">
87         <div id="defender-name">${monster.name}</div>
88         <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>
89       </div>
90     </div>
91     <div id="fight-actions">
92       ${displayFightActions ? `
93       <form hx-post="/fight/turn" hx-target="#fight-container">
94         <select id="fight-target" name="fightTarget">
95           <option value="head">Head</option>
96           <option value="body">Body</option>
97           <option value="arms">Arms</option>
98           <option value="legs">Legs</option>
99         </select>
100         <button type="submit" class="fight-action red" name="action" value="attack">Attack</button>
101         <button type="submit" class="fight-action red" name="action" value="cast">Cast</button>
102         <button type="submit" class="fight-action" name="action" value="flee">Flee</button>
103       </form>
104       `: ''}
105       </div>
106     <div id="fight-results"></div>
107   </div>
108 </div>`;
109
110   return html;
111 }