@oh-story/dsh 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/lib/client.js +209 -73
- package/lib/client.js.map +3 -3
- package/lib/drama/manifest.json +248 -168
- package/lib/drama/skills/short-drama/SKILL.md +16 -4
- package/lib/drama/skills/short-drama/assets/project-template/short-drama.json +3 -0
- package/lib/drama/skills/short-drama/references/creator-documents.md +3 -0
- package/lib/drama/skills/short-drama/references/knowhow-index.md +15 -0
- package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +14 -0
- package/lib/drama/skills/short-drama/scripts/project_tool.py +131 -0
- package/lib/drama/skills/short-drama-assets/SKILL.md +2 -1
- package/lib/drama/skills/short-drama-assets/references/asset-review-checklist.md +2 -0
- package/lib/drama/skills/short-drama-assets/references/character-and-look.md +10 -0
- package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +6 -9
- package/lib/drama/skills/short-drama-assets/references/era-anchors.md +37 -0
- package/lib/drama/skills/short-drama-assets/references/stage-contract.md +2 -0
- package/lib/drama/skills/short-drama-assets/references/voice-direction.md +28 -0
- package/lib/drama/skills/short-drama-develop/SKILL.md +10 -4
- package/lib/drama/skills/short-drama-develop/assets/adaptation-map.example.jsonl +1 -1
- package/lib/drama/skills/short-drama-develop/assets/creative-brief.md +8 -0
- package/lib/drama/skills/short-drama-develop/references/adaptation-craft.md +80 -13
- package/lib/drama/skills/short-drama-develop/references/episode-design.md +95 -12
- package/lib/drama/skills/short-drama-develop/references/genre-and-hook-playbook.md +9 -5
- package/lib/drama/skills/short-drama-develop/references/genre-cards//345/244/215/344/273/207/346/211/223/350/204/270.md +1 -1
- package/lib/drama/skills/short-drama-develop/references/genre-cards//347/263/273/347/273/237/346/265/201.md +51 -0
- package/lib/drama/skills/short-drama-develop/references/genre-cards//351/200/206/350/242/255.md +51 -0
- package/lib/drama/skills/short-drama-develop/references/genre-cards//351/207/215/347/224/237/347/251/277/350/266/212.md +51 -0
- package/lib/drama/skills/short-drama-develop/references/genre-cards.md +10 -7
- package/lib/drama/skills/short-drama-develop/references/premise-devices.md +15 -9
- package/lib/drama/skills/short-drama-develop/references/serial-character-and-memory.md +3 -2
- package/lib/drama/skills/short-drama-develop/references/stage-contract.md +14 -7
- package/lib/drama/skills/short-drama-develop/references/story-craft.md +7 -3
- package/lib/drama/skills/short-drama-edit/SKILL.md +65 -44
- package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +49 -13
- package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +4 -2
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Overlay.tsx +31 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +5 -5
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +68 -69
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +39 -29
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/rules.mjs +188 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +26 -13
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/Card.tsx +72 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/CornerChip.tsx +39 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/ScreenText.tsx +36 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/SystemPanel.tsx +44 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/TaskPanel.tsx +100 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/chrome.tsx +197 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/tokens.ts +62 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +1 -0
- package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +6 -4
- package/lib/drama/skills/short-drama-edit/references/cut-craft.md +26 -67
- package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +31 -56
- package/lib/drama/skills/short-drama-edit/references/generated-footage.md +42 -78
- package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +44 -92
- package/lib/drama/skills/short-drama-edit/references/stage-contract.md +14 -16
- package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1272 -125
- package/lib/drama/skills/short-drama-edit/scripts/selftest.py +113 -9
- package/lib/drama/skills/short-drama-image-prompts/SKILL.md +2 -0
- package/lib/drama/skills/short-drama-image-prompts/references/common-recipe.md +11 -0
- package/lib/drama/skills/short-drama-novel-analyze/SKILL.md +3 -3
- package/lib/drama/skills/short-drama-novel-analyze/assets/episode-candidate.example.jsonl +2 -2
- package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-triage.md +8 -4
- package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-value.md +10 -3
- package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +25 -1
- package/lib/drama/skills/short-drama-novel-analyze/references/stage-contract.md +1 -0
- package/lib/drama/skills/short-drama-produce/SKILL.md +5 -1
- package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +14 -20
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +8 -26
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-speech.md +41 -0
- package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +142 -1
- package/lib/drama/skills/short-drama-review/SKILL.md +4 -5
- package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +6 -19
- package/lib/drama/skills/short-drama-review/references/review-method.md +6 -1
- package/lib/drama/skills/short-drama-review/references/rubric-assets-prompts.md +11 -0
- package/lib/drama/skills/short-drama-review/references/rubric-story-script.md +77 -3
- package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +24 -35
- package/lib/drama/skills/short-drama-review/references/stage-contract.md +3 -0
- package/lib/drama/skills/short-drama-storyboard/SKILL.md +23 -11
- package/lib/drama/skills/short-drama-storyboard/references/blocking-playbooks.md +1 -1
- package/lib/drama/skills/short-drama-storyboard/references/lighting-craft.md +39 -0
- package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +2 -2
- package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +139 -34
- package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +5 -3
- package/lib/drama/skills/short-drama-video-prompts/SKILL.md +15 -12
- package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +29 -0
- package/lib/drama/skills/short-drama-video-prompts/references/delivery-profile.md +4 -5
- package/lib/drama/skills/short-drama-video-prompts/references/generability.md +4 -2
- package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +52 -39
- package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +24 -21
- package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +9 -23
- package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +14 -26
- package/lib/drama/skills/short-drama-video-prompts/references/review-and-fixtures.md +1 -1
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +2 -3
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +34 -9
- package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +3 -2
- package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +8 -1
- package/lib/drama/skills/short-drama-video-prompts/references/wan-3.0.md +103 -0
- package/lib/drama/skills/short-drama-video-prompts/scripts/motion_timing_check.py +8 -7
- package/lib/drama/skills/short-drama-write/SKILL.md +10 -7
- package/lib/drama/skills/short-drama-write/references/dialogue-craft.md +1 -1
- package/lib/drama/skills/short-drama-write/references/script-craft.md +56 -3
- package/lib/drama/skills/short-drama-write/references/stage-contract.md +4 -0
- package/lib/drama/skills/short-drama-write/scripts/duration_estimate.py +48 -2
- package/lib/index.js +346 -98
- package/lib/index.js.map +4 -4
- package/lib/novel-to-game/README.md +299 -59
- package/lib/novel-to-game/README_ZH.md +299 -56
- package/lib/novel-to-game/VERSION +1 -1
- package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +3 -1
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +11 -3
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +397 -8
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +0 -31
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +71 -73
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +78 -89
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +37 -14
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +5 -5
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +2 -1
- package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +11 -16
- package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +11 -11
- package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +23 -0
- package/lib/novel-to-game/manifest.json +77 -87
- package/lib/novel-to-game/skills/game-art-direction/SKILL.md +7 -12
- package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +27 -106
- package/lib/novel-to-game/skills/game-build/SKILL.md +13 -14
- package/lib/novel-to-game/skills/game-build/references/blender-asset-workflow.md +24 -0
- package/lib/novel-to-game/skills/game-build/references/build-brief-contract.md +45 -82
- package/lib/novel-to-game/skills/game-build/references/generative-media-pipeline.md +14 -45
- package/lib/novel-to-game/skills/game-build/references/playable-model-contract.md +30 -65
- package/lib/novel-to-game/skills/game-build/references/tts-production-contract.md +13 -27
- package/lib/novel-to-game/skills/game-concept/SKILL.md +13 -15
- package/lib/novel-to-game/skills/game-concept/references/concept-method.md +28 -75
- package/lib/novel-to-game/skills/game-qa/SKILL.md +6 -7
- package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +9 -5
- package/lib/novel-to-game/skills/game-world-design/SKILL.md +12 -16
- package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +23 -72
- package/lib/novel-to-game/skills/game-world-design/references/numeric-design-method.md +14 -48
- package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +36 -103
- package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +4 -10
- package/lib/novel-to-game/skills/novel-game-analyze/references/gameability-protocol.md +4 -4
- package/lib/novel-to-game/skills/novel-to-game/SKILL.md +9 -21
- package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +5 -4
- package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +5 -8
- package/lib/oh-story/manifest.json +607 -327
- package/lib/oh-story/roles/chapter-extractor.md +177 -237
- package/lib/oh-story/roles/character-designer.md +1 -2
- package/lib/oh-story/roles/consistency-checker.md +15 -13
- package/lib/oh-story/roles/narrative-writer.md +36 -38
- package/lib/oh-story/roles/story-architect.md +9 -61
- package/lib/oh-story/roles/story-explorer.md +20 -125
- package/lib/oh-story/roles/story-researcher.md +0 -1
- package/lib/oh-story/skills/story/SKILL.md +15 -9
- package/lib/oh-story/skills/story/VERSION +1 -1
- package/lib/oh-story/skills/story/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story/references/author-memory.md +46 -94
- package/lib/oh-story/skills/story/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-cover/SKILL.md +10 -1
- package/lib/oh-story/skills/story-deslop/SKILL.md +59 -73
- package/lib/oh-story/skills/story-deslop/references/agent-calls.md +5 -0
- package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +12 -11
- package/lib/oh-story/skills/story-deslop/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story-deslop/references/author-memory.md +46 -94
- package/lib/oh-story/skills/story-deslop/references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +22 -5
- package/lib/oh-story/skills/story-deslop/references/style-resolution.md +4 -4
- package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +155 -8
- package/lib/oh-story/skills/story-import/SKILL.md +64 -584
- package/lib/oh-story/skills/story-import/references/character-state-reverse.md +1 -1
- package/lib/oh-story/skills/story-import/references/deep-analysis.md +47 -0
- package/lib/oh-story/skills/story-import/references/format-and-structure.md +1 -1
- package/lib/oh-story/skills/story-import/references/import-report.md +64 -0
- package/lib/oh-story/skills/story-import/references/import-special-cases.md +34 -0
- package/lib/oh-story/skills/story-import/references/import-tracking.md +95 -0
- package/lib/oh-story/skills/story-import/references/length-routing.md +1 -1
- package/lib/oh-story/skills/story-import/references/outline-reverse-rules.md +79 -0
- package/lib/oh-story/skills/story-import/references/outline-reverse.md +24 -0
- package/lib/oh-story/skills/story-import/references/state-tracking.md +4 -69
- package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +98 -92
- package/lib/oh-story/skills/story-import/references/structure-mapping-short.md +24 -12
- package/lib/oh-story/skills/story-import/references/tracking-initialization.md +1 -1
- package/lib/oh-story/skills/story-import/references/tracking-transaction.md +15 -11
- package/lib/oh-story/skills/story-import/scripts/build_outline_brief.py +332 -0
- package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +132 -27
- package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +478 -15
- package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +182 -23
- package/lib/oh-story/skills/story-long-analyze/SKILL.md +81 -270
- package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +252 -0
- package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +3 -3
- package/lib/oh-story/skills/story-long-analyze/references/final-checks.md +19 -0
- package/lib/oh-story/skills/story-long-analyze/references/index-rebuild.md +11 -0
- package/lib/oh-story/skills/story-long-analyze/references/inspiration-library.md +105 -0
- package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +138 -64
- package/lib/oh-story/skills/story-long-analyze/references/semantic-acceptance-fixtures.md +84 -0
- package/lib/oh-story/skills/story-long-analyze/references/stage1-golden-chapters.md +128 -0
- package/lib/oh-story/skills/story-long-analyze/references/stage2-extraction.md +229 -0
- package/lib/oh-story/skills/story-long-analyze/references/stage3-plot-rhythm.md +480 -0
- package/lib/oh-story/skills/story-long-analyze/references/stage4-characters-settings.md +195 -0
- package/lib/oh-story/skills/story-long-analyze/references/stage5-report.md +33 -0
- package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +55 -128
- package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +6 -6
- package/lib/oh-story/skills/story-long-analyze/references/synthesis-inputs.md +39 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/build_chapter_index.py +466 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/inspect_existing_assets.py +702 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/inspiration_index.py +864 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +1145 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/render_relation_chart.py +425 -0
- package/lib/oh-story/skills/story-long-scan/SKILL.md +45 -194
- package/lib/oh-story/skills/story-long-scan/references/platform-ciweimao.md +19 -0
- package/lib/oh-story/skills/story-long-scan/references/platform-fanqie.md +45 -0
- package/lib/oh-story/skills/story-long-scan/references/platform-jjwxc.md +28 -0
- package/lib/oh-story/skills/story-long-scan/references/platform-qidian.md +35 -0
- package/lib/oh-story/skills/story-long-scan/references/platform-qimao.md +27 -0
- package/lib/oh-story/skills/story-long-scan/references/topic-decision.md +6 -2
- package/lib/oh-story/skills/story-long-write/SKILL.md +49 -81
- package/lib/oh-story/skills/story-long-write/references/agent-calls.md +47 -0
- package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +12 -11
- package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +24 -202
- package/lib/oh-story/skills/story-long-write/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story-long-write/references/author-memory.md +46 -94
- package/lib/oh-story/skills/story-long-write/references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +7 -11
- package/lib/oh-story/skills/story-long-write/references/character-relations.md +49 -1
- package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +26 -0
- package/lib/oh-story/skills/story-long-write/references/deslop-gates.md +171 -0
- package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +4 -0
- package/lib/oh-story/skills/story-long-write/references/emotion-on-page.md +116 -0
- package/lib/oh-story/skills/story-long-write/references/emotional-arc-design.md +1 -114
- package/lib/oh-story/skills/story-long-write/references/emotional-methods.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/genre-prose-cards.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +7 -15
- package/lib/oh-story/skills/story-long-write/references/long-format.md +0 -8
- package/lib/oh-story/skills/story-long-write/references/long-genre-catalog.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/long-genre-mechanics.md +3 -3
- package/lib/oh-story/skills/story-long-write/references/opening-design.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/outline-conflict.md +4 -4
- package/lib/oh-story/skills/story-long-write/references/outline-methods.md +7 -7
- package/lib/oh-story/skills/story-long-write/references/outline-rhythm.md +3 -3
- package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +14 -69
- package/lib/oh-story/skills/story-long-write/references/plot-frameworks.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/plot-special-topics.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/project-files.md +19 -13
- package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +13 -5
- package/lib/oh-story/skills/story-long-write/references/reference-index.md +5 -6
- package/lib/oh-story/skills/story-long-write/references/stop-and-fix.md +9 -0
- package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -58
- package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/style-resolution.md +4 -4
- package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +15 -11
- package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +81 -121
- package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +41 -139
- package/lib/oh-story/skills/story-long-write/references/workflow-outline.md +157 -0
- package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +57 -67
- package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +112 -253
- package/lib/oh-story/skills/story-long-write/references/workflow-volume.md +142 -0
- package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +6 -4
- package/lib/oh-story/skills/story-long-write/references/writing-craft.md +19 -65
- package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-long-write/scripts/build_architect_brief.py +260 -0
- package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +226 -25
- package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +155 -8
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +132 -27
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +7 -2
- package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +7 -4
- package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +304 -46
- package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +478 -15
- package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +182 -23
- package/lib/oh-story/skills/story-review/SKILL.md +31 -302
- package/lib/oh-story/skills/story-review/references/agent-prompts.md +184 -0
- package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +12 -11
- package/lib/oh-story/skills/story-review/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story-review/references/author-memory.md +46 -94
- package/lib/oh-story/skills/story-review/references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-review/references/batch-review.md +19 -0
- package/lib/oh-story/skills/story-review/references/character-relations.md +49 -1
- package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +4 -0
- package/lib/oh-story/skills/story-review/references/review-quality.md +6 -11
- package/lib/oh-story/skills/story-review/references/review-tracking.md +10 -0
- package/lib/oh-story/skills/story-review/references/solo.md +52 -0
- package/lib/oh-story/skills/story-review/references/style-resolution.md +4 -4
- package/lib/oh-story/skills/story-review/references/tracking-initialization.md +1 -1
- package/lib/oh-story/skills/story-review/references/tracking-transaction.md +15 -11
- package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +155 -8
- package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +478 -15
- package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +182 -23
- package/lib/oh-story/skills/story-setup/SKILL.md +71 -452
- package/lib/oh-story/skills/story-setup/references/agent-references/agent-quality.md +4 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +12 -11
- package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/benchmark-style-load.md +107 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/character-relations.md +49 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +22 -5
- package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +4 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/emotion-on-page.md +116 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/emotional-arc-design.md +1 -114
- package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/genre-prose-cards.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/long-emotional-methods.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-catalog.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-mechanics.md +3 -3
- package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +7 -5
- package/lib/oh-story/skills/story-setup/references/agent-references/opening-design.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/outline-conflict.md +4 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/outline-methods.md +7 -7
- package/lib/oh-story/skills/story-setup/references/agent-references/outline-rhythm.md +3 -3
- package/lib/oh-story/skills/story-setup/references/agent-references/short-emotional-methods.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +0 -15
- package/lib/oh-story/skills/story-setup/references/agent-references/short-reversal.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -58
- package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +4 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +19 -65
- package/lib/oh-story/skills/story-setup/references/diagnostics.md +4 -4
- package/lib/oh-story/skills/story-short-analyze/SKILL.md +56 -110
- package/lib/oh-story/skills/story-short-analyze/references/analysis-character-relations.md +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/analysis-method.md +42 -0
- package/lib/oh-story/skills/story-short-analyze/references/optional-modules.md +97 -0
- package/lib/oh-story/skills/story-short-analyze/references/output-contract.md +9 -47
- package/lib/oh-story/skills/story-short-analyze/references/quality-checklist.md +80 -0
- package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +4 -4
- package/lib/oh-story/skills/story-short-analyze/references/stage2-3-structure-emotion.md +308 -0
- package/lib/oh-story/skills/story-short-analyze/references/stage4-6-reversal-summary.md +611 -0
- package/lib/oh-story/skills/story-short-scan/SKILL.md +35 -65
- package/lib/oh-story/skills/story-short-scan/references/manual-rank-input.md +36 -0
- package/lib/oh-story/skills/story-short-scan/references/platform-dianzhong.md +24 -0
- package/lib/oh-story/skills/story-short-scan/references/platform-heiyan.md +21 -0
- package/lib/oh-story/skills/story-short-scan/references/topic-match.md +38 -0
- package/lib/oh-story/skills/story-short-write/SKILL.md +23 -175
- package/lib/oh-story/skills/story-short-write/references/agent-calls.md +13 -0
- package/lib/oh-story/skills/story-short-write/references/author-memory-maintenance.md +75 -0
- package/lib/oh-story/skills/story-short-write/references/author-memory.md +46 -94
- package/lib/oh-story/skills/story-short-write/references/banned-words.md +2 -2
- package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +1 -21
- package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +4 -0
- package/lib/oh-story/skills/story-short-write/references/emotional-methods.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +0 -15
- package/lib/oh-story/skills/story-short-write/references/output-contract.md +9 -47
- package/lib/oh-story/skills/story-short-write/references/reference-index.md +17 -47
- package/lib/oh-story/skills/story-short-write/references/scene-craft.md +40 -0
- package/lib/oh-story/skills/story-short-write/references/short-craft.md +7 -43
- package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -1
- package/lib/oh-story/skills/story-short-write/references/short-reversal.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/style-resolution.md +4 -4
- package/lib/oh-story/skills/story-short-write/references/submission-craft.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/villain-and-reveal.md +5 -10
- package/lib/oh-story/skills/story-short-write/references/workflow-design.md +21 -13
- package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +116 -0
- package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +99 -0
- package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +7 -119
- package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +155 -8
- package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +7 -2
- package/lib/types/client/drama-production-view.d.ts.map +1 -1
- package/lib/types/client/file-activity.d.ts +19 -1
- package/lib/types/client/file-activity.d.ts.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/production-prompts.d.ts +7 -0
- package/lib/types/client/production-prompts.d.ts.map +1 -1
- package/lib/types/client/production-runtime.d.ts +16 -0
- package/lib/types/client/production-runtime.d.ts.map +1 -1
- package/lib/types/client/video-studio.d.ts.map +1 -1
- package/lib/types/drama-adapters.d.ts +5 -3
- package/lib/types/drama-adapters.d.ts.map +1 -1
- package/lib/types/native-hooks.d.ts +53 -1
- package/lib/types/native-hooks.d.ts.map +1 -1
- package/lib/types/role-identity.d.ts +17 -0
- package/lib/types/role-identity.d.ts.map +1 -0
- package/lib/types/role-tool.d.ts.map +1 -1
- package/lib/types/skill-provider.d.ts.map +1 -1
- package/lib/types/video-project.d.ts.map +1 -1
- package/lib/types/workspace-route.d.ts.map +1 -1
- package/lib/video-recap/CHANGELOG.md +60 -1
- package/lib/video-recap/README.en.md +348 -137
- package/lib/video-recap/README.md +340 -136
- package/lib/video-recap/manifest.json +406 -251
- package/lib/video-recap/skills/video-assemble/SKILL.md +30 -15
- package/lib/video-recap/skills/video-assemble/references/audio-modes.md +63 -0
- package/lib/video-recap/skills/video-assemble/references/explicit-audio-mix.md +75 -0
- package/lib/video-recap/skills/video-assemble/references/foreground-compose.md +118 -0
- package/lib/video-recap/skills/video-assemble/references/narration-adoption.md +103 -0
- package/lib/video-recap/skills/video-assemble/references/packaging.md +45 -0
- package/lib/video-recap/skills/video-assemble/references/pair-media.md +74 -0
- package/lib/video-recap/skills/video-assemble/references/source-score.md +147 -0
- package/lib/video-recap/skills/video-assemble/references/subtitle-track.md +202 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/__init__.py +1 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/audio_mix_binding.py +279 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/frozen_audio.py +187 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/narration_binding.py +323 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_inputs.py +109 -0
- package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_publish.py +130 -0
- package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +10 -46
- package/lib/video-recap/skills/video-assemble/scripts/assemble.py +378 -119
- package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +29 -12
- package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +95 -44
- package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +75 -32
- package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +11 -11
- package/lib/video-recap/skills/video-assemble/scripts/compose_foreground.py +293 -0
- package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +71 -78
- package/lib/video-recap/skills/video-assemble/scripts/jianying/__init__.py +1 -0
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_builders.py → jianying/builders.py} +39 -67
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_model.py → jianying/model.py} +3 -11
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_optional.py → jianying/optional.py} +1 -1
- package/lib/video-recap/skills/video-assemble/scripts/jianying/schema.py +53 -0
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_templates.py → jianying/templates.py} +1 -1
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_timeline_contract.py → jianying/timeline_contract.py} +34 -13
- package/lib/video-recap/skills/video-assemble/scripts/{jianying_writer.py → jianying/writer.py} +7 -17
- package/lib/video-recap/skills/video-assemble/scripts/lib.py +37 -4
- package/lib/video-recap/skills/video-assemble/scripts/media.py +12 -21
- package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +64 -34
- package/lib/video-recap/skills/video-assemble/scripts/packaging.py +122 -0
- package/lib/video-recap/skills/video-assemble/scripts/pair_media.py +216 -0
- package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +1 -3
- package/lib/video-recap/skills/video-assemble/scripts/source_score.py +469 -0
- package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +25 -9
- package/lib/video-recap/skills/video-assemble/scripts/subtitles/__init__.py +1 -0
- package/lib/video-recap/skills/video-assemble/scripts/{subtitle_core.py → subtitles/core.py} +13 -6
- package/lib/video-recap/skills/video-assemble/scripts/{subtitle_render.py → subtitles/render.py} +5 -4
- package/lib/video-recap/skills/video-assemble/scripts/subtitles/track.py +324 -0
- package/lib/video-recap/skills/video-assemble/scripts/subtitles/track_binding.py +200 -0
- package/lib/video-recap/skills/video-assemble/scripts/timeline.py +30 -46
- package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +91 -7
- package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +22 -8
- package/lib/video-recap/skills/video-cut/SKILL.md +34 -16
- package/lib/video-recap/skills/video-cut/references/shot-review.md +50 -0
- package/lib/video-recap/skills/video-cut/scripts/cut.py +2 -28
- package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +58 -62
- package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +21 -106
- package/lib/video-recap/skills/video-cut/scripts/cut_render.py +14 -9
- package/lib/video-recap/skills/video-cut/scripts/lib.py +39 -0
- package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +2 -155
- package/lib/video-recap/skills/video-cut/scripts/narrative_selection.py +244 -0
- package/lib/video-recap/skills/video-cut/scripts/shot_review.py +357 -0
- package/lib/video-recap/skills/video-recap/SKILL.md +86 -42
- package/lib/video-recap/skills/video-recap/references/audio-routing.md +126 -0
- package/lib/video-recap/skills/video-recap/references/config-playbook.md +12 -8
- package/lib/video-recap/skills/video-recap/references/data-schema.md +44 -33
- package/lib/video-recap/skills/video-recap/references/resource-library.md +151 -0
- package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +1 -1
- package/lib/video-recap/skills/video-recap/scripts/doctor.py +123 -30
- package/lib/video-recap/skills/video-recap/scripts/final_qc.py +22 -75
- package/lib/video-recap/skills/video-recap/scripts/lib.py +3 -3
- package/lib/video-recap/skills/video-recap/scripts/library.py +509 -0
- package/lib/video-recap/skills/video-recap/scripts/materials.py +63 -91
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +8 -70
- package/lib/video-recap/skills/video-recap/scripts/project_binding.py +286 -0
- package/lib/video-recap/skills/video-recap/scripts/qc/__init__.py +1 -0
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_client.py → qc/mimo_client.py} +1 -1
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_evidence.py → qc/mimo_evidence.py} +33 -66
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_observations.py → qc/mimo_observations.py} +3 -11
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_payload.py → qc/mimo_payload.py} +4 -7
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_report.py → qc/mimo_report.py} +17 -28
- package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_runner.py → qc/mimo_runner.py} +2 -2
- package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +0 -19
- package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +119 -50
- package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +32 -114
- package/lib/video-recap/skills/video-recap/scripts/recap_review.py +9 -23
- package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +387 -334
- package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +23 -23
- package/lib/video-recap/skills/video-recap/scripts/recap_source.py +278 -0
- package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +25 -12
- package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +59 -52
- package/lib/video-recap/skills/video-recap/scripts/resource_lock.py +162 -0
- package/lib/video-recap/skills/video-script/SKILL.md +16 -13
- package/lib/video-recap/skills/video-script/references/creative-editing-playbook.md +9 -5
- package/lib/video-recap/skills/video-script/references/promotional-copy.md +68 -0
- package/lib/video-recap/skills/video-script/references/research-guide.md +1 -1
- package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +24 -76
- package/lib/video-recap/skills/video-script/scripts/lib.py +10 -87
- package/lib/video-recap/skills/video-script/scripts/narration_lint.py +63 -39
- package/lib/video-recap/skills/video-script/scripts/review.py +0 -2
- package/lib/video-recap/skills/video-script/scripts/review_grounding.py +35 -59
- package/lib/video-recap/skills/video-script/scripts/review_response.py +66 -128
- package/lib/video-recap/skills/video-script/scripts/review_runner.py +12 -20
- package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +4 -4
- package/lib/video-recap/skills/video-script/scripts/validate.py +53 -42
- package/lib/video-recap/skills/video-understanding/SKILL.md +6 -4
- package/lib/video-recap/skills/video-understanding/references/data-schema.md +50 -156
- package/lib/video-recap/skills/video-understanding/references/research-guide.md +4 -4
- package/lib/video-recap/skills/video-understanding/scripts/asr.py +85 -65
- package/lib/video-recap/skills/video-understanding/scripts/asr_timing_evidence.py +270 -0
- package/lib/video-recap/skills/video-understanding/scripts/brief.py +2 -5
- package/lib/video-recap/skills/video-understanding/scripts/briefing/__init__.py +1 -0
- package/lib/video-recap/skills/{video-script/scripts/agent_brief.py → video-understanding/scripts/briefing/builder.py} +38 -35
- package/lib/video-recap/skills/video-understanding/scripts/{brief_context.py → briefing/context.py} +4 -35
- package/lib/video-recap/skills/{video-script/scripts/brief_inputs.py → video-understanding/scripts/briefing/inputs.py} +9 -31
- package/lib/video-recap/skills/{video-script/scripts/brief_timeline.py → video-understanding/scripts/briefing/timeline.py} +5 -6
- package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +65 -116
- package/lib/video-recap/skills/video-understanding/scripts/detect.py +31 -40
- package/lib/video-recap/skills/video-understanding/scripts/lib.py +30 -86
- package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +63 -39
- package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +4 -4
- package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +17 -79
- package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +14 -40
- package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +64 -46
- package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +31 -11
- package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +19 -14
- package/lib/video-recap/skills/video-understanding/scripts/vlm.py +80 -108
- package/lib/video-recap/skills/video-voiceover/SKILL.md +29 -19
- package/lib/video-recap/skills/video-voiceover/references/index-tts.md +31 -0
- package/lib/video-recap/skills/video-voiceover/scripts/approved_text_policy.py +123 -0
- package/lib/video-recap/skills/video-voiceover/scripts/dub.py +51 -59
- package/lib/video-recap/skills/video-voiceover/scripts/lib.py +8 -44
- package/lib/video-recap/skills/video-voiceover/scripts/providers/__init__.py +1 -0
- package/lib/video-recap/skills/video-voiceover/scripts/providers/index_tts.py +184 -0
- package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +212 -134
- package/package.json +45 -45
- package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +0 -58
- package/lib/novel-to-game/skills/game-world-design/references/game-writing-craft.md +0 -53
- package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -38
- package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +0 -530
- package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +0 -559
- package/lib/oh-story/skills/story-long-scan/references/scan-output-format.md +0 -207
- package/lib/oh-story/skills/story-long-write/references/state-tracking.md +0 -108
- package/lib/oh-story/skills/story-short-analyze/references/material-decomposition.md +0 -678
- package/lib/oh-story/skills/story-short-analyze/references/output-templates.md +0 -561
- package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +0 -98
- package/lib/video-recap/skills/video-recap/references/creative-editing-playbook.md +0 -225
- package/lib/video-recap/skills/video-recap/references/research-guide.md +0 -74
- package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +0 -250
- package/lib/video-recap/skills/video-script/scripts/brief_context.py +0 -348
- package/lib/video-recap/skills/video-script/scripts/narration.py +0 -12
- package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +0 -399
- package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +0 -290
- package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +0 -327
- /package/lib/video-recap/skills/video-assemble/scripts/{jianying_tracks.py → jianying/tracks.py} +0 -0
- /package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_contract.py → qc/mimo_contract.py} +0 -0
- /package/lib/video-recap/skills/video-voiceover/scripts/{fish_audio.py → providers/fish_audio.py} +0 -0
|
@@ -181,9 +181,9 @@ const HEROINE_BOUNDARY_FLAGS = Object.freeze({
|
|
|
181
181
|
// 顺序重演「越界/修复」,才能同时支持修复后重开与后来再次越界重新关门。
|
|
182
182
|
function routeBoundaryBreachActive(state, heroineId) {
|
|
183
183
|
const contract = HEROINE_BOUNDARY_FLAGS[heroineId];
|
|
184
|
-
if (!contract || !state
|
|
184
|
+
if (!contract || !state.flags[contract.broken]) return false;
|
|
185
185
|
let active = null;
|
|
186
|
-
for (const entry of state.history
|
|
186
|
+
for (const entry of state.history) {
|
|
187
187
|
if (entry.type !== 'visit_choice' || entry.heroine !== heroineId) continue;
|
|
188
188
|
const flags = routeChoiceById(heroineId, entry.choice)?.effects?.flags ?? [];
|
|
189
189
|
if (flags.includes(contract.broken)) active = true;
|
|
@@ -246,7 +246,7 @@ function costLockedText(choice) {
|
|
|
246
246
|
|
|
247
247
|
// 安抚实价:妒过四十两起步价之后,每多一点妒加一两。
|
|
248
248
|
export function appeaseCost(state, heroineId) {
|
|
249
|
-
return APPEASE_BASE + Math.max(0,
|
|
249
|
+
return APPEASE_BASE + Math.max(0, state.relations[heroineId].du - APPEASE_DU_FLOOR);
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
const makeRel = () => ({ qing: 8, yu: 6, du: 0, ignored: 0, reasons: [] });
|
|
@@ -263,7 +263,7 @@ export function bondKey(left, right) {
|
|
|
263
263
|
|
|
264
264
|
export function bondValue(state, left, right) {
|
|
265
265
|
const key = bondKey(left, right);
|
|
266
|
-
return key ? state.bonds
|
|
266
|
+
return key ? state.bonds[key] : 0;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
export function bondTier(value) {
|
|
@@ -277,7 +277,7 @@ export function bondTier(value) {
|
|
|
277
277
|
export function bondStatus(state) {
|
|
278
278
|
return PAIR_IDS.map((id) => {
|
|
279
279
|
const [left, right] = id.split('|');
|
|
280
|
-
const value = state.bonds
|
|
280
|
+
const value = state.bonds[id];
|
|
281
281
|
return { id, left, right, value, tier: bondTier(value) };
|
|
282
282
|
});
|
|
283
283
|
}
|
|
@@ -335,8 +335,8 @@ function routeChoiceLane(heroineId, choiceId) {
|
|
|
335
335
|
}
|
|
336
336
|
|
|
337
337
|
function dominantRouteLane(stance) {
|
|
338
|
-
if (
|
|
339
|
-
if (
|
|
338
|
+
if (stance.covenant > stance.private) return 'covenant';
|
|
339
|
+
if (stance.private > stance.covenant) return 'private';
|
|
340
340
|
return null;
|
|
341
341
|
}
|
|
342
342
|
|
|
@@ -367,11 +367,11 @@ function routeBondChanges(heroineId, lane) {
|
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
export function routeStance(state, heroineId) {
|
|
370
|
-
const row = state.routeStances
|
|
370
|
+
const row = state.routeStances[heroineId];
|
|
371
371
|
return {
|
|
372
372
|
covenant: row.covenant,
|
|
373
373
|
private: row.private,
|
|
374
|
-
tone: row.covenant === row.private ? '
|
|
374
|
+
tone: row.covenant === row.private ? '人前人后的话都记着' : row.covenant > row.private ? '更记得你当众做过的事' : '更记得门内只对她说的话',
|
|
375
375
|
};
|
|
376
376
|
}
|
|
377
377
|
|
|
@@ -381,7 +381,7 @@ const ROUTE_BRANCH_MEMORY = Object.freeze({
|
|
|
381
381
|
private: '她记得你总把最难看的账先带进她门内;这一次会追问信任是否又让她独自遮丑。',
|
|
382
382
|
}),
|
|
383
383
|
pan_jinlian: Object.freeze({
|
|
384
|
-
covenant: '
|
|
384
|
+
covenant: '她已经让别人也能拿原话来问。这一次,她要看你自己被问时会不会改口。',
|
|
385
385
|
private: '她记得那些只在角门内成立的偏话;这一次会逼你分清亲近、撒谎与可停止的追问。',
|
|
386
386
|
}),
|
|
387
387
|
li_pinger: Object.freeze({
|
|
@@ -400,7 +400,7 @@ const ROUTE_BRANCH_MEMORY = Object.freeze({
|
|
|
400
400
|
|
|
401
401
|
export function routeBranchContext(state, heroineId) {
|
|
402
402
|
const stepIndex = routeStep(state, heroineId);
|
|
403
|
-
const stance = state.routeStances
|
|
403
|
+
const stance = state.routeStances[heroineId];
|
|
404
404
|
const lane = dominantRouteLane(stance);
|
|
405
405
|
if (!lane || !ROUTE_BRANCHES[heroineId]?.[stepIndex]?.[lane]) return null;
|
|
406
406
|
const lead = lane === 'covenant' ? stance.covenant : stance.private;
|
|
@@ -419,7 +419,7 @@ export function routeBranchContext(state, heroineId) {
|
|
|
419
419
|
function changeBond(state, left, right, delta) {
|
|
420
420
|
const key = bondKey(left, right);
|
|
421
421
|
if (!key || !delta) return;
|
|
422
|
-
state.bonds[key] = clamp(
|
|
422
|
+
state.bonds[key] = clamp(state.bonds[key] + delta, -100, 100);
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
function dayNetworkChanges(day, actionId, actor) {
|
|
@@ -559,8 +559,8 @@ export function dayPressureRule(state, day = state.day) {
|
|
|
559
559
|
export function dayFavorSolution(state, day = state.day) {
|
|
560
560
|
const row = DAY_FAVOR_SOLUTIONS[day - 1];
|
|
561
561
|
if (!row) return null;
|
|
562
|
-
const stance = state.routeStances
|
|
563
|
-
const qing = state.relations
|
|
562
|
+
const stance = state.routeStances[row.heroine];
|
|
563
|
+
const qing = state.relations[row.heroine].qing;
|
|
564
564
|
const bond = bondValue(state, row.heroine, row.observer);
|
|
565
565
|
const accord = heroineAccordReady(state, row.heroine);
|
|
566
566
|
const leverageReady = accord
|
|
@@ -613,11 +613,11 @@ function resolvePressure(state, actionId, joint = false, planned = null) {
|
|
|
613
613
|
: { house: 4, exposure: -8 };
|
|
614
614
|
const momentum = pressureMomentum(state);
|
|
615
615
|
if (momentum.resolved >= 2) {
|
|
616
|
-
reward.house
|
|
616
|
+
reward.house += 2;
|
|
617
617
|
reward.power = 1;
|
|
618
618
|
}
|
|
619
619
|
if (momentum.missed >= 2) {
|
|
620
|
-
reward.house
|
|
620
|
+
reward.house += 6;
|
|
621
621
|
reward.strain = -4;
|
|
622
622
|
}
|
|
623
623
|
changeResources(state, reward);
|
|
@@ -1042,7 +1042,7 @@ function addFlag(state, id) {
|
|
|
1042
1042
|
state.flags[id] = true;
|
|
1043
1043
|
const heroine = OVERRIDE_FLAG_TO_HEROINE[id];
|
|
1044
1044
|
if (heroine) {
|
|
1045
|
-
state.publicOverrides[heroine]
|
|
1045
|
+
state.publicOverrides[heroine] += 1;
|
|
1046
1046
|
evaluateBreak(state, heroine);
|
|
1047
1047
|
}
|
|
1048
1048
|
}
|
|
@@ -1068,9 +1068,9 @@ export function evaluateHouseBreak(state) {
|
|
|
1068
1068
|
record(state, 'route_break', { heroine: null, cause: 'house', house: state.resources.house });
|
|
1069
1069
|
}
|
|
1070
1070
|
|
|
1071
|
-
//
|
|
1071
|
+
// 路线是否在冷却中。
|
|
1072
1072
|
export function routeCooling(state, heroineId) {
|
|
1073
|
-
return
|
|
1073
|
+
return state.routeReopensOn[heroineId] > state.day;
|
|
1074
1074
|
}
|
|
1075
1075
|
|
|
1076
1076
|
function changeRel(state, heroineId, delta = {}, reason = '') {
|
|
@@ -1093,7 +1093,7 @@ function setIgnored(state, heroineId, value) {
|
|
|
1093
1093
|
}
|
|
1094
1094
|
|
|
1095
1095
|
function changeHousehold(state, effect, reason = '') {
|
|
1096
|
-
if (!effect?.id || !state.household
|
|
1096
|
+
if (!effect?.id || !state.household[effect.id]) return;
|
|
1097
1097
|
const row = state.household[effect.id];
|
|
1098
1098
|
row.regard = clamp(row.regard + (effect.regard ?? 0), -100, 100);
|
|
1099
1099
|
if (reason && effect.regard) {
|
|
@@ -1104,7 +1104,7 @@ function changeHousehold(state, effect, reason = '') {
|
|
|
1104
1104
|
|
|
1105
1105
|
function changeResources(state, effects = {}) {
|
|
1106
1106
|
applyResourceDelta(state.resources, effects);
|
|
1107
|
-
if (effects.house
|
|
1107
|
+
if (effects.house) evaluateHouseBreak(state);
|
|
1108
1108
|
}
|
|
1109
1109
|
|
|
1110
1110
|
function applyResourceDelta(r, effects = {}) {
|
|
@@ -1999,7 +1999,7 @@ function fivePriceSupport(basis, heroine) {
|
|
|
1999
1999
|
const candidates = HEROINE_IDS
|
|
2000
2000
|
.filter((id) => id !== heroine)
|
|
2001
2001
|
.map((id) => {
|
|
2002
|
-
const trust = basis.bonds[bondKey(heroine, id)]
|
|
2002
|
+
const trust = basis.bonds[bondKey(heroine, id)];
|
|
2003
2003
|
const witnessed = basis.history.some((entry) => (
|
|
2004
2004
|
entry.type === 'pair_interlude'
|
|
2005
2005
|
&& entry.pair?.includes(heroine)
|
|
@@ -2013,7 +2013,7 @@ function fivePriceSupport(basis, heroine) {
|
|
|
2013
2013
|
const strongest = candidates[0] ?? null;
|
|
2014
2014
|
const supported = !!strongest;
|
|
2015
2015
|
const ally = strongest?.heroine ?? null;
|
|
2016
|
-
return { supported, ally, trust: ally ? basis.bonds[bondKey(heroine, ally)]
|
|
2016
|
+
return { supported, ally, trust: ally ? basis.bonds[bondKey(heroine, ally)] : null };
|
|
2017
2017
|
}
|
|
2018
2018
|
|
|
2019
2019
|
function fivePriceBreakSource(basis, breakIndex, heroine) {
|
|
@@ -2050,7 +2050,7 @@ function fivePriceBreakStatus(basis, heroine) {
|
|
|
2050
2050
|
for (let index = 0; index < basis.history.length; index += 1) {
|
|
2051
2051
|
const entry = basis.history[index];
|
|
2052
2052
|
if (entry.type !== 'route_break' || (entry.heroine !== heroine && entry.heroine !== null)) continue;
|
|
2053
|
-
if (entry.heroine === heroine &&
|
|
2053
|
+
if (entry.heroine === heroine && basis.overrides[heroine] < BREAK_OVERRIDE_LIMIT) continue;
|
|
2054
2054
|
breakIndex = index;
|
|
2055
2055
|
}
|
|
2056
2056
|
if (breakIndex < 0) return { entry:null, index:-1, source:null, repair:null, unresolved:false };
|
|
@@ -2112,7 +2112,7 @@ function fivePriceReplyReasons(heroine, { accord, stance, support, arrangement,
|
|
|
2112
2112
|
function expectedFivePriceReply(state, heroine) {
|
|
2113
2113
|
const basis = fivePriceBasis(state);
|
|
2114
2114
|
const accord = basis.accords.has(FIVE_PRICE_ACCORD[heroine]);
|
|
2115
|
-
const stance = basis.stances[heroine]
|
|
2115
|
+
const stance = basis.stances[heroine];
|
|
2116
2116
|
const support = fivePriceSupport(basis, heroine);
|
|
2117
2117
|
const broken = fivePriceUnresolvedBreak(basis, heroine);
|
|
2118
2118
|
const arrangement = latestIntimacyArrangement({ history:basis.history }, heroine);
|
|
@@ -2247,10 +2247,10 @@ export function currentFivePrivatePrices(state) {
|
|
|
2247
2247
|
|| JSON.stringify(pending.coalition) !== JSON.stringify(fivePriceCoalition(pending.protocol, pending.right, pending.replies))) return null;
|
|
2248
2248
|
const names = pending.coalition.members.map((id) => HEROINES[id].short).join('、');
|
|
2249
2249
|
const result = pending.coalition.kind === 'full'
|
|
2250
|
-
? { title:'
|
|
2250
|
+
? { title:'五封信说得不一样,却能对上同一件事', body:'月娘没有把五封信誊成一句。她只把日期、纸脚和各人亲手经过的那一段排在一起;明日若要拿出去,仍要一封一封问主人。' }
|
|
2251
2251
|
: pending.coalition.kind === 'limited'
|
|
2252
|
-
? { title
|
|
2253
|
-
: { title:'
|
|
2252
|
+
? { title:`${names}肯互借一页,其余的信仍各自收好`, body:`${names}只答应明日在彼此看过的那几页上落名。其余人没有被说成不肯帮忙,也没有人替她们把信抽走。` }
|
|
2253
|
+
: { title:'五封信都回到了主人手里', body:'月娘没有强行把信订成一册。明日的外账仍要面对,但今夜没有谁愿意把自己的名字、原话和钥匙一并交给别人。' };
|
|
2254
2254
|
const jiaoerEcho = fivePriceJiaoerEcho(state, 'resolution');
|
|
2255
2255
|
const dayPreparation = fivePriceDayPreparation(state, 'resolution');
|
|
2256
2256
|
return {
|
|
@@ -2324,7 +2324,7 @@ export function advanceFivePrivatePrices(state) {
|
|
|
2324
2324
|
export function jointActionOptions(state) {
|
|
2325
2325
|
const completed = completedJointActions(state);
|
|
2326
2326
|
return JOINT_ACTIONS.map((choice) => {
|
|
2327
|
-
const missing = choice.requires.filter((key) => !state.accords
|
|
2327
|
+
const missing = choice.requires.filter((key) => !state.accords[key]);
|
|
2328
2328
|
const used = completed.has(choice.id);
|
|
2329
2329
|
const unaffordable = cannotAfford(state, choice);
|
|
2330
2330
|
const pairTrust = choice.participants?.length === 2 ? bondValue(state, choice.participants[0], choice.participants[1]) : 0;
|
|
@@ -2418,10 +2418,10 @@ function portablePrecedentBasis(history) {
|
|
|
2418
2418
|
function portablePrecedentReplyFromBasis(basis, event, joint, heroine) {
|
|
2419
2419
|
const pair = basis.history.find((entry) => entry.type === 'pair_interlude'
|
|
2420
2420
|
&& entry.pair?.includes(joint.participants[0]) && entry.pair?.includes(joint.participants[1])) ?? null;
|
|
2421
|
-
const stance = basis.stances[heroine]
|
|
2421
|
+
const stance = basis.stances[heroine];
|
|
2422
2422
|
const lane = stance.covenant === stance.private ? 'tie' : stance.covenant > stance.private ? 'covenant' : 'private';
|
|
2423
2423
|
const broken = fivePriceUnresolvedBreak(basis, heroine);
|
|
2424
|
-
const trust = basis.bonds[bondKey(joint.participants[0], joint.participants[1])]
|
|
2424
|
+
const trust = basis.bonds[bondKey(joint.participants[0], joint.participants[1])];
|
|
2425
2425
|
const accordKey = Object.values(ACCORD_META).find((row) => row.heroine === heroine)?.key ?? null;
|
|
2426
2426
|
const accord = accordKey ? basis.accords.has(accordKey) : false;
|
|
2427
2427
|
let outcome = 'narrow';
|
|
@@ -4309,10 +4309,10 @@ export function publicEvidenceOptions(state) {
|
|
|
4309
4309
|
...item,
|
|
4310
4310
|
strength,
|
|
4311
4311
|
meta: strength === 2
|
|
4312
|
-
? (item.id === 'cross_words' ? '
|
|
4312
|
+
? (item.id === 'cross_words' ? '正好收住前两样 · 改口有物可对' : '接得上 · 下一样还能往下查')
|
|
4313
4313
|
: strength === 1
|
|
4314
|
-
? (item.id === 'grain_measure' ? '
|
|
4315
|
-
: '
|
|
4314
|
+
? (item.id === 'grain_measure' ? '米斗来迟了 · 短米仍真,前面的空处却补不回' : '能添一笔 · 还不能回答前面的反问')
|
|
4315
|
+
: '前后接不上 · 堂下会当场追问',
|
|
4316
4316
|
};
|
|
4317
4317
|
});
|
|
4318
4318
|
}
|
|
@@ -4327,24 +4327,24 @@ export function choosePublicEvidence(state, evidenceId) {
|
|
|
4327
4327
|
return {
|
|
4328
4328
|
ok:true,
|
|
4329
4329
|
text:evidence.resistance,
|
|
4330
|
-
announcement:`第${state.publicEvidence.selected.length}
|
|
4330
|
+
announcement:`第${state.publicEvidence.selected.length}样,${evidence.label}已经摆上堂。${evidence.resistance}`,
|
|
4331
4331
|
};
|
|
4332
4332
|
}
|
|
4333
4333
|
const evaluation = publicEvidenceEvaluationForState(state, state.publicEvidence.selected);
|
|
4334
|
-
if (!evaluation) return { ok:false, error:'
|
|
4334
|
+
if (!evaluation) return { ok:false, error:'这三样还没有按能查下去的次序摆好。' };
|
|
4335
4335
|
state.publicEvidence.result = evaluation.id;
|
|
4336
4336
|
state.log.push(evaluation.outcome.body);
|
|
4337
4337
|
return {
|
|
4338
4338
|
ok:true,
|
|
4339
4339
|
text:evaluation.outcome.body,
|
|
4340
|
-
announcement
|
|
4340
|
+
announcement:`第三样,${evidence.label}已经摆上堂。结果:${evaluation.outcome.label}——${evaluation.outcome.title}。${evaluation.outcome.body}`,
|
|
4341
4341
|
};
|
|
4342
4342
|
}
|
|
4343
4343
|
|
|
4344
4344
|
export function completePublicEvidence(state) {
|
|
4345
4345
|
const current = currentPublicEvidence(state);
|
|
4346
|
-
if (!current?.resolved || !current.result) return { ok:false, error:'
|
|
4347
|
-
applyEffects(state, current.result.effects, null,
|
|
4346
|
+
if (!current?.resolved || !current.result) return { ok:false, error:'先把三样东西依次递完,再决定由谁在收案文书上落款。' };
|
|
4347
|
+
applyEffects(state, current.result.effects, null, `堂前对账:${current.result.label}`);
|
|
4348
4348
|
record(state, 'public_evidence_chain', {
|
|
4349
4349
|
event:PUBLIC_EVIDENCE_CHAIN.id,
|
|
4350
4350
|
chain:[...current.selected],
|
|
@@ -4511,7 +4511,7 @@ function publicEvidenceFutureEcho(state) {
|
|
|
4511
4511
|
if (evidence.id === 'rebuttable') return `第十五日的案卷既有承接空白,也保留韩道国先于证物被押的时辰。复案必须同时补证并区分押前、押后口供;主签不能把一段新证据扩成对旧预断的追认。${coda}`;
|
|
4512
4512
|
return `第十五日三份证物没有接成链,韩道国又先被押成共同答案。堂外已经把这场公审讲成五院围住一个伙计逼供;今日若不同时清证物次序与错误归罪,缺口会继续被一名替罪者吞掉。${coda}`;
|
|
4513
4513
|
}
|
|
4514
|
-
if (evidence.id === 'complete') return
|
|
4514
|
+
if (evidence.id === 'complete') return `第十五日三样东西仍可重新摆一遍:先称雪娥的米,中间以账页或门簿追经手,最后才拿改口来对。韩道国、玳安与应伯爵可以各问其中一段,却不能再用一句圆话把短米、中间那只手和最后的改口一并抹掉。${coda}`;
|
|
4515
4515
|
if (evidence.id === 'rebuttable') return `第十五日的案卷仍有一处承接空白。韩道国正要求重验,应伯爵也把“待复核”讲成五院自相矛盾;今日结外账时,必须决定由谁补证而不是再靠主签压过去。${coda}`;
|
|
4516
4516
|
return `第十五日三份真证没有接成一条链。玳安未认空白门路,韩道国与应伯爵已经把公审改讲成围人逼供;今日若仍只清银不清经手,这个版本会比原件传得更远。${coda}`;
|
|
4517
4517
|
}
|
|
@@ -4989,11 +4989,11 @@ export function resolveFinalReckoningAftermath(state, choiceId) {
|
|
|
4989
4989
|
}
|
|
4990
4990
|
|
|
4991
4991
|
export function accordStatus(state) {
|
|
4992
|
-
return Object.values(ACCORD_META).map((row) => ({ ...row, complete:
|
|
4992
|
+
return Object.values(ACCORD_META).map((row) => ({ ...row, complete: state.accords[row.key] }));
|
|
4993
4993
|
}
|
|
4994
4994
|
|
|
4995
4995
|
export function coalitionProofStatus(state) {
|
|
4996
|
-
return Object.values(COALITION_PROOF_META).map((row) => ({ ...row, complete: !!state.flags
|
|
4996
|
+
return Object.values(COALITION_PROOF_META).map((row) => ({ ...row, complete: !!state.flags[row.flag] }));
|
|
4997
4997
|
}
|
|
4998
4998
|
|
|
4999
4999
|
export function publicPromisesReady(state) {
|
|
@@ -5033,11 +5033,11 @@ function personalFinaleDepartureBasis(history) {
|
|
|
5033
5033
|
}
|
|
5034
5034
|
|
|
5035
5035
|
function personalFinaleDepartureOutcome(basis, heroine, procedure) {
|
|
5036
|
-
const stance = basis.stances[heroine]
|
|
5036
|
+
const stance = basis.stances[heroine];
|
|
5037
5037
|
const lane = stance.covenant === stance.private ? 'tie' : stance.covenant > stance.private ? 'covenant' : 'private';
|
|
5038
5038
|
const accord = basis.accords.has(FIVE_PRICE_ACCORD[heroine]);
|
|
5039
5039
|
const visits = basis.history.filter((entry) => entry.type === 'visit_choice' && entry.heroine === heroine).length;
|
|
5040
|
-
const arrangements = basis.arrangements[heroine]
|
|
5040
|
+
const arrangements = basis.arrangements[heroine];
|
|
5041
5041
|
const close = visits >= 6 || arrangements.length > 0;
|
|
5042
5042
|
const broken = fivePriceUnresolvedBreak(basis, heroine);
|
|
5043
5043
|
const match = procedure?.lane === lane && lane !== 'tie';
|
|
@@ -5253,24 +5253,24 @@ export function personalFinaleRouteReason(history, heroineId, procedure) {
|
|
|
5253
5253
|
});
|
|
5254
5254
|
const covenantRows = rows.filter((row) => row.lane === 'covenant');
|
|
5255
5255
|
const privateRows = rows.filter((row) => row.lane === 'private');
|
|
5256
|
-
let historyText = '
|
|
5256
|
+
let historyText = '你们之前没有做成一件足以回答今日的事。她不会因为气氛到了,就替空白点头。';
|
|
5257
5257
|
if (covenantRows.length > privateRows.length) {
|
|
5258
5258
|
const latest = covenantRows.at(-1);
|
|
5259
|
-
historyText =
|
|
5259
|
+
historyText = `你更常把她的话带到人前。最近一次是第${latest.day}日的“${latest.label}”:${latest.text}她今日记得的是这件真事,不是你们累计了多少次。`;
|
|
5260
5260
|
} else if (privateRows.length > covenantRows.length) {
|
|
5261
5261
|
const latest = privateRows.at(-1);
|
|
5262
|
-
historyText =
|
|
5262
|
+
historyText = `你更常把她的话留在门内。最近一次是第${latest.day}日的“${latest.label}”:${latest.text}她今日要从这件真事往下谈,不让一句“我们亲近”替代回答。`;
|
|
5263
5263
|
} else if (rows.length) {
|
|
5264
5264
|
const covenant = covenantRows.at(-1);
|
|
5265
5265
|
const privateChoice = privateRows.at(-1);
|
|
5266
|
-
historyText =
|
|
5266
|
+
historyText = `你们既有人前做过的事,也有只在门内说过的话。最近的两件是第${covenant.day}日“${covenant.label}”:${covenant.text}以及第${privateChoice.day}日“${privateChoice.label}”:${privateChoice.text}她不打算为了今夜好看,就把其中一件当成没发生。`;
|
|
5267
5267
|
}
|
|
5268
|
-
return `${historyText}
|
|
5268
|
+
return `${historyText}现在摆在她面前的是“${procedure?.label ?? '还没说清的安排'}”:${procedure?.summary ?? ''}它会直接动到${procedure?.focus ?? '她自己手里的东西'}。`;
|
|
5269
5269
|
}
|
|
5270
5270
|
|
|
5271
5271
|
export function personalFinaleSelectedProcedureReason(procedure, heroineId) {
|
|
5272
5272
|
if (!procedure?.id || !HEROINE_IDS.includes(heroineId) || !PERSONAL_FINALE_DEPARTURES[procedure.id]) return '';
|
|
5273
|
-
return
|
|
5273
|
+
return `你和${HEROINES[heroineId].short}最后说定的是“${procedure.label}”:${procedure.summary}这件事只动到${procedure.focus}。她能答应自己怎样做,也能当面不答应;另外四个人仍要一个个开口,她不替任何人点头。`;
|
|
5274
5274
|
}
|
|
5275
5275
|
|
|
5276
5276
|
export function personalFinaleSelectedReasons(history, heroineId, beatIndex, selectedChoice) {
|
|
@@ -5301,7 +5301,7 @@ export function personalFinaleSelectedReasons(history, heroineId, beatIndex, sel
|
|
|
5301
5301
|
}
|
|
5302
5302
|
|
|
5303
5303
|
function personalFinaleDepartureReasons(basis, heroine, procedure, outcome) {
|
|
5304
|
-
const arrangements = basis.arrangements[heroine]
|
|
5304
|
+
const arrangements = basis.arrangements[heroine];
|
|
5305
5305
|
const relationText = arrangements.length
|
|
5306
5306
|
? personalFinaleIntimacyReason(basis.history, heroine, procedure)
|
|
5307
5307
|
: personalFinaleRelationshipReason(basis.history, heroine);
|
|
@@ -5632,7 +5632,7 @@ function sharedNightAccordEntry(state, heroineId) {
|
|
|
5632
5632
|
const accordRow = [...state.history].reverse().find((entry) => entry.type === 'accord_term' && entry.heroine === heroineId && entry.choice === accord?.id) ?? null;
|
|
5633
5633
|
const proof = COALITION_PROOF_META[heroineId];
|
|
5634
5634
|
const day20 = allianceDay20Protection(state, heroineId, settlement.right);
|
|
5635
|
-
if (!reply || !protocol || !right || !offer || !outcome || !finalChoice || !aftermathChoice || aftermathRow.approach !== finalRow.choice || !accordRow || !proof || !state.flags
|
|
5635
|
+
if (!reply || !protocol || !right || !offer || !outcome || !finalChoice || !aftermathChoice || aftermathRow.approach !== finalRow.choice || !accordRow || !proof || !state.flags[proof.flag]) return null;
|
|
5636
5636
|
const boundary = PERSONAL_FINALE_BOUNDARY_OBJECTS[heroineId];
|
|
5637
5637
|
const protectionLabel = SHARED_NIGHT_PROTECTION_LABELS[day20.day20Protection];
|
|
5638
5638
|
const protectionText = sharedNightProtectionText(settlement.right, day20.day20Protection);
|
|
@@ -6199,7 +6199,7 @@ export function sharedNightStatus(state) {
|
|
|
6199
6199
|
visible: state.day === MAX_DAY && state.phase === 'choose_visit',
|
|
6200
6200
|
ready: !reason,
|
|
6201
6201
|
reason,
|
|
6202
|
-
complete: ACCORD_KEYS.filter((key) => state.accords
|
|
6202
|
+
complete: ACCORD_KEYS.filter((key) => state.accords[key]).length,
|
|
6203
6203
|
total: ACCORD_KEYS.length,
|
|
6204
6204
|
jointComplete: Math.min(jointComplete, JOINT_ACTION_TARGET),
|
|
6205
6205
|
jointTotal: JOINT_ACTION_TARGET,
|
|
@@ -6317,11 +6317,11 @@ function sharedFinaleRouteReason(history, heroineId) {
|
|
|
6317
6317
|
const lane = routeChoiceLane(heroineId, entry.choice);
|
|
6318
6318
|
return choice && lane ? [{ day:entry.day, choice, lane }] : [];
|
|
6319
6319
|
});
|
|
6320
|
-
if (!rows.length) return `${HEROINES[heroineId].short}
|
|
6320
|
+
if (!rows.length) return `${HEROINES[heroineId].short}之前没有和你做成一件足以带到今夜的事。重念一遍约定,也不能替她编出早已愿意的答案。`;
|
|
6321
6321
|
const covenant = rows.filter((row) => row.lane === 'covenant');
|
|
6322
6322
|
const privateRows = rows.filter((row) => row.lane === 'private');
|
|
6323
6323
|
const latest = rows.at(-1);
|
|
6324
|
-
return
|
|
6324
|
+
return `她最近记得的是第${latest.day}日“${latest.choice.label}”(${latest.choice.hint}):${latest.choice.text}今夜的灯再暖,也只能从这件真事往下谈,不能把她以前的点头或拒绝一并抹掉。`;
|
|
6325
6325
|
}
|
|
6326
6326
|
|
|
6327
6327
|
function sharedAfterglowChoiceReason(choice, heroineId, beatIndex) {
|
|
@@ -6741,19 +6741,19 @@ function finishSharedNight(state) {
|
|
|
6741
6741
|
// 个人弧线的拍号 = 你第几次进她的门(结算成功才计次)。
|
|
6742
6742
|
// 取代旧的 state.day - 1:按日历天索引会让轮换玩家撞上「好选项被锁、只能选伤害项」。
|
|
6743
6743
|
function routeStep(state, heroineId) {
|
|
6744
|
-
return state.visits
|
|
6744
|
+
return state.visits[heroineId];
|
|
6745
6745
|
}
|
|
6746
6746
|
|
|
6747
6747
|
export function routeComplete(state, heroineId) {
|
|
6748
6748
|
const routeDone = routeStep(state, heroineId) >= (ROUTE_CHOICES[heroineId]?.length ?? 0);
|
|
6749
6749
|
const accord = ACCORD_CHOICES[heroineId];
|
|
6750
|
-
return routeDone && (!accord ||
|
|
6750
|
+
return routeDone && (!accord || state.accords[accord.effects.accord]);
|
|
6751
6751
|
}
|
|
6752
6752
|
|
|
6753
6753
|
export function visitChoices(state, heroineId) {
|
|
6754
|
-
const rows = routeRowsFor(heroineId, routeStep(state, heroineId), state.routeStances
|
|
6754
|
+
const rows = routeRowsFor(heroineId, routeStep(state, heroineId), state.routeStances[heroineId]);
|
|
6755
6755
|
const accord = ACCORD_CHOICES[heroineId];
|
|
6756
|
-
const choices = accord && !state.accords
|
|
6756
|
+
const choices = accord && !state.accords[accord.effects.accord] ? [...rows, accord] : rows;
|
|
6757
6757
|
return choices.map((choice) => {
|
|
6758
6758
|
const conditionLocked = !!choice.condition && !hasToken(state, choice.condition);
|
|
6759
6759
|
const unaffordable = cannotAfford(state, choice);
|
|
@@ -7127,7 +7127,7 @@ export function chooseVisit(state, choiceId) {
|
|
|
7127
7127
|
}
|
|
7128
7128
|
for (const row of routeBondChanges(heroine, lane)) changeBond(state, heroine, row.other, row.delta);
|
|
7129
7129
|
}
|
|
7130
|
-
state.visits[heroine]
|
|
7130
|
+
state.visits[heroine] += 1;
|
|
7131
7131
|
record(state, 'visit_choice', { heroine, choice: choiceId, lane, public: !!PUBLIC_EVENTS[state.day] });
|
|
7132
7132
|
}
|
|
7133
7133
|
state.log.push(choice.text);
|
|
@@ -7191,7 +7191,7 @@ export function visitForecast(state, heroineId) {
|
|
|
7191
7191
|
choice.effects?.accord ? '院约' : routeChoiceLane(heroineId, choice.id) === 'covenant' ? '共担' : '私情'
|
|
7192
7192
|
)))];
|
|
7193
7193
|
const obligation = activeObligations(state).find((row) => row.heroine === heroineId && row.type !== 'cooldown') ?? null;
|
|
7194
|
-
const reopenDay = state.routeReopensOn
|
|
7194
|
+
const reopenDay = state.routeReopensOn[heroineId];
|
|
7195
7195
|
const branch = routeBranchContext(state, heroineId);
|
|
7196
7196
|
return {
|
|
7197
7197
|
mostJealous,
|
|
@@ -8798,7 +8798,7 @@ export function activeObligations(state) {
|
|
|
8798
8798
|
}
|
|
8799
8799
|
|
|
8800
8800
|
for (const heroine of HEROINE_IDS) {
|
|
8801
|
-
const reopenDay = state.routeReopensOn
|
|
8801
|
+
const reopenDay = state.routeReopensOn[heroine];
|
|
8802
8802
|
if (reopenDay <= state.day) continue;
|
|
8803
8803
|
rows.push({
|
|
8804
8804
|
id:`cooldown:${heroine}`, type:'cooldown', status:'locked',
|
|
@@ -9286,7 +9286,7 @@ function morningSettlementNarrowAuthorized(state, heroine) {
|
|
|
9286
9286
|
&& entry.day === state.morningSettlement.sourceDay
|
|
9287
9287
|
&& entry.action === state.morningSettlement.sourceId
|
|
9288
9288
|
&& entry.actor === heroine);
|
|
9289
|
-
return (!!accord &&
|
|
9289
|
+
return (!!accord && state.accords[accord] || sourceIsNamed)
|
|
9290
9290
|
&& !fivePriceUnresolvedBreak(morningSettlementBasis(state), heroine);
|
|
9291
9291
|
}
|
|
9292
9292
|
|
|
@@ -10034,7 +10034,7 @@ function combinations(rows, size, start = 0, prefix = [], result = []) {
|
|
|
10034
10034
|
|
|
10035
10035
|
function heroineAccordReady(state, heroineId) {
|
|
10036
10036
|
const key = Object.values(ACCORD_META).find((row) => row.heroine === heroineId)?.key;
|
|
10037
|
-
return !!key && !!state.accords
|
|
10037
|
+
return !!key && !!state.accords[key];
|
|
10038
10038
|
}
|
|
10039
10039
|
|
|
10040
10040
|
function allianceEndingText(members, style = null) {
|
|
@@ -10053,18 +10053,18 @@ function allianceEndingText(members, style = null) {
|
|
|
10053
10053
|
: style === '明账共恋'
|
|
10054
10054
|
? '去处与偏爱仍围着你发生,却不再靠猜;每一次靠近、改口与独宿都必须当着联盟成员说清。'
|
|
10055
10055
|
: style === '有限共居'
|
|
10056
|
-
? '
|
|
10056
|
+
? '她们仍各自收着院门钥匙,只把亲口答应的东西放到桌中。坐得近,不等于从此什么都归在一起。'
|
|
10057
10057
|
: '';
|
|
10058
10058
|
if (exact) return `${exact}${styleText ? ` ${styleText}` : ''}`;
|
|
10059
10059
|
const names = members.map((id) => HEROINES[id].name).join('、');
|
|
10060
|
-
return `${names}
|
|
10060
|
+
return `${names}只把彼此亲手经过、亲口答应的事写在同一页。没有坐进来的人仍收着自己的账、钥匙和去处;你不能因为今夜亲近,就说五处院门都已点头。${styleText ? ` ${styleText}` : ''}`;
|
|
10061
10061
|
}
|
|
10062
10062
|
|
|
10063
10063
|
function heroineEpilogueVariant(state, endingId, allianceMembers, exclusiveHeroine, heroineId) {
|
|
10064
10064
|
if (endingId === 'balanced') return 'balanced';
|
|
10065
10065
|
if (endingId === 'alliance') return allianceMembers?.includes(heroineId) ? 'alliance' : 'outside';
|
|
10066
10066
|
if (endingId === 'exclusive') return exclusiveHeroine === heroineId ? 'exclusive' : 'outside';
|
|
10067
|
-
const relation = state.relations
|
|
10067
|
+
const relation = state.relations[heroineId];
|
|
10068
10068
|
return relation.qing >= 35 && relation.du < 65 ? 'personal' : 'outside';
|
|
10069
10069
|
}
|
|
10070
10070
|
|
|
@@ -10083,7 +10083,7 @@ function endingEpilogues(state, endingId, allianceMembers, exclusiveHeroine) {
|
|
|
10083
10083
|
const morningSettlements = recordedMorningSettlements(state);
|
|
10084
10084
|
return HEROINE_IDS.map((heroine) => {
|
|
10085
10085
|
const stance = routeStance(state, heroine);
|
|
10086
|
-
const relation = state.relations
|
|
10086
|
+
const relation = state.relations[heroine];
|
|
10087
10087
|
const variant = heroineEpilogueVariant(state, endingId, allianceMembers, exclusiveHeroine, heroine);
|
|
10088
10088
|
const base = EPILOGUES[heroine][variant];
|
|
10089
10089
|
const habit = nightRelationshipPattern(state, heroine);
|
|
@@ -10118,11 +10118,11 @@ function endingEpilogues(state, endingId, allianceMembers, exclusiveHeroine) {
|
|
|
10118
10118
|
: '';
|
|
10119
10119
|
const firstOpeningText = firstOpening?.epilogueTexts?.[heroine] ?? '';
|
|
10120
10120
|
const routeHistoryNote = stance.covenant > stance.private
|
|
10121
|
-
?
|
|
10121
|
+
? `二十日里,你更常把她说过的话带到人前,让别人也能看见你有没有照做。这封笺记的是那些真正发生过的事。`
|
|
10122
10122
|
: stance.private > stance.covenant
|
|
10123
|
-
?
|
|
10124
|
-
|
|
10125
|
-
?
|
|
10123
|
+
? `二十日里,你更常把话留在她的门内。那些亲近是真的,门外等过、猜过和来问过的人也是真的。`
|
|
10124
|
+
: stance.covenant
|
|
10125
|
+
? `你既在人前接过她的话,也和她关过门。她记得这是两种不同的事,不打算替你混成一句“都很好”。`
|
|
10126
10126
|
: '你没有真正走进她的路线;结局仍会交代她怎样收回自己的名字、钥匙与去处。';
|
|
10127
10127
|
const habitNote = habit.mode
|
|
10128
10128
|
? `已走的 ${habit.chapters}/4 章夜谈更偏向“${habit.label}”:明说 ${habit.counts.honest}、由她定界 ${habit.counts.listen}、门内私情 ${habit.counts.private}。`
|
|
@@ -10298,7 +10298,7 @@ export function determineEnding(state) {
|
|
|
10298
10298
|
state.day === MAX_DAY
|
|
10299
10299
|
&& recordedFivePriceSettlement(state)?.coalition.kind === 'full'
|
|
10300
10300
|
&& state.flags.harem_coalition
|
|
10301
|
-
&& ACCORD_KEYS.every((key) => state.accords
|
|
10301
|
+
&& ACCORD_KEYS.every((key) => state.accords[key])
|
|
10302
10302
|
&& state.unlocked.includes('inner_court_accord')
|
|
10303
10303
|
&& state.unlocked.includes('inner_court_afterglow')
|
|
10304
10304
|
&& state.sharedAfterglowChoices.length === SHARED_AFTERGLOW_BEATS.length
|
|
@@ -10717,7 +10717,7 @@ export function startFateCoda(state) {
|
|
|
10717
10717
|
|
|
10718
10718
|
function fateCodaInstitutionEcho(state) {
|
|
10719
10719
|
const accordNames = Object.values(ACCORD_META)
|
|
10720
|
-
.filter((row) => state.accords
|
|
10720
|
+
.filter((row) => state.accords[row.key])
|
|
10721
10721
|
.map((row) => ({
|
|
10722
10722
|
order: '月娘留下的正堂定账',
|
|
10723
10723
|
truth: '金莲留下的去处真话',
|
|
@@ -10726,10 +10726,10 @@ function fateCodaInstitutionEcho(state) {
|
|
|
10726
10726
|
hearth: '雪娥留下的停灶与工账',
|
|
10727
10727
|
})[row.key]);
|
|
10728
10728
|
const accordCount = accordNames.length;
|
|
10729
|
-
const covenant = Object.values(state.routeStances
|
|
10730
|
-
const privateCount = Object.values(state.routeStances
|
|
10731
|
-
const publicProof = ['harem_coalition', ...Object.keys(state.flags
|
|
10732
|
-
.some((key) => state.flags
|
|
10729
|
+
const covenant = Object.values(state.routeStances).reduce((sum, row) => sum + row.covenant, 0);
|
|
10730
|
+
const privateCount = Object.values(state.routeStances).reduce((sum, row) => sum + row.private, 0);
|
|
10731
|
+
const publicProof = ['harem_coalition', ...Object.keys(state.flags).filter((key) => key.includes('public') || key.includes('balance'))]
|
|
10732
|
+
.some((key) => state.flags[key]);
|
|
10733
10733
|
const accordEcho = accordCount
|
|
10734
10734
|
? `二十日里真正立过的${accordNames.join('、')}没有救回死者,却让后来的人仍能据此拒绝被并账。`
|
|
10735
10735
|
: '二十日里没有一条院约真正落稳;离散来时,每个人只能凭自己还握得住的物件作证。';
|
|
@@ -13064,14 +13064,3 @@ export function snapshot(state) {
|
|
|
13064
13064
|
return structuredClone(state);
|
|
13065
13065
|
}
|
|
13066
13066
|
|
|
13067
|
-
export const APPROVED_ADULT_IDS = Object.freeze([
|
|
13068
|
-
'wu_yueniang', 'pan_jinlian', 'li_pinger', 'meng_yulou', 'sun_xuee',
|
|
13069
|
-
]);
|
|
13070
|
-
|
|
13071
|
-
export function sceneIsAdultSafe(scene) {
|
|
13072
|
-
const approved = new Set(APPROVED_ADULT_IDS);
|
|
13073
|
-
return !!scene
|
|
13074
|
-
&& Array.isArray(scene.participants)
|
|
13075
|
-
&& scene.participants.length > 0
|
|
13076
|
-
&& scene.participants.every((id) => approved.has(id) && HEROINES[id]?.adult === true);
|
|
13077
|
-
}
|