Production buildings are now independent private-sector agents: they keep what their output sells for, run only to the demand they can actually sell, and spend that cash on steel and high-tech upgrades when their demand grows. Grid power is a paid private flow between plants and their consumers, and regions synthesise the food their own harvest and the reachable market cannot supply. Island regions no longer famine: a region with no reachable supplier grows its whole shortfall from energy, and grid power now feeds cities and food before the converters, so a famine never waits on a factory. Bundles the in-progress tree cleanup that was already present in the working tree.
56 lines
1.8 KiB
JavaScript
56 lines
1.8 KiB
JavaScript
// The game feed: a chat-like column of short-lived messages pinned to the
|
|
// lower-left corner of the map. Newest lines sit at the bottom and each line
|
|
// retires on its own, so the map is never permanently obstructed.
|
|
|
|
export const FEED_TTL_MS = 4500;
|
|
export const FEED_ALERT_TTL_MS = 8000;
|
|
const FEED_FADE_MS = 400;
|
|
|
|
export class GameFeed {
|
|
constructor($container, options = {}) {
|
|
this.$container = $container;
|
|
this.ttl = options.ttl !== undefined ? options.ttl : FEED_TTL_MS;
|
|
this.alertTtl = options.alertTtl !== undefined ? options.alertTtl : FEED_ALERT_TTL_MS;
|
|
this.fade = options.fade !== undefined ? options.fade : FEED_FADE_MS;
|
|
this._timers = new Set();
|
|
}
|
|
|
|
// Appends one line at the bottom of the feed. `alert` marks a message the
|
|
// player must not miss (being declared war on) and lets it linger longer.
|
|
// A negative `ttl` keeps the line until `clear` or a later retirement.
|
|
push(text, { alert = false, ttl } = {}) {
|
|
if (!this.$container || !this.$container.length) return null;
|
|
const life = ttl !== undefined ? ttl : alert ? this.alertTtl : this.ttl;
|
|
const $line = $("<div class='feed-line'></div>").text(text);
|
|
if (alert) $line.addClass("feed-alert");
|
|
this.$container.append($line);
|
|
if (life >= 0) {
|
|
const timer = setTimeout(() => {
|
|
this._timers.delete(timer);
|
|
this._retire($line);
|
|
}, life);
|
|
this._timers.add(timer);
|
|
}
|
|
return $line;
|
|
}
|
|
|
|
_retire($line) {
|
|
$line.addClass("leaving");
|
|
if (this.fade <= 0) {
|
|
$line.remove();
|
|
return;
|
|
}
|
|
const timer = setTimeout(() => {
|
|
this._timers.delete(timer);
|
|
$line.remove();
|
|
}, this.fade);
|
|
this._timers.add(timer);
|
|
}
|
|
|
|
clear() {
|
|
for (const timer of this._timers) clearTimeout(timer);
|
|
this._timers.clear();
|
|
if (this.$container) this.$container.empty();
|
|
}
|
|
}
|