|
|
|
|
@@ -1,13 +1,7 @@
|
|
|
|
|
const AUTHORIZED_ALLIANCES = {
|
|
|
|
|
"s58-fr": ["NAZGUL"]
|
|
|
|
|
"s58": ["NAZGUL"]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const MOVING_FACTOR = {
|
|
|
|
|
"s56-fr": 3,
|
|
|
|
|
"s57-fr": 4,
|
|
|
|
|
"s58-fr": 1.98,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const BUILDINGS = {
|
|
|
|
|
"main": "Château",
|
|
|
|
|
"stone": "Carrière",
|
|
|
|
|
@@ -292,10 +286,10 @@ function customizeNavbar(layCastleElement) {
|
|
|
|
|
shortcutContainers[2].classList.add("shortcut_container_right");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function countUpMs(tomorrow, afterTomorrow, movingDuration) {
|
|
|
|
|
function countUpMs(tomorrow, after_tomorrow, movingDuration) {
|
|
|
|
|
let arrivalDate = new Date(new Date().getTime() + movingDuration * 1000);
|
|
|
|
|
let prefix = "";
|
|
|
|
|
if (arrivalDate >= afterTomorrow) {
|
|
|
|
|
if (arrivalDate >= after_tomorrow) {
|
|
|
|
|
prefix = "le " + arrivalDate.getDate() + "." + arrivalDate.getMonth() + " ";
|
|
|
|
|
} else if (arrivalDate > tomorrow) {
|
|
|
|
|
prefix = "demain ";
|
|
|
|
|
@@ -311,47 +305,32 @@ function countUpMs(tomorrow, afterTomorrow, movingDuration) {
|
|
|
|
|
+ Math.floor(arrivalDate.getMilliseconds() / 100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function convertTimestamp(timestamp) {
|
|
|
|
|
function countdownMS(formattedDate) {
|
|
|
|
|
let now = new Date();
|
|
|
|
|
let tomorrow = new Date(now.getTime() + 24*3600*1000);
|
|
|
|
|
tomorrow.setHours(0);
|
|
|
|
|
tomorrow.setMinutes(0);
|
|
|
|
|
tomorrow.setSeconds(0);
|
|
|
|
|
tomorrow.setMilliseconds(0);
|
|
|
|
|
let afterTomorrow = new Date(tomorrow.getTime() + 24*3600*1000);
|
|
|
|
|
let date = new Date(timestamp);
|
|
|
|
|
|
|
|
|
|
let prefix = "";
|
|
|
|
|
if (date >= afterTomorrow) {
|
|
|
|
|
prefix = "le " + date.getDate() + "." + date.getMonth() + " ";
|
|
|
|
|
} else if (date > tomorrow) {
|
|
|
|
|
prefix = "demain ";
|
|
|
|
|
if (formattedDate.startsWith("à")) {
|
|
|
|
|
let start = new Date();
|
|
|
|
|
let hms = formattedDate.replace(/^à (\d\d:\d\d:\d\d) heures$/, "$1").split(":");
|
|
|
|
|
start.setHours(parseInt(hms[0]));
|
|
|
|
|
start.setMinutes(parseInt(hms[1]));
|
|
|
|
|
start.setSeconds(parseInt(hms[2]));
|
|
|
|
|
return start.getTime() - now.getTime();
|
|
|
|
|
}
|
|
|
|
|
return prefix
|
|
|
|
|
+ "à "
|
|
|
|
|
+ date.getHours().toString().padStart(2, "0")
|
|
|
|
|
+ ":"
|
|
|
|
|
+ date.getMinutes().toString().padStart(2, "0")
|
|
|
|
|
+ ":"
|
|
|
|
|
+ date.getSeconds().toString().padStart(2, "0")
|
|
|
|
|
+ "."
|
|
|
|
|
+ Math.floor(date.getMilliseconds() / 100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function convertDurationUntil(timestamp) {
|
|
|
|
|
let now = new Date();
|
|
|
|
|
let duration = timestamp - now.getTime();
|
|
|
|
|
let hours = Math.floor(duration / (3600*1000));
|
|
|
|
|
duration -= hours * 3600 * 1000;
|
|
|
|
|
let minutes = Math.floor(duration / (60*1000));
|
|
|
|
|
duration -= minutes * 60 * 1000;
|
|
|
|
|
let seconds = Math.floor(duration / 1000);
|
|
|
|
|
duration -= seconds * 1000;
|
|
|
|
|
let tenth = Math.floor(duration / 100);
|
|
|
|
|
return hours.toString().padStart(2, "0") + ":"
|
|
|
|
|
+ minutes.toString().padStart(2, "0") + ":"
|
|
|
|
|
+ seconds.toString().padStart(2, "0") + "."
|
|
|
|
|
+ tenth.toString();
|
|
|
|
|
if (formattedDate.startsWith("demain")) {
|
|
|
|
|
let start = new Date(now.getTime() + 24*60*60*1000);
|
|
|
|
|
let hms = formattedDate.replace(/^demain à (\d\d:\d\d:\d\d) heures$/, "$1").split(":");
|
|
|
|
|
start.setHours(parseInt(hms[0]));
|
|
|
|
|
start.setMinutes(parseInt(hms[1]));
|
|
|
|
|
start.setSeconds(parseInt(hms[2]));
|
|
|
|
|
return start.getTime() - now.getTime();
|
|
|
|
|
}
|
|
|
|
|
let start = new Date();
|
|
|
|
|
let hms = formattedDate.replace(/^le (\d\d)\.(\d\d) à (\d\d:\d\d:\d\d) heures$/, "$1:$2:$3");
|
|
|
|
|
start.setDate(parseInt(hms[0]));
|
|
|
|
|
start.setMonth(parseInt(hms[1]));
|
|
|
|
|
start.setHours(parseInt(hms[0]));
|
|
|
|
|
start.setMinutes(parseInt(hms[1]));
|
|
|
|
|
start.setSeconds(parseInt(hms[2]));
|
|
|
|
|
return start.getTime() - now.getTime();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function removeAdsBanner() {
|
|
|
|
|
@@ -458,421 +437,13 @@ function showAutoPlanerMenu(village, module) {
|
|
|
|
|
navRow.insertBefore(separatorCell, navCells[6]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function insertAutoPlanedOrder(table, orderId, order) {
|
|
|
|
|
let row = createCustomElement(
|
|
|
|
|
"tr",
|
|
|
|
|
{
|
|
|
|
|
"data-id": orderId,
|
|
|
|
|
"data-time": order.start_time,
|
|
|
|
|
"data-order": JSON.stringify(order),
|
|
|
|
|
"data-status": "waiting",
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let kindCell = createCustomElement("td");
|
|
|
|
|
let kindImg = createCustomElement("img");
|
|
|
|
|
switch (order.kind) {
|
|
|
|
|
case "attack":
|
|
|
|
|
kindImg.setAttribute("src", "/img/command/attack.png");
|
|
|
|
|
kindImg.setAttribute("title", "Attaque");
|
|
|
|
|
break;
|
|
|
|
|
case "support":
|
|
|
|
|
kindImg.setAttribute("src", "/img/command/support.png");
|
|
|
|
|
kindImg.setAttribute("title", "Renfort");
|
|
|
|
|
break
|
|
|
|
|
case "spying":
|
|
|
|
|
kindImg.setAttribute("src", "/img/units/unit_spy-slow.png");
|
|
|
|
|
kindImg.setAttribute("title", "Espionnage");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
kindCell.appendChild(kindImg);
|
|
|
|
|
row.appendChild(kindCell);
|
|
|
|
|
|
|
|
|
|
let unitCounts = [];
|
|
|
|
|
for (let unit in UNITS) {
|
|
|
|
|
unitCounts.push(order[unit]);
|
|
|
|
|
}
|
|
|
|
|
let labelCell = createCustomElement(
|
|
|
|
|
"td",
|
|
|
|
|
{"title": "Programmé " + order.occurrences.toString() + " fois"},
|
|
|
|
|
"(x" + order.occurrences + ") " + order.label,
|
|
|
|
|
);
|
|
|
|
|
row.appendChild(labelCell);
|
|
|
|
|
|
|
|
|
|
let headCell = createCustomElement(
|
|
|
|
|
"td",
|
|
|
|
|
{
|
|
|
|
|
"onmouseover":
|
|
|
|
|
"Tip(tipUnitDetails('/img', '" + Object.keys(UNITS).join(":") + "', '" + unitCounts.join(":") + "'))",
|
|
|
|
|
"onmouseout": "UnTip()",
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
let headImg = createCustomElement("img", {"src": "/img/units/unit_" + order.head + ".png"});
|
|
|
|
|
headCell.appendChild(headImg);
|
|
|
|
|
row.appendChild(headCell);
|
|
|
|
|
|
|
|
|
|
let originCell = createCustomElement("td");
|
|
|
|
|
let originInfoLink = createCustomElement(
|
|
|
|
|
"a",
|
|
|
|
|
{"href": "/?s=info_village&id=" + order.start_id, "title": order.start_name},
|
|
|
|
|
order.start_name,
|
|
|
|
|
);
|
|
|
|
|
let originMapLink = createCustomElement(
|
|
|
|
|
"a",
|
|
|
|
|
{"href": "/?s=map&x=" + order.start_x + "&y=" + order.start_y},
|
|
|
|
|
"(" + order.start_x + "|" + order.start_y + ")",
|
|
|
|
|
)
|
|
|
|
|
originCell.appendChild(originInfoLink);
|
|
|
|
|
originCell.appendChild(originMapLink);
|
|
|
|
|
row.appendChild(originCell);
|
|
|
|
|
|
|
|
|
|
let targetCell = createCustomElement("td");
|
|
|
|
|
let targetInfoLink = createCustomElement(
|
|
|
|
|
"a",
|
|
|
|
|
{"href": "/?s=info_village&id=" + order.target_id, "title": order.target_name},
|
|
|
|
|
order.target_name,
|
|
|
|
|
);
|
|
|
|
|
let targetMapLink = createCustomElement(
|
|
|
|
|
"a",
|
|
|
|
|
{"href": "/?s=map&x=" + order.target_x + "&y=" + order.target_y},
|
|
|
|
|
" (" + order.target_x + "|" + order.target_y + ")",
|
|
|
|
|
)
|
|
|
|
|
targetCell.appendChild(targetInfoLink);
|
|
|
|
|
targetCell.appendChild(targetMapLink);
|
|
|
|
|
row.appendChild(targetCell);
|
|
|
|
|
|
|
|
|
|
row.appendChild(createCustomElement("td", null, convertTimestamp(parseInt(order.start_time))));
|
|
|
|
|
row.appendChild(createCustomElement("td", null, convertTimestamp(parseInt(order.target_time))));
|
|
|
|
|
row.appendChild(createCustomElement("td", null, convertDurationUntil(parseInt(order.start_time))));
|
|
|
|
|
|
|
|
|
|
let playCell = createCustomElement("td");
|
|
|
|
|
let playLink = createCustomElement(
|
|
|
|
|
"a",
|
|
|
|
|
{
|
|
|
|
|
"href": "/?village=" + order.start_id + "&s=build_barracks&m=command" +
|
|
|
|
|
"&send_x=" + order.target_x + "&send_y=" + order.target_y + "&farmer=" + order.farmer +
|
|
|
|
|
"&sword=" + order.sword + "&spear=" + order.spear + "&axe=" + order.axe + "&bow=" + order.bow +
|
|
|
|
|
"&spy=" + order.spy + "&light=" + order.light + "&heavy=" + order.heavy + "&ram=" + order.ram +
|
|
|
|
|
"&kata=" + order.kata + "&snob=" + order.snob,
|
|
|
|
|
"title": "Lancer manuellement",
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
let playImg = createCustomElement(
|
|
|
|
|
"img", {"src": chrome.runtime.getURL("/images/play.svg")}, null, {"width": "18px"}
|
|
|
|
|
);
|
|
|
|
|
playLink.appendChild(playImg);
|
|
|
|
|
playCell.appendChild(playLink);
|
|
|
|
|
row.appendChild(playCell);
|
|
|
|
|
|
|
|
|
|
let cancelCell = createCustomElement("td");
|
|
|
|
|
let cancelImg = createCustomElement(
|
|
|
|
|
"img",
|
|
|
|
|
{"src": chrome.runtime.getURL("/images/cancel.svg"), "title": "Annuler"},
|
|
|
|
|
null,
|
|
|
|
|
{"width": "18px", "cursor": "pointer"},
|
|
|
|
|
);
|
|
|
|
|
cancelImg.addEventListener("click", function() {
|
|
|
|
|
row.remove();
|
|
|
|
|
let autoPlanedOrders = localStorage.getItem("autoPlanedOrders");
|
|
|
|
|
if (autoPlanedOrders === null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
autoPlanedOrders = JSON.parse(autoPlanedOrders);
|
|
|
|
|
delete autoPlanedOrders[orderId];
|
|
|
|
|
localStorage.setItem("autoPlanedOrders", JSON.stringify(autoPlanedOrders));
|
|
|
|
|
});
|
|
|
|
|
cancelCell.appendChild(cancelImg);
|
|
|
|
|
row.appendChild(cancelCell);
|
|
|
|
|
|
|
|
|
|
// Insert row at right time place
|
|
|
|
|
let rows = table.getElementsByTagName("tr");
|
|
|
|
|
for (let i = 1; i < rows.length; i ++) {
|
|
|
|
|
if (parseInt(rows[i].getAttribute("data-time")) > parseInt(order.start_time)) {
|
|
|
|
|
table.insertBefore(row, rows[i]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
table.appendChild(row);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function autoPlanerInterval() {
|
|
|
|
|
let now = new Date().getTime();
|
|
|
|
|
let table = document.getElementById("autoPlanedOrders");
|
|
|
|
|
let rows = table.getElementsByTagName("tr");
|
|
|
|
|
let delay = 100;
|
|
|
|
|
for (let i = 1; i < rows.length; i ++) {
|
|
|
|
|
if (rows[i].getAttribute("data-status") !== "waiting") {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let startTime = parseInt(rows[i].getAttribute("data-time"));
|
|
|
|
|
let duration = startTime - now;
|
|
|
|
|
if (duration <= 0) {
|
|
|
|
|
rows[i].setAttribute("data-status", "done");
|
|
|
|
|
rows[i].style.opacity = "0.5";
|
|
|
|
|
let order = JSON.parse(rows[i].getAttribute("data-order"));
|
|
|
|
|
let orderToken = sessionStorage.getItem("orderToken");
|
|
|
|
|
let formData = new FormData();
|
|
|
|
|
for (let unit in UNITS) {
|
|
|
|
|
formData.set(unit, order[unit]);
|
|
|
|
|
}
|
|
|
|
|
switch (order.kind) {
|
|
|
|
|
case "attack":
|
|
|
|
|
formData.set("attack", "Attaquer");
|
|
|
|
|
formData.set("espy", "");
|
|
|
|
|
if (order.kata !== "0") {
|
|
|
|
|
formData.set("kata_target", order.building);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "support":
|
|
|
|
|
formData.set("attack", "");
|
|
|
|
|
formData.set("espy", "");
|
|
|
|
|
break;
|
|
|
|
|
case "spying":
|
|
|
|
|
formData.set("attack", "");
|
|
|
|
|
formData.set("espy", "Espionner");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
formData.set("send_x", order.target_x);
|
|
|
|
|
formData.set("send_y", order.target_y);
|
|
|
|
|
formData.set("transport", "none");
|
|
|
|
|
let formParams = new URLSearchParams(formData);
|
|
|
|
|
|
|
|
|
|
for (let j = 0; j < parseInt(order.occurrences); j ++) {
|
|
|
|
|
let xhr = new XMLHttpRequest();
|
|
|
|
|
xhr.open(
|
|
|
|
|
"POST", "/?village=" + order.start_id + "&s=build_barracks&m=command&a=sendTroop&p=" + orderToken
|
|
|
|
|
);
|
|
|
|
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
|
|
|
xhr.send(formParams.toString());
|
|
|
|
|
|
|
|
|
|
let autoPlanedOrders = localStorage.getItem("autoPlanedOrders");
|
|
|
|
|
if (autoPlanedOrders === null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
autoPlanedOrders = JSON.parse(autoPlanedOrders);
|
|
|
|
|
delete autoPlanedOrders[rows[i].getAttribute("data-id")];
|
|
|
|
|
localStorage.setItem("autoPlanedOrders", JSON.stringify(autoPlanedOrders));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
rows[i].getElementsByTagName("td")[7].textContent = convertDurationUntil(startTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
setTimeout(autoPlanerInterval, delay);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleAutoPlanerUnitChange() {
|
|
|
|
|
let buildingSelect = document.getElementById("autoPlanerBuilding");
|
|
|
|
|
let unitInputs = document.getElementById("autoPlanerUnitRow").getElementsByTagName("input");
|
|
|
|
|
let totalUnitCount = 0;
|
|
|
|
|
let spyCount = 0;
|
|
|
|
|
let kataCount = 0;
|
|
|
|
|
let attackButton = document.getElementById("autoPlanerSubmitAttack");
|
|
|
|
|
let supportButton = document.getElementById("autoPlanerSubmitSupport");
|
|
|
|
|
let spyingButton = document.getElementById("autoPlanerSubmitSpying");
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < unitInputs.length; i ++) {
|
|
|
|
|
let unitCount = 0;
|
|
|
|
|
if (unitInputs[i].value !== "") {
|
|
|
|
|
unitCount = parseInt(unitInputs[i].value);
|
|
|
|
|
}
|
|
|
|
|
if (unitInputs[i].getAttribute("name") === "spy") {
|
|
|
|
|
spyCount = unitCount;
|
|
|
|
|
}
|
|
|
|
|
if (unitInputs[i].getAttribute("name") === "kata") {
|
|
|
|
|
kataCount = unitCount;
|
|
|
|
|
}
|
|
|
|
|
totalUnitCount += unitCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (kataCount > 0) {
|
|
|
|
|
buildingSelect.removeAttribute("disabled");
|
|
|
|
|
} else {
|
|
|
|
|
buildingSelect.setAttribute("disabled", "disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (spyCount > 0 && spyCount === totalUnitCount) {
|
|
|
|
|
spyingButton.removeAttribute("disabled");
|
|
|
|
|
} else {
|
|
|
|
|
spyingButton.setAttribute("disabled", "disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (totalUnitCount > 0) {
|
|
|
|
|
attackButton.removeAttribute("disabled");
|
|
|
|
|
supportButton.removeAttribute("disabled");
|
|
|
|
|
} else {
|
|
|
|
|
attackButton.setAttribute("disabled", "disabled");
|
|
|
|
|
supportButton.setAttribute("disabled", "disabled");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleAutoPlanerSubmit(event) {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
|
|
|
|
let autoPlanerError = document.getElementById("autoPlanerError");
|
|
|
|
|
autoPlanerError.textContent = " ";
|
|
|
|
|
|
|
|
|
|
let nowTime = Date.now();
|
|
|
|
|
let formData = new FormData(this);
|
|
|
|
|
formData.set("kind", event.submitter.getAttribute("name"));
|
|
|
|
|
|
|
|
|
|
// Check start village
|
|
|
|
|
let ownVillages = sessionStorage.getItem("ownVillages");
|
|
|
|
|
if (ownVillages === null) {
|
|
|
|
|
autoPlanerError.textContent = "Impossible de récupérer la liste de vos propres villages, " +
|
|
|
|
|
"merci de recharger la page ou de vous reconnecter au jeu si le problème persiste!"
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ownVillages = JSON.parse(ownVillages);
|
|
|
|
|
for (let ownVillageId in ownVillages) {
|
|
|
|
|
let ownVillage = ownVillages[ownVillageId];
|
|
|
|
|
if (ownVillage.x === parseInt(formData.get("start_x").toString()) &&
|
|
|
|
|
ownVillage.y === parseInt(formData.get("start_y").toString())) {
|
|
|
|
|
formData.set("start_id", ownVillageId);
|
|
|
|
|
formData.set("start_name", ownVillage.name);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (! formData.has("start_id")) {
|
|
|
|
|
autoPlanerError.textContent = "Opération impossible car le village d'origine ne vous appartient pas!";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check target time
|
|
|
|
|
let targetTime = Date.parse(
|
|
|
|
|
formData.get("year").toString() + "-" +
|
|
|
|
|
formData.get("month").toString().padStart(2, "0") + "-" +
|
|
|
|
|
formData.get("day").toString().padStart(2, "0") + "T" +
|
|
|
|
|
formData.get("hour").toString().padStart(2, "0") + ":" +
|
|
|
|
|
formData.get("minute").toString().padStart(2, "0") + ":" +
|
|
|
|
|
formData.get("second").toString().padStart(2, "0")
|
|
|
|
|
) + parseInt(formData.get("tenth").toString()) * 100;
|
|
|
|
|
if (nowTime > targetTime) {
|
|
|
|
|
autoPlanerError.textContent = "Opération impossible car l'heure d'arrivée est dans le passé!";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
formData.set("target_time", targetTime.toString());
|
|
|
|
|
formData.delete("year");
|
|
|
|
|
formData.delete("month");
|
|
|
|
|
formData.delete("day");
|
|
|
|
|
formData.delete("hour");
|
|
|
|
|
formData.delete("minute");
|
|
|
|
|
formData.delete("second");
|
|
|
|
|
formData.delete("tenth");
|
|
|
|
|
|
|
|
|
|
// Replace empty unit values by 0
|
|
|
|
|
for (let unit in UNITS) {
|
|
|
|
|
if (formData.get(unit) === "") {
|
|
|
|
|
formData.set(unit, "0");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Calculate start time
|
|
|
|
|
let serverId = window.location.hostname.replace(/^([^.]+).*$/, "$1");
|
|
|
|
|
let moving_factor = 1;
|
|
|
|
|
if (serverId in MOVING_FACTOR) {
|
|
|
|
|
moving_factor = MOVING_FACTOR[serverId];
|
|
|
|
|
}
|
|
|
|
|
let durationSeconds = Math.sqrt(
|
|
|
|
|
Math.pow(parseInt(formData.get("target_x").toString()) - parseInt(formData.get("start_x").toString()), 2) +
|
|
|
|
|
Math.pow(parseInt(formData.get("target_y").toString()) - parseInt(formData.get("start_y").toString()), 2)
|
|
|
|
|
)
|
|
|
|
|
if (formData.get("snob") !== "0") {
|
|
|
|
|
durationSeconds *= 2100 / moving_factor;
|
|
|
|
|
formData.set("head", "snob");
|
|
|
|
|
} else if (formData.get("kata") !== "0") {
|
|
|
|
|
durationSeconds *= 1800 / moving_factor;
|
|
|
|
|
formData.set("head", "kata");
|
|
|
|
|
} else if (formData.get("ram") !== "0") {
|
|
|
|
|
durationSeconds *= 1800 / moving_factor;
|
|
|
|
|
formData.set("head", "ram");
|
|
|
|
|
} else if (formData.get("kind") === "spying") {
|
|
|
|
|
durationSeconds *= 1800 / moving_factor;
|
|
|
|
|
formData.set("head", "spy");
|
|
|
|
|
} else if (formData.get("sword") !== "0") {
|
|
|
|
|
durationSeconds *= 1320 / moving_factor;
|
|
|
|
|
formData.set("head", "sword");
|
|
|
|
|
} else if (formData.get("farmer") !== "0") {
|
|
|
|
|
durationSeconds *= 1200 / moving_factor;
|
|
|
|
|
formData.set("head", "farmer");
|
|
|
|
|
} else if (formData.get("spear") !== "0") {
|
|
|
|
|
durationSeconds *= 1080 / moving_factor;
|
|
|
|
|
formData.set("head", "spear");
|
|
|
|
|
} else if (formData.get("axe") !== "0") {
|
|
|
|
|
durationSeconds *= 1080 / moving_factor;
|
|
|
|
|
formData.set("head", "axe");
|
|
|
|
|
} else if (formData.get("bow") !== "0") {
|
|
|
|
|
durationSeconds *= 1080 / moving_factor;
|
|
|
|
|
formData.set("head", "bow");
|
|
|
|
|
} else if (formData.get("heavy") !== "0") {
|
|
|
|
|
durationSeconds *= 660 / moving_factor;
|
|
|
|
|
formData.set("head", "heavy");
|
|
|
|
|
} else if (formData.get("light") !== "0") {
|
|
|
|
|
durationSeconds *= 600 / moving_factor;
|
|
|
|
|
formData.set("head", "light");
|
|
|
|
|
} else if (formData.get("spy") !== "0") {
|
|
|
|
|
durationSeconds *= 540 / moving_factor;
|
|
|
|
|
formData.set("head", "spy");
|
|
|
|
|
} else {
|
|
|
|
|
autoPlanerError.textContent = "Opération impossible car aucune unité n'a été sélectionnée!";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let duration = Math.round(durationSeconds) * 1000;
|
|
|
|
|
let startTime = targetTime - duration;
|
|
|
|
|
if (nowTime > startTime) {
|
|
|
|
|
autoPlanerError.textContent = "Opération impossible car l'heure de départ est dans le passé!";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
formData.set("start_time", startTime.toString());
|
|
|
|
|
|
|
|
|
|
// Check target village
|
|
|
|
|
let xhr = new XMLHttpRequest();
|
|
|
|
|
xhr.addEventListener("readystatechange", function () {
|
|
|
|
|
if (xhr.readyState === xhr.DONE) {
|
|
|
|
|
let parser = new DOMParser();
|
|
|
|
|
let doc = parser.parseFromString(xhr.responseText, "text/html");
|
|
|
|
|
let mapContainer = doc.getElementById("mapContainer");
|
|
|
|
|
let map = mapContainer.getElementsByTagName("table")[1];
|
|
|
|
|
let tbody = map.getElementsByTagName("tbody")[0];
|
|
|
|
|
let mapCell = tbody.children[6].children[8];
|
|
|
|
|
let mapLinks = mapCell.getElementsByTagName("a");
|
|
|
|
|
if (mapLinks.length === 0) {
|
|
|
|
|
autoPlanerError.textContent = "Opération impossible car le village cible n'existe pas!";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
formData.set("target_id", mapLinks[0].getAttribute("href").replace(/^.*id=(\d{4}).*$/, "$1"));
|
|
|
|
|
let targetName = mapLinks[0].getAttribute("onmouseover").replace(/^.*'(.*) \(\d{3}\|\d{3}\).*$/, "$1");
|
|
|
|
|
targetName = targetName.replace(/ <.*>/, "");
|
|
|
|
|
formData.set("target_name", targetName);
|
|
|
|
|
|
|
|
|
|
// Save attack in localStorage
|
|
|
|
|
let autoPlanedOrders = localStorage.getItem("autoPlanedOrders");
|
|
|
|
|
if (autoPlanedOrders === null) {
|
|
|
|
|
autoPlanedOrders = {};
|
|
|
|
|
} else {
|
|
|
|
|
autoPlanedOrders = JSON.parse(autoPlanedOrders);
|
|
|
|
|
}
|
|
|
|
|
let orderId = crypto.randomUUID();
|
|
|
|
|
let order = Object.fromEntries(formData);
|
|
|
|
|
insertAutoPlanedOrder(document.getElementById("autoPlanedOrders"), orderId, order);
|
|
|
|
|
autoPlanedOrders[orderId] = order;
|
|
|
|
|
localStorage.setItem("autoPlanedOrders", JSON.stringify(autoPlanedOrders));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
xhr.open(
|
|
|
|
|
"GET",
|
|
|
|
|
"/?s=map&x=" + formData.get("target_x").toString() + "&y=" + formData.get("target_y").toString(),
|
|
|
|
|
);
|
|
|
|
|
xhr.send();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showAutoPlanerPage(village) {
|
|
|
|
|
let mainContentPane = document.getElementsByClassName("contentpane")[1];
|
|
|
|
|
for (let i = mainContentPane.childNodes.length - 1; i >= 5; i --) {
|
|
|
|
|
mainContentPane.childNodes[i].remove();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let autoPlanerForm = createCustomElement("form", {"name": "kingsage", "id": "autoPlanerForm"});
|
|
|
|
|
let autoPlanerForm = createCustomElement("form", {"name": "kingsage"});
|
|
|
|
|
let borderList = createCustomElement("table", {"class": "borderlist", "width": "820"});
|
|
|
|
|
let titleRow = createCustomElement("tr");
|
|
|
|
|
let titleCell = createCustomElement("th", {"colspan": "7"}, "Nouvel ordre autonome");
|
|
|
|
|
@@ -954,7 +525,7 @@ function showAutoPlanerPage(village) {
|
|
|
|
|
"number",
|
|
|
|
|
"target_x",
|
|
|
|
|
null,
|
|
|
|
|
{"id": "target_x", "required": "required", "min": "0", "max": "999"},
|
|
|
|
|
{"id": "target_x", "required": "required", "min": "1", "max": "999"},
|
|
|
|
|
{"width": "50px"},
|
|
|
|
|
);
|
|
|
|
|
targetXCell.appendChild(targetXInput);
|
|
|
|
|
@@ -965,7 +536,7 @@ function showAutoPlanerPage(village) {
|
|
|
|
|
"number",
|
|
|
|
|
"target_y",
|
|
|
|
|
null,
|
|
|
|
|
{"id": "target_y", "required": "required", "min": "0", "max": "999"},
|
|
|
|
|
{"id": "target_y", "required": "required", "min": "1", "max": "999"},
|
|
|
|
|
{"width": "50px"},
|
|
|
|
|
);
|
|
|
|
|
targetYCell.appendChild(targetYInput);
|
|
|
|
|
@@ -1001,7 +572,7 @@ function showAutoPlanerPage(village) {
|
|
|
|
|
dateCell.appendChild(createCustomInput(
|
|
|
|
|
"number",
|
|
|
|
|
"month",
|
|
|
|
|
(now.getMonth() + 1).toString(),
|
|
|
|
|
now.getMonth().toString(),
|
|
|
|
|
{"required": "required", "min": "1", "max": "12"},
|
|
|
|
|
{"width": "40px"},
|
|
|
|
|
));
|
|
|
|
|
@@ -1060,20 +631,23 @@ function showAutoPlanerPage(village) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unitBorderList.appendChild(unitTitleRow);
|
|
|
|
|
let unitInputRow = createCustomElement("tr", {"id": "autoPlanerUnitRow"});
|
|
|
|
|
let unitInputRow = createCustomElement("tr");
|
|
|
|
|
for (let unit in UNITS) {
|
|
|
|
|
let unitInputCell = createCustomElement("td");
|
|
|
|
|
let unitInput = createCustomInput(
|
|
|
|
|
"number",
|
|
|
|
|
unit,
|
|
|
|
|
null,
|
|
|
|
|
{"id": "autoPlanerUnit" + unit.charAt(0).toUpperCase() + unit.slice(1), "min": "0"}, {"width": "61px"},
|
|
|
|
|
);
|
|
|
|
|
unitInput.addEventListener("change", handleAutoPlanerUnitChange);
|
|
|
|
|
let unitInput = createCustomInput("number", unit, null, {"min": "0"}, {"width": "61px"});
|
|
|
|
|
switch (unit) {
|
|
|
|
|
case "spy": case "light": case "heavy": case "ram": case "snob":
|
|
|
|
|
unitInput.style.width = "62px";
|
|
|
|
|
break;
|
|
|
|
|
case "kata":
|
|
|
|
|
unitInput.addEventListener("change", function () {
|
|
|
|
|
if (autoPlanerForm.kata.value !== "0" && autoPlanerForm.genre.value === "attack") {
|
|
|
|
|
autoPlanerForm.building.removeAttribute("disabled");
|
|
|
|
|
} else {
|
|
|
|
|
autoPlanerForm.building.setAttribute("disabled", "disabled");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
unitInputCell.appendChild(unitInput);
|
|
|
|
|
unitInputRow.appendChild(unitInputCell);
|
|
|
|
|
@@ -1089,7 +663,7 @@ function showAutoPlanerPage(village) {
|
|
|
|
|
labelRow.appendChild(createCustomElement("td", null, "Étiquette:"));
|
|
|
|
|
let labelCell = createCustomElement("td", {"colspan": "6"});
|
|
|
|
|
let labelInput = createCustomInput(
|
|
|
|
|
"text", "label", null, {"maxlength": "10", "placeholder": "Optionnel"}, {"width": "100px"}
|
|
|
|
|
"text", "label", null, {"maxlength": "10"}, {"width": "100px"}
|
|
|
|
|
);
|
|
|
|
|
labelCell.appendChild(labelInput);
|
|
|
|
|
labelRow.appendChild(labelCell);
|
|
|
|
|
@@ -1105,12 +679,33 @@ function showAutoPlanerPage(village) {
|
|
|
|
|
occurrencesRow.appendChild(occurrencesCell);
|
|
|
|
|
additionalBorderList.appendChild(occurrencesRow);
|
|
|
|
|
|
|
|
|
|
let genreRow = createCustomElement("tr");
|
|
|
|
|
genreRow.appendChild(createCustomElement("td", null, "Type:"));
|
|
|
|
|
let genreCell = createCustomElement("td", {"colspan": "6"});
|
|
|
|
|
let genreSelect = createCustomElement(
|
|
|
|
|
"select", {"name": "genre", "value": "attack"}, {"required": "required"}, {"width": "200px"}
|
|
|
|
|
);
|
|
|
|
|
genreSelect.appendChild(createCustomElement("option", {"value": "attack"}, "Attaque"));
|
|
|
|
|
genreSelect.appendChild(createCustomElement("option", {"value": "support"}, "Renfort"));
|
|
|
|
|
genreSelect.appendChild(createCustomElement("option", {"value": "spy"}, "Espionnage"));
|
|
|
|
|
genreSelect.addEventListener("change", function () {
|
|
|
|
|
if (autoPlanerForm.kata.value !== "0" && autoPlanerForm.genre.value === "attack") {
|
|
|
|
|
autoPlanerForm.building.removeAttribute("disabled");
|
|
|
|
|
} else {
|
|
|
|
|
autoPlanerForm.building.setAttribute("disabled", "disabled");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
genreCell.appendChild(genreSelect);
|
|
|
|
|
genreRow.appendChild(genreCell);
|
|
|
|
|
additionalBorderList.appendChild(genreRow);
|
|
|
|
|
|
|
|
|
|
let buildingRow = createCustomElement("tr");
|
|
|
|
|
buildingRow.appendChild(createCustomElement("td", null, "Bâtiment visé:"));
|
|
|
|
|
let buildingCell = createCustomElement("td", {"colspan": "6"});
|
|
|
|
|
let buildingSelect = createCustomElement(
|
|
|
|
|
"select", {"name": "building", "disabled": "disabled", "id": "autoPlanerBuilding"}, null, {"width": "200px"}
|
|
|
|
|
"select", {"name": "building", "disabled": "disabled"}, null, {"width": "200px"}
|
|
|
|
|
);
|
|
|
|
|
buildingSelect.appendChild(createCustomElement("option", null, "Sélectionner bâtiment"));
|
|
|
|
|
for (let building in BUILDINGS) {
|
|
|
|
|
buildingSelect.appendChild(createCustomElement("option", {"value": building}, BUILDINGS[building]));
|
|
|
|
|
}
|
|
|
|
|
@@ -1118,19 +713,19 @@ function showAutoPlanerPage(village) {
|
|
|
|
|
buildingRow.appendChild(buildingCell);
|
|
|
|
|
additionalBorderList.appendChild(buildingRow);
|
|
|
|
|
|
|
|
|
|
autoPlanerForm.appendChild(createCustomElement(
|
|
|
|
|
"p",
|
|
|
|
|
null,
|
|
|
|
|
"!ATTENTION! Les programmations sur cette page sont sauvegardées sur ce navigateur uniquement. " +
|
|
|
|
|
"Afin que les troupes soient envoyées automatiquement, il faut garder cette page ouverte sur " +
|
|
|
|
|
"ce navigateur et rester connecté ici. Vous ne pourrez donc pas voir les programmations d'ici sur " +
|
|
|
|
|
"un autre navigateur ou un autre appareil. Cependant, les programmations sont persistantes sur " +
|
|
|
|
|
"votre navigateur, donc vous pouvez le fermer et le rouvrir, vous verrez toujours les programmations ici.",
|
|
|
|
|
{"font-weight": "bold"},
|
|
|
|
|
));
|
|
|
|
|
autoPlanerForm.appendChild(createCustomElement("br"));
|
|
|
|
|
autoPlanerForm.appendChild(createCustomElement("p", {"class": "error", "id": "autoPlanerError"}, " "));
|
|
|
|
|
autoPlanerForm.appendChild(createCustomElement("br"));
|
|
|
|
|
autoPlanerForm.addEventListener("submit", function (event) {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
let formData = new FormData(this);
|
|
|
|
|
let autoPlanedAttacks = localStorage.getItem("autoPlanedAttacks");
|
|
|
|
|
if (autoPlanedAttacks === null) {
|
|
|
|
|
autoPlanedAttacks = [];
|
|
|
|
|
} else {
|
|
|
|
|
autoPlanedAttacks = JSON.parse(autoPlanedAttacks);
|
|
|
|
|
}
|
|
|
|
|
autoPlanedAttacks.push(Object.fromEntries(formData));
|
|
|
|
|
localStorage.setItem("autoPlanedAttacks", JSON.stringify(autoPlanedAttacks));
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
autoPlanerForm.appendChild(borderList);
|
|
|
|
|
autoPlanerForm.appendChild(createCustomElement("br"));
|
|
|
|
|
autoPlanerForm.appendChild(unitBorderList);
|
|
|
|
|
@@ -1139,57 +734,12 @@ function showAutoPlanerPage(village) {
|
|
|
|
|
autoPlanerForm.appendChild(createCustomElement("br"));
|
|
|
|
|
autoPlanerForm.appendChild(createCustomInput(
|
|
|
|
|
"submit",
|
|
|
|
|
"attack",
|
|
|
|
|
"> Programmer une nouvelle attaque",
|
|
|
|
|
{"id": "autoPlanerSubmitAttack", "disabled": "disabled"},
|
|
|
|
|
{"font-weight": "bold", "width": "250px", "padding": "5px 0", "cursor": "pointer"}
|
|
|
|
|
null,
|
|
|
|
|
"> Ajouter une nouvelle entrée",
|
|
|
|
|
null,
|
|
|
|
|
{"font-weight": "bold", "padding": "5px 20px", "cursor": "pointer"}
|
|
|
|
|
));
|
|
|
|
|
autoPlanerForm.appendChild(createCustomInput(
|
|
|
|
|
"submit",
|
|
|
|
|
"support",
|
|
|
|
|
"> Programmer un nouveau renfort",
|
|
|
|
|
{"id": "autoPlanerSubmitSupport", "disabled": "disabled"},
|
|
|
|
|
{"font-weight": "bold", "width": "250px", "padding": "5px 0", "margin": "0 35px", "cursor": "pointer"}
|
|
|
|
|
));
|
|
|
|
|
autoPlanerForm.appendChild(createCustomInput(
|
|
|
|
|
"submit",
|
|
|
|
|
"spying",
|
|
|
|
|
"> Programmer un nouvel espionnage",
|
|
|
|
|
{"id": "autoPlanerSubmitSpying", "disabled": "disabled"},
|
|
|
|
|
{"font-weight": "bold", "width": "250px", "padding": "5px 0", "cursor": "pointer"}
|
|
|
|
|
));
|
|
|
|
|
autoPlanerForm.addEventListener("submit", handleAutoPlanerSubmit);
|
|
|
|
|
mainContentPane.appendChild(autoPlanerForm);
|
|
|
|
|
|
|
|
|
|
let ordersBorderList = createCustomElement(
|
|
|
|
|
"table", {"id": "autoPlanedOrders", "class": "borderlist"}, null, {"width": "820px"}
|
|
|
|
|
);
|
|
|
|
|
let ordersTitleRow = createCustomElement("tr");
|
|
|
|
|
ordersTitleRow.appendChild(createCustomElement("th", {"colspan": "3"}));
|
|
|
|
|
ordersTitleRow.appendChild(createCustomElement("th", null, "Village originel"));
|
|
|
|
|
ordersTitleRow.appendChild(createCustomElement("th", null, "Village cible"));
|
|
|
|
|
ordersTitleRow.appendChild(createCustomElement("th", null, "Heure du début"));
|
|
|
|
|
ordersTitleRow.appendChild(createCustomElement("th", null, "Heure d'arrivée"));
|
|
|
|
|
ordersTitleRow.appendChild(createCustomElement("th", null, "Décompte"));
|
|
|
|
|
ordersTitleRow.appendChild(createCustomElement("th", {"colspan": "2"}));
|
|
|
|
|
ordersBorderList.appendChild(ordersTitleRow);
|
|
|
|
|
|
|
|
|
|
mainContentPane.appendChild(createCustomElement("br"));
|
|
|
|
|
mainContentPane.appendChild(createCustomElement("br"));
|
|
|
|
|
mainContentPane.appendChild(ordersBorderList);
|
|
|
|
|
|
|
|
|
|
let autoPlanedOrders = localStorage.getItem("autoPlanedOrders");
|
|
|
|
|
if (autoPlanedOrders === null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
autoPlanedOrders = JSON.parse(autoPlanedOrders);
|
|
|
|
|
if (autoPlanedOrders.length === 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (let orderId in autoPlanedOrders) {
|
|
|
|
|
insertAutoPlanedOrder(ordersBorderList, orderId, autoPlanedOrders[orderId]);
|
|
|
|
|
}
|
|
|
|
|
autoPlanerInterval();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showVillageUnitPoints() {
|
|
|
|
|
@@ -1359,16 +909,16 @@ function showOccurrencesInput() {
|
|
|
|
|
form.addEventListener("submit", function (event) {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
let formData = new FormData(this);
|
|
|
|
|
let occurrences = parseInt(formData.get("occurrences").toString());
|
|
|
|
|
let attackCount = parseInt(formData.get("occurrences").toString());
|
|
|
|
|
formData.delete("occurrences");
|
|
|
|
|
let sent = 0;
|
|
|
|
|
for (let i = 0; i < occurrences; i ++) {
|
|
|
|
|
for (let i = 0; i < attackCount; i ++) {
|
|
|
|
|
let xhr = new XMLHttpRequest();
|
|
|
|
|
xhr.addEventListener("readystatechange", function () {
|
|
|
|
|
if (this.readyState === this.DONE) {
|
|
|
|
|
sent ++;
|
|
|
|
|
}
|
|
|
|
|
if (sent === occurrences) {
|
|
|
|
|
if (sent === attackCount) {
|
|
|
|
|
window.location.replace(xhr.responseURL);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
@@ -1386,8 +936,7 @@ function fixSelectVillageBug() {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
selects[0].removeAttribute("onchange");
|
|
|
|
|
selects[0].setAttribute("id", "ownlist");
|
|
|
|
|
selects[0].addEventListener("change", function () { selectVillage("ownlist", "send_x", "send_y") });
|
|
|
|
|
selects[0].addEventListener("change", function () { selectVillage("TODO", "send_x", "send_y") });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showThousandInputs() {
|
|
|
|
|
@@ -1451,6 +1000,7 @@ function showSecondsAndCalculator() {
|
|
|
|
|
if (rows[titleRowIndex].getElementsByTagName("th").length === 0) {
|
|
|
|
|
titleRowIndex = 1;
|
|
|
|
|
}
|
|
|
|
|
console.log(titleRowIndex)
|
|
|
|
|
|
|
|
|
|
let headCell = createCustomElement("th", null, "Calcul", {"width": "45px"});
|
|
|
|
|
rows[titleRowIndex].appendChild(headCell);
|
|
|
|
|
@@ -1514,7 +1064,7 @@ function main() {
|
|
|
|
|
|
|
|
|
|
/* Exit immediately if not authorized */
|
|
|
|
|
let xhrAlly = new XMLHttpRequest();
|
|
|
|
|
let serverID = window.location.hostname.replace(/^([^.]+).*$/, "$1");
|
|
|
|
|
let serverID = window.location.hostname.replace(/^(s\d+)-.*$/, "$1");
|
|
|
|
|
if (serverID in AUTHORIZED_ALLIANCES) {
|
|
|
|
|
xhrAlly.addEventListener("readystatechange", function () {
|
|
|
|
|
if (xhrAlly.readyState === xhrAlly.DONE) {
|
|
|
|
|
|