Spaces:
Runtime error
Runtime error
feat: add Cain as silent red lobster in frontend animation
Browse files- Cain renders as 🦞 emoji (48px) instead of guest_anim sprite
- Cain wanders randomly like other guests but never shows speech bubbles
- Added SILENT_AGENTS set to suppress both API-driven and periodic bubbles
- Added Cain to REMOTE_AGENTS env var on Home Space
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
frontend/electron-standalone.html
CHANGED
|
@@ -4499,6 +4499,8 @@ function toggleBrokerPanel() {
|
|
| 4499 |
|
| 4500 |
// 父母固定点位(cats 静态猫)
|
| 4501 |
const PARENT_IDS = new Set(['adam', 'eve']);
|
|
|
|
|
|
|
| 4502 |
const PARENT_POSITIONS = {
|
| 4503 |
adam: { breakroom: { x: 511, y: 262 }, writing: { x: 190, y: 526 }, error: { x: 932, y: 275 } },
|
| 4504 |
eve: { breakroom: { x: 841, y: 621 }, writing: { x: 380, y: 683 }, error: { x: 1109, y: 327 } }
|
|
@@ -4546,22 +4548,23 @@ function toggleBrokerPanel() {
|
|
| 4546 |
} else {
|
| 4547 |
// 儿子及其他访客:使用 guest_anim 动画精灵(32×32,8 帧 idle 动画)
|
| 4548 |
const aid = String(agent.agentId || '');
|
| 4549 |
-
|
| 4550 |
if (aid.toLowerCase() === 'cain') {
|
| 4551 |
-
|
|
|
|
| 4552 |
} else {
|
| 4553 |
let hash = 0;
|
| 4554 |
for (let i = 0; i < aid.length; i++) hash = (hash * 31 + aid.charCodeAt(i)) >>> 0;
|
| 4555 |
-
animIdx = (hash % 6) + 1;
|
| 4556 |
-
|
| 4557 |
-
|
| 4558 |
-
const animIdleKey = `guest_anim_${animIdx}_idle`;
|
| 4559 |
|
| 4560 |
-
|
| 4561 |
-
|
| 4562 |
-
|
| 4563 |
-
|
| 4564 |
-
|
|
|
|
| 4565 |
}
|
| 4566 |
}
|
| 4567 |
sprite.setDepth(2600);
|
|
@@ -4609,9 +4612,9 @@ function toggleBrokerPanel() {
|
|
| 4609 |
|
| 4610 |
g.nameText.setText(agent.name || 'Guest');
|
| 4611 |
|
| 4612 |
-
// Show bubble immediately when bubbleText changes from API
|
| 4613 |
const bubbleKey = chatLang === 'zh' ? (agent.bubbleTextZh || agent.bubbleText) : agent.bubbleText;
|
| 4614 |
-
if (bubbleKey && bubbleKey !== (g._lastBubbleText || '')) {
|
| 4615 |
g._lastBubbleText = bubbleKey;
|
| 4616 |
if (guestBubbles[id]) { guestBubbles[id].destroy(); delete guestBubbles[id]; }
|
| 4617 |
const bx = g.sprite.x;
|
|
@@ -4657,7 +4660,7 @@ function toggleBrokerPanel() {
|
|
| 4657 |
function maybeShowGuestBubble(time) {
|
| 4658 |
if (time - lastGuestBubbleAt < 5200) return;
|
| 4659 |
lastGuestBubbleAt = time;
|
| 4660 |
-
const ids = Object.keys(guestSprites);
|
| 4661 |
if (ids.length === 0) return;
|
| 4662 |
const id = ids[Math.floor(Math.random() * ids.length)];
|
| 4663 |
const g = guestSprites[id];
|
|
|
|
| 4499 |
|
| 4500 |
// 父母固定点位(cats 静态猫)
|
| 4501 |
const PARENT_IDS = new Set(['adam', 'eve']);
|
| 4502 |
+
// Cain(孩子)是沉默的——不显示任何气泡
|
| 4503 |
+
const SILENT_AGENTS = new Set(['cain']);
|
| 4504 |
const PARENT_POSITIONS = {
|
| 4505 |
adam: { breakroom: { x: 511, y: 262 }, writing: { x: 190, y: 526 }, error: { x: 932, y: 275 } },
|
| 4506 |
eve: { breakroom: { x: 841, y: 621 }, writing: { x: 380, y: 683 }, error: { x: 1109, y: 327 } }
|
|
|
|
| 4548 |
} else {
|
| 4549 |
// 儿子及其他访客:使用 guest_anim 动画精灵(32×32,8 帧 idle 动画)
|
| 4550 |
const aid = String(agent.agentId || '');
|
| 4551 |
+
|
| 4552 |
if (aid.toLowerCase() === 'cain') {
|
| 4553 |
+
// Cain(孩子)= 红色龙虾 🦞,随机漫游,不说话
|
| 4554 |
+
sprite = game.add.text(p.x, p.y, '🦞', { fontFamily: 'ArkPixel, monospace', fontSize: '48px' }).setOrigin(0.5, 1);
|
| 4555 |
} else {
|
| 4556 |
let hash = 0;
|
| 4557 |
for (let i = 0; i < aid.length; i++) hash = (hash * 31 + aid.charCodeAt(i)) >>> 0;
|
| 4558 |
+
const animIdx = (hash % 6) + 1;
|
| 4559 |
+
const animKey = `guest_anim_${animIdx}`;
|
| 4560 |
+
const animIdleKey = `guest_anim_${animIdx}_idle`;
|
|
|
|
| 4561 |
|
| 4562 |
+
if (game.textures.exists(animKey) && game.anims.exists(animIdleKey)) {
|
| 4563 |
+
sprite = game.add.sprite(p.x, p.y, animKey).setOrigin(0.5, 1).setScale(4.0);
|
| 4564 |
+
sprite.anims.play(animIdleKey, true);
|
| 4565 |
+
} else {
|
| 4566 |
+
sprite = game.add.text(p.x, p.y, '🦞', { fontFamily: 'ArkPixel, monospace', fontSize: '30px' }).setOrigin(0.5, 1);
|
| 4567 |
+
}
|
| 4568 |
}
|
| 4569 |
}
|
| 4570 |
sprite.setDepth(2600);
|
|
|
|
| 4612 |
|
| 4613 |
g.nameText.setText(agent.name || 'Guest');
|
| 4614 |
|
| 4615 |
+
// Show bubble immediately when bubbleText changes from API (skip silent agents like Cain)
|
| 4616 |
const bubbleKey = chatLang === 'zh' ? (agent.bubbleTextZh || agent.bubbleText) : agent.bubbleText;
|
| 4617 |
+
if (bubbleKey && bubbleKey !== (g._lastBubbleText || '') && !SILENT_AGENTS.has(id.toLowerCase())) {
|
| 4618 |
g._lastBubbleText = bubbleKey;
|
| 4619 |
if (guestBubbles[id]) { guestBubbles[id].destroy(); delete guestBubbles[id]; }
|
| 4620 |
const bx = g.sprite.x;
|
|
|
|
| 4660 |
function maybeShowGuestBubble(time) {
|
| 4661 |
if (time - lastGuestBubbleAt < 5200) return;
|
| 4662 |
lastGuestBubbleAt = time;
|
| 4663 |
+
const ids = Object.keys(guestSprites).filter(id => !SILENT_AGENTS.has(id.toLowerCase()));
|
| 4664 |
if (ids.length === 0) return;
|
| 4665 |
const id = ids[Math.floor(Math.random() * ids.length)];
|
| 4666 |
const g = guestSprites[id];
|