From c6f974b0bf762e5d3c9b1a2fccec7f851223459e Mon Sep 17 00:00:00 2001 From: Shawnsdaddy Date: Fri, 27 Oct 2023 00:07:23 -0700 Subject: [PATCH] #352 --- arknights_mower/solvers/base_schedule.py | 24 ++++++++++++++------ arknights_mower/utils/operators.py | 29 +++++++++++++++++++++--- arknights_mower/utils/plan.py | 18 ++++++++++++++- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/arknights_mower/solvers/base_schedule.py b/arknights_mower/solvers/base_schedule.py index 369be7123..10fa97292 100644 --- a/arknights_mower/solvers/base_schedule.py +++ b/arknights_mower/solvers/base_schedule.py @@ -875,6 +875,7 @@ def get_resting_plan(self, agents, exist_replacement, plan, high_free, low_free) def initialize_operators(self): self.op_data = Operators(self.global_plan) + Operators.current_room_changed_callback = self.current_room_changed return self.op_data.init_and_validate() def check_fia(self): @@ -1935,6 +1936,21 @@ def get_order_remaining_time(self): use_digit_reader=True) return round((execute_time - datetime.now()).total_seconds(), 1) + def current_room_changed(self, instance): + logger.info(f"{instance.name} 房间变动") + ref_rooms = instance.refresh_order_room[1] if instance.refresh_order_room[1] else list(self.op_data.run_order_rooms.keys()) + for ref_room in ref_rooms: + self.refresh_run_order_time(ref_room) + + def refresh_run_order_time(self,room): + logger.debug("检测到插拔房间人员变动!") + run_order_task = find_next_task(self.tasks, datetime.now() + timedelta(minutes=15), + task_type=TaskTypes.RUN_ORDER, + meta_data=room, compare_type=">") + if run_order_task is not None: + logger.info("移除超过5分钟的跑单任务以刷新时间") + self.tasks.remove(run_order_task) + def agent_arrange_room(self, new_plan, room, plan, skip_enter=False, get_time=False): finished = False choose_error = 0 @@ -1966,13 +1982,7 @@ def agent_arrange_room(self, new_plan, room, plan, skip_enter=False, get_time=Fa if room in self.op_data.run_order_rooms and len( new_plan) == 0 and self.task.type != TaskTypes.RUN_ORDER: if plan[room] != self.op_data.get_current_room(room): - logger.debug("检测到插拔房间人员变动!") - run_order_task = find_next_task(self.tasks, datetime.now() + timedelta(minutes=15), - task_type=TaskTypes.RUN_ORDER, - meta_data=room, compare_type=">") - if run_order_task is not None: - logger.info("移除超过15分钟的跑单任务以刷新时间") - self.tasks.remove(run_order_task) + self.refresh_run_order_time(room) checked = True current_room = self.op_data.get_current_room(room, True) same = len(plan[room]) == len(current_room) diff --git a/arknights_mower/utils/operators.py b/arknights_mower/utils/operators.py index 57fd5d808..fa4cd7270 100644 --- a/arknights_mower/utils/operators.py +++ b/arknights_mower/utils/operators.py @@ -1,5 +1,5 @@ from datetime import datetime, timedelta -from ..data import agent_list, agent_arrange_order +from ..data import agent_list, agent_arrange_order, base_room_list from ..solvers.record import save_action_to_sqlite_decorator from ..utils.log import logger import copy @@ -18,6 +18,8 @@ class Operators(object): plan_name = "" shadow_copy = {} + current_room_changed_callback = None + def __init__(self, plan): self.operators = {} self.groups = {} @@ -32,6 +34,7 @@ def __init__(self, plan): self.swap_plan() self.run_order_rooms = {} self.clues = [] + self.current_room_changed_callback = None def __repr__(self): return f'Operators(operators={self.operators})' @@ -178,6 +181,7 @@ def init_and_validate(self, update=False): return f'{key} 分组无法排班,替换组数量不够' else: _replacement.append(_candidate) + if self.operators[name].workaholic: continue if self.operators[name].resting_priority == 'high': high_count += 1 else: @@ -370,6 +374,7 @@ def add(self, operator): operator.exhaust_require = self.config.get_config(operator.name, 1) operator.rest_in_full = self.config.get_config(operator.name, 0) operator.workaholic = self.config.get_config(operator.name, 2) + operator.refresh_order_room = self.config.get_config(operator.name, 5) if operator.name in agent_arrange_order: operator.arrange_order = agent_arrange_order[operator.name] # 复制基建数据 @@ -482,7 +487,10 @@ class Operator(object): def __init__(self, name, room, index=-1, group='', replacement=[], resting_priority='low', current_room='', exhaust_require=False, mood=24, upper_limit=24, rest_in_full=False, current_index=-1, lower_limit=0, operator_type="low", - depletion_rate=0, time_stamp=None): + depletion_rate=0, time_stamp=None, refresh_order_room=None): + if refresh_order_room is not None: + self.refresh_order_room = refresh_order_room + self.refresh_order_room = [False, []] self.name = name self.room = room self.operator_type = operator_type @@ -490,6 +498,7 @@ def __init__(self, name, room, index=-1, group='', replacement=[], resting_prior self.group = group self.replacement = replacement self.resting_priority = resting_priority + self._current_room = None self.current_room = current_room self.exhaust_require = exhaust_require self.upper_limit = upper_limit @@ -500,12 +509,26 @@ def __init__(self, name, room, index=-1, group='', replacement=[], resting_prior self.depletion_rate = depletion_rate self.time_stamp = time_stamp + @property + def current_room(self): + return self._current_room + + @current_room.setter + def current_room(self, value): + if self._current_room != value: + self._current_room = value + if Operators.current_room_changed_callback and self.refresh_order_room[0]: + Operators.current_room_changed_callback(self) + def is_high(self): return self.operator_type == 'high' def is_resting(self): return self.current_room.startswith("dorm") + def is_working(self): + return self.current_room in base_room_list and not self.is_resting() + def need_to_refresh(self, h=2, r=""): # 是否需要读取心情 if self.time_stamp is None or ( @@ -535,4 +558,4 @@ def current_mood(self): return self.mood def __repr__(self): - return f"Operator(name='{self.name}', room='{self.room}', index={self.index}, group='{self.group}', replacement={self.replacement}, resting_priority='{self.resting_priority}', current_room='{self.current_room}',exhaust_require={self.exhaust_require},mood={self.mood}, upper_limit={self.upper_limit}, rest_in_full={self.rest_in_full}, current_index={self.current_index}, lower_limit={self.lower_limit}, operator_type='{self.operator_type}',depletion_rate={self.depletion_rate},time_stamp='{self.time_stamp}')" + return f"Operator(name='{self.name}', room='{self.room}', index={self.index}, group='{self.group}', replacement={self.replacement}, resting_priority='{self.resting_priority}', current_room='{self.current_room}',exhaust_require={self.exhaust_require},mood={self.mood}, upper_limit={self.upper_limit}, rest_in_full={self.rest_in_full}, current_index={self.current_index}, lower_limit={self.lower_limit}, operator_type='{self.operator_type}',depletion_rate={self.depletion_rate},time_stamp='{self.time_stamp}',refresh_order_room = {self.refresh_order_room})" diff --git a/arknights_mower/utils/plan.py b/arknights_mower/utils/plan.py index 4f3900d7b..eed6f7e65 100644 --- a/arknights_mower/utils/plan.py +++ b/arknights_mower/utils/plan.py @@ -31,7 +31,9 @@ class PlanConfig(object): # run_order_buffer_time: # > 0 时是葛朗台跑单 # <= 0 时是无人机跑单 - def __init__(self, rest_in_full, exhaust_require, resting_priority, ling_xi=0, workaholic="", max_resting_count=4,free_blacklist="",read_mood =True,skip_validation=False, run_order_buffer_time = 30,resting_threshold = 0.5): + def __init__(self, rest_in_full, exhaust_require, resting_priority, ling_xi=0, workaholic="", max_resting_count=4, + free_blacklist="", read_mood=True, skip_validation=False, run_order_buffer_time=30, + resting_threshold=0.5, refresh_trading_config=''): self.rest_in_full = to_list(rest_in_full) self.exhaust_require = to_list(exhaust_require) self.workaholic = to_list(workaholic) @@ -46,6 +48,11 @@ def __init__(self, rest_in_full, exhaust_require, resting_priority, ling_xi=0, w self.skip_validation = skip_validation self.run_order_buffer_time = run_order_buffer_time self.resting_threshold = resting_threshold + # 格式为 干员名字+ 括弧 +指定房间(逗号分隔) + # 不指定房间则默认全跑单站 + # example: 阿米娅,夕,令 + # 夕(room_3_1,room_1_3),令(room_3_1) + self.refresh_trading_config = [e.strip() for e in refresh_trading_config.split(',')] def get_config(self, agent_name, config_type): if config_type == 0: @@ -58,3 +65,12 @@ def get_config(self, agent_name, config_type): return agent_name in self.resting_priority elif config_type == 4: return agent_name in self.free_blacklist + elif config_type == 5: + match = next((e for e in self.refresh_trading_config if agent_name in e.lower()), None) + if match is not None: + if match.replace(agent_name, '') != '': + return [True, match.replace(agent_name, '').split(',')] + else: + return [True, []] + else: + return [False, []]