aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/companion
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/companion')
-rw-r--r--desktop/companion/Mood.js6
-rw-r--r--desktop/companion/test_mood.js14
2 files changed, 19 insertions, 1 deletions
diff --git a/desktop/companion/Mood.js b/desktop/companion/Mood.js
index 2f66873..b59c1ab 100644
--- a/desktop/companion/Mood.js
+++ b/desktop/companion/Mood.js
@@ -24,6 +24,7 @@ var T = {
typingHold: 2000,
waveHold: 3000,
singHold: 4000, // her singing reaction to the headphones connecting
+ djHold: 6000, // behind the decks when a track starts or changes
wakeHold: 1500, // the stretch after idling
lineCooldown: 30000,
monologueCooldown: 3600000,
@@ -69,6 +70,7 @@ function pick(s) {
if (s.busy) return st("think", "think");
if (s.now - s.repliedAt < T.waveHold) return st("wave", "wave");
if (s.now - s.singAt < T.singHold) return st("sing", "sing");
+ if (s.now - s.djAt < T.djHold) return st("dj", "dj");
if (s.clicks.count > 0 && s.now - s.clicks.at < T.clickHold)
return st("clicks", clickFrame(s.clicks.count));
if (s.now - s.admireAt < T.admireLook + T.admireBlush)
@@ -80,7 +82,9 @@ function pick(s) {
if (s.monologue) return st("muse", "muse");
if (s.idle >= 3) return st("lying", "lying");
if (s.idle === 2) return st("yawn", "yawn");
- if (s.idle === 1) return st("bored", "sleepy");
+ // Music turns boredom into a groove picked by Companion.qml; the
+ // deeper idle stages still win, so music does not keep her awake.
+ if (s.idle === 1) return s.music ? st("groove", s.groove || "whistle") : st("bored", "sleepy");
return st("base", "base");
}
diff --git a/desktop/companion/test_mood.js b/desktop/companion/test_mood.js
index 1331f70..3439f7c 100644
--- a/desktop/companion/test_mood.js
+++ b/desktop/companion/test_mood.js
@@ -29,6 +29,7 @@ const NOW = 10000000;
const calm = over => Object.assign({
leaving: false, now: NOW, destructAt: 0, dodging: false, shoved: false, shovedAt: 0, recording: false, busy: false,
repliedAt: 0, clicks: { count: 0, at: 0 }, mockAt: 0, typingAt: 0, wakeAt: 0, admireAt: 0, singAt: 0,
+ djAt: 0, music: false, groove: "",
monologue: false, idle: 0,
}, over);
const state = over => M.pick(calm(over)).state;
@@ -49,6 +50,7 @@ const ladder = [
["think", { busy: true }],
["wave", { repliedAt: NOW - 10 }],
["sing", { singAt: NOW - 10 }],
+ ["dj", { djAt: NOW - 10 }],
["clicks", { clicks: { count: 2, at: NOW - 10 } }],
["admire", { admireAt: NOW - 10 }],
["mock", { mockAt: NOW - 10 }],
@@ -78,9 +80,21 @@ assert.deepStrictEqual(M.pick(calm({ idle: 1 })), { state: "bored", frame: "slee
assert.deepStrictEqual(M.pick(calm({ idle: 2 })), { state: "yawn", frame: "yawn" });
assert.deepStrictEqual(M.pick(calm({ idle: 3 })), { state: "lying", frame: "lying" });
+// Music while bored: she grooves with the picked frame instead, whistling
+// when nothing was picked; yawning and lying down are unchanged.
+assert.deepStrictEqual(M.pick(calm({ idle: 1, music: true, groove: "headbang" })), { state: "groove", frame: "headbang" });
+assert.deepStrictEqual(M.pick(calm({ idle: 1, music: true })), { state: "groove", frame: "whistle" });
+assert.deepStrictEqual(M.pick(calm({ idle: 1, groove: "headbang" })), { state: "bored", frame: "sleepy" });
+assert.strictEqual(state({ idle: 2, music: true }), "yawn");
+assert.strictEqual(state({ idle: 3, music: true }), "lying");
+// Music while awake is the rest pose; the DJ is only the burst.
+assert.strictEqual(state({ music: true }), "base");
+assert.deepStrictEqual(M.pick(calm({ djAt: NOW - 10 })), { state: "dj", frame: "dj" });
+
// Holds end on time.
assert.strictEqual(state({ repliedAt: NOW - M.T.waveHold }), "base");
assert.strictEqual(state({ singAt: NOW - M.T.singHold }), "base");
+assert.strictEqual(state({ djAt: NOW - M.T.djHold }), "base");
assert.strictEqual(state({ typingAt: NOW - M.T.typingHold }), "base");
assert.strictEqual(state({ wakeAt: NOW - M.T.wakeHold }), "base");
assert.strictEqual(state({ clicks: { count: 3, at: NOW - M.T.clickHold } }), "base");