Files
builazoo/web/js/animal-visual-state.js
ncantu c7d389ecbb 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
2026-03-04 15:32:27 +01:00

102 lines
4.0 KiB
JavaScript

/**
* Visual state of an animal cell for feedback (no gauges). Used by UI to add CSS classes.
* Refs: docs/specs/animal_generique.md, temperature.md.
*/
import { LootTables } from "./loot-tables.js";
import { getDisplayTemperature } from "./biome-rules.js";
import { getCurrentSeason, getSeasonTemperatureModifier } from "./seasons.js";
import { GameConfig } from "./config.js";
/**
* @param {number} cellTemp
* @param {number} idealTemp
* @param {number} tolerance
* @returns {{ cold: boolean, hot: boolean }}
*/
function getTemperatureState(cellTemp, idealTemp, tolerance) {
return {
cold: cellTemp < idealTemp - tolerance,
hot: cellTemp > idealTemp + tolerance,
};
}
/**
* @param {{ fedAgo: number, visitAgo: number, maxFood: number, maxVisit: number, cold: boolean, hot: boolean }} opts
* @returns {{ hungry: boolean, sick: boolean, happy: boolean }}
*/
function getCareState(opts) {
const { fedAgo, visitAgo, maxFood, maxVisit, cold, hot } = opts;
const hungry = fedAgo > maxFood * 0.6;
const sick = cold || hot || hungry || visitAgo > maxVisit * 0.8;
const happy = !sick && fedAgo < maxFood * 0.3 && visitAgo < maxVisit * 0.3
&& !cold && !hot;
return { hungry, sick, happy };
}
const EMPTY_VISUAL = { cold: false, hot: false, hungry: false, sick: false, happy: false };
/**
* @param {import("./types.js").AnimalCell} cell
* @param {import("./types.js").GameState} state
* @param {{ width: number, height: number }} grid
* @param {string} originKey
* @returns {{ cellTemp: number, idealTemp: number, tolerance: number } | null}
*/
function getAnimalTempInputs(cell, state, grid, originKey) {
const def = LootTables.Animals[cell.id];
if (!def) return null;
const m = originKey.match(/^(\d+)_(\d+)$/);
if (!m) return null;
const ox = Number(m[1]);
const oy = Number(m[2]);
const baseTemp = getDisplayTemperature(ox, oy, grid);
const seasonMod = getSeasonTemperatureModifier(getCurrentSeason(state));
const cellTemp = baseTemp + seasonMod;
const idealTemp = def.idealTemperature ?? 18;
const tolerance = def.temperatureTolerance ?? 5;
return { cellTemp, idealTemp, tolerance };
}
/**
* @param {import("./types.js").AnimalCell} cell
* @returns {{ fedAgo: number, visitAgo: number, maxFood: number, maxVisit: number }}
*/
function getAnimalTimeInputs(cell) {
const nowUnix = Math.floor(Date.now() / 1000);
const lastFed = cell.lastFedAt ?? cell.placedAt ?? nowUnix;
const lastVisited = cell.lastVisitedAt ?? cell.placedAt ?? nowUnix;
const maxFood = GameConfig.Food?.MaxSecondsWithoutFood ?? 120;
const maxVisit = GameConfig.Visitor?.MaxSecondsWithoutVisit ?? 300;
return { fedAgo: nowUnix - lastFed, visitAgo: nowUnix - lastVisited, maxFood, maxVisit };
}
/**
* @param {import("./types.js").AnimalCell} cell
* @param {import("./types.js").GameState} state
* @param {{ width: number, height: number }} grid
* @param {string} originKey
* @returns {{ cellTemp: number, idealTemp: number, tolerance: number, fedAgo: number, visitAgo: number, maxFood: number, maxVisit: number } | null}
*/
function getAnimalVisualInputs(cell, state, grid, originKey) {
const temp = getAnimalTempInputs(cell, state, grid, originKey);
if (!temp) return null;
const time = getAnimalTimeInputs(cell);
return { ...temp, ...time };
}
/**
* @param {import("./types.js").AnimalCell} cell Origin animal cell.
* @param {import("./types.js").GameState} state
* @param {{ width: number, height: number }} grid
* @param {string} originKey "x_y" of origin cell.
* @returns {{ cold: boolean, hot: boolean, hungry: boolean, sick: boolean, happy: boolean }}
*/
export function getAnimalVisualState(cell, state, grid, originKey) {
const inputs = getAnimalVisualInputs(cell, state, grid, originKey);
if (!inputs) return EMPTY_VISUAL;
const { cold, hot } = getTemperatureState(inputs.cellTemp, inputs.idealTemp, inputs.tolerance);
const { hungry, sick, happy } = getCareState({ fedAgo: inputs.fedAgo, visitAgo: inputs.visitAgo, maxFood: inputs.maxFood, maxVisit: inputs.maxVisit, cold, hot });
return { cold, hot, hungry, sick, happy };
}