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:
273
web/js/ui-grid-cells.js
Normal file
273
web/js/ui-grid-cells.js
Normal file
@@ -0,0 +1,273 @@
|
||||
import {
|
||||
getNurseryBuildCost,
|
||||
getSouvenirShopBuildCost,
|
||||
getResearchBuildCost,
|
||||
getBilleterieBuildCost,
|
||||
getFoodBuildCost,
|
||||
getReceptionBuildCost,
|
||||
getBiomeChangeColorBuildCost,
|
||||
getBiomeChangeTempBuildCost,
|
||||
getSchoolUpgradeCost,
|
||||
getReceptionUpgradeCost,
|
||||
getNurseryUpgradeCost,
|
||||
getSouvenirShopUpgradeCost,
|
||||
getResearchUpgradeCost,
|
||||
getBilleterieUpgradeCost,
|
||||
getFoodUpgradeCost,
|
||||
getBiomeChangeColorUpgradeCost,
|
||||
getBiomeChangeTempUpgradeCost,
|
||||
} from "./economy.js";
|
||||
import { getAnimalVisualState } from "./animal-visual-state.js";
|
||||
import { GameConfig } from "./config.js";
|
||||
import { eggTypeLabel, animalLabel } from "./texts-fr.js";
|
||||
|
||||
const EGG_EMOJI = "🥚";
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, playSound: (s: string) => void, gridEl: HTMLElement, getHatched: () => Array<{ x: number, y: number }>, selected: { x: number, y: number }, emptyCellChoice: { x: number, y: number } | null, selectedTokenId: number | null, lastActionWasDrop: boolean, clampSelection: () => void, animalEmoji: Record<string, string> }} ctx
|
||||
* @param {HTMLElement} divEl
|
||||
* @param {import("./types.js").ReceptionCell} receptionCell
|
||||
* @param {string} cellKey
|
||||
*/
|
||||
export function fillReceptionCell(ctx, divEl, receptionCell, cellKey) {
|
||||
const { state, animalEmoji } = ctx;
|
||||
divEl.classList.add("reception");
|
||||
const level = receptionCell.level ?? 1;
|
||||
const maxLevel = GameConfig.Reception?.MaxLevel ?? 7;
|
||||
const canUpgrade = level < maxLevel && state.coins >= getReceptionUpgradeCost(level);
|
||||
if (canUpgrade) divEl.classList.add("can-upgrade");
|
||||
const recAnimal = (state.receptionAnimals ?? []).find((r) => r.receptionCellKey === cellKey);
|
||||
const nowUnix = Math.floor(Date.now() / 1000);
|
||||
if (recAnimal) {
|
||||
const isReady = nowUnix >= recAnimal.readyAt;
|
||||
const emoji = animalEmoji[recAnimal.animalId] ?? "🐾";
|
||||
const label = isReady ? "Animal prêt" : "Acclimatation…";
|
||||
divEl.classList.add("cell-draggable");
|
||||
divEl.draggable = isReady;
|
||||
const arrow = canUpgrade ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
divEl.innerHTML = `<span class="cell-emoji">${emoji}</span><span class="cell-label">${label}</span>${arrow}`;
|
||||
if (isReady) divEl.dataset.receptionCellKey = cellKey;
|
||||
} else {
|
||||
const arrow = canUpgrade ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
divEl.innerHTML = `<span class="cell-emoji">📥</span><span class="cell-label">Accueil ${level}</span>${arrow}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState, animalEmoji: Record<string, string> }} ctx
|
||||
* @param {HTMLElement} divEl
|
||||
* @param {import("./types.js").NurseryCell} nurseryCell
|
||||
* @param {string} cellKey
|
||||
*/
|
||||
export function fillNurseryCell(ctx, divEl, nurseryCell, cellKey) {
|
||||
const { state, animalEmoji } = ctx;
|
||||
divEl.classList.add("nursery");
|
||||
const nurseryLevel = nurseryCell.level ?? 1;
|
||||
const nurseryMax = GameConfig.Nursery?.MaxLevel ?? 7;
|
||||
const canUpgradeNursery = nurseryLevel < nurseryMax && state.coins >= getNurseryUpgradeCost(nurseryLevel);
|
||||
if (canUpgradeNursery) divEl.classList.add("can-upgrade");
|
||||
const pendingBaby = (state.pendingBabies ?? []).find((p) => p.nurseryCellKey === cellKey);
|
||||
const token = nurseryCell.tokenId !== null && nurseryCell.tokenId !== undefined
|
||||
? state.pendingEggTokens.find((tok) => tok.tokenId === nurseryCell.tokenId) : null;
|
||||
if (pendingBaby) {
|
||||
const nowUnix = Math.floor(Date.now() / 1000);
|
||||
const isMature = nowUnix >= pendingBaby.readyAt;
|
||||
const emoji = animalEmoji[pendingBaby.animalId] ?? "🐾";
|
||||
const label = isMature ? "Bébé prêt" : "Bébé…";
|
||||
divEl.classList.add("cell-draggable");
|
||||
divEl.draggable = isMature;
|
||||
divEl.innerHTML = `<span class="cell-emoji">${emoji}</span><span class="cell-label">${label}</span>`;
|
||||
if (isMature) divEl.dataset.nurseryCellKey = cellKey;
|
||||
} else if (token) {
|
||||
divEl.classList.add("cell-draggable");
|
||||
divEl.draggable = true;
|
||||
const label = eggTypeLabel[token.eggType] ?? token.eggType;
|
||||
divEl.innerHTML = `<span class="cell-emoji">${EGG_EMOJI}</span><span class="cell-label">${label}</span>`;
|
||||
divEl.dataset.tokenId = String(nurseryCell.tokenId);
|
||||
} else {
|
||||
const arrow = canUpgradeNursery ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
divEl.innerHTML = `<span class="cell-emoji">🐣</span><span class="cell-label">Nurserie ${nurseryLevel}</span>${arrow}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState, animalEmoji: Record<string, string> }} ctx
|
||||
* @param {HTMLElement} divEl
|
||||
* @param {import("./types.js").AnimalCell} animalCell
|
||||
* @param {string} cellKey
|
||||
*/
|
||||
export function fillAnimalCell(ctx, divEl, animalCell, cellKey) {
|
||||
const { state, animalEmoji } = ctx;
|
||||
divEl.classList.add("animal", "cell-draggable");
|
||||
divEl.draggable = true;
|
||||
const w = animalCell.cellsWide ?? 1;
|
||||
const h = animalCell.cellsHigh ?? 1;
|
||||
const isMulti = w > 1 || h > 1;
|
||||
const isOrigin = animalCell.originKey === null || animalCell.originKey === undefined || animalCell.originKey === cellKey;
|
||||
const originKey = isOrigin ? cellKey : (animalCell.originKey ?? cellKey);
|
||||
const originCell = isOrigin ? animalCell : state.grid.cells[originKey];
|
||||
if (originCell && originCell.kind === "animal") {
|
||||
const visual = getAnimalVisualState(originCell, state, state.grid, originKey);
|
||||
if (visual.cold) divEl.classList.add("animal-cold");
|
||||
if (visual.hot) divEl.classList.add("animal-hot");
|
||||
if (visual.hungry) divEl.classList.add("animal-hungry");
|
||||
if (visual.sick) divEl.classList.add("animal-sick");
|
||||
if (visual.happy) divEl.classList.add("animal-happy");
|
||||
}
|
||||
if (isMulti) divEl.classList.add("multi-cell");
|
||||
if (isMulti && isOrigin) divEl.classList.add("multi-cell-origin");
|
||||
const emoji = animalEmoji[animalCell.id] ?? "🐾";
|
||||
const label = animalLabel[animalCell.id] ?? animalCell.id;
|
||||
divEl.innerHTML = `<span class="cell-emoji">${emoji}</span><span class="cell-label">${label}</span>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState }} ctx
|
||||
* @param {HTMLElement} div
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
*/
|
||||
export function fillEmptyCell(ctx, div, x, y) {
|
||||
const { state } = ctx;
|
||||
const emptyCellChoice = ctx.emptyCellChoice.current;
|
||||
div.classList.add("empty");
|
||||
if (emptyCellChoice && emptyCellChoice.x === x && emptyCellChoice.y === y) {
|
||||
const nurseryCost = getNurseryBuildCost();
|
||||
const shopCost = getSouvenirShopBuildCost();
|
||||
const researchCost = getResearchBuildCost();
|
||||
const billeterieCost = getBilleterieBuildCost();
|
||||
const foodCost = getFoodBuildCost();
|
||||
const receptionCost = getReceptionBuildCost();
|
||||
const biomeColorCost = getBiomeChangeColorBuildCost();
|
||||
const biomeTempCost = getBiomeChangeTempBuildCost();
|
||||
const canNursery = state.coins >= nurseryCost;
|
||||
const canShop = state.coins >= shopCost;
|
||||
const canResearch = state.coins >= researchCost;
|
||||
const canBilleterie = state.coins >= billeterieCost;
|
||||
const canFood = state.coins >= foodCost;
|
||||
const canReception = state.coins >= receptionCost;
|
||||
const canBiomeColor = state.coins >= biomeColorCost;
|
||||
const canBiomeTemp = state.coins >= biomeTempCost;
|
||||
div.innerHTML = `<button type="button" class="cell-choice-btn" data-choice="nursery" ${canNursery ? "" : "disabled"}>🐣 Nurserie (${nurseryCost})</button><button type="button" class="cell-choice-btn" data-choice="shop" ${canShop ? "" : "disabled"}>🛒 Boutique (${shopCost})</button><button type="button" class="cell-choice-btn" data-choice="research" ${canResearch ? "" : "disabled"}>🔬 Recherche (${researchCost})</button><button type="button" class="cell-choice-btn" data-choice="billeterie" ${canBilleterie ? "" : "disabled"}>🎫 Billeterie (${billeterieCost})</button><button type="button" class="cell-choice-btn" data-choice="food" ${canFood ? "" : "disabled"}>🥗 Nourriture (${foodCost})</button><button type="button" class="cell-choice-btn" data-choice="reception" ${canReception ? "" : "disabled"}>📥 Accueil (${receptionCost})</button><button type="button" class="cell-choice-btn" data-choice="biomeColor" ${canBiomeColor ? "" : "disabled"}>🎨 Couleur (${biomeColorCost})</button><button type="button" class="cell-choice-btn" data-choice="biomeTemp" ${canBiomeTemp ? "" : "disabled"}>🌡️ Temp (${biomeTempCost})</button>`;
|
||||
div.classList.add("empty-choice");
|
||||
} else {
|
||||
div.textContent = "";
|
||||
}
|
||||
}
|
||||
|
||||
function fillSchoolCell(ctx, div, cell) {
|
||||
const { state } = ctx;
|
||||
div.classList.add("school");
|
||||
const schoolMaxLevel = (GameConfig.School && GameConfig.School.MaxLevel) || 8;
|
||||
const canUpgradeSchool = cell.level < schoolMaxLevel && state.coins >= getSchoolUpgradeCost(cell.level);
|
||||
if (canUpgradeSchool) div.classList.add("can-upgrade");
|
||||
const arrow = canUpgradeSchool ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
div.innerHTML = `<span class="cell-emoji">🏫</span><span class="cell-label">École ${cell.level}</span>${arrow}`;
|
||||
}
|
||||
|
||||
function fillSouvenirShopCell(ctx, div, cell) {
|
||||
const { state } = ctx;
|
||||
div.classList.add("souvenir-shop");
|
||||
const shopLevel = cell.level ?? 1;
|
||||
const shopMax = GameConfig.SouvenirShop?.MaxLevel ?? 7;
|
||||
const canUpgradeShop = shopLevel < shopMax && state.coins >= getSouvenirShopUpgradeCost(shopLevel);
|
||||
if (canUpgradeShop) div.classList.add("can-upgrade");
|
||||
const arrow = canUpgradeShop ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
div.innerHTML = `<span class="cell-emoji">🛒</span><span class="cell-label">Boutique ${shopLevel}</span>${arrow}`;
|
||||
}
|
||||
|
||||
function fillResearchCell(ctx, div, cell) {
|
||||
const { state } = ctx;
|
||||
div.classList.add("research");
|
||||
const level = cell.level ?? 1;
|
||||
const maxLevel = GameConfig.Research?.MaxLevel ?? 7;
|
||||
const canUpgrade = level < maxLevel && state.coins >= getResearchUpgradeCost(level);
|
||||
if (canUpgrade) div.classList.add("can-upgrade");
|
||||
const arrow = canUpgrade ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
div.innerHTML = `<span class="cell-emoji">🔬</span><span class="cell-label">Recherche ${level}</span>${arrow}`;
|
||||
}
|
||||
|
||||
function fillBilleterieCell(ctx, div, cell) {
|
||||
const { state } = ctx;
|
||||
div.classList.add("billeterie");
|
||||
const level = cell.level ?? 1;
|
||||
const maxLevel = GameConfig.Billeterie?.MaxLevel ?? 7;
|
||||
const canUpgrade = level < maxLevel && state.coins >= getBilleterieUpgradeCost(level);
|
||||
if (canUpgrade) div.classList.add("can-upgrade");
|
||||
const arrow = canUpgrade ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
div.innerHTML = `<span class="cell-emoji">🎫</span><span class="cell-label">Billeterie ${level}</span>${arrow}`;
|
||||
}
|
||||
|
||||
function fillFoodCell(ctx, div, cell) {
|
||||
const { state } = ctx;
|
||||
div.classList.add("food");
|
||||
const level = cell.level ?? 1;
|
||||
const maxLevel = GameConfig.Food?.MaxLevel ?? 7;
|
||||
const canUpgrade = level < maxLevel && state.coins >= getFoodUpgradeCost(level);
|
||||
if (canUpgrade) div.classList.add("can-upgrade");
|
||||
const arrow = canUpgrade ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
div.innerHTML = `<span class="cell-emoji">🥗</span><span class="cell-label">Nourriture ${level}</span>${arrow}`;
|
||||
}
|
||||
|
||||
function fillBiomeChangeColorCell(ctx, div, cell) {
|
||||
const { state } = ctx;
|
||||
div.classList.add("biome-change-color");
|
||||
const level = cell.level ?? 1;
|
||||
const maxLevel = GameConfig.BiomeChangeColor?.MaxLevel ?? 7;
|
||||
const canUpgrade = level < maxLevel && state.coins >= getBiomeChangeColorUpgradeCost(level);
|
||||
if (canUpgrade) div.classList.add("can-upgrade");
|
||||
const arrow = canUpgrade ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
div.innerHTML = `<span class="cell-emoji">🎨</span><span class="cell-label">Couleur ${level}</span>${arrow}`;
|
||||
}
|
||||
|
||||
function fillBiomeChangeTempCell(ctx, div, cell) {
|
||||
const { state } = ctx;
|
||||
div.classList.add("biome-change-temp");
|
||||
const level = cell.level ?? 1;
|
||||
const maxLevel = GameConfig.BiomeChangeTemp?.MaxLevel ?? 7;
|
||||
const canUpgrade = level < maxLevel && state.coins >= getBiomeChangeTempUpgradeCost(level);
|
||||
if (canUpgrade) div.classList.add("can-upgrade");
|
||||
const arrow = canUpgrade ? '<span class="cell-upgrade-arrow" aria-hidden="true">▲</span>' : "";
|
||||
div.innerHTML = `<span class="cell-emoji">🌡️</span><span class="cell-label">Temp ${level}</span>${arrow}`;
|
||||
}
|
||||
|
||||
function fillEggCell(ctx, div, cell) {
|
||||
div.classList.add("egg", "cell-draggable");
|
||||
div.draggable = true;
|
||||
const label = eggTypeLabel[cell.eggType] ?? cell.eggType;
|
||||
div.innerHTML = `<span class="cell-emoji">${EGG_EMOJI}</span><span class="cell-label">${label}</span>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ state: import("./types.js").GameState, setState: () => void, setError: (s: string) => void, playSound: (s: string) => void, gridEl: HTMLElement, getHatched: () => Array<{ x: number, y: number }>, selected: { x: number, y: number }, emptyCellChoice: { current: { x: number, y: number } | null }, selectedTokenId: { current: number | null }, lastActionWasDrop: { current: boolean }, clampSelection: () => void, animalEmoji: Record<string, string> }} ctx
|
||||
* @param {HTMLElement} div
|
||||
* @param {{ cell: import("./types.js").GridCell | null | undefined, key: string, x: number, y: number }} cellInfo
|
||||
*/
|
||||
export function fillCellContent(ctx, div, cellInfo) {
|
||||
const { cell, key, x, y } = cellInfo;
|
||||
if (cell === null || cell === undefined) {
|
||||
fillEmptyCell(ctx, div, x, y);
|
||||
return;
|
||||
}
|
||||
const filler = FILL_BY_KIND[cell.kind];
|
||||
if (filler) {
|
||||
filler(ctx, div, cell, key);
|
||||
return;
|
||||
}
|
||||
fillAnimalCell(ctx, div, cell, key);
|
||||
}
|
||||
|
||||
const FILL_BY_KIND = {
|
||||
school: (ctx, div, cell) => fillSchoolCell(ctx, div, cell),
|
||||
nursery: (ctx, div, cell, key) => fillNurseryCell(ctx, div, cell, key),
|
||||
souvenirShop: (ctx, div, cell) => fillSouvenirShopCell(ctx, div, cell),
|
||||
research: (ctx, div, cell) => fillResearchCell(ctx, div, cell),
|
||||
billeterie: (ctx, div, cell) => fillBilleterieCell(ctx, div, cell),
|
||||
food: (ctx, div, cell) => fillFoodCell(ctx, div, cell),
|
||||
reception: (ctx, div, cell, key) => fillReceptionCell(ctx, div, cell, key),
|
||||
biomeChangeColor: (ctx, div, cell) => fillBiomeChangeColorCell(ctx, div, cell),
|
||||
biomeChangeTemp: (ctx, div, cell) => fillBiomeChangeTempCell(ctx, div, cell),
|
||||
egg: (ctx, div, cell) => fillEggCell(ctx, div, cell),
|
||||
};
|
||||
|
||||
export { EGG_EMOJI };
|
||||
Reference in New Issue
Block a user