AWBW Helper

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

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

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

})();