chore(release): 0.2.10
[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       if(roundData.player.hp === 0) {
23         html.push(`<p>You were killed...</p>`);
24       }
25       html.push('<p><button hx-get="/player/explore" hx-target="#explore">Back to Town</button></p>');
26     break;
27     case 'in-progress':
28       // fight still in progress, so we don't send any final actions back
29     break;
30   }
31
32
33   return html.join("\n");
34 }
35
36 export function renderFight(monster: MonsterForFight, results: string = '', displayFightActions: boolean = true) {
37   const hpPercent = Math.floor((monster.hp / monster.maxHp) * 100);
38
39   let html = `
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">
44       </div>
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>
48       </div>
49     </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>
58         </select>
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>
62       </form>
63       `: ''}
64       </div>
65     <div id="fight-results">${results}</div>
66   </div>
67 </div>`;
68
69   return html;
70 }
71
72 export function renderFightPreRound(monster: MonsterForFight,  displayFightActions: boolean = true, location: LocationWithCity, closestTown: number) {
73   const hpPercent = Math.floor((monster.hp / monster.maxHp) * 100);
74
75   let html = `
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>
79   </div>
80   <div class="city-details">
81     <h3 class="location-name"><span>${location.name}</span></h3>
82
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">
87       </div>
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>
91       </div>
92     </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>
101         </select>
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>
105       </form>
106       `: ''}
107       </div>
108     <div id="fight-results"></div>
109   </div>
110 </div>
111 </section>
112 `;
113
114   return html;
115 }