AWBW Helper

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

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==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();

})();