Lint: fix errors and remove unused variables
**Motivations:** - Ensure lint config is not degraded and fix all lint errors for pousse workflow. **Root causes:** - Unused variables kept with _ prefix instead of removed (_row, _questReward, _i). - getAnimalBlockOrigin had 5 parameters (max 4). - use of continue statement (no-continue rule). **Correctifs:** - ESLint config verified; no eslint-disable in codebase. - Removed unused variable _row (biome-rules); removed dead function _questReward (quests); removed unused map param _i (state.js). - getAnimalBlockOrigin refactored to 4 params (pos object instead of x, y). - Replaced continue with if (cell) block in normalizeLoadedCells (state.js). - JSDoc param names aligned with _height, _y (biome-rules). **Evolutions:** - (none) **Pages affectées:** - web/js/biome-rules.js - web/js/quests.js - web/js/state.js - web/js/placement.js
This commit is contained in:
224
web/js/ui-render-dom-panels.js
Normal file
224
web/js/ui-render-dom-panels.js
Normal file
@@ -0,0 +1,224 @@
|
||||
import { tryUpgradeWorldMap, tryUpgradePlot } from "./zoo.js";
|
||||
import { tryUpgradeTruck } from "./conveyor.js";
|
||||
import { getTruckUpgradeCost } from "./economy.js";
|
||||
import { playSound } from "./audio.js";
|
||||
import { t, errorMessage, sellZoneTitle, sellZoneShortLabel } from "./texts-fr.js";
|
||||
import { GameConfig } from "./config.js";
|
||||
import { handleWorldMapTruckDrop, handleSellZoneDrop } from "./ui-render-dom-drops.js";
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} panelWorld
|
||||
* @param {{ state: import("./types.js").GameState }} setup
|
||||
* @returns {{ worldMapEl: HTMLElement, worldMapTruckEl: HTMLElement, worldMapNpcTrucksEl: HTMLElement }}
|
||||
*/
|
||||
function buildWorldMapWrap(panelWorld, setup) {
|
||||
const { state } = setup;
|
||||
const worldMapWrap = document.createElement("div");
|
||||
worldMapWrap.className = "world-map-wrap world-map-wrap-square";
|
||||
const worldMapEl = document.createElement("div");
|
||||
worldMapEl.className = "world-map world-map-biomes";
|
||||
const mapLevel = state.worldMapLevel ?? 1;
|
||||
const zoom = Math.min(0.65 + (mapLevel - 1) * 0.2, 1.45);
|
||||
worldMapEl.style.transformOrigin = "50% 50%";
|
||||
worldMapEl.style.transform = `scale(${zoom})`;
|
||||
worldMapWrap.appendChild(worldMapEl);
|
||||
const worldMapTruckEl = document.createElement("div");
|
||||
worldMapTruckEl.className = "world-map-truck";
|
||||
worldMapTruckEl.setAttribute("aria-hidden", "true");
|
||||
worldMapWrap.appendChild(worldMapTruckEl);
|
||||
const worldMapNpcTrucksEl = document.createElement("div");
|
||||
worldMapNpcTrucksEl.className = "world-map-trucks";
|
||||
worldMapNpcTrucksEl.setAttribute("aria-hidden", "true");
|
||||
worldMapWrap.appendChild(worldMapNpcTrucksEl);
|
||||
panelWorld.appendChild(worldMapWrap);
|
||||
return { worldMapEl, worldMapTruckEl, worldMapNpcTrucksEl };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void }} setup
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
function buildWorldMapUpgradeZone(setup) {
|
||||
const { state, setState, setError } = setup;
|
||||
const worldMapUpgradeZone = document.createElement("div");
|
||||
worldMapUpgradeZone.className = "world-map-upgrade-zone";
|
||||
worldMapUpgradeZone.setAttribute("aria-label", "Agrandir la carte");
|
||||
worldMapUpgradeZone.title = "Agrandir la carte";
|
||||
worldMapUpgradeZone.innerHTML = "<span class=\"world-map-upgrade-zone-icon\" aria-hidden=\"true\">🗺️</span><span class=\"world-map-upgrade-zone-label\">Agrandir carte</span><span class=\"world-map-upgrade-zone-cost\" aria-hidden=\"true\"></span><span class=\"world-map-upgrade-zone-arrow\" aria-hidden=\"true\">▲</span>";
|
||||
worldMapUpgradeZone.setAttribute("role", "button");
|
||||
worldMapUpgradeZone.setAttribute("tabindex", "0");
|
||||
worldMapUpgradeZone.addEventListener("click", () => {
|
||||
const [ok, reason] = tryUpgradeWorldMap(state);
|
||||
if (!ok) {
|
||||
setError(String(t.upgradeWorldMapFailed).replace("%s", errorMessage[reason] ?? reason));
|
||||
playSound("error");
|
||||
} else {
|
||||
setError("");
|
||||
playSound("worldMapUpgrade");
|
||||
}
|
||||
setState();
|
||||
});
|
||||
worldMapUpgradeZone.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
worldMapUpgradeZone.click();
|
||||
}
|
||||
});
|
||||
return worldMapUpgradeZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void }} setup
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
function buildWorldMapTruckDropZone(setup) {
|
||||
const worldMapTruckDropZone = document.createElement("div");
|
||||
worldMapTruckDropZone.className = "world-map-truck-drop-zone";
|
||||
worldMapTruckDropZone.setAttribute("aria-label", "Camion pour acheter un œuf");
|
||||
worldMapTruckDropZone.title = "Glissez un œuf ici pour l'acheter";
|
||||
worldMapTruckDropZone.innerHTML = "<span class=\"world-map-truck-drop-icon\" aria-hidden=\"true\">🚚</span><span class=\"world-map-truck-drop-label\">Acheter œuf</span>";
|
||||
worldMapTruckDropZone.addEventListener("dragover", (e) => {
|
||||
e.preventDefault();
|
||||
const hasOffer = e.dataTransfer.types.includes("application/x-builazoo-eggtype")
|
||||
|| e.dataTransfer.types.includes("application/x-builazoo-baby-offer")
|
||||
|| e.dataTransfer.types.includes("application/x-builazoo-animal-offer");
|
||||
e.dataTransfer.dropEffect = hasOffer ? "copy" : "none";
|
||||
if (hasOffer) worldMapTruckDropZone.classList.add("dragover");
|
||||
});
|
||||
worldMapTruckDropZone.addEventListener("dragleave", () => worldMapTruckDropZone.classList.remove("dragover"));
|
||||
worldMapTruckDropZone.addEventListener("drop", (ev) => handleWorldMapTruckDrop(ev, setup));
|
||||
return worldMapTruckDropZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void }} setup
|
||||
* @returns {{ worldMapUpgradeZone: HTMLElement, worldMapCounters: HTMLElement, worldMapTruckDropZone: HTMLElement, worldMapActions: HTMLElement }}
|
||||
*/
|
||||
function buildWorldMapActions(setup) {
|
||||
const worldMapActions = document.createElement("div");
|
||||
worldMapActions.className = "world-map-actions";
|
||||
const worldMapUpgradeZone = buildWorldMapUpgradeZone(setup);
|
||||
worldMapActions.appendChild(worldMapUpgradeZone);
|
||||
const worldMapCounters = document.createElement("div");
|
||||
worldMapCounters.className = "world-map-counters";
|
||||
worldMapCounters.setAttribute("aria-label", "Compteurs carte du monde");
|
||||
worldMapActions.appendChild(worldMapCounters);
|
||||
const worldMapTruckDropZone = buildWorldMapTruckDropZone(setup);
|
||||
worldMapActions.appendChild(worldMapTruckDropZone);
|
||||
return { worldMapUpgradeZone, worldMapCounters, worldMapTruckDropZone, worldMapActions };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} panelWorld
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, playSound: (s: string) => void }} setup
|
||||
* @returns {{ worldMapEl: HTMLElement, worldMapTruckEl: HTMLElement, worldMapNpcTrucksEl: HTMLElement, worldMapUpgradeZone: HTMLElement, worldMapCounters: HTMLElement }}
|
||||
*/
|
||||
export function buildWorldMapSection(panelWorld, setup) {
|
||||
const wrapResult = buildWorldMapWrap(panelWorld, setup);
|
||||
const actionsResult = buildWorldMapActions(setup);
|
||||
panelWorld.appendChild(actionsResult.worldMapActions);
|
||||
return { ...wrapResult, worldMapUpgradeZone: actionsResult.worldMapUpgradeZone, worldMapCounters: actionsResult.worldMapCounters };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void }} setup
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
function buildPlotUpgradeZone(setup) {
|
||||
const { state, setState, setError } = setup;
|
||||
const plotUpgradeZone = document.createElement("div");
|
||||
plotUpgradeZone.className = "plot-upgrade-zone";
|
||||
plotUpgradeZone.setAttribute("aria-label", t.upgradePlot);
|
||||
plotUpgradeZone.title = t.upgradePlot;
|
||||
plotUpgradeZone.innerHTML = "<span class=\"plot-upgrade-zone-icon\" aria-hidden=\"true\">📐</span><span class=\"plot-upgrade-zone-label\">Agrandir zoo</span><span class=\"plot-upgrade-zone-arrow\" aria-hidden=\"true\">▲</span>";
|
||||
plotUpgradeZone.setAttribute("role", "button");
|
||||
plotUpgradeZone.setAttribute("tabindex", "0");
|
||||
plotUpgradeZone.addEventListener("click", () => {
|
||||
const [ok, reason] = tryUpgradePlot(state);
|
||||
if (!ok) {
|
||||
setError(String(t.upgradePlotFailed).replace("%s", errorMessage[reason] ?? reason));
|
||||
playSound("error");
|
||||
} else {
|
||||
setError("");
|
||||
playSound("plotUpgrade");
|
||||
}
|
||||
setState();
|
||||
});
|
||||
plotUpgradeZone.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
plotUpgradeZone.click();
|
||||
}
|
||||
});
|
||||
return plotUpgradeZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} panelZoo
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, playSound: (s: string) => void, lastActionWasDropRef: { current: boolean }, sellZoneJustDroppedRef: { current: boolean } }} setup
|
||||
* @returns {{ gridEl: HTMLElement, plotUpgradeZone: HTMLElement, sellZone: HTMLElement }}
|
||||
*/
|
||||
export function buildGridSection(panelZoo, setup) {
|
||||
const gridWrap = document.createElement("div");
|
||||
gridWrap.className = "grid-wrap";
|
||||
const gridEl = document.createElement("div");
|
||||
gridEl.className = "grid";
|
||||
gridWrap.appendChild(gridEl);
|
||||
const plotUpgradeZone = buildPlotUpgradeZone(setup);
|
||||
gridWrap.appendChild(plotUpgradeZone);
|
||||
const sellZone = document.createElement("div");
|
||||
sellZone.className = "sell-zone";
|
||||
sellZone.setAttribute("aria-label", sellZoneTitle);
|
||||
sellZone.title = sellZoneTitle;
|
||||
sellZone.innerHTML = "<span class=\"sell-zone-icon\" aria-hidden=\"true\">🚚</span><span class=\"sell-zone-label\">" + sellZoneShortLabel + "</span><span class=\"sell-zone-upgrade-arrow\" aria-hidden=\"true\">▲</span>";
|
||||
attachSellZoneListeners(sellZone, setup);
|
||||
gridWrap.appendChild(sellZone);
|
||||
const visitorsLayer = document.createElement("div");
|
||||
visitorsLayer.className = "visitors-layer";
|
||||
visitorsLayer.setAttribute("aria-hidden", "true");
|
||||
gridWrap.appendChild(visitorsLayer);
|
||||
panelZoo.appendChild(gridWrap);
|
||||
return { gridEl, plotUpgradeZone, sellZone };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} sellZone
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, playSound: (s: string) => void, lastActionWasDropRef: { current: boolean }, sellZoneJustDroppedRef: { current: boolean } }} setup
|
||||
* @returns {void}
|
||||
*/
|
||||
function attachSellZoneListeners(sellZone, setup) {
|
||||
sellZone.addEventListener("dragover", (e) => {
|
||||
e.preventDefault();
|
||||
const hasCell = e.dataTransfer.types.includes("text/plain");
|
||||
e.dataTransfer.dropEffect = hasCell ? "move" : "none";
|
||||
if (hasCell) sellZone.classList.add("dragover");
|
||||
});
|
||||
sellZone.addEventListener("dragleave", () => sellZone.classList.remove("dragover"));
|
||||
sellZone.addEventListener("drop", (e) => handleSellZoneDrop(e, setup));
|
||||
sellZone.addEventListener("click", () => handleSellZoneClick(setup));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, sellZoneJustDroppedRef: { current: boolean } }} setup
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleSellZoneClick(setup) {
|
||||
if (setup.sellZoneJustDroppedRef.current) {
|
||||
setup.sellZoneJustDroppedRef.current = false;
|
||||
return;
|
||||
}
|
||||
const state = setup.state;
|
||||
const truckLevel = state.truckLevel ?? 1;
|
||||
const truckMax = (GameConfig.Truck && GameConfig.Truck.MaxLevel) || 5;
|
||||
if (truckLevel >= truckMax) return;
|
||||
if (state.coins < getTruckUpgradeCost(truckLevel)) return;
|
||||
const [ok, reason] = tryUpgradeTruck(state);
|
||||
if (!ok) {
|
||||
setup.setError(String(t.upgradeConveyorFailed).replace("%s", errorMessage[reason] ?? reason));
|
||||
playSound("error");
|
||||
} else {
|
||||
setup.setError("");
|
||||
playSound("truckUpgrade");
|
||||
}
|
||||
setup.setState();
|
||||
}
|
||||
Reference in New Issue
Block a user