perf: 优化自动战斗界面显示 (#14795)

* perf: 优化自动战斗界面显示

* fix: 不勾选战斗列表时也会吃理智药

* i18n: KR

* i18n: 加個空白

* i18n: EN

* i18n: JP

* rft: 使用自动换行

* style: increase size a bit

* perf: 优化界面布局

* rft: UserAdditional 改为序列化存储,增加自选模组

* fix: 列表过长时超链接无法显示

* perf: 未激活追加自定干员也可以进行编辑

* perf: 战斗列表自适应宽度

* chore: 按钮放上面

* perf: 优化日志栏宽度,占用 1/2 或 2/5

* perf: 突袭改成用背景色提示

---------

Co-authored-by: HX3N <scarlet7518@gmail.com>
Co-authored-by: momomochi987 <as99us301@gmail.com>
Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com>
Co-authored-by: Manicsteiner <Manicsteiner@outlook.com>
Co-authored-by: status102 <102887808+status102@users.noreply.github.com>
This commit is contained in:
uye
2025-11-22 02:30:44 +08:00
committed by GitHub
parent 20b19fabc3
commit 14ca2f2a54
8 changed files with 839 additions and 377 deletions

View File

@@ -127,8 +127,19 @@ public class AsstCopilotTask : AsstBaseTask
[JsonProperty("name")]
public string Name { get; set; } = string.Empty;
/// <summary>
/// Gets or sets 技能序号,可选,默认为 1取值范围 [1, 3]
/// </summary>
[JsonProperty("skill")]
public int Skill { get; set; }
public int Skill { get; set; } = 1;
/// <summary>
/// Gets or sets 模组编号,可选,默认为 0
/// -1: 不切换模组 / 无要求, 0: 不使用模组, 1: 模组 χ, 2: 模组 γ, 3: 模组 α, 4: 模组 Δ
/// 当前核心仅使用 name 和 skill 字段module 作为预留字段
/// </summary>
[JsonProperty("module")]
public int Module { get; set; }
}
public class MultiTask

View File

@@ -842,14 +842,21 @@ Only level rewards can be farmed; to get the Engraved Medal, all 「Key Objectiv
<system:String x:Key="ThanksForLikeWebJson">Thanks for the likes!\nThe comment section is already open on the web page, please feel free to leave your comment!</system:String>
<system:String x:Key="AutoSquad">Auto Squad</system:String>
<system:String x:Key="AutoSquadTip">「Favourite」 marked {key=Operator}s may not be recognized</system:String>
<system:String x:Key="SupportUnitUsage">Support Unit Borrowing Strategy</system:String>
<system:String x:Key="SupportUnitUsage.None">Don't Borrow</system:String>
<system:String x:Key="SupportUnitUsage.WhenNeeded">Only for Filling Gaps</system:String>
<system:String x:Key="SupportUnitUsage">Use Support Unit</system:String>
<system:String x:Key="SupportUnitUsage.Tip">Missing one operator is manageable, but if two or more are missing, consider switching to a different job.</system:String>
<system:String x:Key="SupportUnitUsage.None">Never</system:String>
<system:String x:Key="SupportUnitUsage.WhenNeeded">When Needed</system:String>
<system:String x:Key="SupportUnitUsage.Random">Random</system:String>
<system:String x:Key="AddTrust">Add low-trust {key=Operator}s</system:String>
<system:String x:Key="Copilot.IgnoreRequirements">Ignore {key=Operator} requirements</system:String>
<system:String x:Key="Copilot.IgnoreRequirements.Tip" xml:space="preserve">Some jobs require specific Modules or other prerequisites.
Enabling this will skip these checks, but may cause the job to fail.</system:String>
<system:String x:Key="AddUserAdditional">Add custom {key=Operator}s</system:String>
<system:String x:Key="AddUserAdditionalTip">Use 「;」 as the separator, 「,」 to separate the {key=Operator} name and skills, for example: W, 3; Ash, 2</system:String>
<system:String x:Key="UserAdditional.OperatorName">{key=Operator} Name</system:String>
<system:String x:Key="UserAdditional.Skill">Skill</system:String>
<system:String x:Key="UserAdditional.Action">Action</system:String>
<system:String x:Key="UserAdditional.Add">Add</system:String>
<system:String x:Key="LoopTimes">Loop Times</system:String>
<system:String x:Key="UseCopilotList">Battle list</system:String>
<system:String x:Key="UseCopilotListTip" xml:space="preserve">Only supported in the following modes:
@@ -859,12 +866,12 @@ Only level rewards can be farmed; to get the Engraved Medal, all 「Key Objectiv
4. {key=ParadoxSimulation}: Start from the {key=Operator} list
Please start from the corresponding screen. Cross-chapter navigation is not supported.
- When 「{key=UseCopilotList}」 is enabled, individual copilot will be automatically added to 「{key=UseCopilotList}」.</system:String>
When 「{key=UseCopilotList}」 is enabled, individual jobs will be automatically added to 「{key=UseCopilotList}」.</system:String>
<system:String x:Key="CopilotTaskRaidStage">(Challenge)</system:String>
<system:String x:Key="CopilotAddTask" xml:space="preserve">Left-click to add Normal difficulty
Right click to add challenge difficulty</system:String>
<system:String x:Key="CopilotClearTask" xml:space="preserve">Left-click to clear all tasks
Right-click to clear inactive tasks</system:String>
<system:String x:Key="CopilotClearTask" xml:space="preserve">Left-click to clear all jobs
Right-click to clear inactive jobs</system:String>
<system:String x:Key="Start">Start</system:String>
<system:String x:Key="VideoLink">Video Link</system:String>
<system:String x:Key="CopilotSkill">Skill</system:String>
@@ -894,21 +901,21 @@ Right-click to clear inactive tasks</system:String>
<!-- Logs -->
<system:String x:Key="CopilotTip">
Tips: \n\n
1. Before using, please confirm the task file matches your selected stage type.\n\n
1. Before using, please confirm the job file matches your selected stage type.\n\n
2. {key=MainStage}, {key=StoryCollection}, {key=SideStory}: Please start from the screen where the blue "Start" button appears in the bottom right corner.\n\n
3. {key=SSS}: Multiple built-in files are in the resource/copilot folder. First create your squad manually, then start from the screen where the "Start Deployment" button appears in the bottom right. Can be used with 「{key=LoopTimes}」.\n\n
4. {key=ParadoxSimulation}: After selecting skills, start from the skill selection screen where the "Start Simulation" button appears. For 1/2★ {key=Operator}s (without skills), start from the screen with the "Start Simulation" button in the bottom right. If using 「{key=UseCopilotList}」, please start from the 「Level/Rarity」 tab in the {key=Operator} list.\n\n
5. When using a support unit, turn off 「{key=AutoSquad}」 and 「{key=UseCopilotList}」, manually select the {key=Operator}, then start from the squad screen where the "Mission Start" button appears in the bottom right.\n\n
6. {key=Operator}s marked as "Favorite" may affect 「{key=AutoSquad}」 recognition and selection. When using 「{key=AutoSquad}」, consider removing favorites, or if errors occur, turn off 「{key=AutoSquad}」 and manually supplement the missing {key=Operator}s as prompted.\n\n
7. In the Copilot workstation, you can paste the mysterious code by clicking the paste button on the right side of the input box:\n
- click the second button = Add a single job.\n
- click the third button = Add a job set.\n\n
7. In the Copilot workstation, you can paste codes by clicking the paste button on the right side of the input box:\n
● Second button = Add a single job.\n
● Third button = Add a job set.\n\n
8. {key=UseCopilotList}:\n
- After selecting a task, check that the stage name below is correct (e.g.: CV-EX-1).\n
- Add: Left-click for normal difficulty, right-click for challenge mode.\n
- Clear: Left-click to clear all, right-click to remove only inactive tasks.\n
- Start from a screen where the target stage name is visible. Cross-chapter navigation is not supported.\n
- Operation will stop automatically when encountering insufficient sanity, battle failure, or failure to achieve 3-star clear.
After selecting a job, verify the stage name below is correct (e.g., CV-EX-1).\n
Add: Left-click for Normal difficulty, right-click for Challenge difficulty.\n
Clear: Left-click to clear all jobs, right-click to remove only inactive jobs.\n
Start from a screen where the target stage name is visible. Cross-chapter navigation is not supported.\n
● Execution will stop automatically when sanity is insufficient, battle fails, or fails to achieve a 3-star clear.
</system:String>
<system:String x:Key="CopilotFileReadError">Failed to read file!</system:String>
<system:String x:Key="CopilotNoFound">No corresponding file found!</system:String>

