Files
builazoo/web/js/world-map.js
Nicolas Cantu e031c9a1d2 Initial commit
**Motivations:**
- Initialisation du versionning git pour le projet

**Root causes:**
- N/A (Nouveau projet)

**Correctifs:**
- N/A

**Evolutions:**
- Structure initiale du projet
- Ajout du .gitignore

**Pages affectées:**
- Tous les fichiers
2026-03-03 22:24:17 +01:00

90 lines
2.9 KiB
JavaScript

import { GameConfig } from "./config.js";
import { LootTables, getColorNames } from "./loot-tables.js";
const truckMs = () => (GameConfig.WorldMap && GameConfig.WorldMap.TruckAnimationMs) || 2500;
const npcIntervalMs = () => (GameConfig.WorldMap && GameConfig.WorldMap.NpcTruckIntervalMs) || 8000;
/**
* Remove expired truck sales (player and NPC).
* @param {import("./types.js").GameState} state
* @param {number} now
*/
export function pruneTruckSales(state, now) {
const ms = truckMs();
if (state.truckSale && state.truckSale.startAt && now - state.truckSale.startAt >= ms) {
delete state.truckSale;
}
if (state.worldTruckSales && state.worldTruckSales.length > 0) {
state.worldTruckSales = state.worldTruckSales.filter(
(t) => t.startAt && now - t.startAt < ms
);
}
}
/**
* Add one NPC truck sale between two random zoos (can include player as destination).
* @param {import("./types.js").GameState} state
* @param {number} now
*/
export function addNpcTruckSale(state, now) {
const zoos = state.worldZoos ?? [];
if (zoos.length < 2) return;
const fromIdx = Math.floor(Math.random() * zoos.length);
let toIdx = Math.floor(Math.random() * zoos.length);
if (toIdx === fromIdx) toIdx = (toIdx + 1) % zoos.length;
const fromZooId = zoos[fromIdx].id;
const toZooId = zoos[toIdx].id;
if (!state.worldTruckSales) state.worldTruckSales = [];
state.worldTruckSales.push({ fromZooId, toZooId, startAt: now });
}
/**
* @param {import("./types.js").GameState} state
* @param {number} nowUnix
*/
export function tickWorldMap(state, nowUnix) {
const nowMs = nowUnix * 1000;
pruneTruckSales(state, nowMs);
}
/**
* Should we add an NPC truck this tick? Call from game loop with a lastNpcTruckAt tracker.
* @param {number} nowMs
* @param {number} lastNpcTruckAt
* @returns {boolean}
*/
export function shouldAddNpcTruck(nowMs, lastNpcTruckAt) {
return nowMs - lastNpcTruckAt >= npcIntervalMs();
}
/**
* Laboratory offer duration in seconds.
*/
const LAB_OFFER_DURATION = 45;
/**
* Chance per refresh (0-1) that the lab has a special offer.
*/
const LAB_OFFER_CHANCE = 0.25;
/**
* Refresh or expire laboratory offer. Special egg = one of Basic, Ocean, Mountain with a price modifier.
* @param {import("./types.js").GameState} state
* @param {number} nowUnix
* @param {() => number} rng
*/
export function tickLaboratory(state, nowUnix, rng = Math.random) {
const lab = state.laboratoryOffer;
if (lab && nowUnix >= lab.endAt) {
state.laboratoryOffer = null;
}
if (!lab && rng() < LAB_OFFER_CHANCE) {
const types = getColorNames();
const eggType = types[Math.floor(rng() * types.length)];
const eggDef = LootTables.EggTypes[eggType];
const base = eggDef ? eggDef.price : 50;
const price = Math.floor(base * (0.8 + rng() * 0.4));
state.laboratoryOffer = { eggType, price, endAt: nowUnix + LAB_OFFER_DURATION };
}
}