merge: 合併 origin/main,情感注入改由 rules.ts 的 PAD 增減換算

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 08:00:38 +00:00
co-authored by Claude Sonnet 5.5
9 changed files with 234 additions and 41 deletions
@@ -1,4 +1,4 @@
import { clamp } from './mood'
import { clamp, MOOD_EVENTS } from './mood'
import type { MoodEvent } from './mood'
import { bar } from './seg'
import type { Pad } from './types'
@@ -94,20 +94,30 @@ export function fromPad(mood: Pad & { at: number }, baseline: Emotions, basePad:
}
}
// 情感注入:事件對各維度的增減。mood/upset/energy/shy 的合成效果與舊 PAD 事件一致
export const EMOTION_EVENTS = {
thanks: { mood: 0.075, energy: 0.025, shy: -0.05, heartbeat: 0.05 },
scold: { mood: -0.06, upset: 0.08, energy: 0.075, shy: 0.1 },
success: { mood: 0.04, energy: 0.015 },
toolFail: { mood: -0.02, upset: 0.04, energy: 0.05, shy: 0.08 },
return: { mood: 0.05, energy: 0.04, missing: -0.3, heartbeat: 0.1 },
lateNight: { mood: -0.025, energy: -0.05, homesick: 0.05 },
favorite: { mood: 0.06, energy: 0.04, heartbeat: 0.08 },
ignored: { mood: -0.025, energy: -0.015, missing: 0.1 },
} as const satisfies Record<MoodEvent, Partial<Emotions>>
// 情感注入:事件(評估標籤)對各維度的增減。mood/upset/energy/shy 由 rules.ts 的 PAD 增減換算
// (p>0 → 心情 p/2;p<0 → 心情 0.3p、不悅 −0.4p;a/2 → 精力;−d → 害羞),合成後與 PAD 增減一致;
// 心跳、想念、想家等新維度的額外效果寫在 EXTRA
const EXTRA: Partial<Record<MoodEvent, Partial<Emotions>>> = {
thanks: { heartbeat: 0.05 },
return: { missing: -0.3, heartbeat: 0.1 },
lateNight: { homesick: 0.05 },
favorite: { heartbeat: 0.08 },
ignored: { missing: 0.1 },
cared: { heartbeat: 0.05, missing: -0.1 },
remembered: { heartbeat: 0.05 },
}
export function emotionEffect(ev: MoodEvent): Partial<Emotions> {
const { p, a, d } = MOOD_EVENTS[ev]
return {
mood: p > 0 ? p / 2 : p * 0.3,
upset: p < 0 ? -p * 0.4 : 0,
energy: a / 2,
shy: -d,
...EXTRA[ev],
}
}
const POSITIVE: ReadonlySet<MoodEvent> = new Set(['thanks', 'success', 'return', 'favorite'])
const NEGATIVE: ReadonlySet<MoodEvent> = new Set(['scold', 'toolFail', 'ignored'])
// 「壞」方向:心情下降,或不悅、忌妒上升
const isBad = (d: Dim, x: number) => (d === 'mood' ? x < 0 : (d === 'upset' || d === 'jealous') && x > 0)
@@ -133,11 +143,12 @@ const habitCount = (h: Habit, ev: MoodEvent, now: number) => {
*/
export function applyEvent(cur: Emotions, habit: Habit, ev: MoodEvent, now: number): { emotions: Emotions; habit: Habit } {
const n = habitCount(habit, ev, now)
const gain = POSITIVE.has(ev) ? Math.pow(HABITUATION, n) : 1
const harm = NEGATIVE.has(ev) ? Math.min(SENSITIZATION_MAX, 1 + SENSITIZATION * n) : 1
const p = MOOD_EVENTS[ev].p
const gain = p > 0 ? Math.pow(HABITUATION, n) : 1
const harm = p < 0 ? Math.min(SENSITIZATION_MAX, 1 + SENSITIZATION * n) : 1
const irritable = cur.energy < TIRED ? IRRITABLE : 1
const out = { ...cur }
for (const [d, raw] of Object.entries(EMOTION_EVENTS[ev]) as [Dim, number][]) {
for (const [d, raw] of Object.entries(emotionEffect(ev)) as [Dim, number][]) {
const dx = raw * (isBad(d, raw) ? harm * irritable : gain)
out[d] = clampDim(out[d] + clamp(dx, -TURN_CAP, TURN_CAP))
}