View File

@@ -842,14 +842,21 @@ C:\\leidian\\LDPlayer9
<system:String x:Key="ThanksForLikeWebJson">感謝と評価!\nウェブページには既にコメント欄が開放されており、あなたのコメントを心待ちにしています</system:String>
<system:String x:Key="AutoSquad">自動編成</system:String>
<system:String x:Key="AutoSquadTip">自動編成では、一時的に「戦術要員」{key=Operator}を認識できません</system:String>
<system:String x:Key="SupportUnitUsage">支援要員借用戦略</system:String>
<system:String x:Key="SupportUnitUsage">戦友サポート借用</system:String>
<system:String x:Key="SupportUnitUsage.Tip">1つ足りないくらいならまだ使えますが、2つ以上欠けている場合は別の攻略に替えたほうがいいでしょう。</system:String>
<system:String x:Key="SupportUnitUsage.None">借用しない</system:String>
<system:String x:Key="SupportUnitUsage.WhenNeeded">補完のみ</system:String>
<system:String x:Key="SupportUnitUsage.Random">ランダム</system:String>
<system:String x:Key="AddTrust">信頼度低の{key=Operator}追加</system:String>
<system:String x:Key="Copilot.IgnoreRequirements">{key=Operator}要件を無視</system:String>
<system:String x:Key="Copilot.IgnoreRequirements.Tip" xml:space="preserve">一部の攻略は特定のモジュールなどを前提条件とします
この項目を選択するとこれらのチェックをスキップしますが、タスクが正常に動作しなくなる可能性があります。</system:String>
<system:String x:Key="AddUserAdditional">カスタム{key=Operator}追加</system:String>
<system:String x:Key="AddUserAdditionalTip">「;」はセパレータ、「,」で{key=Operator}の名前とスキルを区切ります。例: Surtr, 3; Eyjafjalla, 1</system:String>
<system:String x:Key="UserAdditional.OperatorName">{key=Operator}名</system:String>
<system:String x:Key="UserAdditional.Skill">スキル</system:String>
<system:String x:Key="UserAdditional.Action">操作</system:String>
<system:String x:Key="UserAdditional.Add">追加</system:String>
<system:String x:Key="LoopTimes">ループ回数</system:String>
<system:String x:Key="UseCopilotList">バトルリスト</system:String>
<system:String x:Key="UseCopilotListTip" xml:space="preserve">以下のモードのみ対応:
@@ -859,7 +866,7 @@ C:\\leidian\\LDPlayer9
4. {key=ParadoxSimulation}: {key=Operator}リストから起動
対応する画面から開始してください。章間のナビゲーションはサポートされていません。
- 「{key=UseCopilotList}」を有効にすると、個々のジョブが自動的に「{key=UseCopilotList}」に追加されます。</system:String>
「{key=UseCopilotList}」を有効にすると、個々のジョブが自動的に「{key=UseCopilotList}」に追加されます。</system:String>
<system:String x:Key="CopilotTaskRaidStage">(強襲)</system:String>
<system:String x:Key="CopilotAddTask" xml:space="preserve">左クリックで通常難易度を追加
右クリックしてレイドの難易度を追加します</system:String>
@@ -901,14 +908,14 @@ C:\\leidian\\LDPlayer9
5. サポートを使うときは、「{key=AutoSquad}」と「{key=UseCopilotList}」をオフにし、手動で {key=Operator} を選択した後、編成画面の右下に「行動開始」ボタン画面で開始してください。\n\n
6. 「戦術要員」機能を有効にすると、「{key=AutoSquad}」の{key=Operator}選択に影響を与える可能性があります。「{key=AutoSquad}」を 使用する際は「戦術要員」をオフにするか、不足している{key=Operator}を手動で補充して編成を完成させることをお勧めします。\n\n
7. Copilot作業ステーションでは、入力欄の右側にある貼り付けボタンをクリックして、謎のコードを貼り付けることができます\n
- 2番目のボタンをクリック = 割り当てを追加。\n
- 3番目のボタンをクリック = 割り当てセットを追加。\n\n
2番目のボタンをクリック = 割り当てを追加。\n
3番目のボタンをクリック = 割り当てセットを追加。\n\n
8. {key=UseCopilotList}:\n
- 攻略ファイルを選択した後、リストの下のステージ名が正しいことを確認してください(例: CV-EX-1。 \n
- 追加: 左クリックして通常難易度を追加し、右クリックして強襲難易度を追加します。\n
- クリア: 左クリックするとリストがクリアされ、右クリックすると非アクティブなタスクのみが削除されます。\n
- ターゲットのステージ名が見える画面で起動してください。章間のナビゲーションはサポートされていません。\n
- 理性不足の場合、戦闘が失敗した場合、または 3 つ星を解決できない場合、アクションは終了します。
攻略ファイルを選択した後、リストの下のステージ名が正しいことを確認してください(例: CV-EX-1。 \n
追加: 左クリックして通常難易度を追加し、右クリックして強襲難易度を追加します。\n
クリア: 左クリックするとリストがクリアされ、右クリックすると非アクティブなタスクのみが削除されます。\n
ターゲットのステージ名が見える画面で起動してください。章間のナビゲーションはサポートされていません。\n
理性不足の場合、戦闘が失敗した場合、または 3 つ星を解決できない場合、アクションは終了します。
</system:String>
<system:String x:Key="CopilotFileReadError">ファイルの読み取りに失敗しました!</system:String>
<system:String x:Key="CopilotNoFound">対応する攻略ファイルが見つかりません!</system:String>

View File

@@ -843,14 +843,21 @@ C:\\leidian\\LDPlayer9
<system:String x:Key="ThanksForLikeWebJson">감사합니다!\n웹사이트에 댓글을 남길 수도 있으니 의견을 남겨 주세요!</system:String>
<system:String x:Key="AutoSquad">자동 편성</system:String>
<system:String x:Key="AutoSquadTip">자동 편성은 「선호」 설정 된 {key=Operator}를 인식할 수 없습니다</system:String>
<system:String x:Key="SupportUnitUsage">지원 유닛 모집 전략</system:String>
<system:String x:Key="SupportUnitUsage">지원 유닛 모집</system:String>
<system:String x:Key="SupportUnitUsage.Tip">하나 정도 부족한 것은 문제가 없지만, 둘 이상 부족하면 다른 작업을 사용하는 것을 권장합니다.</system:String>
<system:String x:Key="SupportUnitUsage.None">모집안함</system:String>
<system:String x:Key="SupportUnitUsage.WhenNeeded">보완용</system:String>
<system:String x:Key="SupportUnitUsage.Random">랜덤</system:String>
<system:String x:Key="AddTrust">신뢰도가 낮은 {key=Operator} 추가</system:String>
<system:String x:Key="Copilot.IgnoreRequirements">{key=Operator} 요구 사항 무시</system:String>
<system:String x:Key="Copilot.IgnoreRequirements.Tip" xml:space="preserve">일부 작업은 특정 모듈이 필요합니다
이 옵션을 선택하면 검사 과정을 건너뛰지만 작업이 정상적으로 동작하지 않을 수 있습니다.</system:String>
<system:String x:Key="AddUserAdditional">커스텀 {key=Operator} 추가</system:String>
<system:String x:Key="AddUserAdditionalTip">「;」 로 {key=Operator}를 구분하고, 「,」 로 스킬을 구분합니다. 예시: W, 3; Ash, 2</system:String>
<system:String x:Key="UserAdditional.OperatorName">{key=Operator} 이름</system:String>
<system:String x:Key="UserAdditional.Skill">스킬</system:String>
<system:String x:Key="UserAdditional.Action">작업</system:String>
<system:String x:Key="UserAdditional.Add">추가</system:String>
<system:String x:Key="LoopTimes">반복 횟수</system:String>
<system:String x:Key="UseCopilotList">작업 목록</system:String>
<system:String x:Key="UseCopilotListTip" xml:space="preserve">다음 모드에서만 지원됩니다:
@@ -860,7 +867,7 @@ C:\\leidian\\LDPlayer9
4. {key=ParadoxSimulation}: {key=Operator} 목록에서 시작
해당 화면에서 시작하세요. 챕터 간 이동은 지원되지 않습니다.
- 「{key=UseCopilotList}」 가 활성화되면 개별 작업이 자동으로 「{key=UseCopilotList}」 에 추가됩니다.</system:String>
「{key=UseCopilotList}」 가 활성화되면 개별 작업이 자동으로 「{key=UseCopilotList}」 에 추가됩니다.</system:String>
<system:String x:Key="CopilotTaskRaidStage">(하드)</system:String>
<system:String x:Key="CopilotAddTask" xml:space="preserve">좌클릭으로 일반 난이도 추가
하드 모드를 추가하려면 마우스 오른쪽 버튼을 클릭하세요</system:String>
@@ -902,14 +909,14 @@ C:\\leidian\\LDPlayer9
5. 지원 유닛을 사용할 때는 「{key=AutoSquad}」 및 「{key=UseCopilotList}」를 끄고, 수동으로 오퍼레이터를 선택한 다음, 우측 하단에 "작전 개시" 버튼이 나타나는 분대 화면에서 시작하세요.\n\n
6. "선호"로 표시된 오퍼레이터는 「{key=AutoSquad}」 인식 및 선택에 영향을 줄 수 있습니다. 「{key=AutoSquad}」 사용 시, 선호 표시를 해제하거나 오류 발생 시 「{key=AutoSquad}」를 끄고 안내에 따라 누락된 오퍼레이터를 수동으로 편성하는 것을 고려하세요.\n\n
7. 자동지휘 작업 공간에서, 입력 상자 오른쪽의 붙여넣기 버튼을 클릭하여 코드를 붙여넣을 수 있습니다:\n
- 두 번째 버튼을 왼쪽 클릭 = 작업 추가.\n
- 세 번째 버튼을 클릭 = 작업 목록 추가.\n\n
두 번째 버튼을 왼쪽 클릭 = 작업 추가.\n
세 번째 버튼을 클릭 = 작업 목록 추가.\n\n
8. {key=UseCopilotList}:\n
- 작업 선택 후, 아래의 스테이지 이름이 올바른지 확인하세요 (예: CV-EX-1).\n
- 추가: 좌클릭은 일반, 우클릭은 하드 모드입니다.\n
- 지우기: 좌클릭은 전체 삭제, 우클릭은 비활성 작업만 삭제합니다.\n
- 목표 스테이지 이름이 보이는 화면에서 시작하세요. 챕터 간 이동은 지원되지 않습니다.\n
- 이성 부족, 작전 실패, 또는 3성 클리어 실패 시 작전이 자동으로 중지됩니다.
작업 선택 후, 아래의 스테이지 이름이 올바른지 확인하세요 (예: CV-EX-1).\n
추가: 좌클릭은 일반, 우클릭은 하드 모드입니다.\n
지우기: 좌클릭은 전체 삭제, 우클릭은 비활성 작업만 삭제합니다.\n
목표 스테이지 이름이 보이는 화면에서 시작하세요. 챕터 간 이동은 지원되지 않습니다.\n
이성 부족, 작전 실패, 또는 3성 클리어 실패 시 작전이 자동으로 중지됩니다.
</system:String>
<system:String x:Key="CopilotFileReadError">파일을 읽지 못했습니다!</system:String>
<system:String x:Key="CopilotNoFound">해당 파일을 찾을 수 없습니다!</system:String>

View File

@@ -842,14 +842,21 @@ C:\\leidian\\LDPlayer9。\n
<system:String x:Key="ThanksForLikeWebJson">感谢评价!\n网页已经开放评论区欢迎前往留下你的评论</system:String>
<system:String x:Key="AutoSquad">自动编队</system:String>
<system:String x:Key="AutoSquadTip">自动编队可能无法识别带有 「特别关注」 标记的{key=Operator}</system:String>
<system:String x:Key="SupportUnitUsage">助战干员借用策略</system:String>
<system:String x:Key="SupportUnitUsage">助战</system:String>
<system:String x:Key="SupportUnitUsage.Tip">缺一个还能用用,缺两个以上还是换份作业吧</system:String>
<system:String x:Key="SupportUnitUsage.None">不借用</system:String>
<system:String x:Key="SupportUnitUsage.WhenNeeded">仅用于补漏</system:String>
<system:String x:Key="SupportUnitUsage.Random">随机</system:String>
<system:String x:Key="AddTrust">补充低信赖{key=Operator}</system:String>
<system:String x:Key="Copilot.IgnoreRequirements">忽略{key=Operator}属性要求</system:String>
<system:String x:Key="Copilot.IgnoreRequirements.Tip" xml:space="preserve">某些作业需要特定模组等作为前置条件
勾选此项将跳过这些检查,但可能导致作业无法正常运行</system:String>
<system:String x:Key="AddUserAdditional">追加自定{key=Operator}</system:String>
<system:String x:Key="AddUserAdditionalTip">以英文 「;」 为分隔符,英文 「,」 分隔{key=Operator}名与技能,例: 史尔特尔,3;艾雅法拉,1</system:String>
<system:String x:Key="UserAdditional.OperatorName">{key=Operator}名</system:String>
<system:String x:Key="UserAdditional.Skill">技能</system:String>
<system:String x:Key="UserAdditional.Action">操作</system:String>
<system:String x:Key="UserAdditional.Add">添加</system:String>
<system:String x:Key="LoopTimes">循环次数</system:String>
<system:String x:Key="UseCopilotList">战斗列表</system:String>
<system:String x:Key="UseCopilotListTip" xml:space="preserve">仅支持以下模式:
@@ -859,7 +866,7 @@ C:\\leidian\\LDPlayer9。\n
4. {key=ParadoxSimulation}: 从{key=Operator}列表启动
请在对应界面启动,不支持跨章节导航
- 当 「{key=UseCopilotList}」 启用后, 选择单个作业时会自动添加到 「{key=UseCopilotList}」</system:String>
当 「{key=UseCopilotList}」 启用后, 选择单个作业时会自动添加到 「{key=UseCopilotList}」</system:String>
<system:String x:Key="CopilotTaskRaidStage">(突袭)</system:String>
<system:String x:Key="CopilotAddTask" xml:space="preserve">左键添加普通难度
右键添加突袭难度</system:String>
@@ -901,14 +908,14 @@ C:\\leidian\\LDPlayer9。\n
5. 使用好友助战时,请关闭 「{key=AutoSquad}」 和 「{key=UseCopilotList}」,手动选择{key=Operator}后,在编队界面右下角存在 「开始行动」 按钮界面启动。\n\n
6. {key=Operator}若被标记为 「特别关注」,可能影响 「{key=AutoSquad}」 的识别与选择。建议使用 「{key=AutoSquad}」 时移除关注,或在报错后关闭 「{key=AutoSquad}」,根据提示手动补充缺失的{key=Operator}。\n\n
7. Copilot 作业站的神秘代码可通过输入框右侧的粘贴按钮粘贴:\n
- 单击第 2 个按钮 = 添加作业。\n
- 单击第 3 个按钮 = 添加作业集。\n\n
单击第 2 个按钮 = 添加作业。\n
单击第 3 个按钮 = 添加作业集。\n\n
8. {key=UseCopilotList}:\n
- 选择作业后,检查下方关卡名是否正确 (例: CV-EX-1)。\n
- 添加: 左键 = 普通难度,右键 = 突袭难度。\n
- 清除: 左键 = 全部清空,右键 = 仅移除未激活任务。\n
- 请在能看到目标关卡名的界面启动,不支持跨章节导航。\n
- 遇到理智不足、战斗失败、未能三星结算时将自动中止。
选择作业后,检查下方关卡名是否正确 (例: CV-EX-1)。\n
添加: 左键 = 普通难度,右键 = 突袭难度。\n
清除: 左键 = 全部清空,右键 = 仅移除未激活任务。\n
请在能看到目标关卡名的界面启动,不支持跨章节导航。\n
遇到理智不足、战斗失败、未能三星结算时将自动中止。
</system:String>
<system:String x:Key="CopilotFileReadError">读取文件失败!</system:String>
<system:String x:Key="CopilotNoFound">未找到对应作业!</system:String>

View File

@@ -843,14 +843,21 @@ C:\\leidian\\LDPlayer9。\n
<system:String x:Key="ThanksForLikeWebJson">感謝評價!\n網頁已經開放評論區歡迎前往留下你的評論</system:String>
<system:String x:Key="AutoSquad">自動編隊</system:String>
<system:String x:Key="AutoSquadTip">自動編隊可能無法辨識 「特別關注」 的{key=Operator}</system:String>
<system:String x:Key="SupportUnitUsage">助戰幹員借用策略</system:String>
<system:String x:Key="SupportUnitUsage">助戰</system:String>
<system:String x:Key="SupportUnitUsage.Tip">缺一個還能用用,缺兩個以上還是換份作業吧</system:String>
<system:String x:Key="SupportUnitUsage.None">不借用</system:String>
<system:String x:Key="SupportUnitUsage.WhenNeeded">僅用於補漏</system:String>
<system:String x:Key="SupportUnitUsage.Random">隨機</system:String>
<system:String x:Key="AddTrust">補充低信賴{key=Operator}</system:String>
<system:String x:Key="Copilot.IgnoreRequirements">忽略{key=Operator}屬性要求</system:String>
<system:String x:Key="Copilot.IgnoreRequirements.Tip" xml:space="preserve">某些作業需要特定模組等作為前置條件
勾選此項將跳過這些檢查,但可能導致作業無法正常執行</system:String>
<system:String x:Key="AddUserAdditional">追加自定{key=Operator}</system:String>
<system:String x:Key="AddUserAdditionalTip">使用 「;」 作為分隔符,用 「,」 分隔{key=Operator}姓名和技能,例:史爾特爾,3;艾雅法拉,1</system:String>
<system:String x:Key="UserAdditional.OperatorName">{key=Operator}名</system:String>
<system:String x:Key="UserAdditional.Skill">技能</system:String>
<system:String x:Key="UserAdditional.Action">操作</system:String>
<system:String x:Key="UserAdditional.Add">添加</system:String>
<system:String x:Key="UseCopilotList">戰鬥列表</system:String>
<system:String x:Key="UseCopilotListTip" xml:space="preserve">僅支援以下模式:
1. {key=MainStage}: 同一章節內導航
@@ -859,7 +866,7 @@ C:\\leidian\\LDPlayer9。\n
4. {key=ParadoxSimulation}: 從{key=Operator}列表啟動
請在對應介面啟動,不支援跨章節導航
- 當 「{key=UseCopilotList}」 啟用後, 選擇單一作業時會自動新增至 「{key=UseCopilotList}」</system:String>
當 「{key=UseCopilotList}」 啟用後, 選擇單一作業時會自動新增至 「{key=UseCopilotList}」</system:String>
<system:String x:Key="CopilotTaskRaidStage">(突襲)</system:String>
<system:String x:Key="CopilotAddTask" xml:space="preserve">左鍵加入普通難度
右鍵加入突襲難度</system:String>
@@ -902,14 +909,14 @@ C:\\leidian\\LDPlayer9。\n
5. 使用好友助戰時,請關閉 「{key=AutoSquad}」 和 「{key=UseCopilotList}」,手動選擇{key=Operator}後,在編隊介面右下角存在 「開始行動」 按鈕的介面啟動。\n\n
6. {key=Operator}若被標記為 「特別關注」,可能影響 「{key=AutoSquad}」 的辨識與選擇。建議使用 「{key=AutoSquad}」 時移除關注,或在報錯後關閉 「{key=AutoSquad}」,依據提示手動補充缺少的{key=Operator}。\n\n
7. Copilot 作業站的神秘代碼可透過輸入框右側的貼上按鈕貼上:\n
- 點選第 2 個按鈕 = 新增作業。\n
- 點選第3個按鈕 = 新增作業集。\n\n
點選第 2 個按鈕 = 新增作業。\n
點選第 3 個按鈕 = 新增作業集。\n\n
8. {key=UseCopilotList}:\n
- 選擇作業後,檢查下方關卡名是否正確 (例: CV-EX-1)。\n
- 加入: 左鍵 = 普通難度,右鍵 = 突襲難度。\n
- 清除: 左鍵 = 全部清空,右鍵 = 僅移除未啟用任務。\n
- 請在能看到目標關卡名的介面啟動,不支援跨章節導航。\n
- 遇到理智不足、戰鬥失敗、未能三星結算時將會自動中止。
選擇作業後,檢查下方關卡名是否正確 (例: CV-EX-1)。\n
加入: 左鍵 = 普通難度,右鍵 = 突襲難度。\n
清除: 左鍵 = 全部清空,右鍵 = 僅移除未啟用任務。\n
請在能看到目標關卡名的介面啟動,不支援跨章節導航。\n
遇到理智不足、戰鬥失敗、未能三星結算時將會自動中止。
</system:String>
<system:String x:Key="CopilotFileReadError">讀取檔案失敗!</system:String>
<system:String x:Key="CopilotNoFound">未找到對應作業!</system:String>

View File

@@ -317,7 +317,7 @@ public partial class CopilotViewModel : Screen
}
}
private string _userAdditional = ConfigurationHelper.GetValue(ConfigurationKeys.CopilotUserAdditional, string.Empty).Replace("", ",").Replace("", ";").Trim();
private string _userAdditional = ConfigurationHelper.GetValue(ConfigurationKeys.CopilotUserAdditional, string.Empty).Trim();
/// <summary>
/// Gets or sets a value indicating whether to use auto-formation.
@@ -327,12 +327,239 @@ public partial class CopilotViewModel : Screen
get => _userAdditional;
set
{
value = value.Replace("", ",").Replace("", ";").Trim();
value = value.Trim();
SetAndNotify(ref _userAdditional, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CopilotUserAdditional, value);
}
}
private bool _isUserAdditionalPopupOpen;
/// <summary>
/// Gets or sets a value indicating whether the UserAdditional popup is open.
/// </summary>
public bool IsUserAdditionalPopupOpen
{
get => _isUserAdditionalPopupOpen;
set => SetAndNotify(ref _isUserAdditionalPopupOpen, value);
}
/// <summary>
/// Gets the view models of UserAdditional items.
/// </summary>
public ObservableCollection<UserAdditionalItemViewModel> UserAdditionalItems { get; } = [];
/// <summary>
/// Opens the UserAdditional popup for editing.
/// </summary>
public void OpenUserAdditionalPopup()
{
// 清空列表
UserAdditionalItems.Clear();
// 优先按 JSON 反序列化
if (!string.IsNullOrWhiteSpace(UserAdditional))
{
try
{
var list = JsonConvert.DeserializeObject<List<UserAdditional>>(UserAdditional) ?? [];
foreach (var op in list)
{
if (string.IsNullOrWhiteSpace(op.Name))
{
continue;
}
int skill = op.Skill;
if (skill < 1)
{
skill = 1;
}
else if (skill > 3)
{
skill = 3;
}
var item = new UserAdditionalItemViewModel
{
Name = op.Name,
Skill = skill,
Module = op.Module,
};
UserAdditionalItems.Add(item);
}
}
catch
{
// 兼容旧格式:以 ; 和 , 解析 "name,skill;name,skill" 形式
try
{
Regex regex = new(@"(?<=;)(?<name>[^,;]+)(?:, *(?<skill>\d))?(?=;)", RegexOptions.Compiled);
var matches = regex.Matches(";" + UserAdditional + ";");
foreach (Match match in matches)
{
var name = match.Groups["name"].Value.Trim();
var skillStr = match.Groups["skill"].Value;
int skill = string.IsNullOrEmpty(skillStr) ? 1 : int.Parse(skillStr);
if (skill < 1)
{
skill = 1;
}
else if (skill > 3)
{
skill = 3;
}
var item = new UserAdditionalItemViewModel
{
Name = name,
Skill = skill,
Module = 0,
};
UserAdditionalItems.Add(item);
}
}
catch
{
// ignore
}
}
}
// 如果列表为空,添加一行空行
if (UserAdditionalItems.Count == 0)
{
var newItem = new UserAdditionalItemViewModel { Name = string.Empty, Skill = 1, Module = 0 };
UserAdditionalItems.Add(newItem);
}
IsUserAdditionalPopupOpen = true;
}
/// <summary>
/// Saves the UserAdditional value from the popup.
/// </summary>
public void SaveUserAdditional()
{
// 将列表转换为 UserAdditional 并序列化为 JSON
var list = new List<UserAdditional>();
foreach (var item in UserAdditionalItems)
{
if (string.IsNullOrWhiteSpace(item.Name))
{
continue; // 跳过空行
}
int skill = item.Skill;
if (skill < 1)
{
skill = 1;
}
else if (skill > 3)
{
skill = 3;
}
list.Add(new UserAdditional
{
Name = item.Name.Trim(),
Skill = skill,
Module = item.Module,
});
}
UserAdditional = list.Count > 0
? JsonConvert.SerializeObject(list, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore })
: string.Empty;
IsUserAdditionalPopupOpen = false;
}
/// <summary>
/// Cancels editing UserAdditional and closes the popup.
/// </summary>
public void CancelUserAdditionalEdit()
{
IsUserAdditionalPopupOpen = false;
}
/// <summary>
/// Gets a value indicating whether can add a new UserAdditional item.
/// </summary>
public bool CanAddUserAdditionalItem => UserAdditionalItems.All(item => !string.IsNullOrWhiteSpace(item.Name));
/// <summary>
/// Adds a new UserAdditional item.
/// </summary>
public void AddUserAdditionalItem()
{
if (!CanAddUserAdditionalItem)
{
return;
}
var newItem = new UserAdditionalItemViewModel { Name = string.Empty, Skill = 1, Module = 0 };
UserAdditionalItems.Add(newItem);
}
/// <summary>
/// Removes a UserAdditional item.
/// </summary>
/// <param name="item">The item to remove.</param>
public void RemoveUserAdditionalItem(UserAdditionalItemViewModel item)
{
if (item != null && UserAdditionalItems.Contains(item))
{
UserAdditionalItems.Remove(item);
}
}
public static Dictionary<string, int> ModuleMapping { get; } = new()
{
{ LocalizationHelper.GetString("CopilotWithoutModule"), 0 },
{ "χ", 1 },
{ "γ", 2 },
{ "α", 3 },
{ "Δ", 4 },
};
public class UserAdditionalItemViewModel : PropertyChangedBase
{
private string _name = string.Empty;
/// <summary>
/// Gets or sets the operator name.
/// </summary>
public string Name
{
get => _name;
set => SetAndNotify(ref _name, value);
}
private int _skill;
/// <summary>
/// Gets or sets the skill number.
/// </summary>
public int Skill
{
get => _skill;
set => SetAndNotify(ref _skill, value);
}
private int _module;
/// <summary>
/// Gets or sets the module number.
/// -1: 不切换模组 / 无要求, 0: 不使用模组, 1-4: 不同模组
/// </summary>
public int Module
{
get => _module;
set => SetAndNotify(ref _module, value);
}
}
private bool _useFormation;
public bool UseFormation
@@ -351,7 +578,7 @@ public partial class CopilotViewModel : Screen
private int _formationIndex = ConfigurationHelper.GetValue(ConfigurationKeys.CopilotSelectFormation, 1);
public int SelectFormation
public int FormationIndex
{
get => _formationIndex;
set
@@ -361,6 +588,14 @@ public partial class CopilotViewModel : Screen
}
}
private bool _useSupportUnitUsage;
public bool UseSupportUnitUsage
{
get => _useSupportUnitUsage;
set => SetAndNotify(ref _useSupportUnitUsage, value);
}
private int _supportUnitUsage = ConfigurationHelper.GetValue(ConfigurationKeys.CopilotSupportUnitUsage, 0);
public int SupportUnitUsage
@@ -375,7 +610,7 @@ public partial class CopilotViewModel : Screen
public List<GenericCombinedData<int>> SupportUnitUsageList { get; } =
[
new() { Display = LocalizationHelper.GetString("SupportUnitUsage.None"), Value = 0 },
/* new() { Display = LocalizationHelper.GetString("SupportUnitUsage.None"), Value = 0 }, */
new() { Display = LocalizationHelper.GetString("SupportUnitUsage.WhenNeeded"), Value = 1 },
new() { Display = LocalizationHelper.GetString("SupportUnitUsage.Random"), Value = 3 },
];
@@ -1359,13 +1594,70 @@ public partial class CopilotViewModel : Screen
return;
}
Regex regex = new Regex(@"(?<=;)(?<name>[^,;]+)(?:, *(?<skill>\d))?(?=;)", RegexOptions.Compiled);
var userAdditional = regex.Matches(";" + UserAdditional + ";").ToList().Select(match => new UserAdditional
// 反序列化自定义追加干员列表JSON兼容旧格式
IEnumerable<UserAdditional> userAdditional = [];
if (!string.IsNullOrWhiteSpace(UserAdditional))
{
Name = match.Groups[1].Value.Trim(),
Skill = string.IsNullOrEmpty(match.Groups[2].Value) ? 0 : int.Parse(match.Groups[2].Value),
});
try
{
var list = JsonConvert.DeserializeObject<List<UserAdditional>>(UserAdditional) ?? [];
foreach (var op in list)
{
if (string.IsNullOrWhiteSpace(op.Name))
{
continue;
}
int skill = op.Skill;
if (skill < 1)
{
skill = 1;
}
else if (skill > 3)
{
skill = 3;
}
op.Skill = skill;
}
userAdditional = list.Where(op => !string.IsNullOrWhiteSpace(op.Name));
}
catch
{
// 兼容旧格式:以 ; 和 , 解析 "name,skill;name,skill" 形式
try
{
Regex regex = new(@"(?<=;)(?<name>[^,;]+)(?:, *(?<skill>\d))?(?=;)", RegexOptions.Compiled);
var matches = regex.Matches(";" + UserAdditional + ";").ToList();
userAdditional = matches.Select(match =>
{
var name = match.Groups[1].Value.Trim();
var skillStr = match.Groups[2].Value;
int skill = string.IsNullOrEmpty(skillStr) ? 1 : int.Parse(skillStr);
if (skill < 1)
{
skill = 1;
}
else if (skill > 3)
{
skill = 3;
}
return new UserAdditional
{
Name = name,
Skill = skill,
Module = 0,
};
}).Where(op => !string.IsNullOrWhiteSpace(op.Name));
}
catch
{
userAdditional = [];
}
}
}
bool ret = true;
try
@@ -1383,13 +1675,13 @@ public partial class CopilotViewModel : Screen
var task = new AsstCopilotTask()
{
MultiTasks = [.. t],
Formation = _form,
SupportUnitUsage = _supportUnitUsage,
AddTrust = _addTrust,
IgnoreRequirements = _ignoreRequirements,
UserAdditionals = AddUserAdditional ? userAdditional.ToList() : [],
UseSanityPotion = _useSanityPotion,
FormationIndex = UseFormation ? _formationIndex : 0,
Formation = Form,
SupportUnitUsage = UseSupportUnitUsage ? SupportUnitUsage : 0,
AddTrust = AddTrust,
IgnoreRequirements = IgnoreRequirements,
UserAdditionals = AddUserAdditional ? [.. userAdditional] : [],
UseSanityPotion = UseSanityPotion,
FormationIndex = UseFormation ? FormationIndex : 0,
};
ret = Instances.AsstProxy.AsstAppendTaskWithEncoding(AsstProxy.TaskType.Copilot, task);
@@ -1414,14 +1706,14 @@ public partial class CopilotViewModel : Screen
var task = new AsstCopilotTask()
{
FileName = IsDataFromWeb ? TempCopilotFile : Filename,
Formation = _form,
SupportUnitUsage = _supportUnitUsage,
AddTrust = _addTrust,
IgnoreRequirements = _ignoreRequirements,
UserAdditionals = AddUserAdditional ? userAdditional.ToList() : [],
Formation = Form,
SupportUnitUsage = SupportUnitUsage,
AddTrust = AddTrust,
IgnoreRequirements = IgnoreRequirements,
UserAdditionals = AddUserAdditional ? [.. userAdditional] : [],
LoopTimes = Loop ? LoopTimes : 1,
UseSanityPotion = _useSanityPotion,
FormationIndex = UseFormation ? _formationIndex : 0,
UseSanityPotion = false,
FormationIndex = UseFormation ? FormationIndex : 0,
};
ret = Instances.AsstProxy.AsstAppendTaskWithEncoding(AsstProxy.TaskType.Copilot, _taskType, task.Serialize().Params);
ret = ret && Instances.AsstProxy.AsstStart();

