NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

missionObjectivesTracker.py (12909B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\missions\client\missionObjectivesTracker.py
      2 from carbon.common.script.sys.service import Service
      3 from carbonui.util.bunch import Bunch
      4 from carbonui.util.sortUtil import SortListOfTuples
      5 from collections import defaultdict
      6 from eveexceptions.exceptionEater import ExceptionEater
      7 from eve.common.lib.appConst import agentMissionStateAccepted, agentMissionAccepted, agentMissionQuit, agentMissionModified
      8 from eve.common.script.sys import idCheckers
      9 from gametime import GetWallclockTime
     10 import inventorycommon.const as const
     11 from .ui.missionObjectiveData import CreateObjective
     12 from .active_agent_mission import ActiveAgentMission
     13 AGENT_FOR_LAST_ACCEPTED_MISSION_SETTING = 'AgentForLastAcceptedMission'
     14 DELAY_ON_DUNGEON_TRIGGER_SECS = 1.0
     15 MISSION_UPDATE_DELAY_MSEC = 3000
     16 
     17 class MissionObjectivesTracker(Service):
     18     __guid__ = 'svc.missionObjectivesTracker'
     19     __notifyevents__ = ['OnItemsChanged',
     20      'OnMissionsUpdated',
     21      'OnAgentMissionChanged',
     22      'OnAgentMissionObjectivesCompleted',
     23      'OnAgentMissionObjectivesFailed',
     24      'OnClientEvent_WarpFinished',
     25      'OnSessionChanged',
     26      'OnSessionReset',
     27      'OnBallparkSetState']
     28     __startupdependencies__ = ['journal']
     29 
     30     def Run(self, *args):
     31         super(MissionObjectivesTracker, self).Run(*args)
     32         self.Initialize()
     33 
     34     def Initialize(self):
     35         self.agentList = []
     36         self.agentMissions = {}
     37         self.waitingForTypeIDs = defaultdict(lambda : [])
     38         self.agentsWaitingForStuff = {}
     39         self.destinationTriggers = defaultdict(lambda : [])
     40         self.currentAgentMissionInfo = None
     41         self.missionObjectives = defaultdict(lambda : None)
     42         self.missionTrackerMgr = sm.RemoteSvc('missionTrackerMgr')
     43 
     44     def GetAgentMissions(self, *args):
     45         allMissionsList = []
     46         missions = self.journal.GetMyAgentJournalDetails()[0]
     47         HOMEBASE = 0
     48         NOTHOMEBASE = 1
     49         if missions:
     50             for mission in missions:
     51                 missionState, _, _, missionNameID, agentID, expirationTime, bookmarks, _, _, contentID = mission
     52                 if missionState != agentMissionStateAccepted or expirationTime and expirationTime < GetWallclockTime():
     53                     continue
     54                 homeBaseBms = []
     55                 otherBms = []
     56                 foundHomeBaseBm = False
     57                 for bm in bookmarks:
     58                     if bm.locationType == 'agenthomebase':
     59                         homeBaseBms.append((HOMEBASE, bm))
     60                     elif 'isAgentBase' in bm.__dict__ and bm.isAgentBase:
     61                         foundHomeBaseBm = True
     62                         otherBms.append((HOMEBASE, bm))
     63                     else:
     64                         otherBms.append((NOTHOMEBASE, bm))
     65 
     66                 bookmarksIwant = otherBms
     67                 if not foundHomeBaseBm:
     68                     bookmarksIwant.extend(homeBaseBms)
     69                 bookmarksIwant = SortListOfTuples(bookmarksIwant)
     70                 bmInfo = Bunch(missionNameID=missionNameID, contentID=contentID, bookmarks=bookmarksIwant, agentID=agentID)
     71                 allMissionsList.append((expirationTime, bmInfo))
     72 
     73             allMissionsList = SortListOfTuples(allMissionsList)
     74         return allMissionsList
     75 
     76     def OnClientEvent_WarpFinished(self, *args, **kwargs):
     77         self._ResetAgentMissionInfoForAllMissions()
     78         self.UpdateMissionsPanel()
     79 
     80     def OnSessionChanged(self, isRemote, sess, change):
     81         if not session.charid:
     82             return
     83         self.UpdateMissionStatusForSessionChange(change)
     84         self.UpdateMissionsPanel()
     85 
     86     def OnSessionReset(self):
     87         self.Initialize()
     88 
     89     def OnBallparkSetState(self, *args):
     90         self.UpdateMissionsPanel()
     91 
     92     def OnItemsChanged(self, items, change, locationData):
     93         relevantDestinations = [const.flagCargo,
     94          const.flagGeneralMiningHold,
     95          const.flagSpecialAsteroidHold,
     96          const.flagSpecializedIceHold,
     97          const.flagSpecializedGasHold,
     98          const.flagSpecializedMineralHold,
     99          const.flagSpecializedSalvageHold,
    100          const.flagSpecializedShipHold,
    101          const.flagSpecializedSmallShipHold,
    102          const.flagSpecializedMediumShipHold,
    103          const.flagSpecializedLargeShipHold,
    104          const.flagSpecializedIndustrialShipHold,
    105          const.flagJunkyardTrashed]
    106         if session.stationid:
    107             relevantDestinations.append(const.flagHangar)
    108         agentList = []
    109         for item in items:
    110             if item.typeID in self.waitingForTypeIDs.keys():
    111                 if item.flagID in relevantDestinations:
    112                     agentID = self.waitingForTypeIDs[item.typeID]
    113                     agentList += agentID
    114 
    115         if agentList:
    116             self.UpdateMissionStatusData(agentList)
    117 
    118     def _WantNotificationWhenTypeIDArrives(self, info):
    119         if not info:
    120             return False
    121         if info[0].startswith('MissionFetch'):
    122             return True
    123         for key in ('TransportItemsMissing', 'DropOffItemsMissing', 'AllObjectivesComplete'):
    124             if key in info:
    125                 return True
    126 
    127         return False
    128 
    129     def OnMissionsUpdated(self, missions):
    130         for mission in missions:
    131             agentID = mission['agentID']
    132             info = mission['info'] or None
    133             if self._WantNotificationWhenTypeIDArrives(info):
    134                 self.NotifyTrackerWhenTypeIDArrives(agentID, int(info[1]))
    135             else:
    136                 self.StopNotifyingTrackerForTypeID(agentID)
    137             isUpdateRequired = self.currentAgentMissionInfo.get(agentID, None) != info
    138             self.missionObjectives[agentID] = None
    139             self.SetCurrentAgentMissionInfo(agentID, info)
    140             if agentID in self.agentMissions:
    141                 self.agentMissions[agentID].update_objective(info)
    142             if isUpdateRequired:
    143                 sm.ScatterEvent('OnAgentMissionChange', agentMissionModified, agentID)
    144 
    145     def OnAgentMissionChanged(self, missionEvent, agentID):
    146         if missionEvent != agentMissionModified:
    147             self.SetCurrentAgentMissionInfo(agentID, None)
    148         self.missionObjectives[agentID] = None
    149         self._UpdateAgentMissions()
    150         with ExceptionEater('exception during - missiontracker remove/add agent'):
    151             if missionEvent == agentMissionQuit:
    152                 if agentID in self.agentList:
    153                     self.agentList.remove(agentID)
    154                     self.RemoveDestinationNotificationTrigger(agentID)
    155             elif missionEvent == agentMissionAccepted:
    156                 if agentID not in self.agentList:
    157                     self.agentList.append(agentID)
    158                 self.UpdateMissionStatusData((agentID,))
    159                 self._SetAgentForLastAcceptedMission(agentID)
    160         callback = sm.GetService('infoPanel').UpdateExpandedAgentMission if missionEvent == agentMissionAccepted else None
    161         self.UpdateMissionsPanel(callback)
    162 
    163     def OnAgentMissionObjectivesCompleted(self, agentID):
    164         self._UpdateCurrentAgentMissionInfo(agentID)
    165 
    166     def OnAgentMissionObjectivesFailed(self, agentID):
    167         self._UpdateCurrentAgentMissionInfo(agentID)
    168 
    169     def NotifyTrackerWhenTypeIDArrives(self, agentID, typeID):
    170         if idCheckers.IsNPCCharacter(typeID):
    171             activeMission = self.agentMissions.get(agentID)
    172             if activeMission and activeMission.context:
    173                 typeID = activeMission.context.get_value('deliver_items', {}).get('type_id', typeID)
    174         self.agentsWaitingForStuff[agentID] = typeID
    175         if agentID not in self.waitingForTypeIDs[typeID]:
    176             self.waitingForTypeIDs[typeID].append(agentID)
    177 
    178     def StopNotifyingTrackerForTypeID(self, agentID):
    179         if agentID not in self.agentsWaitingForStuff:
    180             return
    181         typeID = self.agentsWaitingForStuff[agentID]
    182         if agentID in self.waitingForTypeIDs[typeID]:
    183             self.waitingForTypeIDs[typeID].remove(agentID)
    184             del self.agentsWaitingForStuff[agentID]
    185 
    186     def UpdateMissionStatusForSessionChange(self, change):
    187         if 'locationid' in change:
    188             if change['locationid'][0] in self.destinationTriggers.keys():
    189                 self.UpdateMissionStatusData(self.destinationTriggers[change['locationid'][0]])
    190             if change['locationid'][1] in self.destinationTriggers.keys():
    191                 self.UpdateMissionStatusData(self.destinationTriggers[change['locationid'][1]])
    192         self._ResetAgentMissionInfoForAllMissions()
    193 
    194     def UpdateMissionStatusData(self, agentList):
    195         with ExceptionEater('Exception during missiontracker.UpdateAllMissions'):
    196             if agentList:
    197                 self.missionTrackerMgr.UpdateAllMissions(agentList)
    198 
    199     def SetDestinationNotificationTrigger(self, locationID, agentID):
    200         if agentID not in self.destinationTriggers[locationID]:
    201             self.destinationTriggers[locationID].append(agentID)
    202 
    203     def RemoveDestinationNotificationTrigger(self, agentID):
    204         for locationID in self.destinationTriggers.keys():
    205             if agentID in self.destinationTriggers[locationID]:
    206                 self.destinationTriggers[locationID].remove(agentID)
    207 
    208     def RegisterMissionTracking(self):
    209         with ExceptionEater('exception during RegisterMissionTracking'):
    210             self._UpdateAgentMissions()
    211             missions = self.journal.GetMyAgentJournalDetails()[0]
    212             for mission in missions:
    213                 missionState, _, _, _, agentID, expirationTime, _, _, _, _ = mission
    214                 if missionState != agentMissionStateAccepted or expirationTime and expirationTime < GetWallclockTime():
    215                     continue
    216                 if agentID not in self.agentList:
    217                     self.agentList.append(agentID)
    218 
    219             self.UpdateMissionStatusData(self.agentList)
    220 
    221     def _UpdateAgentMissions(self):
    222         missions = self.journal.GetMyAgentJournalDetails()[0]
    223         activeMissions = set()
    224         for mission in missions:
    225             missionState = mission[0]
    226             agentID = mission[4]
    227             expirationTime = mission[5]
    228             if missionState == agentMissionStateAccepted and not (expirationTime and expirationTime < GetWallclockTime()):
    229                 activeMissions.add(agentID)
    230                 if agentID not in self.agentMissions:
    231                     self.agentMissions[agentID] = ActiveAgentMission(mission)
    232 
    233         for agentID in self.agentMissions.keys():
    234             if agentID not in activeMissions:
    235                 self.agentMissions[agentID].stop()
    236                 del self.agentMissions[agentID]
    237 
    238     def _InitializeCurrentAgentMissionInfo(self):
    239         self.currentAgentMissionInfo = {}
    240         for mission in self.GetAgentMissions():
    241             self._UpdateCurrentAgentMissionInfo(mission.agentID)
    242 
    243     def _UpdateCurrentAgentMissionInfo(self, agentID):
    244         missionInfo = self.missionTrackerMgr.GetMissionInfoItems(agentID)
    245         self.currentAgentMissionInfo[agentID] = missionInfo or None
    246         if missionInfo and agentID in self.agentMissions:
    247             self.agentMissions[agentID].update_objective(missionInfo)
    248 
    249     def SetCurrentAgentMissionInfo(self, agentID, info):
    250         if self.currentAgentMissionInfo is None:
    251             self._InitializeCurrentAgentMissionInfo()
    252         self.currentAgentMissionInfo[agentID] = info
    253 
    254     def GetCurrentAgentMissionInfo(self, agentID):
    255         if self.currentAgentMissionInfo is None:
    256             self._InitializeCurrentAgentMissionInfo()
    257         return self.currentAgentMissionInfo.get(agentID, None)
    258 
    259     def GetCurrentMissionObjective(self, agentID):
    260         currentMissionInfo = self.GetCurrentAgentMissionInfo(agentID)
    261         objectiveData = CreateObjective(currentMissionInfo, agentID)
    262         return objectiveData
    263 
    264     def _ResetAgentMissionInfoForAllMissions(self):
    265         self._InitializeCurrentAgentMissionInfo()
    266         self.missionObjectives = defaultdict(lambda : None)
    267 
    268     def HasActiveMission(self, agentID):
    269         for mission in self.GetAgentMissions():
    270             if mission.agentID == agentID:
    271                 return True
    272 
    273         return False
    274 
    275     def GetAllAgentMissionInfo(self, agentID):
    276         if not self.missionObjectives[agentID]:
    277             self.missionObjectives[agentID] = self.missionTrackerMgr.GetAllMissionObjectives(agentID)
    278         return self.missionObjectives[agentID]
    279 
    280     def GetAgentForLastAcceptedMission(self):
    281         return settings.char.ui.Get(AGENT_FOR_LAST_ACCEPTED_MISSION_SETTING, None)
    282 
    283     def _SetAgentForLastAcceptedMission(self, agentID):
    284         settings.char.ui.Set(AGENT_FOR_LAST_ACCEPTED_MISSION_SETTING, agentID)
    285 
    286     def IsInActiveMissionDungeon(self, agentID):
    287         return self.missionTrackerMgr.IsInActiveDungeonID(agentID)
    288 
    289     def UpdateMissionsPanel(self, callback = None):
    290         sm.GetService('infoPanel').UpdateMissionsPanel(callback)