epicArcController.py (16582B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\epicArcs\epicArcController.py 2 from __future__ import print_function 3 from carbonui.util.color import Color 4 from eve.client.script.ui.shared.epicArcs import epicArcConst 5 from eve.client.script.ui.station.agents import agentConst 6 from eve.client.script.ui.station.agents.agentUtil import IsAgentStandingSufficientToUse, GetAgentStandingThreshold 7 from evemissions.common.epic_arcs_data import MESSAGE_CHAPTER_TITLE 8 from evemissions.common.epic_arcs_data import MESSAGE_COMPLETED 9 from evemissions.common.epic_arcs_data import MESSAGE_IN_PROGRESS 10 from evemissions.common.epic_arcs_data import get_agent_in_epic_arc_mission 11 from evemissions.common.epic_arcs_data import get_epic_arc_missions 12 from evemissions.common.epic_arcs_data import iter_epic_arcs 13 from evemissions.common.epic_arcs_data import get_epic_arc_restart_interval 14 from evemissions.common.epic_arcs_data import get_next_epic_arc_missions 15 from localization import GetByMessageID, GetByLabel 16 from evemissions.common.epic_arcs_data import get_epic_arc_faction_id 17 18 class EpicArcController(object): 19 20 def __init__(self, missionStatusesByEpicArcID): 21 self.epicArcs = self._GetEpicArcs() 22 self._missionStatusesByEpicArcID = missionStatusesByEpicArcID 23 self._GetEpicArcNodesByMissionID() 24 for arc in self.epicArcs.values(): 25 arc.FixChapterIDs() 26 27 def GetEpicArcs(self): 28 return self.epicArcs 29 30 def _GetEpicArcs(self): 31 epicArcs = {} 32 for epicArcID, epicArcNameID in iter_epic_arcs(): 33 if self.IsValidArc(epicArcID): 34 epicArcs[epicArcID] = EpicArc(epicArcID, epicArcNameID) 35 36 return epicArcs 37 38 def IsValidArc(self, epicArcID): 39 arcRestartInterval = get_epic_arc_restart_interval(epicArcID) 40 return arcRestartInterval > 1 41 42 def _GetFirstMissionIDs(self, connections): 43 nextMissionIDs = [ c.nextMissionID for c in connections ] 44 return [ c.currentMissionID for c in connections if c.currentMissionID not in nextMissionIDs ] 45 46 def _GetEpicArcNodesByMissionID(self): 47 self.nodesByMissionID = {} 48 for epicArcID, _ in iter_epic_arcs(): 49 missions = get_epic_arc_missions(epicArcID) 50 for missionID in missions: 51 self._ConstructNode(epicArcID, missionID) 52 53 self._ConnectAllNodes() 54 firstNodes = [ node for node in self.nodesByMissionID.values() if not node.previousNodes ] 55 for node in firstNodes: 56 epicArc = self.epicArcs.get(node.epicArcID, None) 57 if epicArc: 58 epicArc.AddStartNode(node) 59 60 def _GetMissionMessageID(self, missionID, messageType): 61 messages = sm.RemoteSvc('agentMgr').GetMessagesForEpicArcMissions() 62 return messages.get(messageType, {}).get(missionID, None) 63 64 def _ConnectAllNodes(self): 65 for node in self.nodesByMissionID.values(): 66 chapterID = self._GetMissionMessageID(node.missionID, MESSAGE_CHAPTER_TITLE) 67 node.SetChapterID(chapterID) 68 nextMissions = get_next_epic_arc_missions(node.epicArcID, node.missionID, []) 69 for nextMissionID in nextMissions: 70 nextNode = self.nodesByMissionID.get(nextMissionID, None) 71 if nextNode: 72 node.AddNextNode(nextNode) 73 74 def _ConstructNode(self, epicArcID, missionID): 75 acceptedDate, completedDate, nameID, quitDate = self._GetMissionStatus(epicArcID, missionID) 76 agentID = get_agent_in_epic_arc_mission(epicArcID, missionID) 77 node = EpicArcMissionNode(epicArcID=epicArcID, missionID=missionID, agentID=agentID, inProgressMsgID=self._GetMissionMessageID(missionID, MESSAGE_IN_PROGRESS), completedMsgID=self._GetMissionMessageID(missionID, MESSAGE_COMPLETED), acceptedDate=acceptedDate, completedDate=completedDate, quitDate=quitDate, nameID=nameID) 78 self.nodesByMissionID[node.missionID] = node 79 80 def _GetMissionStatus(self, epicArcID, missionID): 81 status = self._missionStatusesByEpicArcID.get(epicArcID, {}).get(missionID, None) 82 if status: 83 acceptedDate = status.acceptedDate 84 completedDate = status.completedDate 85 quitDate = status.quitDate 86 nameID = status.nameID 87 else: 88 acceptedDate = completedDate = quitDate = nameID = None 89 return (acceptedDate, 90 completedDate, 91 nameID, 92 quitDate) 93 94 95 class EpicArcMissionNode(object): 96 97 def __init__(self, epicArcID, missionID, agentID, inProgressMsgID, completedMsgID, acceptedDate = None, completedDate = None, quitDate = None, nameID = None): 98 self.epicArcID = epicArcID 99 self.missionID = missionID 100 self.agentID = agentID 101 self.inProgressMsgID = inProgressMsgID 102 self.completedMsgID = completedMsgID 103 self.acceptedDate = acceptedDate 104 self.completedDate = completedDate 105 self.quitDate = quitDate 106 self.nameID = nameID 107 self.nextNodes = [] 108 self.previousNodes = [] 109 self.chapterID = None 110 111 def GetAgentID(self): 112 return self.agentID 113 114 def GetDestinationAgentID(self): 115 activeMission = sm.GetService('journal').GetActiveMissionForAgent(self.GetAgentID()) 116 if activeMission: 117 return activeMission.GetDestinationAgentID() 118 else: 119 return self.GetAgentID() 120 121 def AddNextNode(self, node): 122 self.nextNodes.append(node) 123 node.previousNodes.append(self) 124 125 def GetLastNodesInArc(self): 126 lastNodes = set() 127 self._GetLastNodesInArc(lastNodes) 128 return lastNodes 129 130 def _GetLastNodesInArc(self, lastNodes): 131 if self.IsLastInArc(): 132 lastNodes.add(self) 133 else: 134 for node in self.nextNodes: 135 node._GetLastNodesInArc(lastNodes) 136 137 def SetChapterID(self, chapterID): 138 self.chapterID = chapterID 139 140 def GetChapterID(self): 141 if self.chapterID: 142 return self.chapterID 143 if self.previousNodes: 144 return self.previousNodes[0].GetChapterID() 145 146 def IsLastInChapter(self): 147 if self.IsLastInArc(): 148 return True 149 else: 150 return self.GetChapterID() != self.nextNodes[0].GetChapterID() 151 152 def IsFirstInChapter(self): 153 if self.IsFirstInArc(): 154 return True 155 else: 156 return self.GetChapterID() != self.previousNodes[0].GetChapterID() 157 158 def GetName(self): 159 if self.nameID: 160 return GetByMessageID(self.nameID) 161 162 def GetInProgressText(self): 163 return GetByMessageID(self.inProgressMsgID) 164 165 def GetCompletedText(self): 166 return GetByMessageID(self.completedMsgID) 167 168 def GetStateText(self): 169 state = self.GetState() 170 if state == epicArcConst.MISSION_COMPLETED: 171 text = GetByLabel('UI/Agency/EpicArcComplete', completeTime=self.completedDate) 172 elif state == epicArcConst.MISSION_ACCEPTED: 173 text = GetByLabel('UI/Agency/EpicArcMissionAccepted') 174 elif state == epicArcConst.MISSION_OFFERED: 175 text = GetByLabel('UI/Agency/EpicArcMissionOffered') 176 elif state == epicArcConst.MISSION_UNAVAILABLE: 177 if self.IsFirstInArc(): 178 text = GetByLabel('UI/Agency/EpicArcMissionUnavailableFirst', agent=self.agentID) 179 else: 180 text = GetByLabel('UI/Agency/EpicArcMissionUnavailable') 181 color = self.GetStateColor() 182 return '<color=%s>%s</color>' % (Color.RGBtoHex(*color), text) 183 184 def GetHint(self): 185 stateText = self.GetStateText() 186 if not self.IsOffered(): 187 return stateText 188 if self.IsComplete(): 189 text = self.GetCompletedText() 190 else: 191 text = self.GetInProgressText() 192 return '<b>%s</b>\n%s\n%s' % (self.GetName(), text, stateText) 193 194 def GetStateColor(self): 195 state = self.GetState() 196 if state == epicArcConst.MISSION_COMPLETED: 197 if self.IsLastInChapter(): 198 return agentConst.COLOR_ACCEPTED_LAST 199 else: 200 return agentConst.COLOR_ACCEPTED 201 else: 202 if state == epicArcConst.MISSION_ACCEPTED: 203 return agentConst.COLOR_ACCEPTED 204 if state == epicArcConst.MISSION_OFFERED: 205 return agentConst.COLOR_OFFERED 206 if state == epicArcConst.MISSION_UNAVAILABLE: 207 return (1.0, 1.0, 1.0, 0.85) 208 209 def IsLastInArc(self): 210 return not bool(self.nextNodes) 211 212 def IsFirstInArc(self): 213 return not bool(self.previousNodes) 214 215 def IsComplete(self): 216 return bool(self.completedDate) 217 218 def IsNextComplete(self): 219 node = self._GetNextNode() 220 if node: 221 return node.IsComplete() 222 223 def IsAccepted(self): 224 return bool(self.acceptedDate) 225 226 def IsOffered(self): 227 return bool(self.nameID) 228 229 def IsActive(self): 230 return self.IsOffered() and not self.IsComplete() 231 232 def GetState(self): 233 if self.IsComplete(): 234 return epicArcConst.MISSION_COMPLETED 235 elif self.IsAccepted(): 236 return epicArcConst.MISSION_ACCEPTED 237 elif self.IsOffered(): 238 return epicArcConst.MISSION_OFFERED 239 else: 240 return epicArcConst.MISSION_UNAVAILABLE 241 242 def IsArcComplete(self): 243 if self.IsLastInArc(): 244 return self.IsComplete() 245 else: 246 for node in self.nextNodes: 247 if node.IsArcComplete(): 248 return True 249 250 return False 251 252 def GetArcCompleteTime(self): 253 if self.IsLastInArc(): 254 return self.completedDate 255 else: 256 return self._GetNextNode().GetArcCompleteTime() 257 258 def GetActiveMissions(self): 259 if self.IsActive(): 260 return [self] 261 for node in self.nextNodes: 262 ret = node.GetActiveMissions() 263 if ret: 264 return ret 265 266 def GetNumMissions(self, num): 267 if self.nextNodes: 268 num += self.nextNodes[0].GetNumMissions(num) 269 return num + 1 270 271 def GetMissionNumber(self, num = 0): 272 if not self.IsFirstInArc(): 273 num += self.previousNodes[0].GetMissionNumber(num) 274 return num + 1 275 276 def GetNumChapters(self, num): 277 if self.nextNodes: 278 num += self.nextNodes[0].GetNumChapters(num) 279 if self.chapterID: 280 num += 1 281 return num 282 283 def GetChapterMissions(self, chapterID, missions): 284 if missions and self.chapterID and self.chapterID != chapterID: 285 return 286 if self.chapterID == chapterID or missions: 287 missions.append(self) 288 node = self._GetNextNode() 289 if node: 290 node.GetChapterMissions(chapterID, missions) 291 292 def _GetNextNode(self): 293 if not self.nextNodes: 294 return 295 for node in self.nextNodes: 296 if node.IsAccepted(): 297 return node 298 299 for node in self.nextNodes: 300 if node.IsOffered(): 301 return node 302 303 return self.nextNodes[0] 304 305 def GetChapterIDs(self, chapterIDs): 306 if self.chapterID and self.chapterID not in chapterIDs: 307 chapterIDs.append(self.chapterID) 308 nextNode = self._GetNextNode() 309 if nextNode: 310 nextNode.GetChapterIDs(chapterIDs) 311 312 def GetCurrentChapterID(self, chapterID = None): 313 if self.chapterID: 314 chapterID = self.chapterID 315 if self.IsActive(): 316 return chapterID 317 node = self._GetNextNode() 318 if node: 319 return node.GetCurrentChapterID(chapterID) 320 321 def GetNextChapterID(self): 322 nextNode = self._GetNextNode() 323 if not nextNode: 324 return 325 elif nextNode.chapterID: 326 return nextNode.chapterID 327 else: 328 return nextNode.GetNextChapterID() 329 330 def PrintArc(self): 331 print('%s: %s\n' % (self.missionID, self.GetName())) 332 node = self._GetNextNode() 333 if node: 334 node.PrintArc() 335 336 337 class EpicArc(object): 338 339 def __init__(self, epicArcID, nameID): 340 self.epicArcID = epicArcID 341 self.nameID = nameID 342 self.startNodes = [] 343 344 def AddStartNode(self, startNode): 345 self.startNodes.append(startNode) 346 347 def FixChapterIDs(self): 348 for node in self.startNodes: 349 if not node.chapterID: 350 node.chapterID = node.GetNextChapterID() 351 352 def GetName(self): 353 return GetByMessageID(self.nameID) 354 355 def GetDescription(self): 356 pass 357 358 def GetFactionID(self): 359 return get_epic_arc_faction_id(self.epicArcID) 360 361 def IsComplete(self): 362 for node in self.startNodes: 363 if node.IsArcComplete(): 364 return True 365 366 return False 367 368 def GetActiveMissions(self): 369 missions = None 370 for node in self.startNodes: 371 if node.IsAccepted(): 372 missions = node.GetActiveMissions() 373 374 return missions or self.startNodes[:] 375 376 def GetState(self): 377 if self.IsComplete(): 378 return epicArcConst.ARC_COMPLETE 379 elif self.IsStarted(): 380 return epicArcConst.ARC_STARTED 381 elif self.IsStandingSufficientToStart(): 382 return epicArcConst.ARC_AVAILABLE 383 else: 384 return epicArcConst.ARC_UNAVAILABLE 385 386 def IsStandingSufficientToStart(self): 387 for node in self.startNodes: 388 agent = self._GetAgent(node.GetAgentID()) 389 if IsAgentStandingSufficientToUse(agent): 390 return True 391 392 return False 393 394 def GetRequiredStanding(self): 395 for node in self.startNodes: 396 agent = self._GetAgent(node.GetAgentID()) 397 return GetAgentStandingThreshold(agent.level) 398 399 def IsStarted(self): 400 for node in self.startNodes: 401 if node.IsAccepted(): 402 return True 403 404 return False 405 406 def GetNumMissions(self): 407 return self._GetStartNode().GetNumMissions(0) 408 409 def GetNumChapters(self): 410 return len(self.GetChapterIDs()) 411 412 def GetCurrChapterNum(self): 413 if not self.IsStarted(): 414 return 0 415 chapterID = self.GetCurrentChapterID() 416 return self.GetChapterIDs().index(chapterID) + 1 417 418 def GetActiveAgent(self): 419 mission = self.GetActiveMission() 420 if mission: 421 return self._GetAgent(mission.GetDestinationAgentID()) 422 423 def GetActiveMission(self): 424 missions = self.GetActiveMissions() 425 missions = sorted(missions, key=self._GetAgentSortKey) 426 return missions[0] 427 428 def _GetAgent(self, agentID): 429 return sm.GetService('agents').GetAgentByID(agentID) 430 431 def _GetAgentSortKey(self, mission): 432 agent = self._GetAgent(mission.agentID) 433 return -int(IsAgentStandingSufficientToUse(agent)) 434 435 def GetActiveMissionNum(self): 436 if not self.IsStarted(): 437 return 0 438 mission = self.GetActiveMissions()[0] 439 return mission.GetMissionNumber() 440 441 def GetNumMissionsCompleted(self): 442 if self.IsComplete(): 443 return self.GetNumMissions() 444 return max(0, self.GetActiveMissionNum() - 1) 445 446 def GetProgressRatio(self): 447 return float(self.GetNumMissionsCompleted()) / self.GetNumMissions() 448 449 def GetCompleteTime(self): 450 return self._GetStartNode().GetArcCompleteTime() 451 452 def GetChapterIDs(self): 453 chapterIDs = [] 454 startNode = self._GetStartNode() 455 startNode.GetChapterIDs(chapterIDs) 456 return chapterIDs 457 458 def GetChapterMissions(self, chapterID): 459 missions = [] 460 node = self._GetStartNode() 461 node.GetChapterMissions(chapterID, missions) 462 return missions 463 464 def _GetStartNode(self): 465 for node in self.startNodes: 466 if node.IsAccepted(): 467 return node 468 469 for node in self.startNodes: 470 if node.IsOffered(): 471 return node 472 473 return self.GetActiveMission() 474 475 def GetCurrentChapterID(self): 476 node = self._GetStartNode() 477 chapterID = node.GetCurrentChapterID() 478 return chapterID or self.GetChapterIDs()[0] 479 480 def PrintArc(self): 481 node = self._GetStartNode() 482 node.PrintArc() 483 484 def GetStartNodes(self): 485 return self.startNodes 486 487 def GetEndNodes(self): 488 nodes = set() 489 for node in self.GetStartNodes(): 490 nodes.update(node.GetLastNodesInArc()) 491 492 return nodes