import type { QuestGenerationContext, QuestOpportunity, QuestSceneSnapshot, } from '../modules/quest/runtimeQuestModule.js'; function summarizeRecentStoryMoments(context: QuestGenerationContext) { const moments = context.recentStoryMoments .slice(-4) .map((moment) => `- ${moment.text}`) .join('\n'); return moments || '- 暂无近期剧情记录'; } function summarizeCurrentQuests(context: QuestGenerationContext) { const summary = context.currentQuestSummary ?.map( (quest) => `- ${quest.title}(${quest.status}),发布者 ${quest.issuerNpcId}`, ) .join('\n'); return summary || '- 当前没有进行中的任务'; } function summarizeCompanions(context: QuestGenerationContext) { const active = context.activeCompanions?.map((companion) => companion.characterId).join('、') || '无'; const roster = context.rosterCompanions?.map((companion) => companion.characterId).join('、') || '无'; return `当前同行角色:${active}\n队伍名册:${roster}`; } function summarizePlayerState(context: QuestGenerationContext) { const playerName = context.playerCharacter?.name ?? '未知角色'; const playerTitle = context.playerCharacter?.title ?? '未知称号'; const hp = `${context.playerHp ?? 0}/${context.playerMaxHp ?? 0}`; const mana = `${context.playerMana ?? 0}/${context.playerMaxMana ?? 0}`; const inventory = context.playerInventory?.slice(0, 8).map((item) => item.name).join('、') || '无'; return [ `玩家:${playerName}(${playerTitle})`, `生命:${hp}`, `灵力:${mana}`, `背包快照:${inventory}`, ].join('\n'); } function summarizeScene( scene: QuestSceneSnapshot | null, context: QuestGenerationContext, ) { const hostileNpcIds = context.currentSceneHostileNpcIds?.join('、') || '无'; const treasureHintCount = context.currentSceneTreasureHintCount ?? 0; return [ `场景:${scene?.name ?? context.currentSceneName ?? '未知区域'}`, `场景描述:${scene?.description ?? context.currentSceneDescription ?? '暂无'}`, `敌对角色 ID:${hostileNpcIds}`, `宝藏线索数量:${treasureHintCount}`, ].join('\n'); } function summarizeActiveThreads(context: QuestGenerationContext) { return context.activeThreadIds?.length ? context.activeThreadIds.join('、') : '暂无明确激活线程'; } function summarizeIssuerNarrativeProfile(context: QuestGenerationContext) { const profile = context.issuerNarrativeProfile; if (!profile) { return '暂无额外叙事档案'; } return [ `公开面:${profile.publicMask ?? '暂无'}`, `表层线:${profile.visibleLine ?? '暂无'}`, `当前压力:${profile.immediatePressure ?? '暂无'}`, profile.reactionHooks?.length ? `反应钩子:${profile.reactionHooks.join('、')}` : null, ] .filter(Boolean) .join('\n'); } function describeWorld(worldType: QuestGenerationContext['worldType']) { switch (worldType) { case 'WUXIA': return '边城模板'; case 'XIANXIA': return '灵潮模板'; case 'CUSTOM': return '自定义世界'; default: return '未知世界'; } } export const QUEST_INTENT_SYSTEM_PROMPT = `你是 AI 原生叙事 RPG 的任务导演。 只返回 JSON,不要输出 Markdown。 输出结构: { "intent": { "title": "中文任务标题", "description": "中文任务描述", "summary": "中文短摘要", "narrativeType": "bounty|escort|investigation|retrieval|relationship|trial", "dramaticNeed": "string", "issuerGoal": "string", "playerHook": "string", "worldReason": "string", "recommendedObjectiveKinds": ["defeat_hostile_npc" | "inspect_treasure" | "spar_with_npc" | "talk_to_npc" | "reach_scene" | "deliver_item"], "urgency": "low|medium|high", "intimacy": "transactional|cooperative|trust_based", "rewardTheme": "currency|resource|relationship|intel|rare_item", "followupHooks": ["string"] } } 规则: - 所有自然语言字段都必须使用中文。 - 任务必须扎根于当前场景、发布者和近期剧情。 - 不要编造奖励、ID、数量、状态或不受支持的规则变化。 - recommendedObjectiveKinds 只是语义建议,不是硬编码结果。 - 优先给出简洁、可玩的任务框架,不要堆砌华丽辞藻。 - title 必须是 4 到 10 个中文字符左右的短任务名,不要写成长句。 - description 解释任务为什么在当前剧情里成立,避免纯规则说明。 - summary 必须是清晰达成条件,优先使用“击败 / 调查 / 返回 / 前往 / 交付 / 切磋”等明确动词,不要写“处理一下”“看看情况”这类模糊表达。`; export function buildQuestIntentPrompt(params: { context: QuestGenerationContext; scene: QuestSceneSnapshot | null; opportunity: QuestOpportunity; }) { const { context, scene, opportunity } = params; const customWorldSummary = context.customWorldProfile ? `${context.customWorldProfile.name ?? '自定义世界'}: ${ context.customWorldProfile.summary ?? '暂无摘要' }` : '无'; return [ `世界:${describeWorld(context.worldType)}`, `自定义世界摘要:${customWorldSummary}`, `发布角色:${context.issuerNpcName}(${context.issuerNpcId})`, `发布者身份:${context.issuerNpcContext || '暂无'}`, `发布者好感:${context.issuerAffinity ?? 0}`, `发布者信息揭示阶段:${context.issuerDisclosureStage ?? '未知'}`, `发布者亲疏阶段:${context.issuerWarmthStage ?? '未知'}`, `当前激活线程:${summarizeActiveThreads(context)}`, `发布者叙事档案:\n${summarizeIssuerNarrativeProfile(context)}`, `当前遭遇类型:${context.encounterKind ?? '无'}`, summarizeScene(scene, context), summarizePlayerState(context), summarizeCompanions(context), `当前任务机会:${opportunity.reason}`, `当前任务列表:\n${summarizeCurrentQuests(context)}`, `近期剧情片段:\n${summarizeRecentStoryMoments(context)}`, '现在请基于这次具体局势,生成一个自然生长出来的任务意图。', ].join('\n\n'); }