tao-shen Claude Opus 4.6 commited on
Commit
14bfb6e
·
1 Parent(s): 0379408

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>

Files changed (1) hide show
  1. frontend/electron-standalone.html +17 -14
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
- let animIdx;
4550
  if (aid.toLowerCase() === 'cain') {
4551
- animIdx = 1; // Cain (first child) = red (guest_anim_1)
 
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
- const animKey = `guest_anim_${animIdx}`;
4558
- const animIdleKey = `guest_anim_${animIdx}_idle`;
4559
 
4560
- if (game.textures.exists(animKey) && game.anims.exists(animIdleKey)) {
4561
- sprite = game.add.sprite(p.x, p.y, animKey).setOrigin(0.5, 1).setScale(4.0);
4562
- sprite.anims.play(animIdleKey, true);
4563
- } else {
4564
- sprite = game.add.text(p.x, p.y, '🦞', { fontFamily: 'ArkPixel, monospace', fontSize: '30px' }).setOrigin(0.5, 1);
 
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];