AWBW Helper

Outils de jeu (unités en attente, prévisualisation de portée) pour AWBW

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         AWBW Helper
// @version      1.1.0
// @author       StormSheep
// @description  Outils de jeu (unités en attente, prévisualisation de portée) pour AWBW
// @license      MIT
// @match        https://awbw.amarriner.com/*
// @namespace https://greasyfork.org/users/1626573
// ==/UserScript==

(function () {
  'use strict';

  function getNextUnitButton() {
    return nextUnitBtn;
  }
  function isGameReady() {
    return typeof unitsInfo === "object" && typeof playersUnits === "object" && typeof getViewerPId === "function" && typeof unitClickHandler === "function";
  }
  function selectUnit(id) {
    unitClickHandler({ id });
  }
  function unitIconUrl(unit) {
    const unitSlug = unit.units_name.toLowerCase().replace(" ", "");
    return `terrain/ani/${unit.countries_code}${unitSlug}.gif`;
  }
  function unitHpIconUrl(unit) {
    if (unit.units_hit_points === 10) return null;
    return `terrain/ani/${unit.units_hit_points}.gif`;
  }
  const LOWEST_PRIORITY_UNIT_NAMES = /* @__PURE__ */ new Set(["black boat"]);
  const LOW_PRIORITY_UNIT_NAMES = /* @__PURE__ */ new Set(["missile", "pipe runner"]);
  function unitPriority(unit) {
    const name = unit.units_name.toLowerCase();
    if (LOWEST_PRIORITY_UNIT_NAMES.has(name)) return 2;
    if (LOW_PRIORITY_UNIT_NAMES.has(name)) return 1;
    return 0;
  }
  function isViewerTurn() {
    return currentTurn === getViewerPId();
  }
  function getPendingUnits() {
    const viewerId = getViewerPId();
    const viewerUnits = playersUnits[viewerId];
    if (!viewerUnits) return [];
    return Object.keys(viewerUnits).map((id) => unitsInfo[id]).filter((unit) => unit && unit.units_moved === 0 && unit.units_carried === "N").sort((a, b) => unitPriority(a) - unitPriority(b));
  }
  function getPendingMove() {
    var _a;
    if (!moving || !(currentClick == null ? void 0 : currentClick.info) || !((_a = currentClick.path) == null ? void 0 : _a.length)) return null;
    const destNode = currentClick.path[currentClick.path.length - 1];
    const { x, y } = coordsFromNode(destNode);
    return { unit: currentClick.info, destX: x, destY: y };
  }
  function heldPreviewKey() {
    if (!isGameFocused()) return null;
    if (keyboardKeysPressed.get("shift")) return "movement";
    if (keyboardKeysPressed.get("control")) return "range";
    if (keyboardKeysPressed.get("alt")) return "vision";
    return null;
  }
  function previewTilesAt(unit, x, y, type) {
    const previewUnit = { ...unit, units_x: x, units_y: y };
    const original = getUnitAt;
    getUnitAt = (px, py) => px === x && py === y ? previewUnit : original(px, py);
    try {
      addTilesForUnitAt(x, y, type);
    } finally {
      getUnitAt = original;
    }
  }
  function redrawPendingMovePath() {
    if (!(currentClick == null ? void 0 : currentClick.path)) return;
    const lastNode = currentClick.path[currentClick.path.length - 1];
    const { x, y } = coordsFromNode(lastNode);
    currentClick.path = drawPathTiles(movementInfo, x, y, currentClick.path);
  }
  const TICK_MS = 50;
  let lastPreviewKey = null;
  function tick() {
    const move = getPendingMove();
    const type = move ? heldPreviewKey() : null;
    if (!move) {
      lastPreviewKey = null;
      return;
    }
    if (!type) {
      if (lastPreviewKey !== null) {
        lastPreviewKey = null;
        previewTilesAt(move.unit, move.unit.units_x, move.unit.units_y, "movement");
        redrawPendingMovePath();
      }
      return;
    }
    const key = `${type}:${move.destX},${move.destY}`;
    if (key === lastPreviewKey) return;
    lastPreviewKey = key;
    previewTilesAt(move.unit, move.destX, move.destY, type);
    redrawPendingMovePath();
  }
  function initMovePreviewFeature() {
    setInterval(tick, TICK_MS);
  }
  const TILE_SIZE = 16;
  const HIGHLIGHT_KEY = "t";
  const HIGHLIGHT_CLASS = "awbw-pending-highlight";
  function buildPanel(nativeBtn) {
    const btn = document.createElement("div");
    btn.id = "awbw-pending-units-btn";
    btn.className = nativeBtn.className;
    btn.style.cursor = "pointer";
    btn.style.position = "relative";
    const bg = document.createElement("div");
    bg.className = "game-tools-bg";
    bg.style.position = "relative";
    const icon = document.createElement("img");
    icon.style.position = "relative";
    icon.style.left = "-3px";
    bg.appendChild(icon);
    const hpBadge = document.createElement("img");
    hpBadge.style.position = "absolute";
    hpBadge.style.right = "11px";
    hpBadge.style.bottom = "8px";
    bg.appendChild(hpBadge);
    const arrow = document.createElement("span");
    arrow.textContent = "▼";
    arrow.style.position = "absolute";
    arrow.style.right = "1px";
    arrow.style.top = "50%";
    arrow.style.transform = "translateY(-50%)";
    arrow.style.fontSize = "9px";
    arrow.style.lineHeight = "1";
    arrow.style.color = "#fff";
    arrow.style.textShadow = "0 0 2px #000, 0 0 2px #000";
    bg.appendChild(arrow);
    const label = document.createElement("span");
    label.className = "game-tools-btn-text small_text";
    btn.appendChild(bg);
    btn.appendChild(label);
    const list = document.createElement("div");
    list.style.position = "absolute";
    list.style.top = "100%";
    list.style.left = "0";
    list.style.display = "none";
    list.style.flexDirection = "column";
    list.style.background = "#fff";
    list.style.border = "1px solid #999";
    list.style.maxHeight = "300px";
    list.style.overflowY = "auto";
    list.style.zIndex = "1000";
    list.style.whiteSpace = "nowrap";
    const refreshButton = () => {
      const units = getPendingUnits();
      nativeBtn.style.display = "none";
      if (!isViewerTurn() || units.length === 0) {
        btn.style.display = "none";
        list.style.display = "none";
        return;
      }
      btn.style.display = "flex";
      icon.src = units[0] ? unitIconUrl(units[0]) : "";
      icon.style.visibility = units[0] ? "visible" : "hidden";
      const hpUrl = units[0] ? unitHpIconUrl(units[0]) : null;
      hpBadge.src = hpUrl ?? "";
      hpBadge.style.display = hpUrl ? "block" : "none";
      label.textContent = `Unités en attente (${units.length})`;
    };
    const refresh = () => {
      refreshButton();
      const units = getPendingUnits();
      list.innerHTML = "";
      for (const unit of units) {
        const row = document.createElement("div");
        row.style.display = "flex";
        row.style.alignItems = "center";
        row.style.gap = "6px";
        row.style.padding = "4px 8px";
        row.style.cursor = "pointer";
        row.style.fontFamily = "sans-serif";
        row.style.fontSize = "12px";
        row.addEventListener("mouseenter", () => row.style.background = "#eee");
        row.addEventListener("mouseleave", () => row.style.background = "");
        const rowIconWrap = document.createElement("div");
        rowIconWrap.style.position = "relative";
        rowIconWrap.style.width = "16px";
        rowIconWrap.style.height = "16px";
        rowIconWrap.style.flex = "none";
        const rowIcon = document.createElement("img");
        rowIcon.src = unitIconUrl(unit);
        rowIcon.width = 16;
        rowIcon.height = 16;
        rowIconWrap.appendChild(rowIcon);
        const rowHpUrl = unitHpIconUrl(unit);
        if (rowHpUrl) {
          const rowHp = document.createElement("img");
          rowHp.src = rowHpUrl;
          rowHp.style.position = "absolute";
          rowHp.style.right = "-2px";
          rowHp.style.bottom = "-2px";
          rowIconWrap.appendChild(rowHp);
        }
        const rowLabel = document.createElement("span");
        rowLabel.textContent = `(${unit.units_x}, ${unit.units_y})`;
        row.appendChild(rowIconWrap);
        row.appendChild(rowLabel);
        row.addEventListener("click", () => {
          selectUnit(unit.units_id);
          list.style.display = "none";
          refresh();
        });
        list.appendChild(row);
      }
    };
    btn.addEventListener("click", () => {
      const opening = list.style.display === "none";
      if (opening) refresh();
      list.style.display = opening ? "flex" : "none";
    });
    document.addEventListener("click", (event) => {
      if (!btn.contains(event.target) && !list.contains(event.target)) {
        list.style.display = "none";
      }
    });
    refresh();
    setInterval(refreshButton, 500);
    btn.appendChild(list);
    return btn;
  }
  function clearHighlights() {
    const existing = document.querySelectorAll(`.${HIGHLIGHT_CLASS}`);
    existing.forEach((el) => el.remove());
    return existing.length > 0;
  }
  function showHighlights() {
    const gamemap = document.getElementById("gamemap");
    if (!gamemap) return;
    for (const unit of getPendingUnits()) {
      const highlight = document.createElement("div");
      highlight.className = HIGHLIGHT_CLASS;
      highlight.style.position = "absolute";
      highlight.style.left = `${unit.units_x * TILE_SIZE}px`;
      highlight.style.top = `${unit.units_y * TILE_SIZE}px`;
      highlight.style.width = `${TILE_SIZE}px`;
      highlight.style.height = `${TILE_SIZE}px`;
      highlight.style.backgroundColor = "rgba(255, 255, 0, 0.45)";
      highlight.style.boxShadow = "0 0 0 1px rgba(255, 200, 0, 0.9) inset";
      highlight.style.pointerEvents = "none";
      highlight.style.zIndex = "999";
      gamemap.appendChild(highlight);
    }
  }
  function toggleHighlights() {
    if (!clearHighlights()) {
      showHighlights();
    }
  }
  function initPendingUnitsFeature() {
    const nativeBtn = getNextUnitButton();
    const panel = buildPanel(nativeBtn);
    nativeBtn.insertAdjacentElement("beforebegin", panel);
    nativeBtn.style.display = "none";
    document.addEventListener("keydown", (event) => {
      const target = event.target;
      if (target && /^(input|textarea|select)$/i.test(target.tagName)) return;
      if (event.key.toLowerCase() === HIGHLIGHT_KEY) {
        toggleHighlights();
      }
    });
  }
  function waitForGame() {
    if (isGameReady()) {
      initPendingUnitsFeature();
      initMovePreviewFeature();
      return;
    }
    setTimeout(waitForGame, 300);
  }
  waitForGame();

})();