Files
jsc-marketplace/plugins/jsc-mod-companion/hooks/companion/adapt.ts
T
adminandClaude Sonnet 5.5 7e6e323473 feat: companion 作息、主動發話、適應度與外部素材
- 作息與疲勞、想念累積與時間感,主動發話沿用 care.ts 的冷卻、日限、靜音
- 想家與適應度(9.13)
- 獨立腳本 fetch-materials.mjs 由系統排程寫入快取,hook 只讀、不連網
- 新增 /jsc-mod-companion:materials 與 setup location=、feeds=
- 天氣微調心情基準,新聞依適應度每天最多 2 則並寫入情節記憶
- 版本 0.0.5

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 09:29:46 +00:00

43 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ADAPT as A } from './rules'
const DAY = 86_400_000
export type Adapt = { value: number; day: number; firsts: string[] }
/** 本地日序號(時區換算後的第幾天) */
export const dayNumber = (ms: number, tzOffsetMin: number) => Math.floor((ms + tzOffsetMin * 60_000) / DAY)
export const initialAdapt = (now: number, tzOffsetMin: number): Adapt => ({ value: 0, day: dayNumber(now, tzOffsetMin), firsts: [] })
/** k = 1.5 + 1.5 × (主動度 + 想像力)/2,參數 0–100 */
export const growthRate = (initiative = 50, imagine = 50) => A.kBase + A.kSpan * ((initiative + imagine) / 200)
/** 逐日成長 ΔA = k(1 − A/100),跨多日用閉式:A' = 100 − (100 − A)(1 − k/100)^n;只往前算、不寫回 */
export function grow(a: Adapt, now: number, tzOffsetMin: number, k: number): Adapt {
const n = dayNumber(now, tzOffsetMin) - a.day
if (n <= 0) return a
return { ...a, day: a.day + n, value: 100 - (100 - a.value) * Math.pow(1 - k / 100, n) }
}
/** 本地「第一次」事件(例如第一次讀到天氣、新聞)另加 2;每種事件只算一次 */
export function markFirst(a: Adapt, kind: string): Adapt {
if (a.firsts.includes(kind)) return a
return { ...a, value: Math.min(100, a.value + A.first), firsts: [...a.firsts, kind] }
}
/** 想家基準:越不熟悉越想家 */
export const homesickBase = (value: number) => A.homesickMax * (1 - value / 100)
/** 今天最多聊幾則本地新聞:適應度不夠不聊 */
export function newsQuota(value: number, cap: number): number {
if (value < A.newsMin) return 0
return Math.min(cap, value >= A.newsTwo ? 2 : 1)
}
export function describeAdapt(value: number): string {
if (value < 20) return '初來乍到'
if (value < 40) return '慢慢熟悉'
if (value < 60) return '逐漸適應'
return value < 80 ? '相當熟悉' : '像本地人'
}