agents.py (8854B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\dockedUI\agents.py 2 import localization 3 import logging 4 import threadutils 5 from eve.client.script.ui.shared.userentry import AgentEntry 6 from eve.common.lib.appConst import agentMissionStateAllocated, agentMissionStateOffered, agentTypeAura, agentTypeBasicAgent, agentTypeCareerAgent, agentTypeEpicArcAgent, agentTypeEventMissionAgent, agentTypeFactionalWarfareAgent, agentTypeGenericStorylineMissionAgent, agentTypeHeraldry, agentTypeResearchAgent, agentTypeStorylineMissionAgent, rookieAgentList 7 from carbonui import uiconst 8 from carbonui.control.scroll import Scroll 9 from carbonui.primitives.container import Container 10 from carbonui.util.sortUtil import SortListOfTuples 11 from eve.client.script.ui.control.entries.header import Header 12 from eve.client.script.ui.control.entries.util import GetFromClass 13 logger = logging.getLogger(__name__) 14 ON_GOING_MISSION = {agentMissionStateAllocated, agentMissionStateOffered} 15 NORMAL_AGENTS = {agentTypeResearchAgent, 16 agentTypeBasicAgent, 17 agentTypeEventMissionAgent, 18 agentTypeCareerAgent, 19 agentTypeFactionalWarfareAgent, 20 agentTypeHeraldry} 21 SPECIAL_AGENTS = {agentTypeGenericStorylineMissionAgent, 22 agentTypeStorylineMissionAgent, 23 agentTypeEventMissionAgent, 24 agentTypeCareerAgent, 25 agentTypeEpicArcAgent} 26 STORYLINE_AGENTS = {agentTypeGenericStorylineMissionAgent, agentTypeStorylineMissionAgent} 27 28 class LoadState(object): 29 UNLOADED = 1 30 LOAD_PENDING = 2 31 LOADING = 3 32 LOADED = 4 33 34 35 class AgentsPanel(Container): 36 __notifyevents__ = ('OnAgentMissionChanged', 'OnStandingSet') 37 _initialized = False 38 _load_state = LoadState.UNLOADED 39 _scroll = None 40 41 def _layout(self): 42 self._scroll = Scroll(parent=self, align=uiconst.TOALL) 43 44 @threadutils.threaded 45 def _load(self): 46 if not self._initialized: 47 self._initialized = True 48 self._layout() 49 sm.RegisterNotify(self) 50 is_already_loading = self._load_state in {LoadState.LOADING, LoadState.LOAD_PENDING} 51 self._load_state = LoadState.LOAD_PENDING 52 if is_already_loading: 53 return 54 self._scroll.ShowLoading() 55 try: 56 entries = [] 57 while self._load_state == LoadState.LOAD_PENDING: 58 self._load_state = LoadState.LOADING 59 entries = [] 60 relevant_agents = [] 61 mission_state_by_agent = {} 62 agent_missions = sm.GetService('journal').GetMyAgentJournalDetails()[:1][0] 63 for each in agent_missions: 64 mission_state, important_mission, mission_type, mission_name, agent_id, expiration_time, bookmarks, remote_offerable, remote_completable, content_id = each 65 agent = sm.GetService('agents').GetAgentByID(agent_id) 66 mission_state_by_agent[agent_id] = mission_state 67 if mission_state not in ON_GOING_MISSION or agent.agentTypeID in SPECIAL_AGENTS: 68 relevant_agents.append(agent_id) 69 70 agents_in_station = get_agents_in_current_station() 71 local_relevant_agents = [] 72 for agent in agents_in_station: 73 if agent.agentID in relevant_agents: 74 local_relevant_agents.append(agent.agentID) 75 76 if self.destroyed: 77 return 78 available, unavailable = find_available_and_unavailable_agents(agents_in_station, local_relevant_agents, relevant_agents) 79 relevant_here = list(set().union(available, unavailable)) 80 timers = sm.GetService('agents').GetAgentTimers(relevant_here) 81 agents_to_move = [ agent_id for agent_id in available if timers.get(agent_id, None) ] 82 for agent_id in agents_to_move: 83 available.remove(agent_id) 84 unavailable.append(agent_id) 85 86 relevant_nearby = [ agent_id for agent_id in relevant_agents if agent_id not in local_relevant_agents ] 87 agents_of_interest = [] 88 for agent_id in relevant_nearby: 89 agents_of_interest.append(get_agent_entry_with_sort_value(agent_id, mission_state_by_agent.get(agent_id))) 90 91 if agents_of_interest: 92 entries.append(GetFromClass(Header, {'label': localization.GetByLabel('UI/Station/Lobby/AgentsOfInterest')})) 93 entries += SortListOfTuples(agents_of_interest) 94 sections = [('UI/Station/Lobby/AvailableToYou', available), ('UI/Station/Lobby/NotAvailableToYou', unavailable)] 95 for section_label_path, agents in sections: 96 if agents: 97 text = localization.GetByLabel(section_label_path) 98 entries.append(GetFromClass(Header, {'label': text})) 99 section_entries = [] 100 for agent_id in agents: 101 timer = timers.get(agent_id, None) 102 section_entries.append(get_agent_entry_with_sort_value(agent_id, mission_state_by_agent.get(agent_id), timer)) 103 104 entries += SortListOfTuples(section_entries) 105 106 if self.destroyed: 107 return 108 self._scroll.Load(fixedEntryHeight=40, contentList=entries) 109 self._load_state = LoadState.LOADED 110 except Exception: 111 logger.exception('Failed to load the Agents tab in the lobby window') 112 finally: 113 if not self._scroll.destroyed: 114 self._scroll.HideLoading() 115 116 def LoadPanel(self): 117 self._load() 118 119 def OnAgentMissionChanged(self, actionID, agentID): 120 if self._load_state != LoadState.UNLOADED: 121 self._load() 122 123 def OnStandingSet(self, fromID, toID, rank): 124 if self._load_state != LoadState.UNLOADED: 125 self._load() 126 127 128 def get_agents_in_current_station(): 129 if session.stationid: 130 return sm.GetService('agents').GetAgentsByStationID()[session.stationid] 131 else: 132 return [] 133 134 135 def get_agent_entry_with_sort_value(agent_id, mission_state, timer = None): 136 sort_value = cfg.eveowners.Get(agent_id).name 137 entry = GetFromClass(AgentEntry, {'charID': agent_id, 138 'missionState': mission_state, 139 'timer': timer}) 140 return (sort_value, entry) 141 142 143 def find_available_and_unavailable_agents(agents_in_station, local_relevant_agents, relevant_agents): 144 epic_arc_status_service = sm.RemoteSvc('epicArcStatus') 145 standing_service = sm.GetService('standing') 146 unavailable_agents = [] 147 available_agents = [] 148 for agent in agents_in_station: 149 agent_id = agent.agentID 150 agent_type_id = agent.agentTypeID 151 if agent_id in rookieAgentList: 152 continue 153 is_limited_to_fac_war = is_limited_to_factional_warfare(agent_type_id, agent.corporationID) 154 if agent_type_id in NORMAL_AGENTS: 155 standing_is_valid = check_can_use_agent(agent, standing_service) 156 have_mission_from_agent = agent_id in relevant_agents 157 if not is_limited_to_fac_war and (standing_is_valid or have_mission_from_agent): 158 available_agents.append(agent_id) 159 else: 160 unavailable_agents.append(agent_id) 161 elif agent_type_id == agentTypeEpicArcAgent: 162 standing_is_valid = check_can_use_agent(agent, standing_service) 163 have_mission_from_agent = agent_id in relevant_agents 164 epic_agent_available = False 165 if have_mission_from_agent: 166 epic_agent_available = True 167 elif standing_is_valid: 168 if agent_id in relevant_agents or epic_arc_status_service.AgentHasEpicMissionsForCharacter(agent_id): 169 epic_agent_available = True 170 if epic_agent_available: 171 available_agents.append(agent_id) 172 else: 173 unavailable_agents.append(agent_id) 174 if agent_type_id == agentTypeAura: 175 continue 176 elif agent_type_id in STORYLINE_AGENTS: 177 if agent_id in local_relevant_agents: 178 available_agents.append(agent_id) 179 else: 180 unavailable_agents.append(agent_id) 181 182 return (available_agents, unavailable_agents) 183 184 185 def is_limited_to_factional_warfare(agent_type_id, agent_corporation_id): 186 if agent_type_id != agentTypeFactionalWarfareAgent: 187 return False 188 war_faction_id = sm.GetService('facwar').GetCorporationWarFactionID(agent_corporation_id) 189 return war_faction_id != session.warfactionid 190 191 192 def check_can_use_agent(agent, standing_service): 193 return standing_service.CanUseAgent(agent.factionID, agent.corporationID, agent.agentID, agent.level, agent.agentTypeID)