+import _ from "lodash";
+import { DateTime } from "luxon";
+import { Account } from "../repository/accounts";
+import { ArmyQueueWithAttackedOwner } from "../repository/army";
+import { City, CityRepository, CityWithLocation } from "../repository/city";
+import { topbar } from "./topbar";
+import { AVAILABLE_SECTORS } from '../config';
+import {initArray} from "../lib/util";
+
+const cityRepo = new CityRepository();
+
+export function renderOverworldMap(cities: CityWithLocation[], yourCity: CityWithLocation, activeSector: number): string {
+ let map: CityWithLocation[][] = new Array(25);
+ for(let i = 0; i < cities.length; ++i) {
+ if(!map[cities[i].location_y]) {
+ map[cities[i].location_y] = new Array(25);
+ }
+
+ map[cities[i].location_y][cities[i].location_x] = cities[i];
+ }
+
+ let rows: string[] = [];
+ let headerRow: string[] = [];
+ for(let y = 0; y <= 25; ++y) {
+ rows[y] = '<tr>';
+ if(y === 0) {
+ // first row! add the X coors
+ for(let x = 0; x <= 25; ++x) {
+ headerRow.push(`<td class="grid-numbers">${x}</td>`);
+ }
+ }
+ else {
+ for(let x = 0; x <= 25; ++x) {
+ if(x === 0) {
+ rows[y] += `<td class="grid-numbers">${y}</td>`;
+ }
+ else {
+ if(!map[y] || !map[y][x]) {
+ rows[y] += `<td title="(${x},${y})"><div class="empty"></div></td>` ;
+ }
+ else if(map[y][x]) {
+ if(map[y][x].id === yourCity.id)
+ rows[y] += `<td title="You (${x},${y})"><div class="city yours"><img src="/assets/${map[y][x].icon}"></div></td>`;
+ else
+ rows[y] += `<td title="(${x},${y})"><div class="city others" hx-trigger="click" hx-get="/city/${map[y][x].id}" hx-target="#city-offence">
+ <img src="/assets/${map[y][x].icon}">
+ </div></td>`;
+ }
+ else {
+ rows[y] += '<td><div class="empty"></div></td>';
+ }
+ }
+ }
+ }
+ rows[y] += '</tr>';
+ }
+ let sectorSwitch: string[] = [];
+ for(let i = 1; i <= AVAILABLE_SECTORS; ++i) {
+ sectorSwitch.push(
+ `<option value="${i}" ${activeSector === i ? 'selected': ''}>Sector ${i}</option>`
+ );
+ }
+ let html = `
+ <h2 data-augmented-ui="tl-clip bl-clip none">Map</h2>
+ <div id="city-offence"></div>
+ <div id="outgoing-attacks" hx-trigger="reload-outgoing-attacks, every 600s, load" hx-get="/attacks/outgoing"></div>
+ <div id="sector-selector" class="text-right">
+ Switch Scanned Sectors:
+ <select name="sector" hx-trigger="change" hx-post="/poll/map" hx-target="#main">
+ ${sectorSwitch.join("\n")}
+ </select>
+ </div>
+ <table id="overworld-map" style="background-image:url('/assets/bg/mapoverview_${activeSector}.png');">
+ <tr>
+ ${headerRow.join("\n")}
+ </tr>
+ ${rows.join("\n")}
+ </table>
+ <br>
+ `;
+
+
+ return html;
+
+}
+
+export function listOperations(outgoingOps: ArmyQueueWithAttackedOwner[]): string {
+ let html = `
+ <h4>Outgoing Attacks</h4>
+ <table>
+ <tr>
+ <th>Destination</th>
+ <th>Sol.</th>
+ <th>Atk.</th>
+ <th>Def.</th>
+ <th>Sp. Atk.</th>
+ <th>Sp. Def.</th>
+ <th>Est. Arrival</th>
+ </tr>
+
+ ${outgoingOps.map(op => {
+ return `
+ <tr>
+ <td>${op.attacked_account} - (${op.location_x},${op.location_y})</td>
+ <td>${op.soldiers.toLocaleString()}</td>
+ <td>${op.attackers.toLocaleString()}</td>
+ <td>${op.defenders.toLocaleString()}</td>
+ <td>${op.sp_attackers.toLocaleString()}</td>
+ <td>${op.sp_defenders.toLocaleString()}</td>
+ <td>${ _.round(DateTime.fromMillis(op.due).diffNow().as('hours'), 2)} hours</td>
+ </tr>
+ `;
+ }).join("\n")}
+ </table>
+ `;
+
+ return html;
+}
+
+export async function launchOffensive(city: CityWithLocation, owner: Account, yourCity: CityWithLocation, you: Account): Promise<string> {
+ const distance = cityRepo.distanceInHours(city, yourCity);
+ const power = await cityRepo.power({
+ soldiers: yourCity.soldiers,
+ attackers: yourCity.attackers,
+ defenders: yourCity.defenders,
+ sp_attackers: yourCity.sp_attackers,
+ sp_defenders: yourCity.sp_defenders
+ })
+ let html = `
+ <h3 data-augmented-ui="tl-clip bl-clip none">Viewing (${city.location_x},${city.location_y}) owned by ${owner.username}</h3>
+ <h4>Report</h4>
+ <p>This city is ${distance} hours away.</p>
+ <form hx-post="/attack">
+ <input type="hidden" name="city" value="${city.id}">
+ <table>
+ <tr>
+ <th>Soldiers</th>
+ <td>
+ <input type="number" class="potential-attack" name="soldiers" max="${yourCity.soldiers}" value="${yourCity.soldiers}" hx-target="#total-attack-power" hx-post="/attack-power" hx-include=".potential-attack">
+ (${yourCity.soldiers})
+ </td>
+ </tr>
+ <tr>
+ <th>Attackers</th>
+ <td>
+ <input type="number" class="potential-attack" name="attackers" max="${yourCity.attackers}" value="${yourCity.attackers}" hx-target="#total-attack-power" hx-post="/attack-power" hx-include=".potential-attack">
+ (${yourCity.attackers})
+ </td>
+ </tr>
+ <tr>
+ <th>Defenders</th>
+ <td>
+ <input type="number" class="potential-attack" name="defenders" max="${yourCity.defenders}" value="${yourCity.defenders}" hx-target="#total-attack-power" hx-post="/attack-power" hx-include=".potential-attack">
+ (${yourCity.defenders})
+ </td>
+ </tr>
+ <tr>
+ <th>Sp. Attack</th>
+ <td>
+ <input type="number" class="potential-attack" name="sp_attackers" max="${yourCity.sp_attackers}" value="${yourCity.sp_attackers}" hx-target="#total-attack-power" hx-post="/attack-power" hx-include=".potential-attack">
+ (${yourCity.sp_attackers})
+ </td>
+ </tr>
+ <tr>
+ <th>Sp. Defenders</th>
+ <td>
+ <input type="number" class="potential-attack" name="sp_defenders" max="${yourCity.sp_defenders}" value="${yourCity.sp_defenders}" hx-target="#total-attack-power" hx-post="/attack-power" hx-include=".potential-attack">
+ (${yourCity.sp_defenders})
+ </td>
+ </tr>
+ <tr>
+ <th>Total Power</th>
+ <td id="total-attack-power">${power}</td>
+ </tr>
+ <tr>
+ <td colspan="2" style="text-align: right">
+ <button type="submit">Attack (${city.location_x},${city.location_y})</button>
+ </td>
+ </tr>
+ </table>
+ </form>
+ `;
+
+ return html + topbar(yourCity);
+}