This commit is contained in:
130
src/data/affinityLevels.ts
Normal file
130
src/data/affinityLevels.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import type { RoleRelationState } from '../types';
|
||||
|
||||
export type AffinityLevelId =
|
||||
| 'hostile'
|
||||
| 'guarded'
|
||||
| 'eased'
|
||||
| 'friendly'
|
||||
| 'trusted'
|
||||
| 'close';
|
||||
|
||||
export type AffinityLevelMeta = {
|
||||
id: AffinityLevelId;
|
||||
label: string;
|
||||
minAffinity: number;
|
||||
markerAffinity: number;
|
||||
nextAffinity: number | null;
|
||||
description: string;
|
||||
accentClassName: string;
|
||||
relationStance: RoleRelationState['stance'];
|
||||
};
|
||||
|
||||
export const AFFINITY_PROGRESS_MIN = -40;
|
||||
export const AFFINITY_PROGRESS_MAX = 90;
|
||||
|
||||
export const AFFINITY_LEVELS: AffinityLevelMeta[] = [
|
||||
{
|
||||
id: 'hostile',
|
||||
label: '敌对',
|
||||
minAffinity: Number.NEGATIVE_INFINITY,
|
||||
markerAffinity: AFFINITY_PROGRESS_MIN,
|
||||
nextAffinity: 0,
|
||||
description:
|
||||
'好感落入负值区间后,会按敌对关系处理,靠近时通常直接进入对战。',
|
||||
accentClassName: 'border-rose-300/28 bg-rose-500/14 text-rose-100',
|
||||
relationStance: 'hostile',
|
||||
},
|
||||
{
|
||||
id: 'guarded',
|
||||
label: '戒备',
|
||||
minAffinity: 0,
|
||||
markerAffinity: 0,
|
||||
nextAffinity: 15,
|
||||
description: '对方仍保持明显距离,只会给出谨慎而有限的回应。',
|
||||
accentClassName: 'border-white/12 bg-white/8 text-zinc-100',
|
||||
relationStance: 'guarded',
|
||||
},
|
||||
{
|
||||
id: 'eased',
|
||||
label: '缓和',
|
||||
minAffinity: 15,
|
||||
markerAffinity: 15,
|
||||
nextAffinity: 30,
|
||||
description:
|
||||
'戒备已经开始松动,愿意正常交流,也会试探性配合你的节奏。',
|
||||
accentClassName: 'border-sky-300/20 bg-sky-500/10 text-sky-100',
|
||||
relationStance: 'neutral',
|
||||
},
|
||||
{
|
||||
id: 'friendly',
|
||||
label: '友善',
|
||||
minAffinity: 30,
|
||||
markerAffinity: 30,
|
||||
nextAffinity: 60,
|
||||
description:
|
||||
'态度明显友善了许多,愿意配合行动,也会给出更真诚的反馈。',
|
||||
accentClassName:
|
||||
'border-emerald-300/20 bg-emerald-500/10 text-emerald-100',
|
||||
relationStance: 'cooperative',
|
||||
},
|
||||
{
|
||||
id: 'trusted',
|
||||
label: '信任',
|
||||
minAffinity: 60,
|
||||
markerAffinity: 60,
|
||||
nextAffinity: 90,
|
||||
description: '双方已经建立稳定信任,对方更愿意分享想法、资源和立场。',
|
||||
accentClassName: 'border-amber-300/20 bg-amber-500/10 text-amber-100',
|
||||
relationStance: 'bonded',
|
||||
},
|
||||
{
|
||||
id: 'close',
|
||||
label: '深交',
|
||||
minAffinity: 90,
|
||||
markerAffinity: 90,
|
||||
nextAffinity: null,
|
||||
description:
|
||||
'关系已经非常亲近,对方几乎把你视作可以托付后背的自己人。',
|
||||
accentClassName: 'border-rose-300/22 bg-rose-500/12 text-rose-100',
|
||||
relationStance: 'bonded',
|
||||
},
|
||||
];
|
||||
|
||||
export const DEFAULT_AFFINITY_LEVEL = AFFINITY_LEVELS[0]!;
|
||||
|
||||
export const AFFINITY_PROGRESS_MARKERS = AFFINITY_LEVELS.map((level) => ({
|
||||
value: level.markerAffinity,
|
||||
label: level.label,
|
||||
}));
|
||||
|
||||
export const AFFINITY_BACKSTORY_CHAPTER_THRESHOLDS = [
|
||||
getAffinityLevelMetaById('eased').minAffinity,
|
||||
getAffinityLevelMetaById('friendly').minAffinity,
|
||||
getAffinityLevelMetaById('trusted').minAffinity,
|
||||
getAffinityLevelMetaById('close').minAffinity,
|
||||
] as const satisfies readonly [number, number, number, number];
|
||||
|
||||
export const DEFAULT_PRIVATE_CHAT_UNLOCK_AFFINITY =
|
||||
getAffinityLevelMetaById('trusted').minAffinity;
|
||||
|
||||
export function getAffinityLevelMetaById(levelId: AffinityLevelId) {
|
||||
const level = AFFINITY_LEVELS.find((entry) => entry.id === levelId);
|
||||
if (!level) {
|
||||
throw new Error(`Unknown affinity level id: ${levelId}`);
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
export function getAffinityLevelMeta(affinity: number) {
|
||||
return (
|
||||
[...AFFINITY_LEVELS]
|
||||
.reverse()
|
||||
.find((level) => affinity >= level.minAffinity) ?? DEFAULT_AFFINITY_LEVEL
|
||||
);
|
||||
}
|
||||
|
||||
export function resolveRelationStanceFromAffinity(
|
||||
affinity: number,
|
||||
): RoleRelationState['stance'] {
|
||||
return getAffinityLevelMeta(affinity).relationStance;
|
||||
}
|
||||
Reference in New Issue
Block a user