diff --git a/docs/3.6-基建排班协议.md b/docs/3.6-基建排班协议.md index 42195fdf7f..bd805e8f0c 100644 --- a/docs/3.6-基建排班协议.md +++ b/docs/3.6-基建排班协议.md @@ -47,6 +47,24 @@ icon: material-symbols:view-quilt-rounded "rule": "all", // 使用规则,保留字段,目前无作用。以后可能拿来支持插拔等操作 "order": "pre" // 在换干员前使用还是在换完才用,可选,取值范围 "pre" / "post",默认 "pre" }, + "groups":[ // 对于 "control" / "manufacture" / "trading",可以设置干员编组 + { + "name":"古+银", + "operators":[ + "古米", + "银灰", + "梅" + ] + }, + { + "name":"清流", + "operators":[ + "清流", + "森蚺", + "温蒂" + ] + } + ], "rooms": { // 房间信息,必选 // 取值范围 "control" / "manufacture" / "trading" / "power" / "meeting" / "hire" / "dormitory" / "processing" // 缺少某个则该设施使用默认算法进行换班。 @@ -99,6 +117,13 @@ icon: material-symbols:view-quilt-rounded "白面鸮", "赫默" ] + }, + { + "use_operator_groups":true, // 设置为 true 以使用 groups 中的干员编组,默认为 false + "operators":[ // 启用后, operators 中的名字将被解释为编组名 + "古+银", // 将按照心情阈值以及设置顺序选择编组 + "清流" // 如 古+银 组中有干员心情低于阈值,将使用 清流 组 + ] } ], "meeting": [ diff --git a/docs/en-us/3.6-INFRASTRUCTURE_SCHEDULING_SCHEMA.md b/docs/en-us/3.6-INFRASTRUCTURE_SCHEDULING_SCHEMA.md index 913c22807d..23096de074 100644 --- a/docs/en-us/3.6-INFRASTRUCTURE_SCHEDULING_SCHEMA.md +++ b/docs/en-us/3.6-INFRASTRUCTURE_SCHEDULING_SCHEMA.md @@ -44,6 +44,24 @@ Usage and Field Description for `resource/custom_infrast/*.json` files "rule": "all", // Usage rules. Reserved field. Currently unused, but may be used in the future to support plug-ins and other operations. "order": "pre" // Whether to use drones before or after changing operators. Optional. Possible values: "pre" / "post". Default is "pre". }, + "groups":[ // For "control" / "manufacture" / "trading", operator groups can be set + { + "name":"A", + "operators":[ + "古米", + "银灰", + "梅" + ] + }, + { + "name":"B", + "operators":[ + "清流", + "森蚺", + "温蒂" + ] + } + ], "rooms": { // Room information. Required. // Possible values: "control" / "manufacture" / "trading" / "power" / "meeting" / "hire" / "dormitory" / "processing". // If a room is not specified, the default algorithm will be used to change operators. @@ -96,6 +114,13 @@ Usage and Field Description for `resource/custom_infrast/*.json` files "白面鸮", "赫默" ] + }, + { + "use_operator_groups":true, // Set to true to use the grouping of operators in groups, default is false + "operators":[ // When enabled, names in operators will be interpreted as group names + "A", // Grouping will be selected according to mood threshold and setting order + "B" // If any operator in group A whose mood is below the threshold, group B will be used + ] } ], "meeting": [ diff --git a/docs/ja-jp/3.6-インフラスケジュール設定.md b/docs/ja-jp/3.6-インフラスケジュール設定.md index 46098411bc..5fa8de9d1d 100644 --- a/docs/ja-jp/3.6-インフラスケジュール設定.md +++ b/docs/ja-jp/3.6-インフラスケジュール設定.md @@ -37,6 +37,24 @@ "rule": "all", // ルール、予約フィールド、未実装. 後で使用する可能性がある。 "order": "pre" // オペレーターの交換前後の使用設定、オプション、引数 "pre" / "post", デフォルト "pre" (テキーラなど) }, + "groups":[ // "control" / "manufacture" / "trading" の場合、オペレーターグループを設定できます + { + "name":"A", + "operators":[ + "古米", + "银灰", + "梅" + ] + }, + { + "name":"B", + "operators":[ + "清流", + "森蚺", + "温蒂" + ] + } + ], "rooms": { // 部屋情報,必須 // 引数 "control" / "manufacture" / "trading" / "power" / "meeting" / "hire" / "dormitory" / "processing" // 1つもないということは、その施設ではシフト変更にデフォルトのアルゴリズムが使用されていることを意味します。 @@ -87,6 +105,13 @@ "フィリオプシス", "サイレンス" ] + }, + { + "use_operator_groups":true, // グループ内の演算子のグループ化を使用するには true に設定します。デフォルトは false です。 + "operators":[ // 有効にすると、演算子の名前がグループ名として解釈されます。 + "A", // グループ化は気分の閾値と設定順序に従って選択されます + "B" // グループ A に気分がしきい値を下回るオペレーターがいる場合、グループ B が使用されます + ] } ], "meeting": [ diff --git a/docs/zh-tw/3.6-基建排班協議.md b/docs/zh-tw/3.6-基建排班協議.md index b54adc900e..7841160616 100644 --- a/docs/zh-tw/3.6-基建排班協議.md +++ b/docs/zh-tw/3.6-基建排班協議.md @@ -47,6 +47,24 @@ icon: material-symbols:view-quilt-rounded "rule": "all", // 使用規則,保留欄位,目前無作用。以後可能拿來支援插拔等操作 "order": "pre" // 在換幹員前使用還是在換完才用,可選,取值範圍 "pre" / "post",預設 "pre" }, + "groups":[ // 對於 "control" / "manufacture" / "trading",可以設置幹員編組 + { + "name":"古+银", + "operators":[ + "古米", + "银灰", + "梅" + ] + }, + { + "name":"清流", + "operators":[ + "清流", + "森蚺", + "温蒂" + ] + } + ], "rooms": { // 房間資訊,必選 // 取值範圍 "control" / "manufacture" / "trading" / "power" / "meeting" / "hire" / "dormitory" / "processing" // 缺少某個則該設施使用預設算法進行換班。 @@ -99,6 +117,13 @@ icon: material-symbols:view-quilt-rounded "白面鴞", "赫默" ] + }, + { + "use_operator_groups":true, // 設置為 true 以使用 groups 中的干員編組,默認為 false + "operators":[ // 啟用後, operators 中的名字將被解釋為編組名 + "古+银", // 將按照心情閾值以及設置順序選擇編組 + "清流" // 如 古+银 組中有乾員心情低於閾值,將使用 清流 組 + ] } ], "meeting": [ diff --git a/src/MaaCore/Common/AsstInfrastDef.h b/src/MaaCore/Common/AsstInfrastDef.h index 6e32340167..775641b224 100644 --- a/src/MaaCore/Common/AsstInfrastDef.h +++ b/src/MaaCore/Common/AsstInfrastDef.h @@ -126,6 +126,11 @@ namespace asst::infrast }; bool skip = false; + // 是否使用干员编组 + bool use_operator_groups = false; + // 干员编组列表 + std::unordered_map> operator_groups; + // 自定干员 std::vector names; bool autofill = false; Product product = Product::Unknown; diff --git a/src/MaaCore/Task/Infrast/InfrastAbstractTask.cpp b/src/MaaCore/Task/Infrast/InfrastAbstractTask.cpp index cd7dc69f24..af1d240ec4 100644 --- a/src/MaaCore/Task/Infrast/InfrastAbstractTask.cpp +++ b/src/MaaCore/Task/Infrast/InfrastAbstractTask.cpp @@ -85,6 +85,73 @@ asst::infrast::CustomRoomConfig& asst::InfrastAbstractTask::current_room_config( } } +bool asst::InfrastAbstractTask::match_operator_groups() +{ + current_room_config().names.clear(); + int swipe_times = 0; + bool pre_result_no_changes = false, retried = false; + + std::set oper_list; + std::vector temp, pre_temp; + while (true) { + if (need_exit()) { + return false; + } + temp.clear(); + if (!get_opers(temp, m_mood_threshold)) { + return false; + } + if (pre_temp == temp) { + if (pre_result_no_changes) { + Log.warn("partial result is not changed, reset the page"); + if (retried) { + Log.error("already retring"); + break; + } + swipe_to_the_left_of_operlist(swipe_times + 1); + swipe_times = 0; + retried = true; + } + else { + pre_result_no_changes = true; + } + } + else { + pre_result_no_changes = false; + } + oper_list.insert(temp.begin(), temp.end()); + pre_temp = temp; + swipe_of_operlist(); + swipe_times++; + } + swipe_to_the_left_of_operlist(swipe_times + 1); + swipe_times = 0; + // 筛选第一个满足要求的干员组 + for (auto it = current_room_config().operator_groups.begin(); it != current_room_config().operator_groups.end(); + ++it) { + if (ranges::all_of(it->second, [oper_list](std::string& oper) { return oper_list.contains(oper); })) { + current_room_config().names.insert(current_room_config().names.end(), it->second.begin(), it->second.end()); + + json::value sanity_info = basic_info_with_what("CustomInfrastRoomGroupsMatch"); + sanity_info["details"]["group"] = it->first; + callback(AsstMsg::SubTaskExtraInfo, sanity_info); + break; + } + } + // 匹配失败,无分组可用 + if (current_room_config().names.empty() && !current_room_config().operator_groups.empty()) { + json::value info = basic_info_with_what("CustomInfrastRoomGroupsMatchFailed"); + std::vector names; + ranges::for_each( + current_room_config().operator_groups, + [&names](std::pair>& pair) { names.emplace_back(pair.first); }); + info["details"]["groups"] = json::array(std::move(names)); + callback(AsstMsg::SubTaskExtraInfo, info); + return false; + } + return true; +} + bool asst::InfrastAbstractTask::on_run_fails() { LogTraceFunction; @@ -136,6 +203,7 @@ bool asst::InfrastAbstractTask::is_use_custom_opers() } /// @brief 按技能排序->清空干员->选择定制干员->按指定顺序排序 +/// @param is_dorm_order 当前房间是不是宿舍 bool asst::InfrastAbstractTask::swipe_and_select_custom_opers(bool is_dorm_order) { LogTraceFunction; @@ -168,14 +236,17 @@ bool asst::InfrastAbstractTask::swipe_and_select_custom_opers(bool is_dorm_order bool retried = false; bool pre_result_no_changes = false; int swipe_times = 0; + while (true) { if (need_exit()) { return false; } std::vector partial_result; + // 选择自定义干员,同时输出每一页的干员列表 if (!select_custom_opers(partial_result)) { return false; } + // 选完人 / 名单已空 if (static_cast(room_config.selected) >= max_num_of_opers() || (room_config.names.empty() && room_config.candidates.empty())) { break; @@ -347,8 +418,8 @@ bool asst::InfrastAbstractTask::select_custom_opers(std::vector& pa if (auto iter = ranges::find(room_config.names, name); iter != room_config.names.end()) { room_config.names.erase(iter); } - else if (max_num_of_opers() - room_config.selected > - room_config.names.size()) { // names中的数量,比剩余的空位多,就可以选备选的 + else if (max_num_of_opers() - room_config.selected > room_config.names.size()) { + // names中的数量,比剩余的空位多,就可以选备选的 if (auto candd_iter = ranges::find(room_config.candidates, name); candd_iter != room_config.candidates.end()) { room_config.candidates.erase(candd_iter); @@ -370,6 +441,36 @@ bool asst::InfrastAbstractTask::select_custom_opers(std::vector& pa return true; } +bool asst::InfrastAbstractTask::get_opers(std::vector& result, double mood) +{ + LogTraceFunction; + + const auto image = ctrler()->get_image(); + InfrastOperImageAnalyzer oper_analyzer(image); + oper_analyzer.set_to_be_calced(InfrastOperImageAnalyzer::ToBeCalced::Mood); + if (!oper_analyzer.analyze()) { + Log.warn(__FUNCTION__, "No oper"); + return false; + } + oper_analyzer.sort_by_loc(); + + const auto& ocr_replace = Task.get("CharsNameOcrReplace"); + for (const auto& oper : oper_analyzer.get_result()) { + RegionOCRer name_analyzer; + name_analyzer.set_replace(ocr_replace->replace_map, ocr_replace->replace_full); + name_analyzer.set_image(oper.name_img); + name_analyzer.set_bin_expansion(0); + if (!name_analyzer.analyze()) { + continue; + } + std::string name = name_analyzer.get_result().text; + if (oper.mood_ratio >= mood) { + result.emplace_back(std::move(name)); + } + } + return true; +} + void asst::InfrastAbstractTask::order_opers_selection(const std::vector& names) { LogTraceFunction; diff --git a/src/MaaCore/Task/Infrast/InfrastAbstractTask.h b/src/MaaCore/Task/Infrast/InfrastAbstractTask.h index e188b30b17..5535fb2123 100644 --- a/src/MaaCore/Task/Infrast/InfrastAbstractTask.h +++ b/src/MaaCore/Task/Infrast/InfrastAbstractTask.h @@ -28,29 +28,41 @@ namespace asst virtual bool on_run_fails() override; bool enter_facility(int index = 0); - bool enter_oper_list_page(); // 从刚点进设施的界面,到干员列表页 + // 从刚点进设施的界面,到干员列表页 + bool enter_oper_list_page(); virtual int operlist_swipe_times() const noexcept { return 2; } - void swipe_to_the_left_of_operlist(int loop_times = -1); // 滑动到干员列表的最左侧 - void swipe_to_the_left_of_main_ui(); // 滑动基建的主界面到最左侧 - void swipe_to_the_right_of_main_ui(); // 滑动基建的主界面到最右侧 + // 滑动到干员列表的最左侧 + void swipe_to_the_left_of_operlist(int loop_times = -1); + // 滑动基建的主界面到最左侧 + void swipe_to_the_left_of_main_ui(); + // 滑动基建的主界面到最右侧 + void swipe_to_the_right_of_main_ui(); void swipe_of_operlist(); bool is_use_custom_opers(); infrast::CustomRoomConfig& current_room_config(); + bool match_operator_groups(); bool swipe_and_select_custom_opers(bool is_dorm_order = false); bool select_custom_opers(std::vector& partial_result); - bool select_opers_review(infrast::CustomRoomConfig const& origin_room_config, - size_t num_of_opers_expect = 0); // 复核干员选择是否符合期望 + // 扫描当前页满足心情条件的所有干员名 + bool get_opers(std::vector& result, double mood = 1); + // 复核干员选择是否符合期望 + bool select_opers_review(infrast::CustomRoomConfig const& origin_room_config, size_t num_of_opers_expect = 0); void order_opers_selection(const std::vector& names); virtual void click_return_button() override; - virtual bool click_bottom_left_tab(); // 点击进入设施后,左下角的tab(我也不知道这玩意该叫啥) - virtual bool click_clear_button(); // 点击干员选择页面的“清空选择”按钮 - virtual bool click_sort_by_trust_button(); // 点击干员选择页面的“按信赖值排序”按钮 - virtual bool click_filter_menu_not_stationed_button(); // 点击干员选择页面的筛选菜单按钮的“未进驻”按钮 - virtual bool - click_filter_menu_cancel_not_stationed_button(); // 取消点击干员选择页面的筛选菜单按钮的“未进驻”按钮 - virtual bool click_confirm_button(); // 点击干员选择页面的“确认”按钮 + // 点击进入设施后,左下角的tab(我也不知道这玩意该叫啥) + virtual bool click_bottom_left_tab(); + // 点击干员选择页面的“清空选择”按钮 + virtual bool click_clear_button(); + // 点击干员选择页面的“按信赖值排序”按钮 + virtual bool click_sort_by_trust_button(); + // 点击干员选择页面的筛选菜单按钮的“未进驻”按钮 + virtual bool click_filter_menu_not_stationed_button(); + // 取消点击干员选择页面的筛选菜单按钮的“未进驻”按钮 + virtual bool click_filter_menu_cancel_not_stationed_button(); + // 点击干员选择页面的“确认”按钮 + virtual bool click_confirm_button(); int m_last_swipe_id = 0; const std::string m_work_mode_name = diff --git a/src/MaaCore/Task/Infrast/InfrastControlTask.cpp b/src/MaaCore/Task/Infrast/InfrastControlTask.cpp index 76c485e491..5f8b61fb2c 100644 --- a/src/MaaCore/Task/Infrast/InfrastControlTask.cpp +++ b/src/MaaCore/Task/Infrast/InfrastControlTask.cpp @@ -19,6 +19,11 @@ bool asst::InfrastControlTask::_run() return false; } + // 如果是使用了编队组来排班 + if (current_room_config().use_operator_groups) { + match_operator_groups(); + } + for (int i = 0; i <= OperSelectRetryTimes; ++i) { if (need_exit()) { return false; diff --git a/src/MaaCore/Task/Infrast/InfrastProductionTask.cpp b/src/MaaCore/Task/Infrast/InfrastProductionTask.cpp index f1f17fb77c..d4d5269f82 100644 --- a/src/MaaCore/Task/Infrast/InfrastProductionTask.cpp +++ b/src/MaaCore/Task/Infrast/InfrastProductionTask.cpp @@ -213,6 +213,11 @@ bool asst::InfrastProductionTask::shift_facility_list() ctrler()->click(add_button); sleep(add_task_ptr->post_delay); + // 如果是使用了编队组来排班 + if (current_room_config().use_operator_groups) { + match_operator_groups(); + } + for (int i = 0; i <= OperSelectRetryTimes; ++i) { if (need_exit()) { return false; diff --git a/src/MaaCore/Task/Infrast/InfrastProductionTask.h b/src/MaaCore/Task/Infrast/InfrastProductionTask.h index c28932b993..f64bb5fdd9 100644 --- a/src/MaaCore/Task/Infrast/InfrastProductionTask.h +++ b/src/MaaCore/Task/Infrast/InfrastProductionTask.h @@ -22,7 +22,8 @@ namespace asst bool shift_facility_list(); bool facility_list_detect(); bool opers_detect_with_swipe(); - size_t opers_detect(); // 返回当前页面的干员数 + // 返回当前页面的干员数 (可用? + size_t opers_detect(); bool optimal_calc(); bool opers_choose(); bool use_drone(); diff --git a/src/MaaCore/Task/Interface/InfrastTask.cpp b/src/MaaCore/Task/Interface/InfrastTask.cpp index d626fcf433..d30873914f 100644 --- a/src/MaaCore/Task/Interface/InfrastTask.cpp +++ b/src/MaaCore/Task/Interface/InfrastTask.cpp @@ -177,6 +177,18 @@ bool asst::InfrastTask::parse_and_set_custom_config(const std::filesystem::path& } auto& cur_plan = all_plans.at(index); + // 录入干员编组 + std::unordered_map> ori_operator_groups; + if (auto opt = cur_plan.find("groups")) { + for (const auto& group_info : opt.value()) { + std::vector oper_group; + for (const auto& oper_info : group_info.at("operators").as_array()) { + oper_group.emplace_back(oper_info.as_string()); + } + ori_operator_groups.emplace(group_info.at("name").as_string(), std::move(oper_group)); + } + } + for (const auto& [facility, facility_info] : cur_plan.at("rooms").as_object()) { infrast::CustomFacilityConfig facility_config; @@ -185,6 +197,8 @@ bool asst::InfrastTask::parse_and_set_custom_config(const std::filesystem::path& room_config.skip = room_info.get("skip", false); room_config.autofill = room_info.get("autofill", false); room_config.sort = room_info.get("sort", false); + room_config.use_operator_groups = room_info.get("use_operator_groups", false); + static std::unordered_map ProductNames = { { "Battle Record", infrast::CustomRoomConfig::Product::BattleRecord }, { "Pure Gold", infrast::CustomRoomConfig::Product::PureGold }, @@ -204,6 +218,7 @@ bool asst::InfrastTask::parse_and_set_custom_config(const std::filesystem::path& } } + // 设置干员 if (auto opers_opt = room_info.find("operators")) { for (const auto& oper_name : opers_opt.value()) { std::string name = oper_name.as_string(); @@ -213,7 +228,21 @@ bool asst::InfrastTask::parse_and_set_custom_config(const std::filesystem::path& } room_config.names.emplace_back(std::move(name)); } + if (room_config.use_operator_groups) { + // 将引用了的干员编组,装载到对应房间配置 + // name数组此后可以作废 + std::set name_set; + name_set.insert(room_config.names.begin(), room_config.names.end()); + ranges::for_each(ori_operator_groups, + [name_set, &room_config](std::pair> pair) { + if (name_set.contains(pair.first)) { + room_config.operator_groups[pair.first] = std::move(pair.second); + } + }); + } } + + // 备选干员 if (auto candidates_opt = room_info.find("candidates")) { for (const auto& candidate_name : candidates_opt.value()) { std::string name = candidate_name.as_string(); @@ -227,6 +256,7 @@ bool asst::InfrastTask::parse_and_set_custom_config(const std::filesystem::path& facility_config.emplace_back(std::move(room_config)); } + // 不同类型建筑配置 if (facility == "control") { m_control_task_ptr->set_custom_config(facility_config); } @@ -257,6 +287,7 @@ bool asst::InfrastTask::parse_and_set_custom_config(const std::filesystem::path& } } + // 菲亚梅塔 bool Fia_is_pre = false; do { auto Fia_opt = cur_plan.find("Fiammetta"); @@ -302,6 +333,7 @@ bool asst::InfrastTask::parse_and_set_custom_config(const std::filesystem::path& } } while (false); + // 无人机 do { auto drones_opt = cur_plan.find("drones"); if (!drones_opt) { diff --git a/src/MaaWpfGui/Main/AsstProxy.cs b/src/MaaWpfGui/Main/AsstProxy.cs index d9ed26490c..7d27a8b705 100644 --- a/src/MaaWpfGui/Main/AsstProxy.cs +++ b/src/MaaWpfGui/Main/AsstProxy.cs @@ -1073,6 +1073,15 @@ namespace MaaWpfGui.Main Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("UnsupportedLevel"), UiLogColor.Error); break; + case "CustomInfrastRoomGroupsMatch": + // 选用xxx组编组 + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RoomGroupsMatch") + subTaskDetails["group"]); + break; + case "CustomInfrastRoomGroupsMatchFailed": + // 干员编组匹配失败 + JArray groups = (JArray)subTaskDetails["groups"]; + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RoomGroupsMatchFailed") + string.Join(", ", groups)); + break; case "CustomInfrastRoomOperators": string nameStr = string.Empty; foreach (var name in subTaskDetails["names"]) @@ -1085,7 +1094,7 @@ namespace MaaWpfGui.Main nameStr = nameStr.Remove(nameStr.Length - 2); } - Instances.TaskQueueViewModel.AddLog(nameStr.ToString()); + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RoomOperators") + nameStr.ToString()); break; /* 生息演算 */ diff --git a/src/MaaWpfGui/Res/Localizations/en-us.xaml b/src/MaaWpfGui/Res/Localizations/en-us.xaml index cbaae28f45..ce68eeba20 100644 --- a/src/MaaWpfGui/Res/Localizations/en-us.xaml +++ b/src/MaaWpfGui/Res/Localizations/en-us.xaml @@ -81,7 +81,7 @@ 2nd Resolution General Mode (Blocked exception output) Morale Threshold - If custom shift is enabled, this field is only valid for autofilled rooms + If custom shifts are enabled, this field is only valid for rooms with autofill and operator groups Gains Experience Points, clears as many nodes as possible Invests coins, exits after arriving at the second floor @@ -549,6 +549,9 @@ The video aspect ratio needs to be 16:9 without interference factors such as bla Drops: Total Drops: Current Facility: + Match to Group: + Failed to match operator groups, group list: + preferred operators: Product does NOT match the configuration. Unknown Product Product has changed diff --git a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml index 45276b9851..b085aebcc9 100644 --- a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml +++ b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml @@ -73,7 +73,7 @@ 2番目の決議 一般モード(ブロックされた例外出力) 体力が設定した%以下になれば宿舎へ移動する - カスタムシフトが有効な場合、この項目は自動入力された部屋に対してのみ有効です + カスタム シフトが有効な場合、このフィールドは自動入力とオペレーター グループのあるルームに対してのみ有効です 経験値を取得し、できるだけクリア 源石錐の収集、2階到着後終了 @@ -539,6 +539,9 @@ Bilibili: ログイン インターフェイスに表示されるアカウント ドロップ: ドロップ統計: 現在の施設: + グループに合わせる: + オペレータ グループ、グループ リストの一致に失敗しました: + 優先しています: 製品が構成と一致しません。 Unknown Product Product has changed diff --git a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml index b2dca3aec3..c740ae9db0 100644 --- a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml +++ b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml @@ -551,6 +551,9 @@ Bilibili: 로그인 인터페이스에 표시되는 계정 이름(예: Zhang San 드롭: 드롭 통계: 현재 시설: + 그룹에 일치: + 운영자 그룹, 그룹 목록을 일치시키지 못했습니다: + 선호하는 연산자: 생산품이 구성과 맞지 않습니다. 식별할 수 없는 결과물 결과물이 변경됨 diff --git a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml index 34008f9817..8f13eb883d 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml @@ -81,7 +81,7 @@ 第二分辨率 通用模式(屏蔽异常输出) 基建工作心情阈值 - 若启用自定义换班,该字段仅针对 autofill 的房间有效 + 若启用自定义换班,该字段仅针对 autofill 和使用干员编组的房间有效 刷等级,尽可能稳定地打更多层数 刷源石锭,到达第二层后直接退出 烧开水,到达第三层后直接退出 @@ -553,6 +553,9 @@ 本次掉落: 掉落统计: 当前设施: + 匹配到编组: + 匹配干员编组失败,编组列表: + 首选干员: 产物与配置不相符。 无法识别的产物 产物已切换 diff --git a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml index 6c2263f872..0ccd388577 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml @@ -80,7 +80,7 @@ 第二分辨率 通用模式(阻擋異常輸出) 基建工作心情閾值 - 若啟用自定義換班,該欄位僅針對 autofill 的房間有效 + 若啟用自定義換班,該欄位僅針對 autofill 和 幹員編組 的房間有效 刷等級,盡可能穩定地打更多層數 刷源石錠,到達第二層後直接退出 燒開水,到達第三層後直接退出 @@ -551,6 +551,9 @@ 本次掉落: 掉落統計: 當前設施: + 匹配到編組: + 匹配幹員編組失敗,編組列表: + 首選幹員: 產物與配置不相符。 無法辨識的產物 產物已切換