myPinManager.py (34084B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\planet\myPinManager.py 2 from collections import defaultdict 3 import evetypes 4 import threadutils 5 import utillib 6 from carbon.common.script.util.format import FmtDist 7 from carbonui.primitives.container import Container 8 from carbonui.primitives.fill import Fill 9 from eve.client.script.ui.control import eveLabel 10 from eve.client.script.ui.shared.planet.planetConst import GetPinNameShort 11 from eve.client.script.ui.util import uix 12 import carbonui.const as uiconst 13 import log 14 import geo2 15 import trinity 16 import localization 17 import eve.common.script.util.planetCommon as planetCommon 18 from eve.client.script.ui.shared.planet import planetConst 19 from eve.client.script.ui.shared.planet.planetCommon import GetPickIntersectionPoint, GetSchematicDataForID 20 from eve.client.script.ui.shared.planet.planetUILinks import Link 21 from eve.common.script.planet.surfacePoint import SurfacePoint 22 from eve.client.script.ui.shared.planet import planetCommon as planetCommonUI 23 from eve.client.script.ui.shared.planet.planetUIPins import CommandCenterPin, ExtractorPin, ProcessorPin, LaunchpadPin, StorageFacilityPin, EcuPin, DepletionPin, BuildIndicatorPin 24 from carbonui.uicore import uicore 25 from eve.client.script.ui.shared.planet.surveyUI import SurveyWindow 26 from eve.common.lib import appConst as const 27 from eveexceptions import UserError 28 from evelink.client import type_link 29 from eveplanet.client.installSchematicMenu import MultiPinMenuProvider 30 from eveplanet.client.routeReplace import GetRouteToDeleteAndNewRouteData 31 from player_messaging.client.ui_message import prompt_player_fsd_dialog 32 33 class MyPinManager: 34 __notifyevents__ = ['OnPlanetPinsChanged', 35 'OnRefreshPins', 36 'OnEditModeBuiltOrDestroyed', 37 'OnPlanetPinPlaced'] 38 39 def __init__(self): 40 sm.RegisterNotify(self) 41 self.planetUISvc = None 42 self.linkParentID = None 43 self.routeParentID = None 44 self.currentRoute = [] 45 self.routeHoverPath = [] 46 self.oneoffRoute = False 47 self.isEdit = False 48 self.currRouteVolume = None 49 self.newPinType = None 50 self.canMoveHeads = None 51 self.depletionPoints = [] 52 self.extractionHeadDragged = None 53 self.pinsByID = {} 54 self.linksByPinIDs = {} 55 self.linksByGraphicID = {} 56 self.links = [] 57 self.buildIndicatorPin = None 58 self.currentEcuPinID = None 59 self.bracketCurveSet = trinity.TriCurveSet() 60 self.bracketCurveSet.name = 'PlanetBrackets' 61 uicore.desktop.GetRenderObject().curveSets.append(self.bracketCurveSet) 62 63 def Close(self): 64 sm.UnregisterNotify(self) 65 self.planetUISvc = None 66 self.linkParentID = None 67 self.routeParentID = None 68 self.currentRoute = None 69 self.routeHoverPath = None 70 self.currRouteVolume = None 71 self.newPinType = None 72 self.canMoveHeads = None 73 self.depletionPoints = None 74 self.pinsByID = None 75 self.linksByPinIDs = None 76 self.linksByGraphicID = None 77 self.links = None 78 self.buildIndicatorPin = None 79 self.currentEcuPinID = None 80 self.bracketCurveSet = None 81 82 def OnPlanetViewOpened(self): 83 self.planetUISvc = sm.GetService('planetUI') 84 self.eventManager = self.planetUISvc.eventManager 85 sp = SurfacePoint() 86 rubberColor = (1.0, 1.0, 1.0, 1.0) 87 self.rubberLink = self.planetUISvc.curveLineDrawer.DrawArc('rubberLink', sp, sp, 2.0, rubberColor, rubberColor) 88 self.InitRubberLinkLabels() 89 self.ReRender() 90 self.depletionPoints = [] 91 self.bracketCurveSet.Play() 92 93 def OnPlanetViewClosed(self): 94 self.ClearPinsFromScene() 95 self.ClearLinksFromScene() 96 self.bracketCurveSet.Stop() 97 self.isEdit = False 98 99 def ReRender(self): 100 if not sm.GetService('viewState').IsViewActive('planet'): 101 return 102 self.RenderPins() 103 self.RenderLinks() 104 self.ResetPinData() 105 106 def ReRenderPin(self, pin): 107 if not sm.GetService('viewState').IsViewActive('planet'): 108 return 109 uiPin = self.pinsByID.get(pin.id, None) 110 if uiPin is None: 111 return 112 uiPin.Remove() 113 self.RenderPin(pin) 114 115 def InitRubberLinkLabels(self): 116 self.rubberLinkLabelContainer = Container(name='rubberLinkLabels', parent=self.planetUISvc.planetUIContainer, pos=(400, 400, 110, 55), padding=(4, 4, 4, 4), align=uiconst.TOPLEFT, state=uiconst.UI_HIDDEN) 117 self.rubberLinkLabels = utillib.KeyVal() 118 self.rubberLinkLabels.padding = 3 119 self.rubberLinkLabels.columnPadding = 9 120 white = (1.0, 1.0, 1.0, 1.0) 121 gray = (1.0, 1.0, 1.0, 0.6) 122 self.rubberLinkLabels.distanceLbl = eveLabel.EveLabelMedium(text=localization.GetByLabel('UI/Common/Distance'), parent=self.rubberLinkLabelContainer, left=self.rubberLinkLabels.padding, height=16, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, color=gray) 123 maxLabelWidth = uix.GetTextWidth(localization.GetByLabel('UI/Common/Distance')) 124 self.rubberLinkLabels.powerLbl = eveLabel.EveLabelMedium(text=localization.GetByLabel('UI/Common/Power'), parent=self.rubberLinkLabelContainer, top=16, left=self.rubberLinkLabels.padding, height=16, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, color=gray) 125 maxLabelWidth = max(maxLabelWidth, uix.GetTextWidth(localization.GetByLabel('UI/Common/Power'))) 126 self.rubberLinkLabels.cpuLbl = eveLabel.EveLabelMedium(text=localization.GetByLabel('UI/Common/Cpu'), parent=self.rubberLinkLabelContainer, top=32, left=self.rubberLinkLabels.padding, height=16, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, color=gray) 127 maxLabelWidth = max(maxLabelWidth, uix.GetTextWidth(localization.GetByLabel('UI/Common/Cpu'))) 128 maxLabelWidth += self.rubberLinkLabels.columnPadding 129 self.rubberLinkLabels.distance = eveLabel.EveLabelMedium(text='', parent=self.rubberLinkLabelContainer, left=2, align=uiconst.TOPRIGHT, state=uiconst.UI_DISABLED, color=white) 130 self.rubberLinkLabels.power = eveLabel.EveLabelMedium(text='', parent=self.rubberLinkLabelContainer, left=2, top=16, align=uiconst.TOPRIGHT, state=uiconst.UI_DISABLED, color=white) 131 self.rubberLinkLabels.cpu = eveLabel.EveLabelMedium(text='', parent=self.rubberLinkLabelContainer, left=2, top=32, align=uiconst.TOPRIGHT, state=uiconst.UI_DISABLED, color=white) 132 Fill(parent=self.rubberLinkLabelContainer, color=(0.0, 0.0, 0.0, 0.5)) 133 134 def OnPlanetPinsChanged(self, planetID): 135 if sm.GetService('viewState').IsViewActive('planet') and self.planetUISvc and self.planetUISvc.GetCurrentPlanet().planetID == planetID: 136 self.planetUISvc.SetPlanet(planetID) 137 self.ReRender() 138 self.linkParentID = None 139 self.routeParentID = None 140 self.currentRoute = [] 141 142 def ResetPinData(self): 143 if self.planetUISvc.planet.colony is None: 144 return 145 pinData = self.planetUISvc.planet.colony.colonyData.pins 146 for pinID, pinUI in self.pinsByID.iteritems(): 147 pinUI.ResetPinData(pinData[pinID]) 148 149 def OnRefreshPins(self, pinIDs = None): 150 for p in self.pinsByID.values(): 151 p.OnRefreshPins() 152 153 for l in self.linksByPinIDs.values(): 154 l.OnRefreshPins() 155 156 def OnEditModeBuiltOrDestroyed(self, planetID): 157 currentPlanet = self.planetUISvc.GetCurrentPlanet() 158 if currentPlanet and currentPlanet.planetID == planetID: 159 self._OnEditModeBuiltOrDestroyed() 160 161 @threadutils.throttled(0.1) 162 def _OnEditModeBuiltOrDestroyed(self): 163 self.OnRefreshPins() 164 165 def OnPlanetPinPlaced(self, pinID): 166 planet = sm.GetService('planetUI').GetCurrentPlanet() 167 if planet is None: 168 return 169 colony = planet.GetColony(session.charid) 170 if colony is None: 171 return 172 pin = colony.GetPin(pinID) 173 if pin is None: 174 return 175 UIpin = self.RenderPin(pin) 176 UIpin.PlacementAnimation() 177 178 def OnPlanetEnteredEditMode(self): 179 sm.ScatterEvent('OnEditModeChanged', True) 180 181 def OnPlanetExitedEditMode(self): 182 self.ReRender() 183 sm.ScatterEvent('OnEditModeChanged', False) 184 if self.planetUISvc.currentContainer is not None: 185 self.planetUISvc.eventManager.DeselectCurrentlySelected() 186 187 def SetLinkParent(self, parentID): 188 self.eventManager.SetStateCreateLinkEnd() 189 self.linkParams = planetCommon.GetUsageParametersForLinkType(const.typeTestPlanetaryLink) 190 pin = self.pinsByID[parentID] 191 self.planetUISvc.curveLineDrawer.ChangeLinePosition('rubberLink', self.rubberLink, pin.surfacePoint, pin.surfacePoint) 192 self.planetUISvc.curveLineDrawer.ChangeLineSetWidth('rubberLink', 2.0) 193 self.rubberLinkLabelContainer.state = uiconst.UI_DISABLED 194 surfacePoint = planetCommonUI.GetPickIntersectionPoint() 195 self.linkParentID = parentID 196 self.UpdateRubberLink(surfacePoint) 197 198 def EndLinkCreation(self): 199 self.linkParentID = None 200 self.planetUISvc.curveLineDrawer.ChangeLineSetWidth('rubberLink', 0.0) 201 self.rubberLinkLabelContainer.state = uiconst.UI_HIDDEN 202 203 def LaunchCommodities(self, pinID, commoditiesToLaunch): 204 self.planetUISvc.planet.LaunchCommodities(pinID, commoditiesToLaunch) 205 206 def EnterRouteMode(self, pinID, typeID = None, oneoff = False): 207 if typeID or oneoff: 208 self.typeToRoute = typeID 209 else: 210 pin = self.pinsByID[pinID] 211 products = pin.pin.GetProductMaxOutput() 212 if not products: 213 return 214 self.typeToRoute = products.keys()[0] 215 self.eventManager.SetStateCreateRoute() 216 self.routeHoverPath = [] 217 self.currentRoute = [pinID] 218 self.oneoffRoute = oneoff 219 selectedPin = self.eventManager.selectedPin 220 if selectedPin: 221 selectedPin.HideHologramModel() 222 223 def LeaveRouteMode(self): 224 links = self.GetLinksFromPath(self.currentRoute) 225 for l, id in links: 226 l.RemoveAsRoute(id) 227 228 if len(self.routeHoverPath) > 0: 229 links = self.GetLinksFromPath(self.routeHoverPath) 230 for l, id in links: 231 l.RemoveAsRoute(id) 232 233 self.routeHoverPath = [] 234 self.currentRoute = [] 235 self.typeToRoute = None 236 self.currRouteVolume = None 237 selectedPin = self.eventManager.selectedPin 238 if selectedPin: 239 selectedPin.ShowHologramModel() 240 241 def SetRouteWaypoint(self, childID): 242 if childID in self.currentRoute: 243 i = self.currentRoute.index(childID) 244 path = self.currentRoute[i:] 245 links = self.GetLinksFromPath(path) 246 for l, id in links: 247 l.RemoveAsRoute(id) 248 249 self.currentRoute = self.currentRoute[:i + 1] 250 else: 251 lastWaypoint = self.currentRoute[-1] 252 colony = self.planetUISvc.planet.GetColonyByPinID(lastWaypoint) 253 shortestPath = colony.FindShortestPathIDs(lastWaypoint, childID) 254 if not shortestPath: 255 raise UserError('CreateRoutePathNotFound') 256 self.currentRoute.extend(shortestPath[1:]) 257 self.routeHoverPath = [] 258 sm.GetService('audio').SendUIEvent('msg_pi_routes_waypoint_play') 259 260 def _CleanRoute(self, route): 261 pinIDSet = set(route) 262 for pinID in pinIDSet: 263 if pinID not in route: 264 continue 265 if route.count(pinID) > 1: 266 firstPos = route.index(pinID) 267 pos = lastPos = firstPos 268 while True: 269 try: 270 pos = route.index(pinID, pos + 1) 271 lastPos = pos 272 except ValueError: 273 break 274 275 deletedPath = route[firstPos:lastPos + 1] 276 links = self.GetLinksFromPath(deletedPath) 277 for l, id in links: 278 l.RemoveAsRoute(id) 279 280 route = route[0:firstPos + 1] + route[lastPos + 1:] 281 282 def GetPinGraphicsClassForType(self, typeID): 283 if not evetypes.Exists(typeID): 284 raise RuntimeError('Unable to find inventory type for typeID', typeID) 285 groupID = evetypes.GetGroupID(typeID) 286 if groupID == const.groupCommandPins: 287 return CommandCenterPin 288 if groupID == const.groupExtractorPins: 289 return ExtractorPin 290 if groupID == const.groupProcessPins: 291 return ProcessorPin 292 if groupID == const.groupSpaceportPins: 293 return LaunchpadPin 294 if groupID == const.groupStoragePins: 295 return StorageFacilityPin 296 if groupID == const.groupExtractionControlUnitPins: 297 return EcuPin 298 raise RuntimeError('Unable to resolve UI container class for pin of type', typeID) 299 300 def RenderPins(self): 301 if self.planetUISvc.planet.colony is None: 302 return 303 newPinData = self.planetUISvc.planet.colony.colonyData.pins 304 newPinIDs = newPinData.keys() 305 oldPinIDs = self.pinsByID.keys() 306 pinsToDelete = [ pinID for pinID in oldPinIDs if pinID not in newPinIDs ] 307 for pinID in pinsToDelete: 308 pin = self.pinsByID.pop(pinID) 309 pin.Remove() 310 311 pinsToAdd = [ pinID for pinID in newPinIDs if pinID not in oldPinIDs ] 312 for pinID in pinsToAdd: 313 pin = newPinData[pinID] 314 self.RenderPin(pin) 315 316 def RenderPin(self, pin): 317 if pin.id in self.pinsByID: 318 self.pinsByID[pin.id].Remove() 319 surfacePoint = SurfacePoint(phi=pin.latitude, theta=pin.longitude) 320 pinClass = self.GetPinGraphicsClassForType(pin.typeID) 321 UIpin = pinClass(surfacePoint, pin, self.planetUISvc.pinTransform) 322 self.pinsByID[pin.id] = UIpin 323 return UIpin 324 325 def RenderLinks(self): 326 self.ClearLinksFromScene() 327 if session.charid not in self.planetUISvc.planet.colonies: 328 return 329 if self.planetUISvc.planet.colony is not None: 330 for linkID, linkObj in self.planetUISvc.planet.colony.colonyData.links.iteritems(): 331 ep1ID, ep2ID = linkID 332 self.AddLink(ep1ID, ep2ID, linkObj.typeID) 333 334 def AddLink(self, parentID, childID, linkTypeID): 335 colony = self.planetUISvc.planet.GetColony(session.charid) 336 if colony is None: 337 log.LogError('Unable to render link for planet without a colony') 338 return 339 par = colony.GetPin(parentID) 340 child = colony.GetPin(childID) 341 if par is None or child is None: 342 log.LogWarn('Trying to render link for non-existing pin', parentID, childID) 343 return 344 p1 = SurfacePoint(theta=par.longitude, phi=par.latitude) 345 p2 = SurfacePoint(theta=child.longitude, phi=child.latitude) 346 planetLink = colony.colonyData.GetLink(parentID, childID) 347 link = Link(p1, p2, parentID, childID, linkTypeID, planetLink) 348 self.linksByPinIDs[parentID, childID] = link 349 self.linksByPinIDs[childID, parentID] = link 350 self.links.append(link) 351 linkGraphicID1, linkGraphicID2 = link.GetGraphicIDs() 352 self.linksByGraphicID[linkGraphicID1] = link 353 self.linksByGraphicID[linkGraphicID2] = link 354 355 def AddDepletionPoint(self, point): 356 index = len(self.depletionPoints) 357 self.depletionPoints.append(DepletionPin(point, index, self.planetUISvc.pinOthersTransform)) 358 359 def ClearPinsFromScene(self): 360 for pin in self.pinsByID.values(): 361 pin.Remove() 362 363 self.pinsByID = {} 364 365 def ClearLinksFromScene(self): 366 for link in self.links: 367 link.Remove() 368 369 self.planetUISvc.curveLineDrawer.ClearLines('links') 370 self.planetUISvc.curveLineDrawer.ChangeLineSetWidth('rubberLink', 0.0) 371 self.linksByPinIDs = {} 372 self.links = [] 373 self.linksByGraphicID = {} 374 375 def GetPinMenu(self, pinID): 376 pin = self.pinsByID.get(pinID) 377 if pin: 378 return pin.GetMenu() 379 380 def GetLinkMenu(self, linkGraphicID): 381 if linkGraphicID in self.linksByGraphicID: 382 link = self.linksByGraphicID[linkGraphicID] 383 return link.GetMenu() 384 385 def EndPlacingPin(self): 386 self._RemoveBuildIndicatorPin() 387 388 def _RemoveBuildIndicatorPin(self): 389 if self.buildIndicatorPin is not None: 390 self.buildIndicatorPin.Remove() 391 self.buildIndicatorPin = None 392 self.DisplayECUExtractionAreas(show=False) 393 394 def DisplayECUExtractionAreas(self, show = True): 395 for pin in self.pinsByID.values(): 396 if evetypes.GetGroupID(pin.pin.typeID) == const.groupExtractionControlUnitPins: 397 if show: 398 pin.ShowMaxDistanceCircle() 399 else: 400 pin.HideMaxDistanceCircle() 401 402 def ShowECUExtractionAreas(self): 403 for pin in self.pinsByID.values(): 404 if evetypes.GetGroupID(pin.typeID) == const.groupExtractionControlUnitPins: 405 pin.ShowMaxDistanceCircle(1.0) 406 407 def GetLinksFromPath(self, path): 408 links = [] 409 last = None 410 for pinID in path: 411 if last is None: 412 last = pinID 413 continue 414 id = (last, pinID) 415 if id in self.linksByPinIDs: 416 links.append((self.linksByPinIDs[id], id)) 417 else: 418 log.LogWarn('Trying to fetch a non-existing link:', id) 419 last = pinID 420 421 return links 422 423 def CreateRoute(self, amount = None): 424 if self.oneoffRoute: 425 self.planetUISvc.planet.OpenTransferWindow(self.currentRoute) 426 self.planetUISvc.eventManager.DeselectCurrentlySelected() 427 else: 428 route = self.currentRoute 429 links = self.GetLinksFromPath(self.currentRoute) 430 typeToRoute = self.typeToRoute 431 try: 432 self.planetUISvc.planet.CreateRoute(self.currentRoute, self.typeToRoute, amount) 433 except UserError: 434 if self.currentRoute: 435 self.currentRoute = [self.currentRoute[0]] 436 raise 437 finally: 438 for link, id in links: 439 link.RemoveAsRoute(id) 440 441 sm.GetService('audio').SendUIEvent('msg_pi_routes_destination_play') 442 self.currentRoute = [] 443 444 def UpdateRubberLink(self, surfacePoint): 445 surfacePoint = GetPickIntersectionPoint(scale=planetConst.SCALE_RUBBERLINK) 446 pin = self.pinsByID.get(self.linkParentID) 447 if not pin: 448 return 449 if not surfacePoint: 450 surfacePoint = pin.surfacePoint 451 self.planetUISvc.curveLineDrawer.ChangeLinePosition('rubberLink', self.rubberLink, pin.surfacePoint, surfacePoint) 452 self.UpdateRubberLinkLabels(pin.surfacePoint, surfacePoint) 453 454 def GetCommandCenterPin(self): 455 for p in self.pinsByID.values(): 456 if evetypes.GetGroupID(p.pin.typeID) == const.groupCommandPins: 457 return p 458 459 def GetPinsByGroupTypeIDs(self): 460 pinsByGroupTypeID = defaultdict(list) 461 for p in self.pinsByID.values(): 462 pinsByGroupTypeID[evetypes.GetGroupID(p.pin.typeID)].append(p) 463 464 return pinsByGroupTypeID 465 466 def UpdateRubberLinkLabels(self, surfacePointA, surfacePointB): 467 self.rubberLinkLabelContainer.left = uicore.uilib.x + 3 468 self.rubberLinkLabelContainer.top = uicore.uilib.y + 3 469 if surfacePointA == surfacePointB: 470 length = 0.0 471 else: 472 length = surfacePointA.GetDistanceToOther(surfacePointB) * self.planetUISvc.planet.radius 473 self.rubberLinkLabels.distance.text = FmtDist(length) 474 powerUsage = planetCommon.GetPowerUsageForLink(const.typeTestPlanetaryLink, length, 0, self.linkParams) 475 cpuUsage = planetCommon.GetCpuUsageForLink(const.typeTestPlanetaryLink, length, 0, self.linkParams) 476 self.rubberLinkLabels.power.text = localization.GetByLabel('UI/PI/Common/MegaWattsAmount', amount=powerUsage) 477 self.rubberLinkLabels.cpu.text = localization.GetByLabel('UI/PI/Common/TeraFlopsAmount', amount=cpuUsage) 478 479 def OnRouteVolumeChanged(self, volume): 480 self.currRouteVolume = volume 481 for link, linkID in self.GetLinksFromPath(self.currentRoute): 482 link.SetCurrentRouteVolume(volume) 483 484 def DistanceToOtherPinsOK(self, surfacePoint): 485 minDistance = 0.012 486 for pin in self.pinsByID.values(): 487 if surfacePoint.GetDistanceToOther(pin.surfacePoint) < minDistance: 488 return False 489 490 return True 491 492 def PlacePinOnNextClick(self, pinTypeID): 493 self.eventManager.SetStateBuildPin() 494 self._RemoveBuildIndicatorPin() 495 self.newPinType = pinTypeID 496 groupID = evetypes.GetGroupID(pinTypeID) 497 self.buildIndicatorPin = BuildIndicatorPin(SurfacePoint(), pinTypeID, groupID, self.planetUISvc.pinOthersTransform) 498 if groupID == const.groupExtractionControlUnitPins: 499 self.DisplayECUExtractionAreas(show=True) 500 501 def VerifySimulation(self): 502 self.planetUISvc.planet.GMVerifySimulation() 503 504 def HighlightLink(self, pinID, linkID, removeOld = True): 505 link = self.linksByPinIDs[linkID] 506 link.HighlightLink() 507 508 def RemoveHighlightLink(self, linkID): 509 self.linksByPinIDs[linkID].RemoveHighlightLink() 510 511 def ShowRoute(self, routeID): 512 route = self.planetUISvc.planet.colony.colonyData.GetRoute(routeID) 513 path = route.path 514 for link, linkID in self.GetLinksFromPath(path): 515 link.ShowAsRoute(linkID, 1, 1) 516 517 def StopShowingRoute(self, routeID): 518 route = self.planetUISvc.planet.colony.colonyData.GetRoute(routeID) 519 path = route.path 520 for link, linkID in self.GetLinksFromPath(path): 521 link.RemoveAsRoute(linkID) 522 523 def GetCommandCenter(self): 524 if not self.planetUISvc.planet: 525 return None 526 if not self.planetUISvc.planet.colony: 527 return None 528 if not self.planetUISvc.planet.colony.colonyData: 529 return None 530 return self.planetUISvc.planet.colony.colonyData.commandPin 531 532 def RemovePin(self, pinID): 533 self.planetUISvc.GetCurrentPlanet().RemovePin(pinID) 534 pin = self.pinsByID.get(pinID, None) 535 if pin: 536 if pin.pin.IsCommandCenter(): 537 for p in self.pinsByID.values(): 538 p.Remove() 539 540 self.pinsByID = {} 541 self.eventManager.SetStateNormal() 542 else: 543 pin.Remove() 544 self.pinsByID.pop(pinID) 545 self.RenderLinks() 546 self.linkParentID = None 547 self.eventManager.DeselectCurrentlySelected() 548 549 def RemoveLink(self, linkID): 550 link = self.linksByPinIDs[linkID] 551 link.Remove() 552 self.links.remove(link) 553 self.planetUISvc.planet.RemoveLink(*linkID) 554 self.RenderLinks() 555 self.eventManager.DeselectCurrentlySelected() 556 557 def UpgradeLink(self, *args): 558 self.planetUISvc.planet.SetLinkLevel(*args) 559 560 def InstallSchematic(self, pinID, schematicID): 561 self.planetUISvc.planet.InstallSchematic(pinID, schematicID) 562 pin = self.pinsByID[pinID] 563 pin.OnRefreshPins() 564 565 def RemoveRoute(self, routeID): 566 route = self.planetUISvc.planet.colony.colonyData.GetRoute(routeID) 567 if not route: 568 return 569 path = route.path 570 self.planetUISvc.planet.RemoveRoute(routeID) 571 for link, pinIDs in self.GetLinksFromPath(path): 572 link.RenderAccordingToState() 573 574 def PlacePin(self, surfacePoint): 575 newPinType = self.newPinType 576 return self.PlacePinType(surfacePoint, newPinType) 577 578 def PlacePinType(self, surfacePoint, newPinType): 579 if not self.DistanceToOtherPinsOK(surfacePoint): 580 raise UserError('CannotBuildPinCloseToOthers') 581 if not self or self.planetUISvc.planet is None: 582 return 583 self.planetUISvc.planet.CreatePin(newPinType, surfacePoint.phi, surfacePoint.theta) 584 if evetypes.GetGroupID(newPinType) == const.groupCommandPins: 585 sm.GetService('audio').SendUIEvent('msg_pi_build_command_play') 586 self.eventManager.SetStateNormal() 587 else: 588 sm.GetService('audio').SendUIEvent('msg_pi_build_pin_play') 589 590 def SetLinkChild(self, parentID, childID, setState = True): 591 try: 592 self.planetUISvc.planet.CreateLink(parentID, childID, const.typeTestPlanetaryLink) 593 self.AddLink(childID, parentID, const.typeTestPlanetaryLink) 594 sm.GetService('audio').SendUIEvent('msg_pi_build_link_play') 595 finally: 596 if setState: 597 self.eventManager.SetStateCreateLinkStart() 598 599 def EnterSurveyMode(self, ecuPinID): 600 self.eventManager.SetStateSurvey() 601 self.planetUISvc.GetSurveyWindow(ecuPinID) 602 self.currentEcuPinID = ecuPinID 603 ecuPin = self.pinsByID[ecuPinID] 604 ecuPin.EnterSurveyMode() 605 606 def LeaveSurveyMode(self): 607 if self.currentEcuPinID is not None: 608 ecuPin = self.pinsByID.get(self.currentEcuPinID, None) 609 if ecuPin: 610 ecuPin.ExitSurveyMode() 611 self.currentEcuPinID = None 612 self.planetUISvc.CloseSurveyWindow() 613 614 def PlaceExtractionHead(self, ecuPinID, surfacePoint, headID = None): 615 ecuPin = self.pinsByID[self.currentEcuPinID] 616 if ecuPin.pin.IsActive(): 617 return 618 headID = self.planetUISvc.planet.AddExtractorHead(ecuPinID, headID, surfacePoint.phi, surfacePoint.theta) 619 ecuPin.AddHead(headID, surfacePoint) 620 newHead = ecuPin.GetExtractionHead(headID) 621 newHead.ShowUnlocked() 622 wnd = SurveyWindow.GetIfOpen() 623 if wnd: 624 wnd.OnExtractionHeadAdded(headID, surfacePoint) 625 626 def SetExtractionHeadRadius(self, ecuPinID, radius): 627 ecuPin = self.pinsByID[ecuPinID] 628 ecuPin.pin.headRadius = radius 629 ecuPin.SetExtractionHeadRadius(radius) 630 631 def RemoveExtractionHead(self, ecuPinID, headID): 632 ecuPin = self.pinsByID[ecuPinID] 633 if ecuPin.pin.IsActive(): 634 return 635 self.planetUISvc.planet.RemoveExtractorHead(ecuPinID, headID) 636 ecuPin.RemoveHead(headID) 637 wnd = SurveyWindow.GetIfOpen() 638 if wnd: 639 wnd.OnExtractionHeadRemoved(headID) 640 641 def BeginDragExtractionHead(self, ecuPinID, headID): 642 if ecuPinID != self.currentEcuPinID: 643 return 644 ecuPin = self.pinsByID[ecuPinID] 645 if ecuPinID != self.canMoveHeads: 646 return 647 self.extractionHeadDragged = (ecuPin, headID) 648 self.eventManager.SetSubStateMoveExtractionHead() 649 surfacePoint = ecuPin.GetExtractionHead(headID).surfacePoint 650 wnd = self.planetUISvc.GetSurveyWindow(self.currentEcuPinID) 651 wnd.OnBeginDragExtractionHead(headID, surfacePoint) 652 653 def DragExtractionHeadTo(self, surfacePoint): 654 ecuPin, headID = self.extractionHeadDragged 655 distanceFactor = self._EnforceMaximumDinstance(surfacePoint, ecuPin) 656 ecuPin.SetDistanceFactor(distanceFactor) 657 ecuPin.MoveExtractionHeadTo(headID, surfacePoint) 658 wnd = SurveyWindow.GetIfOpen() 659 if wnd: 660 wnd.OnExtractionHeadMoved(headID, surfacePoint) 661 662 def IsDraggingExtractionHead(self): 663 return bool(self.extractionHeadDragged) 664 665 def _EnforceMaximumDinstance(self, headSurfacePoint, uiPin): 666 SAFETYFACTOR = 0.99 667 ecuSurfacePoint = uiPin.surfacePoint 668 distance = headSurfacePoint.GetDistanceToOther(ecuSurfacePoint) 669 areaOfInfluence = uiPin.pin.GetAreaOfInfluence() 670 if distance < areaOfInfluence * SAFETYFACTOR: 671 return distance / areaOfInfluence 672 ecuVector = ecuSurfacePoint.GetAsXYZTuple() 673 v = headSurfacePoint.GetAsXYZTuple() 674 normal = geo2.Vec3Cross(ecuVector, v) 675 rotMat = geo2.MatrixRotationAxis(normal, areaOfInfluence * SAFETYFACTOR) 676 newV = geo2.Multiply(rotMat, ecuVector) 677 headSurfacePoint.SetXYZ(*newV[:3]) 678 return 1.0 679 680 def EndDragExtractionHead(self): 681 uiPin, headID = self.extractionHeadDragged 682 headPin = uiPin.extractionHeadsByNum[headID] 683 self._EnforceMaximumDinstance(headPin.surfacePoint, uiPin) 684 sm.GetService('planetUI').GetCurrentPlanet().MoveExtractorHead(uiPin.pin.id, headID, headPin.surfacePoint.phi, headPin.surfacePoint.theta) 685 self.extractionHeadDragged = None 686 self.eventManager.SetSubStateNormal() 687 wnd = self.planetUISvc.GetSurveyWindow(self.currentEcuPinID) 688 wnd.OnEndDragExtractionHead() 689 690 def OnExtractionHeadMouseEnter(self, ecuPinID, headID): 691 if ecuPinID != self.currentEcuPinID: 692 return 693 ecuPin = self.pinsByID[ecuPinID] 694 if ecuPinID != self.canMoveHeads: 695 return 696 head = ecuPin.GetExtractionHead(headID) 697 if head: 698 head.OnMouseEnter() 699 wnd = self.planetUISvc.GetSurveyWindow(self.currentEcuPinID) 700 wnd.OnHeadEntryMouseEnter(headID) 701 702 def OnExtractionHeadMouseExit(self, ecuPinID, headID): 703 if ecuPinID != self.currentEcuPinID: 704 return 705 ecuPin = self.pinsByID[ecuPinID] 706 head = ecuPin.GetExtractionHead(headID) 707 if head: 708 head.OnMouseExit() 709 wnd = self.planetUISvc.GetSurveyWindow(self.currentEcuPinID) 710 wnd.OnHeadEntryMouseExit(headID) 711 712 def SetEcuOverlapValues(self, ecuPinID, overlapVals): 713 ecuPin = self.pinsByID.get(ecuPinID, None) 714 if ecuPin: 715 ecuPin.SetOverlapValues(overlapVals) 716 717 def UnlockHeads(self, pinID): 718 self.canMoveHeads = pinID 719 ecuPin = self.pinsByID.get(pinID, None) 720 if ecuPin: 721 ecuPin.OnHeadsUnlocked() 722 723 def LockHeads(self): 724 ecuPin = self.pinsByID.get(self.canMoveHeads, None) 725 self.canMoveHeads = None 726 if ecuPin: 727 ecuPin.OnHeadsLocked() 728 729 def GMRunDepletionSim(self, totalDuration): 730 points = [] 731 for point in self.depletionPoints: 732 points.append(utillib.KeyVal(longitude=point.surfacePoint.theta, latitude=point.surfacePoint.phi, amount=point.GetAmount(), duration=point.GetDuration(), headRadius=point.GetHeadRadius())) 733 734 info = utillib.KeyVal(totalDuration=totalDuration, points=points) 735 sm.GetService('planetUI').GetCurrentPlanet().GMRunDepletionSim(self.planetUISvc.selectedResourceTypeID, info) 736 737 def GetMultiPinMenu(self, currentPin): 738 selectedPinIDs = self.eventManager.selectedPinIDs 739 if currentPin.pin.id not in selectedPinIDs: 740 selectedPinIDs.add(currentPin.pin.id) 741 currentPin.SetMultiSelectedDisplay(True) 742 pins = [ self.planetUISvc.planet.GetPin(x) for x in selectedPinIDs ] 743 mp = MultiPinMenuProvider(self.InstallSchematicForMultiplePins) 744 return mp.GetMenu(pins) 745 746 def InstallSchematicForMultiplePins(self, schematicID, pins): 747 resultsByPinID = self._GetRouteToDeleteAndNewRouteData(schematicID, pins) 748 outputRouteFailures = defaultdict(list) 749 inputRouteFailures = defaultdict(list) 750 for pID, results in resultsByPinID.iteritems(): 751 self.InstallSchematic(pID, schematicID) 752 for routeID in results.outputRouteIDsToDelete.union(results.inputRouteIDsToDelete): 753 self.RemoveRoute(routeID) 754 755 for routeInfo, errorDict in ((results.newOutputRouteData, outputRouteFailures), (results.newInputRouteData, inputRouteFailures)): 756 for typeID, qty, path in routeInfo: 757 try: 758 self.planetUISvc.planet.CreateRoute(path, typeID, qty) 759 except UserError: 760 errorDict[typeID].append(path) 761 762 if outputRouteFailures or inputRouteFailures: 763 self._DisplayRouteFailureMessage(outputRouteFailures, inputRouteFailures) 764 765 def _DisplayRouteFailureMessage(self, outputRouteFailures, inputRouteFailures): 766 colony = self.eventManager.GetColony() 767 infoTextList = [] 768 for routeFailures, headerText in ((outputRouteFailures, localization.GetByLabel('UI/PI/FailedToCreateOutgoingRoutes')), (inputRouteFailures, localization.GetByLabel('UI/PI/FailedToCreateIncomingRoutes'))): 769 if not routeFailures: 770 continue 771 infoTextList.append(headerText) 772 for typeID, failedRoutePaths in routeFailures.iteritems(): 773 infoTextList.append(u'\u2022 %s' % type_link(typeID)) 774 for path in failedRoutePaths: 775 sourcePinID, destPinID = path 776 sourcePin = colony.GetPin(sourcePinID) 777 if sourcePin is None: 778 continue 779 destPin = colony.GetPin(destPinID) 780 if destPin is None: 781 continue 782 sourcePinName = GetPinNameShort(sourcePin.typeID, sourcePinID) 783 destPinName = GetPinNameShort(destPin.typeID, destPinID) 784 text = '<t>%s => %s' % (sourcePinName, destPinName) 785 infoTextList.append(text) 786 787 infoText = '<br>'.join(infoTextList) 788 prompt_player_fsd_dialog('CustomInfo', {'info': infoText}, modal=False) 789 790 def _GetRouteToDeleteAndNewRouteData(self, schematicID, pins): 791 colony = self.eventManager.GetColony() 792 return GetRouteToDeleteAndNewRouteData(schematicID, pins, GetSchematicDataForID, colony.colonyData.GetSourceRoutesForPin, self.GetDestRoutesForPin) 793 794 def GetDestRoutesForPin(self, pinID): 795 colony = self.eventManager.GetColony() 796 routesIDsTo = colony.colonyData.GetDestinationRoutesForPin(pinID) 797 return [ colony.GetRoute(routeID) for routeID in routesIDsTo ]