85 lines
2.1 KiB
JavaScript
85 lines
2.1 KiB
JavaScript
/**
|
||
* lab.js
|
||
* Laboratory logic: accept goods, analyse for special goods,
|
||
* trigger medication production. No rendering, no DOM.
|
||
*/
|
||
|
||
const LabState = Object.freeze({
|
||
IDLE: 'idle',
|
||
ANALYZING: 'analyzing',
|
||
});
|
||
|
||
class Lab {
|
||
constructor() {
|
||
this.reset();
|
||
}
|
||
|
||
reset() {
|
||
this.state = LabState.IDLE;
|
||
this.analyzeTimer = 0;
|
||
this.totalProcessed = 0;
|
||
this.flashTimer = 0; // brief visual flash on deposit
|
||
this._onMedReady = null;
|
||
}
|
||
|
||
/**
|
||
* Deposit an array of goods into the lab.
|
||
* @param {Good[]} goods – goods from player inventory
|
||
* @param {function} onMedicationReady – called (no args) when special analysis completes
|
||
* @returns {number} count of goods deposited
|
||
*/
|
||
depositGoods(goods, onMedicationReady) {
|
||
if (!goods.length) return 0;
|
||
|
||
let hasSpecial = false;
|
||
goods.forEach(good => {
|
||
this.totalProcessed++;
|
||
if (good.isSpecial) hasSpecial = true;
|
||
});
|
||
|
||
// Flash feedback
|
||
this.flashTimer = 500;
|
||
|
||
// Start analysis only if we got a special good and aren't already analysing
|
||
if (hasSpecial && this.state === LabState.IDLE) {
|
||
this.state = LabState.ANALYZING;
|
||
this.analyzeTimer = SETTINGS.LAB_ANALYZE_TIME;
|
||
this._onMedReady = onMedicationReady;
|
||
}
|
||
|
||
return goods.length;
|
||
}
|
||
|
||
/** True briefly after goods are deposited (visual feedback). */
|
||
isFlashing() {
|
||
return this.flashTimer > 0;
|
||
}
|
||
|
||
/** True while analysing a special good. */
|
||
isAnalyzing() {
|
||
return this.state === LabState.ANALYZING;
|
||
}
|
||
|
||
/** Progress 0–1 of the current analysis (0 if idle). */
|
||
analyzeProgress() {
|
||
if (this.state !== LabState.ANALYZING) return 0;
|
||
return 1 - this.analyzeTimer / SETTINGS.LAB_ANALYZE_TIME;
|
||
}
|
||
|
||
update(dt) {
|
||
if (this.flashTimer > 0) this.flashTimer -= dt;
|
||
|
||
if (this.state === LabState.ANALYZING) {
|
||
this.analyzeTimer -= dt;
|
||
if (this.analyzeTimer <= 0) {
|
||
this.analyzeTimer = 0;
|
||
this.state = LabState.IDLE;
|
||
if (this._onMedReady) {
|
||
this._onMedReady();
|
||
this._onMedReady = null;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|