View File

@@ -27,15 +27,15 @@
mc:Ignorable="d">
<Grid Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="4*" />
</Grid.ColumnDefinitions>
<Grid>
<Grid Grid.ColumnSpan="{c:Binding 'UseCopilotList ? 3 : 2'}" d:Grid.ColumnSpan="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel
@@ -76,7 +76,7 @@
<TabItem Header="{DynamicResource ParadoxSimulation}" />
<TabItem Header="{DynamicResource OtherActivityStage}" />
</TabControl>
<Grid Width="300" Margin="0,5">
<Grid Margin="0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
@@ -147,328 +147,442 @@
</Grid>
</StackPanel>
<StackPanel
x:Name="RootPanel"
Grid.Row="1"
HorizontalAlignment="Center"
IsEnabled="{Binding Idle}">
<StackPanel HorizontalAlignment="Center">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Vertical" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Form}" Value="False" />
<Condition Binding="{Binding UseCopilotList}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="Orientation" Value="Horizontal" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<StackPanel
<Grid Grid.Row="1" HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid
Grid.Row="0"
Margin="0,5,0,10"
HorizontalAlignment="Center"
Orientation="Horizontal"
Visibility="{c:Binding 'CopilotTabIndex == 0 or CopilotTabIndex == 3'}">
VerticalAlignment="Bottom">
<Button
Width="120"
Height="50"
Command="{s:Action Start}"
Content="{DynamicResource Start}"
IsEnabled="{c:Binding 'StartEnabled and Inited'}"
Visibility="{c:Binding Idle}" />
<Button
Width="120"
Height="50"
Command="{s:Action Stop}"
Content="{DynamicResource Stop}"
IsEnabled="{c:Binding Inited}"
Visibility="{c:Binding !Idle}" />
</Grid>
<StackPanel
Grid.Row="1"
HorizontalAlignment="Center"
IsEnabled="{Binding Idle}">
<!-- AutoSquad -->
<StackPanel
Margin="2.5,5"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<CheckBox Content="{DynamicResource AutoSquad}" IsChecked="{Binding Form}" />
Orientation="Horizontal"
Visibility="{c:Binding 'CopilotTabIndex == 0 or CopilotTabIndex == 3'}">
<CheckBox
Height="20"
Content="{DynamicResource AutoSquad}"
IsChecked="{Binding Form}" />
<controls:TooltipBlock TooltipText="{DynamicResource AutoSquadTip}" />
</StackPanel>
<StackPanel
Margin="2.5,5"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal"
Visibility="{c:Binding Form}">
<!-- UseFormation -->
<StackPanel Orientation="Horizontal" Visibility="{c:Binding '(CopilotTabIndex == 0 or CopilotTabIndex == 3) and Form'}">
<CheckBox
VerticalAlignment="Center"
Margin="2.5,5"
Content="{DynamicResource UseFormation}"
IsChecked="{c:Binding UseFormation}" />
<ComboBox
Margin="2.5,-10,0,-10"
Padding="2.5,-1,0,0"
VerticalAlignment="Center"
BorderThickness="0"
Height="20"
DisplayMemberPath="Display"
ItemsSource="{Binding FormationSelectList}"
SelectedValue="{Binding SelectFormation}"
SelectedValue="{Binding FormationIndex}"
SelectedValuePath="Value"
Visibility="{c:Binding UseFormation}" />
</StackPanel>
</StackPanel>
<StackPanel HorizontalAlignment="Center" Visibility="{c:Binding 'Form and (CopilotTabIndex == 0 or CopilotTabIndex == 3)'}">
<CheckBox
Margin="2.5,5"
HorizontalAlignment="Center"
Content="{DynamicResource Copilot.IgnoreRequirements}"
IsChecked="{Binding IgnoreRequirements}" />
<StackPanel HorizontalAlignment="Center">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Vertical" />
<Style.Triggers>
<DataTrigger Binding="{Binding AddUserAdditional}" Value="False">
<Setter Property="Orientation" Value="Horizontal" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<CheckBox
Margin="2.5,5"
HorizontalAlignment="Center"
Content="{DynamicResource AddTrust}"
IsChecked="{Binding AddTrust}" />
<StackPanel
Margin="2.5,5"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<CheckBox Content="{DynamicResource AddUserAdditional}" IsChecked="{Binding AddUserAdditional}" />
<TextBox
Height="20"
MinWidth="100"
MaxWidth="140"
Margin="2.5,-10"
VerticalContentAlignment="Center"
Text="{Binding UserAdditional, UpdateSourceTrigger=LostFocus}"
Visibility="{c:Binding AddUserAdditional}" />
<controls:TooltipBlock TooltipText="{DynamicResource AddUserAdditionalTip}" Visibility="{c:Binding AddUserAdditional}" />
</StackPanel>
</StackPanel>
<hc:ComboBox
Width="210"
Margin="2.5,5"
hc:InfoElement.Title="{DynamicResource SupportUnitUsage}"
hc:InfoElement.TitlePlacement="Left"
DisplayMemberPath="Display"
ItemsSource="{Binding SupportUnitUsageList}"
SelectedValue="{Binding SupportUnitUsage}"
SelectedValuePath="Value" />
</StackPanel>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<!-- IgnoreRequirements -->
<StackPanel
Margin="2.5,5"
Orientation="Horizontal"
Visibility="{c:Binding 'Form and (CopilotTabIndex == 0 or CopilotTabIndex == 3)'}">
<CheckBox Content="{DynamicResource Copilot.IgnoreRequirements}" IsChecked="{Binding IgnoreRequirements}" />
<controls:TooltipBlock TooltipText="{DynamicResource Copilot.IgnoreRequirements.Tip}" />
</StackPanel>
<!-- SupportUnitUsage -->
<WrapPanel Orientation="Horizontal" Visibility="{c:Binding 'Form and (CopilotTabIndex == 0 or CopilotTabIndex == 3)'}">
<CheckBox
Margin="2.5,5"
Content="{DynamicResource SupportUnitUsage}"
IsChecked="{Binding UseSupportUnitUsage}" />
<StackPanel Orientation="Horizontal">
<hc:ComboBox
Height="20"
MinWidth="100"
Margin="2.5,0"
DisplayMemberPath="Display"
ItemsSource="{Binding SupportUnitUsageList}"
SelectedValue="{Binding SupportUnitUsage}"
SelectedValuePath="Value"
Visibility="{c:Binding UseSupportUnitUsage}" />
<controls:TooltipBlock TooltipText="{DynamicResource SupportUnitUsage.Tip}" />
</StackPanel>
</WrapPanel>
<!-- AddTrust -->
<CheckBox
Margin="2.5,5"
Content="{DynamicResource AddTrust}"
IsChecked="{Binding AddTrust}"
Visibility="{c:Binding 'Form and (CopilotTabIndex == 0 or CopilotTabIndex == 3)'}" />
<!-- AddUserAdditional -->
<WrapPanel Orientation="Horizontal" Visibility="{c:Binding 'Form and (CopilotTabIndex == 0 or CopilotTabIndex == 3)'}">
<CheckBox
Margin="2.5,5"
Content="{DynamicResource AddUserAdditional}"
IsChecked="{Binding AddUserAdditional}" />
<StackPanel Orientation="Horizontal">
<Button
x:Name="UserAdditionalButton"
Width="15"
Height="15"
MinWidth="20"
Margin="2.5,5,0,5"
Padding="0"
hc:IconElement.Geometry="{StaticResource ConfigGeometry}"
BorderThickness="0"
Command="{s:Action OpenUserAdditionalPopup}"
ToolTip="{Binding UserAdditional}" />
<controls:TooltipBlock TooltipText="{DynamicResource AddUserAdditionalTip}" />
<Popup
IsOpen="{Binding IsUserAdditionalPopupOpen}"
Placement="Center"
PlacementTarget="{Binding ElementName=UserAdditionalButton}"
PopupAnimation="Slide"
StaysOpen="False">
<Border
MaxWidth="600"
MaxHeight="500"
Padding="10"
Background="{DynamicResource RegionBrush}"
BorderBrush="{DynamicResource BorderBrush}"
BorderThickness="1"
CornerRadius="4">
<StackPanel>
<TextBlock Margin="0,0,0,5" Text="{DynamicResource AddUserAdditional}" />
<DataGrid
x:Name="UserAdditionalDataGrid"
MaxHeight="350"
AutoGenerateColumns="False"
Background="{DynamicResource RegionBrush}"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserResizeColumns="False"
CanUserResizeRows="False"
HeadersVisibility="Column"
ItemsSource="{Binding UserAdditionalItems}"
RowHeight="40"
SelectionMode="Single">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background" Value="{DynamicResource RegionBrushOpacity25}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{DynamicResource RegionBrushOpacity25}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource MouseOverRegionBrushOpacity75}" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn
Width="Auto"
Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
Foreground="{DynamicResource PrimaryTextBrush}"
Header="{DynamicResource UserAdditional.OperatorName}" />
<DataGridTemplateColumn Width="80" Header="{DynamicResource UserAdditional.Skill}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<hc:NumericUpDown
Height="20"
InputMethod.IsInputMethodEnabled="False"
Maximum="3"
Minimum="1"
Value="{Binding Skill, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="140" Header="{DynamicResource CopilotModule}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
Height="24"
DisplayMemberPath="Key"
ItemsSource="{Binding DataContext.ModuleMapping, RelativeSource={RelativeSource AncestorType=DataGrid}}"
SelectedValue="{Binding Module, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Value">
<!-- TODO: 后续可改为绑定到单独的 Module 选项列表 -->
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="Auto" Header="{DynamicResource UserAdditional.Action}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button
Width="20"
Height="20"
MinWidth="20"
Padding="0"
hc:IconElement.Geometry="{StaticResource CloseGeometry}"
BorderThickness="0"
Command="{s:Action RemoveUserAdditionalItem}"
CommandParameter="{Binding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Grid Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button
Grid.Column="0"
Width="80"
Height="25"
Padding="0"
HorizontalAlignment="Left"
Command="{s:Action AddUserAdditionalItem}"
Content="{DynamicResource UserAdditional.Add}" />
<Button
Grid.Column="1"
Width="60"
Height="25"
Padding="0"
Command="{s:Action SaveUserAdditional}"
Content="{DynamicResource Ok}" />
<Button
Grid.Column="2"
Width="60"
Height="25"
Margin="5,0,0,0"
Padding="0"
Command="{s:Action CancelUserAdditionalEdit}"
Content="{DynamicResource Cancel}" />
</Grid>
</StackPanel>
</Border>
</Popup>
</StackPanel>
</WrapPanel>
<!-- UseCopilotList -->
<StackPanel
Margin="2.5,5"
VerticalAlignment="Center"
Orientation="Horizontal"
Visibility="{c:Binding 'CopilotTabIndex == 0 or CopilotTabIndex == 2'}">
<CheckBox Content="{DynamicResource UseCopilotList}" IsChecked="{Binding UseCopilotList}" />
<controls:TooltipBlock TooltipText="{DynamicResource UseCopilotListTip}" />
</StackPanel>
<!-- UseSanityPotion -->
<CheckBox
Margin="2.5,5"
Content="{DynamicResource UseSanityPotion}"
IsChecked="{Binding UseSanityPotion}"
Visibility="{c:Binding 'UseCopilotList and CopilotTabIndex == 0'}" />
<!-- Loop / LoopTimes -->
<StackPanel Orientation="Horizontal" Visibility="{c:Binding '!UseCopilotList and CopilotTabIndex != 2'}">
<CheckBox
Margin="2.5,5"
Content="{DynamicResource LoopTimes}"
IsChecked="{Binding Loop}" />
<hc:NumericUpDown
Height="20"
InputMethod.IsInputMethodEnabled="False"
Maximum="9999"
Minimum="0"
Value="{Binding LoopTimes}" />
</StackPanel>
</StackPanel>
</StackPanel>
<StackPanel
Margin="2.5,5"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal"
Visibility="{c:Binding '!UseCopilotList and CopilotTabIndex != 2'}">
<CheckBox
VerticalContentAlignment="Center"
Content="{DynamicResource LoopTimes}"
IsChecked="{Binding Loop}" />
<hc:NumericUpDown
Height="20"
Margin="5,-10,0,-10"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
InputMethod.IsInputMethodEnabled="False"
Maximum="9999"
Minimum="0"
Value="{Binding LoopTimes}" />
</StackPanel>
</StackPanel>
</Grid>
<Grid
Grid.Row="2"
Width="200"
Margin="0,7,0,0"
Visibility="{c:Binding 'UseCopilotList and (CopilotTabIndex == 0 or CopilotTabIndex == 2)'}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ListBox
x:Name="CopilotList"
Grid.Row="0"
Grid.ColumnSpan="4"
HorizontalContentAlignment="Stretch"
dd:DragDrop.IsDragSource="{Binding Idle}"
dd:DragDrop.IsDropTarget="{Binding Idle}"
hc:BorderElement.CornerRadius="4,4,0,0"
properties:AutoScroll.AutoScroll="True"
BorderThickness="1,1,1,0"
DragDrop.Drop="{s:Action CopilotItemIndexChanged}"
IsEnabled="{c:Binding StartEnabled}"
ItemsSource="{Binding Path=CopilotItemViewModels}"
Style="{DynamicResource NoSelectedHighlightListBoxStyle}"
ToolTip="{DynamicResource LabelSequenceTip}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0"
IsChecked="{Binding IsChecked}"
IsEnabled="{Binding ElementName=CopilotList, Path=DataContext.Idle}"
IsHitTestVisible="{Binding ElementName=CopilotList, Path=DataContext.Idle}"
ToolTip="{c:Binding CopilotId}">
<TextBlock Text="{Binding Name}" ToolTip="{Binding CopilotId}" />
</CheckBox>
<TextBlock
Grid.Column="1"
MinWidth="35"
VerticalAlignment="Center"
Opacity="{c:Binding 'DataContext.Idle ? 1 : 0.5',
RelativeSource={RelativeSource AncestorType=ListBox}}"
Text="{DynamicResource CopilotTaskRaidStage}"
Visibility="{c:Binding IsRaid}" />
<Button
Grid.Column="2"
Margin="0"
Padding="5,6,5,6"
hc:IconElement.Geometry="{StaticResource ConfigGeometry}"
hc:VisualElement.HighlightBackground="Transparent"
hc:VisualElement.HighlightForeground="{DynamicResource PrimaryBrush}"
Background="Transparent"
BorderThickness="0"
Foreground="{DynamicResource SecondaryTextBrush}"
IsEnabled="{Binding ElementName=CopilotList, Path=DataContext.Idle}"
MouseRightButtonUp="{s:Action SelectCopilotTask}"
PreviewMouseLeftButtonUp="{s:Action SelectCopilotTask}"
Tag="{c:Binding Index}" />
<Button
Grid.Column="3"
Margin="0"
Padding="5,0,10,0"
hc:IconElement.Geometry="{StaticResource CloseGeometry}"
hc:VisualElement.HighlightBackground="Transparent"
hc:VisualElement.HighlightForeground="{DynamicResource PrimaryBrush}"
Background="Transparent"
BorderThickness="0"
Command="{s:Action DeleteCopilotTask}"
CommandParameter="{c:Binding Index}"
IsEnabled="{Binding ElementName=CopilotList, Path=DataContext.Idle}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Row="1" Grid.Column="1">
<hc:TextBox
Height="30"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
hc:BorderElement.CornerRadius="0"
hc:InfoElement.Placeholder="{DynamicResource CopilotTaskName}"
IsEnabled="{Binding Idle}"
MaxLines="1"
Text="{Binding CopilotTaskName, UpdateSourceTrigger=LostFocus}" />
<controls:TooltipBlock
HorizontalAlignment="Right"
VerticalAlignment="Top"
NormalOpacity="0.25"
TooltipText="{DynamicResource CopilotTaskNameTip}" />
</Grid>
<Grid Grid.Row="1" Grid.Column="0">
<Button
Height="30"
MinWidth="30"
hc:BorderElement.CornerRadius="0,0,0,4"
hc:IconElement.Geometry="{StaticResource FolderAdd20Regular}"
BorderThickness="1,1,0,1"
Command="{s:Action ImportFiles}"
IsEnabled="{c:Binding '(Idle) and (StartEnabled)'}" />
<controls:TooltipBlock
HorizontalAlignment="Right"
VerticalAlignment="Top"
MouseLeftButtonDown="{s:Action ImportFiles}"
NormalOpacity="0.25"
TooltipText="{DynamicResource ImportFilesTip}" />
</Grid>
<Grid Grid.Row="1" Grid.Column="2">
<Button
Height="30"
MinWidth="30"
hc:BorderElement.CornerRadius="0"
hc:IconElement.Geometry="{StaticResource Add20Regular}"
BorderThickness="0,1"
Command="{s:Action AddCopilotTask}"
IsEnabled="{c:Binding '(Idle) and (StartEnabled)'}"
MouseRightButtonUp="{s:Action AddCopilotTask_Adverse}" />
<controls:TooltipBlock
HorizontalAlignment="Right"
VerticalAlignment="Top"
MouseLeftButtonDown="{s:Action AddCopilotTask}"
MouseRightButtonUp="{s:Action AddCopilotTask_Adverse}"
NormalOpacity="0.25"
TooltipText="{DynamicResource CopilotAddTask}" />
</Grid>
<Grid Grid.Row="1" Grid.Column="3">
<Button
Height="30"
MinWidth="30"
hc:BorderElement.CornerRadius="0,0,4,0"
hc:IconElement.Geometry="{StaticResource DismissSquareMultiple20Regular}"
BorderThickness="1"
Command="{s:Action ClearCopilotTask}"
Foreground="{DynamicResource DangerBrush}"
IsEnabled="{c:Binding Idle}"
MouseRightButtonUp="{s:Action CleanUnableCopilotTask}" />
<controls:TooltipBlock
HorizontalAlignment="Right"
VerticalAlignment="Top"
MouseLeftButtonDown="{s:Action ClearCopilotTask}"
MouseRightButtonUp="{s:Action CleanUnableCopilotTask}"
NormalOpacity="0.25"
TooltipText="{DynamicResource CopilotClearTask}" />
<Grid
Grid.Column="1"
Margin="5,0,0,10"
Visibility="{c:Binding 'UseCopilotList and (CopilotTabIndex == 0 or CopilotTabIndex == 2)'}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ListBox
x:Name="CopilotList"
Grid.Row="0"
Grid.ColumnSpan="4"
HorizontalContentAlignment="Stretch"
d:ItemsSource="{d:SampleData ItemCount=7}"
dd:DragDrop.IsDragSource="{Binding Idle}"
dd:DragDrop.IsDropTarget="{Binding Idle}"
hc:BorderElement.CornerRadius="4,4,0,0"
properties:AutoScroll.AutoScroll="True"
BorderThickness="1,1,1,0"
DragDrop.Drop="{s:Action CopilotItemIndexChanged}"
IsEnabled="{c:Binding StartEnabled}"
ItemsSource="{Binding Path=CopilotItemViewModels}"
Style="{DynamicResource NoSelectedHighlightListBoxStyle}"
ToolTip="{DynamicResource LabelSequenceTip}">
<ListBox.ItemContainerStyle>
<Style BasedOn="{StaticResource NoSelectedHighlightListBoxItemStyle}" TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsRaid}" Value="True">
<Setter Property="Background" Value="#33FF0000" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0"
IsChecked="{Binding IsChecked}"
IsEnabled="{Binding ElementName=CopilotList, Path=DataContext.Idle}"
IsHitTestVisible="{Binding ElementName=CopilotList, Path=DataContext.Idle}"
ToolTip="{c:Binding CopilotId}">
<TextBlock Text="{Binding Name}" ToolTip="{Binding CopilotId}" />
</CheckBox>
<Button
Grid.Column="1"
Margin="0"
Padding="5,6"
hc:IconElement.Geometry="{StaticResource ConfigGeometry}"
hc:VisualElement.HighlightBackground="Transparent"
hc:VisualElement.HighlightForeground="{DynamicResource PrimaryBrush}"
Background="Transparent"
BorderThickness="0"
Foreground="{DynamicResource SecondaryTextBrush}"
IsEnabled="{Binding ElementName=CopilotList, Path=DataContext.Idle}"
MouseRightButtonUp="{s:Action SelectCopilotTask}"
PreviewMouseLeftButtonUp="{s:Action SelectCopilotTask}"
Tag="{c:Binding Index}" />
<Button
Grid.Column="2"
Margin="0"
Padding="5,0,10,0"
hc:IconElement.Geometry="{StaticResource CloseGeometry}"
hc:VisualElement.HighlightBackground="Transparent"
hc:VisualElement.HighlightForeground="{DynamicResource PrimaryBrush}"
Background="Transparent"
BorderThickness="0"
Command="{s:Action DeleteCopilotTask}"
CommandParameter="{c:Binding Index}"
IsEnabled="{Binding ElementName=CopilotList, Path=DataContext.Idle}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Row="1" Grid.Column="1">
<hc:TextBox
Height="30"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
hc:BorderElement.CornerRadius="0"
hc:InfoElement.Placeholder="{DynamicResource CopilotTaskName}"
IsEnabled="{Binding Idle}"
MaxLines="1"
Text="{Binding CopilotTaskName, UpdateSourceTrigger=LostFocus}" />
<controls:TooltipBlock
HorizontalAlignment="Right"
VerticalAlignment="Top"
NormalOpacity="0.25"
TooltipText="{DynamicResource CopilotTaskNameTip}" />
</Grid>
<Grid Grid.Row="1" Grid.Column="0">
<Button
Height="30"
MinWidth="30"
hc:BorderElement.CornerRadius="0,0,0,4"
hc:IconElement.Geometry="{StaticResource FolderAdd20Regular}"
BorderThickness="1,1,0,1"
Command="{s:Action ImportFiles}"
IsEnabled="{c:Binding '(Idle) and (StartEnabled)'}" />
<controls:TooltipBlock
HorizontalAlignment="Right"
VerticalAlignment="Top"
MouseLeftButtonDown="{s:Action ImportFiles}"
NormalOpacity="0.25"
TooltipText="{DynamicResource ImportFilesTip}" />
</Grid>
<Grid Grid.Row="1" Grid.Column="2">
<Button
Height="30"
MinWidth="30"
hc:BorderElement.CornerRadius="0"
hc:IconElement.Geometry="{StaticResource Add20Regular}"
BorderThickness="0,1"
Command="{s:Action AddCopilotTask}"
IsEnabled="{c:Binding '(Idle) and (StartEnabled)'}"
MouseRightButtonUp="{s:Action AddCopilotTask_Adverse}" />
<controls:TooltipBlock
HorizontalAlignment="Right"
VerticalAlignment="Top"
MouseLeftButtonDown="{s:Action AddCopilotTask}"
MouseRightButtonUp="{s:Action AddCopilotTask_Adverse}"
NormalOpacity="0.25"
TooltipText="{DynamicResource CopilotAddTask}" />
</Grid>
<Grid Grid.Row="1" Grid.Column="3">
<Button
Height="30"
MinWidth="30"
hc:BorderElement.CornerRadius="0,0,4,0"
hc:IconElement.Geometry="{StaticResource DismissSquareMultiple20Regular}"
BorderThickness="1"
Command="{s:Action ClearCopilotTask}"
Foreground="{DynamicResource DangerBrush}"
IsEnabled="{c:Binding Idle}"
MouseRightButtonUp="{s:Action CleanUnableCopilotTask}" />
<controls:TooltipBlock
HorizontalAlignment="Right"
VerticalAlignment="Top"
MouseLeftButtonDown="{s:Action ClearCopilotTask}"
MouseRightButtonUp="{s:Action CleanUnableCopilotTask}"
NormalOpacity="0.25"
TooltipText="{DynamicResource CopilotClearTask}" />
</Grid>
</Grid>
</Grid>
<Grid
Grid.Row="{c:Binding 'UseCopilotList ? 3:2'}"
Margin="0,10"
HorizontalAlignment="Center"
VerticalAlignment="Top"
d:Grid.Row="3">
<Button
Width="120"
Height="50"
Command="{s:Action Start}"
Content="{DynamicResource Start}"
IsEnabled="{c:Binding 'StartEnabled and Inited'}"
Visibility="{c:Binding Idle}" />
<Button
Width="120"
Height="50"
Command="{s:Action Stop}"
Content="{DynamicResource Stop}"
IsEnabled="{c:Binding Inited}"
Visibility="{c:Binding !Idle}" />
</Grid>
<controls:TextBlock Grid.Row="4" Block.TextAlignment="Center">
<controls:TextBlock Grid.Row="2" Block.TextAlignment="Center">
<Hyperlink
Cursor="Hand"
NavigateUri="{Binding CopilotUrl}"
@@ -478,14 +592,17 @@
</controls:TextBlock>
</Grid>
<Grid Grid.Column="1">
<Grid
Grid.Column="{c:Binding 'UseCopilotList ? 3 : 2'}"
Grid.ColumnSpan="{c:Binding 'UseCopilotList ? 1 : 2'}"
d:Grid.Column="3"
d:Grid.ColumnSpan="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<hc:ScrollViewer
Width="360"
properties:AutoScroll.AutoScroll="True"
HorizontalScrollBarVisibility="Disabled"
IsInertiaEnabled="True"
@@ -522,30 +639,37 @@
</ItemsControl.ItemTemplate>
</ItemsControl>
</hc:ScrollViewer>
<StackPanel
<Grid
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Orientation="Horizontal"
Visibility="{c:Binding CouldLikeWebJson}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<controls:TextBlock
Margin="10"
VerticalAlignment="Center"
Block.TextAlignment="Center"
Text="{DynamicResource DoYouLikeThisWebJson}" />
Text="{DynamicResource DoYouLikeThisWebJson}"
TextWrapping="Wrap" />
<Button
Grid.Column="1"
Width="50"
Height="30"
Margin="10"
Command="{s:Action LikeWebJson}"
Content="👍" />
<Button
Grid.Column="2"
Width="50"
Height="30"
Margin="10"
Command="{s:Action DislikeWebJson}"
Content="👎" />
</StackPanel>
</Grid>
<controls:TextBlock
Grid.Row="2"