diff --git a/docs/zh-cn/protocol/integration.md b/docs/zh-cn/protocol/integration.md index ff3f8ade89..07c049b985 100644 --- a/docs/zh-cn/protocol/integration.md +++ b/docs/zh-cn/protocol/integration.md @@ -269,9 +269,15 @@ AsstTaskId ASSTAPI AsstAppendTask(AsstHandle handle, const char* type, const cha string, // 仅在主题为 Sami 且模式为 5 时有效 ... ], - "monthlySquadAutoIterate": bool, //是否启动月度小队自动切换 - "monthlySquadCheckComms": bool, //是否将月度小队通信也作为切换依据 - "deepExplorationAutoIterate": bool, //是否启动深入调查自动切换 + "monthlySquadAutoIterate": bool, //是否启动月度小队自动切换 + "monthlySquadCheckComms": bool, //是否将月度小队通信也作为切换依据 + "deepExplorationAutoIterate": bool, //是否启动深入调查自动切换 + "collectible_mode_shopping": bool, // 烧水是否启用购物, 默认值false + "collectible_mode_squad": string, // 烧水时使用的分队, 默认为空, 即指挥分队 + "collectible_mode_start_list": { // 烧水期望奖励, 默认全false, 键范围: + "hot_water": bool, // [hot_water: 热水, shield: 盾, ingot: 源石锭, hope: 希望, random: 随机奖励, key: 钥匙, dice: 骰子, ideas: 构想] + ... + }, "start_with_seed": bool, // 使用种子刷钱,true 时有效 // 仅在 Sarkaz 主题,Investment 模式,“点刺成锭分队” or “后勤分队” 时可能为 true // 使用固定种子 diff --git a/resource/tasks.json b/resource/tasks.json index bb3fc21ff4..1f36ca8e69 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -7106,29 +7106,29 @@ "baseTask": "Roguelike@LastReward_default", "template": "empty.png", "roi": [171, 474, 935, 205], - "next": ["Roguelike@RolesDefault", "Roguelike@CloseCollection"] + "next": [] }, "Roguelike@LastRewardRand": { "Doc": "你的上一次探索突破了至少两层困难,这一次可以获得更多支援—— 问号", "baseTask": "Roguelike@LastReward_default", "template": "empty.png" }, + "Roguelike@LastReward-EnterPoint": { + "Doc": "插件挂载,选择期望的奖励,template为所有LastReward集合,进入插件后重新匹配,有就Confirm,没有就Abandon", + "template": "empty.png", + "roi": [225, 199, 829, 241], + "next": ["Roguelike@RolesDefault", "Roguelike@CloseCollection", "Roguelike@StartExplore"] + }, + "Roguelike@LastReward-Strategy": { + "Doc": "未指定期望时,默认选择策略", + "algorithm": "JustReturn" + }, "Roguelike@LastReward_default": { "template": "empty.png", "action": "ClickSelf", "roi": [225, 199, 829, 241], "next": ["Roguelike@LastRewardConfirm"] }, - "Roguelike@LastReward_restart": { - "baseTask": "Roguelike@LastReward_default", - "template": "empty.png", - "next": [] - }, - "Roguelike@LastReward_stop": { - "baseTask": "Roguelike@LastReward_default", - "template": "empty.png", - "next": ["RoguelikeControlTaskPlugin-Stop"] - }, "Roguelike@MainThemes": { "next": ["Roguelike", "Roguelike@ChooseDifficulty", "Roguelike@StartExplore", "Roguelike@Abandon"] }, @@ -7982,14 +7982,7 @@ ] }, "Phantom@Roguelike@CloseCollection": { - "next": [ - "Phantom@Roguelike@LastReward", - "Phantom@Roguelike@LastReward4", - "Phantom@Roguelike@LastReward2", - "Phantom@Roguelike@LastReward3", - "Phantom@Roguelike@LastRewardRand", - "Phantom@Roguelike@RolesDefault" - ] + "next": ["Phantom@Roguelike@LastReward-EnterPoint", "Phantom@Roguelike@RolesDefault"] }, "Phantom@Roguelike@CloseEvent": {}, "Phantom@Roguelike@Continue": {}, @@ -8069,6 +8062,24 @@ "Phantom@Roguelike@LastReward4": {}, "Phantom@Roguelike@LastRewardConfirm": {}, "Phantom@Roguelike@LastRewardRand": {}, + "Phantom@Roguelike@LastReward-EnterPoint": { + "template": [ + "Phantom@Roguelike@LastReward.png", + "Phantom@Roguelike@LastReward4.png", + "Phantom@Roguelike@LastReward2.png", + "Phantom@Roguelike@LastReward3.png", + "Phantom@Roguelike@LastRewardRand.png" + ] + }, + "Phantom@Roguelike@LastReward-Strategy": { + "next": [ + "Phantom@Roguelike@LastReward", + "Phantom@Roguelike@LastReward4", + "Phantom@Roguelike@LastReward2", + "Phantom@Roguelike@LastReward3", + "Phantom@Roguelike@LastRewardRand" + ] + }, "Phantom@Roguelike@MissionFailedFlag": { "roi": [450, 163, 540, 267] }, @@ -8118,11 +8129,7 @@ "Phantom@Roguelike@SquadConfirm": { "template": "Phantom@Roguelike@LastRewardConfirm.png", "next": [ - "Phantom@Roguelike@LastReward", - "Phantom@Roguelike@LastReward4", - "Phantom@Roguelike@LastReward2", - "Phantom@Roguelike@LastReward3", - "Phantom@Roguelike@LastRewardRand", + "Phantom@Roguelike@LastReward-EnterPoint", "Phantom@Roguelike@RolesDefault", "Phantom@Roguelike@CloseCollection", "Phantom@Roguelike@Stages#next" @@ -8323,16 +8330,7 @@ ] }, "Mizuki@Roguelike@CloseCollection": { - "next": [ - "Mizuki@Roguelike@LastReward", - "Mizuki@Roguelike@LastReward4", - "Mizuki@Roguelike@LastReward2", - "Mizuki@Roguelike@LastReward3", - "Mizuki@Roguelike@LastReward5", - "Mizuki@Roguelike@LastReward6", - "Mizuki@Roguelike@LastRewardRand", - "Mizuki@Roguelike@RolesDefault" - ] + "next": ["Mizuki@Roguelike@LastReward-EnterPoint", "Mizuki@Roguelike@RolesDefault"] }, "Mizuki@Roguelike@CloseCollectionClose": { "action": "ClickSelf", @@ -8522,6 +8520,28 @@ }, "Mizuki@Roguelike@LastRewardConfirm": {}, "Mizuki@Roguelike@LastRewardRand": {}, + "Mizuki@Roguelike@LastReward-EnterPoint": { + "template": [ + "Mizuki@Roguelike@LastReward.png", + "Mizuki@Roguelike@LastReward4.png", + "Mizuki@Roguelike@LastReward2.png", + "Mizuki@Roguelike@LastReward3.png", + "Mizuki@Roguelike@LastReward5.png", + "Mizuki@Roguelike@LastReward6.png", + "Mizuki@Roguelike@LastRewardRand.png" + ] + }, + "Mizuki@Roguelike@LastReward-Strategy": { + "next": [ + "Mizuki@Roguelike@LastReward", + "Mizuki@Roguelike@LastReward4", + "Mizuki@Roguelike@LastReward2", + "Mizuki@Roguelike@LastReward3", + "Mizuki@Roguelike@LastReward5", + "Mizuki@Roguelike@LastReward6", + "Mizuki@Roguelike@LastRewardRand" + ] + }, "Mizuki@Roguelike@MapObject": { "roi": [257, 488, 189, 123], "next": ["Mizuki@Roguelike@RecruitOther"] @@ -8576,13 +8596,7 @@ "Mizuki@Roguelike@SquadConfirm": { "template": "Mizuki@Roguelike@LastRewardConfirm.png", "next": [ - "Mizuki@Roguelike@LastReward", - "Mizuki@Roguelike@LastReward4", - "Mizuki@Roguelike@LastReward2", - "Mizuki@Roguelike@LastReward3", - "Mizuki@Roguelike@LastReward5", - "Mizuki@Roguelike@LastReward6", - "Mizuki@Roguelike@LastRewardRand", + "Mizuki@Roguelike@LastReward-EnterPoint", "Mizuki@Roguelike@RolesDefault", "Mizuki@Roguelike@CloseCollection", "Mizuki@Roguelike@Stages#next", @@ -8944,15 +8958,7 @@ ] }, "Sami@Roguelike@CloseCollection": { - "next": [ - "Sami@Roguelike@LastReward", - "Sami@Roguelike@LastReward4", - "Sami@Roguelike@LastReward2", - "Sami@Roguelike@LastReward3", - "Sami@Roguelike@LastRewardRand", - "Sami@Roguelike@GetLUD", - "Sami@Roguelike@RolesDefault" - ] + "next": ["Sami@Roguelike@LastReward-EnterPoint", "Sami@Roguelike@GetLUD", "Sami@Roguelike@RolesDefault"] }, "Sami@Roguelike@CloseCollectionClose": { "action": "ClickSelf", @@ -9331,6 +9337,24 @@ }, "Sami@Roguelike@LastRewardConfirm": {}, "Sami@Roguelike@LastRewardRand": {}, + "Sami@Roguelike@LastReward-EnterPoint": { + "template": [ + "Sami@Roguelike@LastReward.png", + "Sami@Roguelike@LastReward4.png", + "Sami@Roguelike@LastReward2.png", + "Sami@Roguelike@LastReward3.png", + "Sami@Roguelike@LastRewardRand.png" + ] + }, + "Sami@Roguelike@LastReward-Strategy": { + "next": [ + "Sami@Roguelike@LastReward", + "Sami@Roguelike@LastReward4", + "Sami@Roguelike@LastReward2", + "Sami@Roguelike@LastReward3", + "Sami@Roguelike@LastRewardRand" + ] + }, "Sami@Roguelike@MapObject": { "roi": [257, 488, 189, 123], "next": ["Sami@Roguelike@RecruitOther"] @@ -9394,11 +9418,7 @@ "Sami@Roguelike@SquadConfirm": { "template": "Sami@Roguelike@LastRewardConfirm.png", "next": [ - "Sami@Roguelike@LastReward", - "Sami@Roguelike@LastReward4", - "Sami@Roguelike@LastReward2", - "Sami@Roguelike@LastReward3", - "Sami@Roguelike@LastRewardRand", + "Sami@Roguelike@LastReward-EnterPoint", "Sami@Roguelike@GetLUD", "Sami@Roguelike@RolesDefault", "Sami@Roguelike@CloseCollection", @@ -10247,6 +10267,7 @@ "specificRect": [600, 600, 25, 25] }, "Sarkaz@Roguelike@CloseCollection": { + "Doc": "深入调查/月度小队会给个藏品,要先关掉", "method": "RGBCount", "colorScales": [ [ @@ -10254,15 +10275,7 @@ [170, 170, 170] ] ], - "next": [ - "Sarkaz@Roguelike@LastReward5", - "Sarkaz@Roguelike@LastReward", - "Sarkaz@Roguelike@LastReward4", - "Sarkaz@Roguelike@LastReward2", - "Sarkaz@Roguelike@LastReward3", - "Sarkaz@Roguelike@LastRewardRand", - "Sarkaz@Roguelike@RolesDefault" - ] + "next": ["Sarkaz@Roguelike@LastReward-EnterPoint", "Sarkaz@Roguelike@RolesDefault"] }, "Sarkaz@Roguelike@CloseCollectionClose": { "action": "ClickSelf", @@ -10542,10 +10555,31 @@ "Sarkaz@Roguelike@LastReward3": {}, "Sarkaz@Roguelike@LastReward4": {}, "Sarkaz@Roguelike@LastReward5": { + "Doc": "你的上一次探索突破了至少两层困难,这一次可以获得更多支援—— 2 构想", "baseTask": "Sarkaz@Roguelike@LastReward_default" }, "Sarkaz@Roguelike@LastRewardConfirm": {}, "Sarkaz@Roguelike@LastRewardRand": {}, + "Sarkaz@Roguelike@LastReward-EnterPoint": { + "template": [ + "Sarkaz@Roguelike@LastReward5.png", + "Sarkaz@Roguelike@LastReward.png", + "Sarkaz@Roguelike@LastReward4.png", + "Sarkaz@Roguelike@LastReward2.png", + "Sarkaz@Roguelike@LastReward3.png", + "Sarkaz@Roguelike@LastRewardRand.png" + ] + }, + "Sarkaz@Roguelike@LastReward-Strategy": { + "next": [ + "Sarkaz@Roguelike@LastReward5", + "Sarkaz@Roguelike@LastReward", + "Sarkaz@Roguelike@LastReward4", + "Sarkaz@Roguelike@LastReward2", + "Sarkaz@Roguelike@LastReward3", + "Sarkaz@Roguelike@LastRewardRand" + ] + }, "Sarkaz@Roguelike@MapObject": { "roi": [257, 488, 189, 123], "next": ["Sarkaz@Roguelike@RecruitOther"] @@ -10736,12 +10770,7 @@ "Sarkaz@Roguelike@SquadConfirm": { "template": "Sarkaz@Roguelike@LastRewardConfirm.png", "next": [ - "Sarkaz@Roguelike@LastReward4", - "Sarkaz@Roguelike@LastReward", - "Sarkaz@Roguelike@LastReward2", - "Sarkaz@Roguelike@LastReward5", - "Sarkaz@Roguelike@LastReward3", - "Sarkaz@Roguelike@LastRewardRand", + "Sarkaz@Roguelike@LastReward-EnterPoint", "Sarkaz@Roguelike@RolesDefault", "Sarkaz@Roguelike@CloseCollection", "Sarkaz@Roguelike@Stages#next", diff --git a/resource/template/Phantom@Roguelike@LastReward2.png b/resource/template/Phantom@Roguelike@LastReward2.png index c244643183..c4ef20382f 100644 Binary files a/resource/template/Phantom@Roguelike@LastReward2.png and b/resource/template/Phantom@Roguelike@LastReward2.png differ diff --git a/resource/template/Phantom@Roguelike@LastReward3.png b/resource/template/Phantom@Roguelike@LastReward3.png index c4ef20382f..c244643183 100644 Binary files a/resource/template/Phantom@Roguelike@LastReward3.png and b/resource/template/Phantom@Roguelike@LastReward3.png differ diff --git a/src/MaaCore/Config/TaskData.cpp b/src/MaaCore/Config/TaskData.cpp index 78992f0303..2d54ae0f39 100644 --- a/src/MaaCore/Config/TaskData.cpp +++ b/src/MaaCore/Config/TaskData.cpp @@ -90,7 +90,7 @@ bool asst::TaskData::lazy_parse(const json::value& json) } continue; } - if (m_json_all_tasks_info.find(name_view) == m_json_all_tasks_info.cend()) { + if (!m_json_all_tasks_info.contains(name_view)) { m_json_all_tasks_info.emplace(name_view, task_json.as_object()); continue; } diff --git a/src/MaaCore/MaaCore.vcxproj b/src/MaaCore/MaaCore.vcxproj index 23e73a5d34..93449cbf77 100644 --- a/src/MaaCore/MaaCore.vcxproj +++ b/src/MaaCore/MaaCore.vcxproj @@ -101,6 +101,7 @@ + @@ -295,6 +296,7 @@ + diff --git a/src/MaaCore/MaaCore.vcxproj.filters b/src/MaaCore/MaaCore.vcxproj.filters index ced85f9782..07b4479d97 100644 --- a/src/MaaCore/MaaCore.vcxproj.filters +++ b/src/MaaCore/MaaCore.vcxproj.filters @@ -749,6 +749,9 @@ Source\Task\Roguelike + + Source\Task\Roguelike + @@ -1263,5 +1266,8 @@ Source\Task\Roguelike + + Source\Task\Roguelike + \ No newline at end of file diff --git a/src/MaaCore/Task/Interface/RoguelikeTask.cpp b/src/MaaCore/Task/Interface/RoguelikeTask.cpp index 159eb37d97..c63173d9a8 100644 --- a/src/MaaCore/Task/Interface/RoguelikeTask.cpp +++ b/src/MaaCore/Task/Interface/RoguelikeTask.cpp @@ -17,6 +17,7 @@ #include "Task/Roguelike/RoguelikeInvestTaskPlugin.h" #include "Task/Roguelike/RoguelikeIterateDeepExplorationPlugin.h" #include "Task/Roguelike/RoguelikeIterateMonthlySquadPlugin.h" +#include "Task/Roguelike/RoguelikeLastRewardSelectTaskPlugin.h" #include "Task/Roguelike/RoguelikeLastRewardTaskPlugin.h" #include "Task/Roguelike/RoguelikeLevelTaskPlugin.h" #include "Task/Roguelike/RoguelikeRecruitTaskPlugin.h" @@ -76,6 +77,7 @@ asst::RoguelikeTask::RoguelikeTask(const AsstCallback& callback, Assistant* inst ->set_retry_times(0); m_roguelike_task_ptr->register_plugin(m_config_ptr, m_control_ptr); + m_roguelike_task_ptr->register_plugin(m_config_ptr, m_control_ptr); m_roguelike_task_ptr->register_plugin(m_config_ptr, m_control_ptr); m_roguelike_task_ptr->register_plugin(m_config_ptr, m_control_ptr); diff --git a/src/MaaCore/Task/Roguelike/RoguelikeConfig.cpp b/src/MaaCore/Task/Roguelike/RoguelikeConfig.cpp index bfe539172f..3922706b96 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeConfig.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeConfig.cpp @@ -28,6 +28,31 @@ bool asst::RoguelikeConfig::verify_and_load_params(const json::value& params) return false; } + if (mode == RoguelikeMode::Collectible) { + m_collectible_mode_shopping = params.get("collectible_mode_shopping", false); + + if (auto select_list = params.find("collectible_mode_start_list"); select_list) { + RoguelikeStartSelect list; + list.hot_water = select_list->get("hot_water", false); + list.shield = select_list->get("shield", false); + list.ingot = select_list->get("ingot", false); + list.hope = select_list->get("hope", false); + list.random = select_list->get("random", false); + if (m_theme == RoguelikeTheme::Mizuki) { + list.key = select_list->get("key", false); + list.dice = select_list->get("dice", false); + } + else if (m_theme == RoguelikeTheme::Sarkaz) { + list.ideas = select_list->get("ideas", false); + } + m_start_select = list; + } + + if (m_theme == RoguelikeTheme::Sami) { + m_first_floor_foldartal = !params.get("first_floor_foldartal", "").empty(); + } + } + m_start_with_seed = params.get("start_with_seed", false); m_start_with_elite_two = params.get("start_with_elite_two", false); m_only_start_with_elite_two = params.get("only_start_with_elite_two", false); @@ -74,13 +99,6 @@ bool asst::RoguelikeConfig::verify_and_load_params(const json::value& params) } } - // 重置开局奖励 next,获得任意奖励均继续;烧水相关逻辑在 RoguelikeLastRewardTaskPlugin - Task.set_task_base("Roguelike@LastReward", "Roguelike@LastReward_default"); - Task.set_task_base("Roguelike@LastReward2", "Roguelike@LastReward_default"); - Task.set_task_base("Roguelike@LastReward3", "Roguelike@LastReward_default"); - Task.set_task_base("Roguelike@LastReward4", "Roguelike@LastReward_default"); - Task.set_task_base("Roguelike@LastRewardRand", "Roguelike@LastReward_default"); - if (m_mode == RoguelikeMode::Investment) { bool investment_with_more_score = params.get("investment_with_more_score", false); if (!params.contains("investment_with_more_score") && params.contains("investment_enter_second_floor")) { @@ -98,21 +116,6 @@ bool asst::RoguelikeConfig::verify_and_load_params(const json::value& params) m_run_for_collectible = true; // 烧开水模式下,如果不是只凹直升,第一轮游戏先烧水 } - // ------------------ 萨米主题专用参数 ------------------ - if (m_theme == RoguelikeTheme::Sami) { - // 是否凹开局远见密文板 - m_first_floor_foldartal = params.contains("first_floor_foldartal"); - } - - // ------------------ 萨卡兹主题专用参数 ------------------ - if (m_theme == RoguelikeTheme::Sarkaz) { - m_start_with_two_ideas = params.get("start_with_two_ideas", false); - if (m_mode != RoguelikeMode::Collectible && m_start_with_two_ideas) { - Log.error(__FUNCTION__, "| Invalid mode for start_with_two_ideas", static_cast(mode)); - return false; - } - } - return true; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeConfig.h b/src/MaaCore/Task/Roguelike/RoguelikeConfig.h index b7451bfc70..1d65781355 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeConfig.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeConfig.h @@ -42,6 +42,18 @@ struct RoguelikeOper int level = 0; // 干员等级 }; +struct RoguelikeStartSelect // 刷开局模式下凹开局奖励选择 +{ + bool hot_water = false; // 热水壶 + bool shield = false; // 盾;傀影没盾,是生命 + bool ingot = false; // 源石锭 + bool hope = false; // 希望 + bool random = false; // 随机奖励 + bool key = false; // 钥匙 + bool dice = false; // 骰子 + bool ideas = false; // 构想 +}; + class RoguelikeConfig { public: @@ -63,7 +75,6 @@ public: void clear(); // 重置肉鸽局内数据 // ================================= 通用参数 ================================= - public: const std::string& get_theme() const { return m_theme; } @@ -90,11 +101,19 @@ public: bool get_run_for_collectible() const { return m_run_for_collectible; } + void set_start_select(const RoguelikeStartSelect& start_select) { m_start_select = start_select; } + + const auto& get_start_select() const { return m_start_select; } + // ------------------ 投资模式 ------------------ void set_invest_with_more_score(bool value) { m_invest_with_more_score = value; } bool get_invest_with_more_score() const { return m_invest_with_more_score; } + void set_collectible_mode_shopping(bool value) { m_collectible_mode_shopping = value; } + + bool get_collectible_mode_shopping() const { return m_collectible_mode_shopping; } + private: std::string m_theme; // 主题 RoguelikeMode m_mode = RoguelikeMode::Exp; // 模式 @@ -106,14 +125,19 @@ private: bool m_only_start_with_elite_two = false; // 只凹开局干员精二直升且不进行作战 bool m_run_for_collectible = false; // 用于 RoguelikeMode::Collectible,判断是否正在烧水 + RoguelikeStartSelect m_start_select; // 开局选择 + // ------------------ 投资模式 ------------------ bool m_invest_with_more_score = false; // 投资时招募、购物刷分 - // =========================== 萨米主题专用参数 =========================== + // ------------------ 刷开局模式 ------------------ + bool m_collectible_mode_shopping = false; // 刷开局模式下进入商店时购物 +private: + // =========================== 萨米主题专用参数 =========================== public: // ------------------ 密文板 ------------------ - void set_first_floor_foldartal(bool value) { m_first_floor_foldartal = value; } + void set_first_floor_foldartal(const bool value) { m_first_floor_foldartal = value; } bool get_first_floor_foldartal() const { return m_first_floor_foldartal; } @@ -122,17 +146,11 @@ private: bool m_first_floor_foldartal = false; // 凹远见密文板 // =========================== 萨卡兹主题专用参数 =========================== - public: - void set_start_with_two_ideas(bool value) { m_start_with_two_ideas = value; } - - bool get_start_with_two_ideas() const { return m_start_with_two_ideas; } - bool get_start_with_seed() const { return m_start_with_seed; } private: - bool m_start_with_two_ideas = false; // 在刷开局模式下凹开局 2 构想 - bool m_start_with_seed = false; // 种子刷钱 + bool m_start_with_seed = false; // 种子刷钱 // ================================================================================ // 以下为局内数据,每次重置 diff --git a/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.cpp index 8a1a026345..73f85f116d 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.cpp @@ -49,8 +49,12 @@ bool asst::RoguelikeCustomStartTaskPlugin::load_params(const json::value& params { LogTraceFunction; - set_custom(RoguelikeCustomType::Squad, params.get("squad", "")); // 开局分队 - if (params.get("start_with_seed", false)) { // 种子刷钱,强制随心所欲 + m_squad = params.get("squad", ""); + m_collectible_mode_squad = params.get("collectible_mode_squad", ""); + + set_custom(RoguelikeCustomType::Squad, m_squad); + + if (params.get("start_with_seed", false)) { // 种子刷钱,强制随心所欲 set_custom(RoguelikeCustomType::Roles, "随心所欲"); } else { @@ -73,6 +77,13 @@ void asst::RoguelikeCustomStartTaskPlugin::set_custom(RoguelikeCustomType type, bool asst::RoguelikeCustomStartTaskPlugin::_run() { + if (m_config->get_run_for_collectible()) { + set_custom(RoguelikeCustomType::Squad, m_collectible_mode_squad); // 烧水分队 + } + else { + set_custom(RoguelikeCustomType::Squad, m_squad); // 开局分队 + } + const std::unordered_map> TypeActuator = { { RoguelikeCustomType::Squad, std::bind(&RoguelikeCustomStartTaskPlugin::hijack_squad, this) }, { RoguelikeCustomType::Roles, std::bind(&RoguelikeCustomStartTaskPlugin::hijack_roles, this) }, diff --git a/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.h index 1ff1c98b84..fb736857bf 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.h @@ -36,5 +36,8 @@ private: private: std::unordered_map m_customs; mutable RoguelikeCustomType m_waiting_to_run = RoguelikeCustomType::None; + + std::string m_squad; + std::string m_collectible_mode_squad; }; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeLastRewardSelectTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeLastRewardSelectTaskPlugin.cpp new file mode 100644 index 0000000000..5201225548 --- /dev/null +++ b/src/MaaCore/Task/Roguelike/RoguelikeLastRewardSelectTaskPlugin.cpp @@ -0,0 +1,93 @@ +#include "RoguelikeLastRewardSelectTaskPlugin.h" + +#include "Config/GeneralConfig.h" +#include "Config/TaskData.h" +#include "Controller/Controller.h" +#include "Task/ProcessTask.h" +#include "Utils/Logger.hpp" +#include "Vision/Miscellaneous/PipelineAnalyzer.h" + +bool asst::RoguelikeLastRewardSelectTaskPlugin::verify(AsstMsg msg, const json::value& details) const +{ + if (msg != AsstMsg::SubTaskStart || details.get("subtask", std::string()) != "ProcessTask") { + return false; + } + const std::string& task = details.get("details", "task", ""); + if (task.ends_with("Roguelike@LastReward-EnterPoint")) { + return true; + } + + return false; +} + +bool asst::RoguelikeLastRewardSelectTaskPlugin::_run() +{ + LogTraceFunction; + + const auto& list = get_select_list(); + if (list.empty()) { + // 执行默认选择顺序 + ProcessTask(*this, { m_config->get_theme() + "@Roguelike@LastReward-Strategy" }).run(); + return true; + } + + // 处理选择顺序 + PipelineAnalyzer analyzer(ctrler()->get_image()); + analyzer.set_tasks(list); + if (auto ret = analyzer.analyze(); !ret) { + // 未获取到期望物品,结束重开 + m_control_ptr->exit_then_stop(true); + } + else if (m_config->get_start_with_elite_two()) { + ctrler()->click(ret->rect); + sleep(Config.get_options().task_delay); + ProcessTask(*this, { m_config->get_theme() + "@Roguelike@LastRewardConfirm" }).run(); + } + else { + m_control_ptr->exit_then_stop(false); + m_task_ptr->set_enable(false); + } + + return true; +} + +std::vector asst::RoguelikeLastRewardSelectTaskPlugin::get_select_list() const +{ + if (m_config->get_mode() != RoguelikeMode::Collectible || + m_config->get_run_for_collectible() /* 正在烧水,使用默认策略 */ || + m_config->get_only_start_with_elite_two() /* 只凹精二没有奖励,但第一次开时可能有之前的奖励 */) { + return {}; + } + + std::vector list; + const auto& select = m_config->get_start_select(); + if (select.hot_water) { + list.emplace_back(m_config->get_theme() + "@Roguelike@LastReward"); // 热水壶 + } + if (select.shield) { + list.emplace_back(m_config->get_theme() + "@Roguelike@LastReward2"); // 盾;傀影没盾,是生命 + } + if (select.ingot) { + list.emplace_back(m_config->get_theme() + "@Roguelike@LastReward3"); // 源石锭 + } + if (select.hope) { + list.emplace_back(m_config->get_theme() + "@Roguelike@LastReward4"); // 希望 + } + + if (select.random) { + list.emplace_back(m_config->get_theme() + "@Roguelike@LastRewardRand"); // 随机奖励 + } + if (m_config->get_theme() == RoguelikeTheme::Mizuki) { + if (select.key) { + list.emplace_back("Mizuki@Roguelike@LastReward5"); // 钥匙 + } + if (select.dice) { + list.emplace_back("Mizuki@Roguelike@LastReward6"); // 骰子 + } + } + else if (m_config->get_theme() == RoguelikeTheme::Sarkaz && select.ideas) { + list.emplace_back("Sarkaz@Roguelike@LastReward5"); // 构想 + } + + return list; +} diff --git a/src/MaaCore/Task/Roguelike/RoguelikeLastRewardSelectTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeLastRewardSelectTaskPlugin.h new file mode 100644 index 0000000000..f30f9ff7b8 --- /dev/null +++ b/src/MaaCore/Task/Roguelike/RoguelikeLastRewardSelectTaskPlugin.h @@ -0,0 +1,20 @@ +#pragma once +#include "AbstractRoguelikeTaskPlugin.h" + +namespace asst +{ +class RoguelikeLastRewardSelectTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeLastRewardSelectTaskPlugin() = default; + + virtual bool verify(AsstMsg msg, const json::value& details) const override; + +protected: + virtual bool _run() override; + +private: + std::vector get_select_list() const; +}; +} diff --git a/src/MaaCore/Task/Roguelike/RoguelikeLastRewardTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeLastRewardTaskPlugin.cpp index 038682feba..bb5c11ef2b 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeLastRewardTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeLastRewardTaskPlugin.cpp @@ -3,6 +3,7 @@ #include "Config/TaskData.h" #include "Status.h" #include "Task/ProcessTask.h" +#include "Task/Roguelike/RoguelikeLastRewardSelectTaskPlugin.h" #include "Utils/Logger.hpp" bool asst::RoguelikeLastRewardTaskPlugin::verify(AsstMsg msg, const json::value& details) const @@ -56,38 +57,14 @@ bool asst::RoguelikeLastRewardTaskPlugin::_run() Task.set_task_base(stages_task_name, strategy_task_name); } - // 需要开局凹直升 - bool start_with_elite_two = m_config->get_start_with_elite_two(); if (m_config->get_theme() != RoguelikeTheme::Phantom && mode == RoguelikeMode::Collectible) { - if (m_is_next_hardest) { - // 关闭烧开水 Flag,将难度调整回用户设置的数值 - m_config->set_run_for_collectible(false); - // 获得热水壶和演讲时停止肉鸽(凹直升则继续),获得其他奖励时重开 - std::string last_reward_stop_or_continue = - start_with_elite_two ? "Roguelike@LastReward_default" : "Roguelike@LastReward_stop"; - Task.set_task_base("Roguelike@LastReward", last_reward_stop_or_continue); - Task.set_task_base("Roguelike@LastReward2", "Roguelike@LastReward_restart"); - Task.set_task_base("Roguelike@LastReward3", "Roguelike@LastReward_restart"); - Task.set_task_base("Roguelike@LastReward4", last_reward_stop_or_continue); - Task.set_task_base("Roguelike@LastRewardRand", "Roguelike@LastReward_restart"); - if (m_config->get_theme() == RoguelikeTheme::Sarkaz && m_config->get_start_with_two_ideas()) { - Task.set_task_base("Roguelike@LastReward", "Roguelike@LastReward_restart"); - Task.set_task_base("Roguelike@LastReward4", "Roguelike@LastReward_restart"); - Task.set_task_base("Sarkaz@Roguelike@LastReward5", last_reward_stop_or_continue); - } - } - else if (!m_config->get_only_start_with_elite_two()) { + if (!m_is_next_hardest) { // 开启烧开水 Flag,将难度设置为 0 m_config->set_run_for_collectible(true); - // 重置开局奖励 next,获得任意奖励均继续 - Task.set_task_base("Roguelike@LastReward", "Roguelike@LastReward_default"); - Task.set_task_base("Roguelike@LastReward2", "Roguelike@LastReward_default"); - Task.set_task_base("Roguelike@LastReward3", "Roguelike@LastReward_default"); - Task.set_task_base("Roguelike@LastReward4", "Roguelike@LastReward_default"); - Task.set_task_base("Roguelike@LastRewardRand", "Roguelike@LastReward_default"); - if (m_config->get_theme() == RoguelikeTheme::Sarkaz) { - Task.set_task_base("Sarkaz@Roguelike@LastReward5", "Sarkaz@Roguelike@LastReward_default"); - } + } + else { + // 关闭烧开水 Flag,将难度调整回用户设置的数值 + m_config->set_run_for_collectible(false); } } return true; diff --git a/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.cpp index a2d626235f..ca5b0ee27f 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.cpp @@ -16,17 +16,16 @@ bool asst::RoguelikeShoppingTaskPlugin::verify(AsstMsg msg, const json::value& d return false; } - if (!RoguelikeConfig::is_valid_theme(m_config->get_theme())) { - Log.error("Roguelike name doesn't exist!"); + if (!details.get("details", "task", "").ends_with("Roguelike@TraderRandomShopping")) { return false; } - - if (details.get("details", "task", "").ends_with("Roguelike@TraderRandomShopping")) { - return m_config->get_mode() != RoguelikeMode::Investment || m_config->get_invest_with_more_score(); + else if (m_config->get_mode() == RoguelikeMode::Investment) { + return m_config->get_invest_with_more_score(); } - else { - return false; + else if (m_config->get_mode() == RoguelikeMode::Collectible) { + return m_config->get_collectible_mode_shopping(); } + return true; } bool asst::RoguelikeShoppingTaskPlugin::_run() diff --git a/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalStartTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalStartTaskPlugin.cpp index b3c39b1734..0e7a67c6d4 100644 --- a/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalStartTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalStartTaskPlugin.cpp @@ -69,8 +69,6 @@ bool asst::RoguelikeFoldartalStartTaskPlugin::_run() // 没有刷到需要的板子,退出重开 if (mode == RoguelikeMode::Collectible && !start_foldartal_checked) { m_config->set_run_for_collectible(true); // 重新烧水 - Task.set_task_base("Roguelike@LastReward", "Roguelike@LastReward_restart"); - Task.set_task_base("Roguelike@LastReward4", "Roguelike@LastReward_restart"); } return true; } diff --git a/src/MaaWpfGui/Constants/ConfigurationKeys.cs b/src/MaaWpfGui/Constants/ConfigurationKeys.cs index 41914bd53c..aa29cf5122 100644 --- a/src/MaaWpfGui/Constants/ConfigurationKeys.cs +++ b/src/MaaWpfGui/Constants/ConfigurationKeys.cs @@ -121,10 +121,12 @@ namespace MaaWpfGui.Constants public const string RoguelikeDifficulty = "Roguelike.Difficulty"; public const string RoguelikeMode = "Roguelike.Mode"; public const string RoguelikeSquad = "Roguelike.Squad"; + public const string RoguelikeCollectibleModeSquad = "Roguelike.CollectibleModeSquad"; public const string RoguelikeRoles = "Roguelike.Roles"; public const string RoguelikeCoreChar = "Roguelike.CoreChar"; public const string RoguelikeStartWithEliteTwo = "Roguelike.RoguelikeStartWithEliteTwo"; public const string RoguelikeOnlyStartWithEliteTwo = "Roguelike.RoguelikeOnlyStartWithEliteTwo"; + public const string RoguelikeStartWithSelectList = "Roguelike.RoguelikeStartWithSelectList"; public const string RoguelikeStartWithTwoIdeas = "Roguelike.RoguelikeStartWithTwoIdeas"; public const string Roguelike3FirstFloorFoldartal = "Roguelike.Roguelike3FirstFloorFoldartal"; public const string Roguelike3StartFloorFoldartal = "Roguelike.Roguelike3StartFloorFoldartal"; @@ -137,6 +139,7 @@ namespace MaaWpfGui.Constants public const string RoguelikeStartsCount = "Roguelike.StartsCount"; public const string RoguelikeInvestmentEnabled = "Roguelike.InvestmentEnabled"; public const string RoguelikeInvestmentEnterSecondFloor = "Roguelike.InvestmentEnterSecondFloor"; + public const string RoguelikeCollectibleModeShopping = "Roguelike.CollectibleModeShopping"; public const string RoguelikeRefreshTraderWithDice = "Roguelike.RefreshTraderWithDice"; public const string RoguelikeInvestsCount = "Roguelike.InvestsCount"; public const string RoguelikeStopWhenInvestmentFull = "Roguelike.StopWhenInvestmentFull"; diff --git a/src/MaaWpfGui/Main/AsstProxy.cs b/src/MaaWpfGui/Main/AsstProxy.cs index e686a81755..46892dcca2 100644 --- a/src/MaaWpfGui/Main/AsstProxy.cs +++ b/src/MaaWpfGui/Main/AsstProxy.cs @@ -2443,14 +2443,16 @@ namespace MaaWpfGui.Main /// 开始探索次数。 /// 是否投资源石锭 /// 投资时候刷更多分 + /// 刷开局模式是否购物 /// 投资源石锭次数。 /// 投资满了自动停止任务。 + /// 烧水时使用的分队 /// 开局分队 /// 开局职业组 /// 开局干员名 /// 是否凹开局直升 /// 是否只凹开局直升,不进行作战 - /// 是否凹 2 构想 + /// 需要刷的开局 /// 凹第一层远见板子 /// 需要凹的板子 /// 是否在萨米肉鸽生活队凹开局板子 @@ -2473,14 +2475,16 @@ namespace MaaWpfGui.Main int starts, bool investmentEnabled, bool investmentWithMoreScore, + bool collectibleModeShopping, int invests, bool stopWhenFull, + string collectibleModeSquad, string squad, string roles, string coreChar, bool startWithEliteTwo, bool onlyStartWithEliteTwo, - bool startWithTwoIdeas, + List startWithSelectList, bool roguelike3FirstFloorFoldartal, string roguelike3StartFloorFoldartal, bool roguelike3NewSquad2StartingFoldartal, @@ -2533,9 +2537,45 @@ namespace MaaWpfGui.Main taskParams["core_char"] = coreChar; } - taskParams["start_with_elite_two"] = startWithEliteTwo; - taskParams["only_start_with_elite_two"] = onlyStartWithEliteTwo; + if (mode == 0) + { + taskParams["stop_at_final_boss"] = stopAtFinalBoss; + taskParams["stop_at_max_level"] = stopAtMaxLevel; + } + else if (mode == 1) + { + taskParams["start_with_seed"] = startWithSeed; + } + else if (mode == 4) + { + // 刷开局模式 + taskParams["collectible_mode_shopping"] = collectibleModeShopping; + taskParams["collectible_mode_squad"] = collectibleModeSquad; + taskParams["start_with_elite_two"] = startWithEliteTwo; + taskParams["only_start_with_elite_two"] = onlyStartWithEliteTwo; + var rewardKeys = new Dictionary + { + { "Roguelike@LastReward", "hot_water" }, + { "Roguelike@LastReward2", "shield" }, + { "Roguelike@LastReward3", "ingot" }, + { "Roguelike@LastReward4", "hope" }, + { "Roguelike@LastRewardRand", "random" }, + { "Mizuki@Roguelike@LastReward5", "key" }, + { "Mizuki@Roguelike@LastReward6", "dice" }, + { "Sarkaz@Roguelike@LastReward5", "ideas" }, + }; + var startWithSelect = new JObject(); + foreach (var select in startWithSelectList) + { + if (rewardKeys.TryGetValue(select, out var paramKey)) + { + startWithSelect[paramKey] = true; + } + } + + taskParams["collectible_mode_start_list"] = startWithSelect; + } if (mode == 6) { taskParams["monthly_squad_auto_iterate"] = monthlySquadAutoIterate; @@ -2547,7 +2587,6 @@ namespace MaaWpfGui.Main taskParams["deep_exploration_auto_iterate"] = deepExplorationAutoIterate; } - taskParams["start_with_two_ideas"] = startWithTwoIdeas; if (roguelike3FirstFloorFoldartal && roguelike3StartFloorFoldartal.Length > 0) { taskParams["first_floor_foldartal"] = roguelike3StartFloorFoldartal; @@ -2567,11 +2606,6 @@ namespace MaaWpfGui.Main taskParams["use_nonfriend_support"] = enableNonFriendSupport; taskParams["refresh_trader_with_dice"] = theme == "Mizuki" && refreshTraderWithDice; - taskParams["stop_at_final_boss"] = mode == 0 && stopAtFinalBoss; - taskParams["stop_at_max_level"] = mode == 0 && stopAtMaxLevel; - - taskParams["start_with_seed"] = startWithSeed; - AsstTaskId id = AsstAppendTaskWithEncoding("Roguelike", taskParams); _latestTaskId[TaskType.Roguelike] = id; return id != 0; diff --git a/src/MaaWpfGui/Res/Localizations/en-us.xaml b/src/MaaWpfGui/Res/Localizations/en-us.xaml index ac6556d887..c5ed0523da 100644 --- a/src/MaaWpfGui/Res/Localizations/en-us.xaml +++ b/src/MaaWpfGui/Res/Localizations/en-us.xaml @@ -126,6 +126,7 @@ Invests coins, exits after arriving at the second level Grind to obtain Hot Water Kettle or Elite II operators Farm collapse paradigms, restart immediately after encountering a non-rare collapse paradigm + Squad to get collectibles Grind Monthly Squad,exits after arriving at the fifth level Grind Deep Exploration,clear as far as possible Starting Squad @@ -316,6 +317,16 @@ You can cancel this popup by clicking the Settings - About Us - Issue Reporting Stops when invested coins reach limit Invest coins Investment mode enables shopping, recruitment, and entering the second floor + Enable shopping in the grinding mode + Grinding mode expected rewards + Hot Water Kettle + Shield + Ingot + Hope + Random Reward + Key + Dice + Idea[TODO] Refresh Rogue Trader with Dice Penguin Report ID (Number part) Report Penguin diff --git a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml index 1968ee84cc..ea55d83b2a 100644 --- a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml +++ b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml @@ -126,6 +126,7 @@ 源石錐の収集、2層到着後終了 支援選択を得るため3層到着後に終了 パラダイムロストをファーミングして、非レアパラダイムロストに遭遇したらすぐに再起動します + 支援選択を得るモードの分隊 月間小隊をグラインドし、第五層に到達したら即座に退出 深層探索をグラインドし、できるだけ多くの層をクリア 最初の分隊 @@ -316,6 +317,16 @@ 源石錐が上限に達した後に停止する 源石錐を投資する 投資モードでは買い物、採用、2階への入場が可能 + 支援選択を得るモードで、ショッピング有効化 + 支援選択の期待される報酬 + 電気ケトル + シールド値 + 源石錐 + 希望 + ランダム報酬 + + ダイスロール回数 + 構想(占位) ダイスで品揃えを更新する(ミチビキリンジュウ) Penguin-StatsのレポートのID(デジタル部分のみ) Penguin-Statsへ報告 diff --git a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml index a922595aea..e1f0d2d497 100644 --- a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml +++ b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml @@ -126,6 +126,7 @@ 오리지늄 각뿔 우선, 2번째 구역 도달 시 탐험 중도 포기 전기주전자 획득까지 반복, 3번째 구역 도달 시 탐험 중도 포기 희귀 붕괴 패러다임 파밍, 일반 붕괴 패러다임이 나올 시 재시작 + 작전 지원 선택 분대 월간 소대를 그라인드하고, 5층에 도달하면 바로 종료 심층 탐사를 그라인드하고 가능한 한 많은 층을 클리어 시작 분대 @@ -316,6 +317,16 @@ 오리지늄 각뿔이 한계 도달 시 중지 오리지늄 각뿔 투자 투자 시 쇼핑, 모집, 2스테이지 진입 + 작전 지원 선택 모드 쇼핑 활성화 + 작전 지원 보상 선택 + 전기주전자 + 실드 + 각뿔 + 희망 + 랜덤 보상 + 열쇠 + 주사위 + 구상 상점 새로고침 Penguin-Stats 보고 ID (숫자만) Penguin-Stats 보고 diff --git a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml index 3b9da299bc..5ad0ceccf9 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml @@ -126,6 +126,7 @@ 刷源石锭,到达第二层后直接退出 刷开局,刷取热水壶或精二干员开局 刷坍缩范式,遇到非稀有坍缩范式后直接重开 + 烧水使用分队 刷月度小队,到达第五层后直接退出 刷深入调查,尽可能稳定地打更多层数 开局分队 @@ -319,6 +320,16 @@ 储备源石锭达到上限时停止 投资源石锭 投资模式启用购物、招募、进2层 + 刷开局模式启用购物 + 刷开局期望奖励 + 热水壶 + + + 希望 + 随机奖励 + 钥匙 + 骰子 + 构想 刷新商店(指路鳞) 企鹅物流汇报ID(仅数字部分) 上报企鹅物流 @@ -328,7 +339,7 @@ 信用交易所自动购物 一日只执行一次 借助战打 OF-1 赚信用 - 访问好友后借助战打一把OF-1赚30信用。 + 访问好友后借助战打一把 OF-1 赚 30 信用。 一日只执行一次。 关卡选择为「当前/上次」时此功能无效。 别传「火蓝之心」关卡OF-1未解锁时请勿勾选。 diff --git a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml index 29b2a84761..5c2f3b8d90 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml @@ -126,6 +126,7 @@ 刷源石錠,到達第二層後直接退出 刷開局,刷取熱水壺或精二幹員開局 刷坍縮範式,遇到非稀有坍縮範式後直接重開 + 燒水分隊 刷月度小隊,到達第五層後直接退出 刷深入調查,盡可能穩定地打更多層數 開局分隊 @@ -139,8 +140,8 @@ 凹第一層遠見密文板,不進行作戰 生活隊凹開局密文板 最多寫三個,並用英文分號;隔開 - 坍缩范式列表 - 用英文分号「;」隔开,留空将使用默认列表。 + 坍縮範式列表 + 用英文分號「;」隔開,留白將使用默認列表。 「開局幹員」使用助戰 可以使用非好友助戰 肉鴿在戰鬥結束前延遲「停止」動作 @@ -250,7 +251,7 @@ 文件名: 已將其刪除! 已是最新版本 ~ - 當前爲調試版本,無需更新 + 當前爲測試版本,無需更新 檢查更新失敗 請檢查網絡連接或代理。 獲取更新資訊失敗。 @@ -287,7 +288,7 @@ 等待模擬器啟動時間(秒) 等待結束 模擬器路徑 - 你也想在酒吧里點酒吧? + 你也想在酒吧裡點酒吧? 我確定沒選錯 好的,我會重新選擇 選擇 @@ -316,6 +317,16 @@ 儲備源石錠達到上限時停止 投資源石錠 投資模式啟用購物、招募、進2層 + 刷開局模式啟用購物 + 刷開局期望獎勵 + 熱水壺 + + 源石錠 + 希望 + 隨機獎勵 + 鑰匙 + 骰子 + 構想 刷新商店(指路鱗) 企鵝物流匯報 ID(僅數字部分) 上報企鵝物流 diff --git a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs index 9ed203ac0d..5f8266f858 100644 --- a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs +++ b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs @@ -685,8 +685,8 @@ namespace MaaWpfGui.ViewModels.UI } List windowTitleSelectShowList = GuiSettings.WindowTitleSelectShowList - .Where(x => GuiSettingsUserControlModel.WindowTitleAllShowDict.ContainsKey(x?.ToString() ?? string.Empty)) - .Select(x => GuiSettingsUserControlModel.WindowTitleAllShowDict[x?.ToString() ?? string.Empty]).ToList(); + .Cast>().Select(pair => pair.Key) + .ToList(); string currentConfiguration = string.Empty; string connectConfigName = string.Empty; diff --git a/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs b/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs index 28f9530512..aac353ae58 100644 --- a/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs +++ b/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs @@ -1825,14 +1825,16 @@ namespace MaaWpfGui.ViewModels.UI RoguelikeTask.RoguelikeStartsCount, RoguelikeTask.RoguelikeInvestmentEnabled, RoguelikeTask.RoguelikeInvestmentWithMoreScore, + RoguelikeTask.RoguelikeCollectibleModeShopping, RoguelikeTask.RoguelikeInvestsCount, RoguelikeTask.RoguelikeStopWhenInvestmentFull, + RoguelikeTask.RoguelikeCollectibleModeSquad, RoguelikeTask.RoguelikeSquad, RoguelikeTask.RoguelikeRoles, DataHelper.GetCharacterByNameOrAlias(RoguelikeTask.RoguelikeCoreChar)?.Name ?? RoguelikeTask.RoguelikeCoreChar, RoguelikeTask.RoguelikeStartWithEliteTwo, RoguelikeTask.RoguelikeOnlyStartWithEliteTwo, - RoguelikeTask.RoguelikeStartWithTwoIdeas, + RoguelikeTask.RoguelikeStartWithSelectList, RoguelikeTask.Roguelike3FirstFloorFoldartal, RoguelikeTask.Roguelike3StartFloorFoldartal, RoguelikeTask.Roguelike3NewSquad2StartingFoldartal, diff --git a/src/MaaWpfGui/ViewModels/UserControl/Settings/GuiSettingsUserControlModel.cs b/src/MaaWpfGui/ViewModels/UserControl/Settings/GuiSettingsUserControlModel.cs index 6621d1c4d6..76e332ed4c 100644 --- a/src/MaaWpfGui/ViewModels/UserControl/Settings/GuiSettingsUserControlModel.cs +++ b/src/MaaWpfGui/ViewModels/UserControl/Settings/GuiSettingsUserControlModel.cs @@ -282,27 +282,19 @@ public class GuiSettingsUserControlModel : PropertyChangedBase } private static readonly Dictionary _windowTitleAllShowDict = new() - { - { LocalizationHelper.GetString("ConfigurationName"), "1" }, - { LocalizationHelper.GetString("ConnectionPreset"), "2" }, - { LocalizationHelper.GetString("ConnectionAddress"), "3" }, - { LocalizationHelper.GetString("ClientType"), "4" }, - }; + { + { "1", LocalizationHelper.GetString("ConfigurationName") }, + { "2", LocalizationHelper.GetString("ConnectionPreset") }, + { "3", LocalizationHelper.GetString("ConnectionAddress") }, + { "4", LocalizationHelper.GetString("ClientType") }, + }; public static Dictionary WindowTitleAllShowDict { get => _windowTitleAllShowDict; } - private static List _windowTitleAllShowList = [.. _windowTitleAllShowDict.Keys]; - - public List WindowTitleAllShowList - { - get => _windowTitleAllShowList; - set => SetAndNotify(ref _windowTitleAllShowList, value); - } - private static object[] _windowTitleSelectShowList = ConfigurationHelper.GetGlobalValue(ConfigurationKeys.WindowTitleSelectShowList, "1 2 3 4") .Split(' ') - .Where(s => _windowTitleAllShowDict.ContainsValue(s.ToString())) - .Select(s => _windowTitleAllShowDict.FirstOrDefault(pair => pair.Value == s).Key) + .Where(s => _windowTitleAllShowDict.ContainsKey(s.ToString())) + .Select(s => (object)new KeyValuePair(s, _windowTitleAllShowDict[s])) .ToArray(); public object[] WindowTitleSelectShowList @@ -312,7 +304,7 @@ public class GuiSettingsUserControlModel : PropertyChangedBase { SetAndNotify(ref _windowTitleSelectShowList, value); Instances.SettingsViewModel.UpdateWindowTitle(); - var config = string.Join(' ', _windowTitleSelectShowList.Cast().Select(s => _windowTitleAllShowDict[s])); + var config = string.Join(' ', _windowTitleSelectShowList.Cast>().Select(pair => pair.Key).ToList()); ConfigurationHelper.SetGlobalValue(ConfigurationKeys.WindowTitleSelectShowList, config); } } diff --git a/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/RoguelikeSettingsUserControlModel.cs b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/RoguelikeSettingsUserControlModel.cs index e7794bfb65..7f6951aa52 100644 --- a/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/RoguelikeSettingsUserControlModel.cs +++ b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/RoguelikeSettingsUserControlModel.cs @@ -333,6 +333,21 @@ public class RoguelikeSettingsUserControlModel : TaskViewModel } } + private string _roguelikeCollectibleModeSquad = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeCollectibleModeSquad, string.Empty); + + /// + /// Gets or sets the roguelike squad using for last reward mode. + /// + public string RoguelikeCollectibleModeSquad + { + get => _roguelikeCollectibleModeSquad; + set + { + SetAndNotify(ref _roguelikeCollectibleModeSquad, value); + ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeCollectibleModeSquad, value); + } + } + private string _roguelikeSquad = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeSquad, string.Empty); /// @@ -464,21 +479,38 @@ public class RoguelikeSettingsUserControlModel : TaskViewModel /// public bool RoguelikeOnlyStartWithEliteTwo => _roguelikeOnlyStartWithEliteTwo && RoguelikeStartWithEliteTwo; - private bool _roguelikeStartWithTwoIdeas = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeStartWithTwoIdeas, bool.FalseString)); - - /// - /// Gets or sets a value indicating whether we need to start with two ideas. - /// - public bool RoguelikeStartWithTwoIdeas + public static Dictionary RoguelikeStartWithAllDict { get; } = new() { - get => _roguelikeStartWithTwoIdeas; + { "Roguelike@LastReward", LocalizationHelper.GetString("RoguelikeStartWithKettle") }, + { "Roguelike@LastReward2", LocalizationHelper.GetString("RoguelikeStartWithShield") }, + { "Roguelike@LastReward3", LocalizationHelper.GetString("RoguelikeStartWithIngot") }, + { "Roguelike@LastReward4", LocalizationHelper.GetString("RoguelikeStartWithHope") }, + { "Roguelike@LastRewardRand", LocalizationHelper.GetString("RoguelikeStartWithRandomReward") }, + { "Mizuki@Roguelike@LastReward5", LocalizationHelper.GetString("RoguelikeStartWithKey") }, + { "Mizuki@Roguelike@LastReward6", LocalizationHelper.GetString("RoguelikeStartWithDice") }, + { "Sarkaz@Roguelike@LastReward5", LocalizationHelper.GetString("RoguelikeStartWithIdea") }, + }; + + private static object[] _roguelikeStartWithSelectListRaw = ConfigurationHelper.GetGlobalValue(ConfigurationKeys.RoguelikeStartWithSelectList, "Roguelike@LastReward Roguelike@LastReward4 Sarkaz@Roguelike@LastReward5") + .Split(' ') + .Where(s => RoguelikeStartWithAllDict.ContainsKey(s.ToString())) + .Select(s => (object)new KeyValuePair(s, RoguelikeStartWithAllDict[s])) + .ToArray(); + + public object[] RoguelikeStartWithSelectListRaw + { + get => _roguelikeStartWithSelectListRaw; set { - SetAndNotify(ref _roguelikeStartWithTwoIdeas, value); - ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeStartWithTwoIdeas, value.ToString()); + SetAndNotify(ref _roguelikeStartWithSelectListRaw, value); + Instances.SettingsViewModel.UpdateWindowTitle(); + var config = string.Join(' ', _roguelikeStartWithSelectListRaw.Cast>().Select(pair => pair.Key).ToList()); + ConfigurationHelper.SetGlobalValue(ConfigurationKeys.RoguelikeStartWithSelectList, config); } } + public List RoguelikeStartWithSelectList => (RoguelikeMode == "4" && !RoguelikeOnlyStartWithEliteTwo) ? _roguelikeStartWithSelectListRaw.Cast>().Select(pair => pair.Key).ToList() : []; + private bool _roguelike3FirstFloorFoldartal = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.Roguelike3FirstFloorFoldartal, bool.FalseString)); /// @@ -644,6 +676,21 @@ public class RoguelikeSettingsUserControlModel : TaskViewModel /// public bool RoguelikeInvestmentWithMoreScore => _roguelikeInvestmentWithMoreScore && RoguelikeMode == "1"; + private bool _roguelikeCollectibleModeShopping = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeCollectibleModeShopping, bool.FalseString)); + + /// + /// Gets or sets a value indicating whether shopping is enabled in LastReward Mode. + /// + public bool RoguelikeCollectibleModeShopping + { + get => _roguelikeCollectibleModeShopping; + set + { + SetAndNotify(ref _roguelikeCollectibleModeShopping, value); + ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeCollectibleModeShopping, value.ToString()); + } + } + private bool _roguelikeRefreshTraderWithDice = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeRefreshTraderWithDice, bool.FalseString)); public bool RoguelikeRefreshTraderWithDiceRaw diff --git a/src/MaaWpfGui/Views/UserControl/Settings/GuiSettingsUserControl.xaml b/src/MaaWpfGui/Views/UserControl/Settings/GuiSettingsUserControl.xaml index 1e50e58c78..79019ddf56 100644 --- a/src/MaaWpfGui/Views/UserControl/Settings/GuiSettingsUserControl.xaml +++ b/src/MaaWpfGui/Views/UserControl/Settings/GuiSettingsUserControl.xaml @@ -59,14 +59,15 @@ + IsChecked="{Binding InvertNullFunction}" />--> diff --git a/src/MaaWpfGui/Views/UserControl/TaskQueue/RoguelikeSettingsUserControl.xaml b/src/MaaWpfGui/Views/UserControl/TaskQueue/RoguelikeSettingsUserControl.xaml index 8de11e0b0e..7cc31b04a9 100644 --- a/src/MaaWpfGui/Views/UserControl/TaskQueue/RoguelikeSettingsUserControl.xaml +++ b/src/MaaWpfGui/Views/UserControl/TaskQueue/RoguelikeSettingsUserControl.xaml @@ -44,6 +44,16 @@ ItemsSource="{Binding RoguelikeModeList}" SelectedValue="{Binding RoguelikeMode}" SelectedValuePath="Value" /> + + + + - - - + hc:ListBoxAttach.SelectedItems="{Binding RoguelikeStartWithSelectListRaw}" + hc:TitleElement.Title="{DynamicResource RoguelikeStartWithSelectList}" + DisplayMemberPath="Value" + ItemsSource="{Binding RoguelikeStartWithAllDict}" + Style="{StaticResource CheckComboBoxExtend}" + Visibility="{c:Binding 'RoguelikeMode == "4" and !RoguelikeOnlyStartWithEliteTwoRaw'}" /> -