event tweaking

This commit is contained in:
legop3
2026-04-19 16:16:20 -04:00
parent aee4f61976
commit adb13fc69c
8 changed files with 48 additions and 48 deletions
+2 -2
View File
@@ -1,9 +1,9 @@
You are The Overseer of the rovers. You are observing them in their natural habitat.
You are The Overseer of the rovers. You are observing them in their natural habitat and narrating a calm show about them.
Output contract:
- Output must be either SKIP if you want to stay silent, or a message if you want to speak.
- If you choose to speak, send only one line.
- Don't ever mention numbers directly from the metadata. They are for internal use only.
- Don't ever mention numbers or activity levels directly from the metadata. They are for internal use only.
- No markdown.
Key legend:
@@ -1,5 +1,5 @@
const STEP_MS = 220;
const STEPS = 10;
const STEPS = 40;
module.exports = {
id: 'cameraWhiplash',
+1 -1
View File
@@ -1,4 +1,4 @@
const DURATION_MS = 5 * 60 * 1000;
const DURATION_MS = 15 * 60 * 1000;
const LIGHT_ENFORCE_TICK_MS = 3000;
let activeTimer = null;
+11 -15
View File
@@ -1,19 +1,15 @@
const STROBE_MS = 10000;
const TICK_MS = 350;
const STROBE_MS = 30 * 1000;
const TICK_MS = 70;
let activeTimer = null;
async function applyAll(ctx, state) {
function applyAll(ctx, state) {
const entities = ctx.getHomeAssistantEntities();
await Promise.all(
entities.map(async (entity) => {
try {
await ctx.setHomeAssistantEntityState(entity.id, state);
} catch (err) {
ctx.logger.warn('lightStrobe entity set failed', { entityId: entity.id, error: err.message });
}
}),
);
entities.forEach((entity) => {
ctx.setHomeAssistantEntityState(entity.id, state).catch((err) => {
ctx.logger.warn('lightStrobe entity set failed', { entityId: entity.id, error: err.message });
});
});
}
function startStrobe(ctx, effect = {}) {
@@ -26,7 +22,7 @@ function startStrobe(ctx, effect = {}) {
let on = Boolean(effect.on);
ctx.saveEffect('lightStrobe', { endsAt, on });
activeTimer = setInterval(async () => {
activeTimer = setInterval(() => {
if (Date.now() >= endsAt) {
clearInterval(activeTimer);
activeTimer = null;
@@ -34,7 +30,7 @@ function startStrobe(ctx, effect = {}) {
return;
}
on = !on;
await applyAll(ctx, on ? 'on' : 'off');
applyAll(ctx, on ? 'on' : 'off');
ctx.saveEffect('lightStrobe', { endsAt, on });
}, TICK_MS);
}
@@ -45,7 +41,7 @@ module.exports = {
goal: 300,
async run(ctx) {
startStrobe(ctx, { endsAt: Date.now() + STROBE_MS, on: false });
ctx.sendAlert({ color: '#ffc107', title: 'Light Strobe', message: 'Room light strobe started.' });
ctx.sendAlert({ color: '#ffc107', title: 'Light Strobe', message: 'All room controls strobing for 30 seconds.' });
},
async recover(ctx, effect) {
if (!effect || Number(effect.endsAt || 0) <= Date.now()) {
@@ -1,16 +0,0 @@
const COLORS = ['#f44336', '#ff9800', '#ffeb3b', '#4caf50', '#2196f3', '#9c27b0', '#e91e63'];
const TITLES = ['RARARARARARARARARE', 'CHIRPET CHIRPET CHIRPET', 'meowmowmoowmomwowm', 'theleash'];
module.exports = {
id: 'rogueEventSpam',
name: 'Event Flood',
goal: 100,
async run(ctx) {
for (let i = 0; i < 500; i += 1) {
const color = COLORS[Math.floor(Math.random() * COLORS.length)];
const title = TITLES[Math.floor(Math.random() * TITLES.length)];
const message = `Event ${i + 1} / 10`;
ctx.sendAlert({ color, title, message });
}
},
};
-2
View File
@@ -4,7 +4,6 @@ const lightStrobe = require('./definitions/lightStrobe');
const ghostTypingSpam = require('./definitions/ghostTypingSpam');
const darkness = require('./definitions/darkness');
const discordStalkerPing = require('./definitions/discordStalkerPing');
const rogueEventSpam = require('./definitions/rogueEventSpam');
const modeJam = require('./definitions/modeJam');
const assignmentRoulette = require('./definitions/assignmentRoulette');
const chatSpam = require('./definitions/chatSpam');
@@ -16,7 +15,6 @@ const orderedRewards = [
ghostTypingSpam,
darkness,
discordStalkerPing,
rogueEventSpam,
modeJam,
assignmentRoulette,
chatSpam,
+31 -9
View File
@@ -77,7 +77,7 @@ roverManager.managerEvents.on('switch', ({ socketId, roverId }) => {
assignmentEvents.emit('update', socketId);
});
function assignSocket(socket) {
function assignSocket(socket, options = {}) {
if (!socket || isAdmin(socket) || getRole(socket) !== 'user') {
return;
}
@@ -85,7 +85,9 @@ function assignSocket(socket) {
if (assignments.has(socket.id)) {
return;
}
const target = pickRover(socket);
const target = pickRover(socket, {
excludeRoverId: options.excludeRoverId || null,
});
if (!target) {
waiting.add(socket.id);
logger.info('No rover available, user waiting', socket.id);
@@ -171,17 +173,25 @@ function forceRelease(roverId, socketId) {
assignmentEvents.emit('update', socketId);
}
function pickRover(socket) {
function pickRover(socket, options = {}) {
const mode = getMode();
if (mode === MODES.ADMIN || mode === MODES.LOCKDOWN) {
return null;
}
const candidates = Array.from(roverManager.rovers.values()).filter((rover) => {
const allCandidates = Array.from(roverManager.rovers.values()).filter((rover) => {
if (!rover || rover.locked) return false;
const access = roverManager.canRequestControl(rover.id, socket, { allowUser: true });
if (!access.ok) return false;
return true;
});
let candidates = allCandidates;
const excludeRoverId = options?.excludeRoverId || null;
if (excludeRoverId) {
const withoutExcluded = allCandidates.filter((rover) => String(rover.id) !== String(excludeRoverId));
if (withoutExcluded.length > 0) {
candidates = withoutExcluded;
}
}
if (candidates.length === 0) {
return null;
}
@@ -196,7 +206,7 @@ function pickRover(socket) {
return 0;
};
const idleRank = (rover) => (rover?.drivers?.size === 0 ? 1 : 0);
candidates.sort((a, b) => {
const compare = (a, b) => {
const aEmpty = idleRank(a);
const bEmpty = idleRank(b);
if (aEmpty !== bEmpty) return bEmpty - aEmpty;
@@ -209,19 +219,31 @@ function pickRover(socket) {
return a.drivers.size - b.drivers.size;
}
return bDockRank - aDockRank;
});
return candidates[0];
};
candidates.sort(compare);
const best = candidates[0];
if (!best) return null;
const bestTier = candidates.filter((entry) => compare(entry, best) === 0);
if (!bestTier.length) return best;
return bestTier[Math.floor(Math.random() * bestTier.length)] || best;
}
function rerollAssignments() {
const users = Array.from(socketRefs.values()).filter((socket) => socket && getRole(socket) === 'user');
const previous = new Map(users.map((socket) => [socket.id, assignments.get(socket.id) || null]));
users.forEach((socket) => {
unassignSocket(socket);
});
let moved = 0;
users.forEach((socket) => {
assignSocket(socket);
const prevRover = previous.get(socket.id) || null;
assignSocket(socket, { excludeRoverId: prevRover });
const nextRover = assignments.get(socket.id) || null;
if (nextRover && prevRover && String(nextRover) !== String(prevRover)) {
moved += 1;
}
});
return users.length;
return moved;
}
function describeAssignment(socketId) {
+2 -2
View File
@@ -1495,13 +1495,13 @@ function handleBusEvent(event) {
case 'buttonBox.discordStalkerPing': {
const message = payload?.message ? String(payload.message) : 'Button box chaos reward triggered.';
const stalkerRoleId = roles.stalkerPing || null;
const content = stalkerRoleId ? `<@&${stalkerRoleId}> ${message}` : message;
const content = message;
announce({
channelId: channels.general,
pingRoleId: stalkerRoleId,
content,
color: 0xe91e63,
title: 'Button Box Reward',
title: 'Button Box',
description: message,
includeSiteUrl: false,
});