feat: add common social fireplace
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
ZONES,
|
||||
colorForName,
|
||||
levelForTotalXp,
|
||||
type CampfireState,
|
||||
type DeltaMsg,
|
||||
type GameEvent,
|
||||
type SnapshotMsg,
|
||||
@@ -38,7 +39,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const currentTick = (): number => Math.floor((Date.now() - startedAt) / cfg.tickMs);
|
||||
|
||||
const db = new Db(cfg.dbPath);
|
||||
const sim = new SimWorld(cfg.channelId, db.loadViewers(cfg.channelId));
|
||||
const sim = new SimWorld(cfg.channelId, db.loadViewers(cfg.channelId), db.loadCampfire(cfg.channelId));
|
||||
const camera = new CameraController();
|
||||
|
||||
function handleCommand(cmd: ChatCommand): void {
|
||||
@@ -101,6 +102,7 @@ const world: WorldSource = {
|
||||
avatars: [...sim.avatars.values()].map((av) => sim.serializeAvatar(av)),
|
||||
nodes: sim.serializeNodes(),
|
||||
stats: sim.stats(),
|
||||
campfire: sim.campfireState(),
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -113,7 +115,8 @@ function buildDelta(events: GameEvent[], camChanged: boolean): DeltaMsg | null {
|
||||
const avatars = sim.takeDirtyAvatars();
|
||||
const nodes = sim.takeDirtyNodes();
|
||||
const stats = sim.takeStatsIfDirty();
|
||||
if (avatars.length === 0 && nodes.length === 0 && !stats && events.length === 0 && !camChanged) {
|
||||
const campfire = sim.takeCampfireStateIfDirty();
|
||||
if (avatars.length === 0 && nodes.length === 0 && !stats && !campfire && events.length === 0 && !camChanged) {
|
||||
return null;
|
||||
}
|
||||
const msg: DeltaMsg = { t: 'delta', tick: currentTick(), serverNow: Date.now() };
|
||||
@@ -121,6 +124,7 @@ function buildDelta(events: GameEvent[], camChanged: boolean): DeltaMsg | null {
|
||||
if (avatars.length > 0) msg.avatars = avatars;
|
||||
if (nodes.length > 0) msg.nodes = nodes;
|
||||
if (stats) msg.stats = stats;
|
||||
if (campfire) msg.campfire = campfire;
|
||||
if (events.length > 0) msg.events = events;
|
||||
return msg;
|
||||
}
|
||||
@@ -131,10 +135,16 @@ setInterval(() => {
|
||||
const camChanged = camera.tick(now, sim.zoneActivity());
|
||||
|
||||
for (const rec of sim.takeDirtyViewers()) db.saveViewer(cfg.channelId, rec);
|
||||
if (sim.isCampfireDirty()) {
|
||||
const cf = sim.campfireState();
|
||||
db.saveCampfire(cfg.channelId, cf.progress, sim.campfireLedgerRows());
|
||||
}
|
||||
|
||||
for (const ev of events) {
|
||||
if (ev.k === 'levelup' && cfg.chatAnnounceLevelUp) {
|
||||
announce(`⭐ ${ev.name} вырос(ла) до ${ev.level}-го уровня: ${SKILL_TITLES[ev.skill] ?? ev.skill}!`);
|
||||
} else if (ev.k === 'firelevel' && cfg.chatAnnounceLevelUp) {
|
||||
announce(`🔥 Костёр вырастает до ${ev.level}-го уровня! Общий вклад: ${sim.campfireState().progress}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +258,24 @@ function handleHttp(req: IncomingMessage, res: ServerResponse): void {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cfg.devHttp && p === '/dev/fire' && req.method === 'POST') {
|
||||
readBody(req, (body) => {
|
||||
try {
|
||||
const parsed = JSON.parse(body || '{}') as { points?: number };
|
||||
const points = Number(parsed.points);
|
||||
if (!Number.isFinite(points) || points <= 0) {
|
||||
json(res, 400, { error: 'нужен points > 0' });
|
||||
return;
|
||||
}
|
||||
sim.addCampfireProgressDev(points);
|
||||
json(res, 200, { ok: true, campfire: sim.campfireState() });
|
||||
} catch (e) {
|
||||
json(res, 400, { error: String(e) });
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (p === '/api/inventory' && req.method === 'GET') {
|
||||
const name = (url.searchParams.get('name') ?? '').trim();
|
||||
const found = name ? sim.lookupViewer(name) : undefined;
|
||||
|
||||
Reference in New Issue
Block a user