modularHangarBehaviours.py (49209B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\view\hangarBehaviours\modularHangarBehaviours.py 2 from __future__ import print_function 3 from __future__ import absolute_import 4 import blue 5 import random as rnd 6 import geo2 7 import trinity 8 import math 9 import uthread 10 import logging 11 from . import modularHangarBehavioursConstants as hConst 12 from cosmetics.common.ships.skins.static_data.skin_type import ShipSkinType 13 from eve.common.script.sys.idCheckers import IsJunkLocation 14 from inventorycommon import const 15 from uthread2 import call_after_simtime_delay 16 from fsdBuiltData.common.graphicIDs import GetGraphicFile 17 from .baseHangarBehaviours import BaseHangarShipBehaviour, BaseHangarShipDroneBehaviour 18 from .modularHangarBehavioursConstants import GetShipSizeClass, IsInLookUpTable 19 import evecamera 20 from evetypes import GetGroupID 21 from gametime import GetSecondsUntilSimTime 22 from appConst import factionAngelCartel, factionGuristasPirates 23 logger = logging.getLogger(__name__) 24 25 class Dock(object): 26 27 def __init__(self, pos, rot): 28 self.translation = pos 29 self.rotation = rot 30 self.isPlayer = False 31 self.dockMultiEffect = None 32 self.dockedShip = None 33 self.isActive = False 34 self.childObject = None 35 self.dockedShipItemID = 0 36 self.exitPoint = (0.0, 0.0, 0.0) 37 self.hallwayPoint = (0.0, 0.0, 0.0) 38 self.relativeMEExitPoint = (0.0, 0.0, 0.0) 39 self.cameraExitPoint = (0.0, 0.0, 0.0) 40 41 def Setup(self, pos, rot): 42 self.translation = pos 43 self.rotation = rot 44 45 def shipDeparture(self): 46 pass 47 48 def shipDocking(self): 49 pass 50 51 52 class ModularHangarShipBehaviour(BaseHangarShipBehaviour): 53 54 def __init__(self): 55 super(ModularHangarShipBehaviour, self).__init__() 56 self.smallDocks = [] 57 self.bigDocks = [] 58 self.playerDock = None 59 self.playerShipItemID = 0 60 self.playerShipTypeID = 0 61 self.shipOffset = (0, 0, 0) 62 self.endPos = (0, 0, 0) 63 self.isInitialized = False 64 self.hangarScene = None 65 self.reflectionProbeThread = None 66 self.flightPath = {'exit1': (0.0, 0.0, 0.0), 67 'hallway1': (0.0, 0.0, 0.0), 68 'hallway2': (0.0, 0.0, 0.0), 69 'exit2': (0.0, 0.0, 0.0)} 70 self.isEnlistmentDockingEnabled = False 71 72 def SetEnlistmentDockingEnabled(self, enabled): 73 self.isEnlistmentDockingEnabled = enabled 74 75 def SetDockingEffectGraphicID(self, graphicID): 76 self.dockingEffectGraphicID = graphicID 77 78 def SetAnchorPoint(self, hangarModel, hangarScene): 79 if hangarModel is None: 80 self.log.error('ModularHangarShipBehaviour.SetAnchorPoint: Setting anchor point when hangarModel is None') 81 return 82 self.hangarScene = hangarScene 83 self._CreateDocks(hangarModel, hangarScene) 84 85 def CleanScene(self): 86 87 def _cleanMultiEffect(multiEffect): 88 if multiEffect is not None: 89 for param in multiEffect.parameters: 90 param.object = None 91 92 multiEffect.bindings.removeAt(-1) 93 94 def _cleanChildObject(obj): 95 if obj is not None: 96 obj.objects.removeAt(-1) 97 for ctrlr in obj.controllers: 98 ctrlr.Stop() 99 100 obj.controllers.removeAt(-1) 101 102 for dock in self.smallDocks: 103 dock.dockedShip = None 104 _cleanChildObject(dock.childObject) 105 dock.childObject = None 106 _cleanMultiEffect(dock.dockMultiEffect) 107 dock.dockMultiEffect = None 108 109 for dock in self.bigDocks: 110 dock.dockedShip = None 111 _cleanChildObject(dock.childObject) 112 dock.childObject = None 113 _cleanMultiEffect(dock.dockMultiEffect) 114 dock.dockMultiEffect = None 115 116 self.GetCamera().ClearRefs() 117 self.hangarScene = None 118 self.playerDock = None 119 self.smallDocks = None 120 self.bigDocks = None 121 self.flightPath = None 122 self.isInitialized = False 123 self.reflectionProbeThread = None 124 125 def GetCamera(self): 126 return sm.GetService('sceneManager').GetRegisteredCamera(evecamera.CAM_MODULARHANGAR) 127 128 def _ReflectionProbePositionUpdateThread(self, probe): 129 try: 130 camera = self.GetCamera() 131 while True: 132 if camera is None or probe is None: 133 break 134 probe.position = camera.GetZoomToPoint() 135 blue.synchro.Yield() 136 137 finally: 138 self.reflectionProbeThread = None 139 140 def PlaceReflectionProbe(self, reflectionProbe): 141 if reflectionProbe: 142 reflectionProbe.lockPosition = True 143 if not self.reflectionProbeThread: 144 self.reflectionProbeThread = uthread.new(self._ReflectionProbePositionUpdateThread, reflectionProbe) 145 146 def _GetEnlistment(self): 147 if not self.isEnlistmentDockingEnabled: 148 return None 149 else: 150 enlistment, _, _ = sm.RemoteSvc('fwCharacterEnlistmentMgr').GetMyEnlistment() 151 return enlistment or 0.0 152 153 def _CreateDocks(self, hangarModel, hangarScene): 154 enlistment = self._GetEnlistment() 155 smallDockLocators, bigDockLocators = [], [] 156 if enlistment is None: 157 smallDockLocators = self.GetLocatorsFromSet(hangarModel, hConst.LOCATORSET_SMALL_DOCK_SHIPS) 158 bigDockLocators = self.GetLocatorsFromSet(hangarModel, hConst.LOCATORSET_MEDIUM_DOCK_SHIPS) 159 if enlistment is not None: 160 smallDockLocators = self.GetLocatorsFromSet(hangarModel, hConst.LOCATORSET_SMALL_DEATHLESS_DOCK) 161 bigDockLocators = self.GetLocatorsFromSet(hangarModel, hConst.LOCATORSET_MEDIUM_DEATHLESS_DOCK) 162 if self.isEnlistmentDockingEnabled and enlistment == factionAngelCartel: 163 smallDockLocators += self.GetLocatorsFromSet(hangarModel, hConst.LOCATORSET_SMALL_ANGEL_DOCK) 164 bigDockLocators += self.GetLocatorsFromSet(hangarModel, hConst.LOCATORSET_MEDIUM_ANGEL_DOCK) 165 elif self.isEnlistmentDockingEnabled and enlistment == factionGuristasPirates: 166 smallDockLocators += self.GetLocatorsFromSet(hangarModel, hConst.LOCATORSET_SMALL_GURISTAS_DOCK) 167 bigDockLocators += self.GetLocatorsFromSet(hangarModel, hConst.LOCATORSET_MEDIUM_GURISTAS_DOCK) 168 hallwayLocatorSetName = hConst.LOCATORSET_HALLWAY_POINTS 169 if not smallDockLocators or not bigDockLocators: 170 self.log.error('ModularHangarShipBehaviour.SetAnchorPoint: not all required LocatorSets are defined.') 171 return 172 smallDockObjects = [] 173 smallDockObjectPosTuples = [] 174 bigDockObjects = [] 175 bigDockObjectPosTuples = [] 176 layoutContainers = [ container for container in hangarModel.effectChildren if container.name == 'layouts' ] 177 try: 178 i = 0 179 for layoutContainer in layoutContainers: 180 containerName = hConst.LOCATORSET_SMALL_DOCK_SHIPS 181 for container in (cont for cont in layoutContainer.objects if cont.name == containerName or cont.name == containerName + '_potato'): 182 smallDockObjects.append(container) 183 pos = container.objects.FindByName('Hull').translation 184 smallDockObjectPosTuples.append((pos[0], 185 pos[1], 186 pos[2], 187 i)) 188 i = i + 1 189 190 i = 0 191 for layoutContainer in layoutContainers: 192 for container in (cont for cont in layoutContainer.objects if cont.name == hConst.LOCATORSET_MEDIUM_DOCK_SHIPS): 193 bigDockObjects.append(container) 194 pos = container.objects.FindByName('Hull').translation 195 bigDockObjectPosTuples.append((pos[0], 196 pos[1], 197 pos[2], 198 i)) 199 i = i + 1 200 201 except AttributeError: 202 self.log.error("modularHangarShipBehaviour._CreateDocks: can't find child objects") 203 return 204 205 def SetExitPoint(dock, shipPos, platformRotation): 206 exitIndex = hangarModel.GetCloseLocatorIndex(shipPos, exitPointSetName) 207 exitPos = hangarModel.GetLocatorPositionFromSet(exitIndex, True, exitPointSetName) 208 relativePos = geo2.Subtract(exitPos, shipPos) 209 relativePosRotated = geo2.QuaternionTransformVector(geo2.QuaternionInverse(platformRotation), relativePos) 210 dock.relativeMEExitPoint = (relativePosRotated[0], 211 relativePosRotated[1], 212 relativePosRotated[2], 213 0.0) 214 return exitPos 215 216 def GetClosestDockObject(isSmall, location): 217 target = -1 218 bestDist = 420 219 bestDist = bestDist * bestDist 220 dock = None 221 if isSmall: 222 for dockObj in smallDockObjectPosTuples: 223 x, y, z, index = dockObj 224 dist = geo2.Vec3DistanceSq(location, (x, y, z)) 225 if dist < bestDist: 226 target = index 227 bestDist = dist 228 229 if target != -1: 230 dock = smallDockObjects[target] 231 else: 232 for dockObj in bigDockObjectPosTuples: 233 x, y, z, index = dockObj 234 dist = geo2.Vec3DistanceSq(location, (x, y, z)) 235 if dist < bestDist: 236 target = index 237 bestDist = dist 238 239 if target != -1: 240 dock = bigDockObjects[target] 241 if target is -1: 242 return 243 return dock 244 245 def CreateDocks(locators, setToAddTo, isSmall): 246 for locator in locators: 247 pos = locator[0] 248 rot = locator[1] 249 potentialChildObject = GetClosestDockObject(isSmall, pos) 250 if potentialChildObject is None: 251 continue 252 dock = Dock(pos, rot) 253 dock.exitPoint = SetExitPoint(dock, pos, rot) 254 cameraExitLocatorIndex = hangarModel.GetCloseLocatorIndex(pos, cameraExitPointSetName) 255 dock.cameraExitPoint = hangarModel.GetLocatorPositionFromSet(cameraExitLocatorIndex, True, cameraExitPointSetName) 256 dock.childObject = potentialChildObject 257 hallwayLocatorIndex = hangarModel.GetCloseLocatorIndex(dock.cameraExitPoint, hallwayLocatorSetName) 258 dock.hallwayPoint = hangarModel.GetLocatorPositionFromSet(hallwayLocatorIndex, True, hallwayLocatorSetName) 259 setToAddTo.append(dock) 260 261 exitPointSetName = hConst.LOCATORSET_SMALL_DOCK_EXITS 262 cameraExitPointSetName = hConst.LOCATORSET_SMALL_DOCK_CAMERA_EXITS 263 CreateDocks(smallDockLocators, self.smallDocks, True) 264 exitPointSetName = hConst.LOCATORSET_MEDIUM_DOCK_EXITS 265 cameraExitPointSetName = hConst.LOCATORSET_MEDIUM_DOCK_CAMERA_EXITS 266 CreateDocks(bigDockLocators, self.bigDocks, False) 267 268 def IsInitialized(self): 269 return self.isInitialized 270 271 def _GetPlayerDock(self): 272 return self.playerDock 273 274 def GetAllDockedShips(self): 275 ships = [] 276 for each in self.smallDocks: 277 if each.dockedShip is not None: 278 ships.append(each.dockedShip) 279 280 for each in self.bigDocks: 281 if each.dockedShip is not None: 282 ships.append(each.dockedShip) 283 284 return ships 285 286 def OnItemChangeProcessed(self, item, itemInfo): 287 if item.itemID is None or item.typeID is None: 288 return 289 isT3cItem = False 290 if item.groupID in const.subsystemSlotGroupIDs or item.groupID == const.groupStrategicCruiser: 291 isT3cItem = True 292 if item.flagID == const.flagHangar and item.quantity < 0: 293 if IsJunkLocation(item.locationID): 294 self._RemoveShipIfItsInTheScene(item.itemID, item.typeID) 295 elif const.categoryTrading in itemInfo and not isT3cItem: 296 self._SpawnANewShipIfThereIsRoom(item.itemID, item.typeID) 297 elif item.flagID == const.flagJunkyardTrashed: 298 self._RemoveShipIfItsInTheScene(item.itemID, item.typeID) 299 300 def _ConfigureShipTransform(self, ship, offset, dock): 301 platformRotation = trinity.Tr2CurveConstant() 302 platformRotation.value = dock.rotation 303 shipTranslation = trinity.Tr2CurveCombiner() 304 platformTranslation = trinity.Tr2TranslationAdapter() 305 platformTranslation.value = geo2.Add(offset, dock.translation) 306 multiEffectTranslation = trinity.Tr2TranslationAdapter() 307 multiEffectTranslation.rotationOffset = dock.rotation 308 shipTranslation.curves.append(platformTranslation) 309 shipTranslation.curves.append(multiEffectTranslation) 310 displayOffset = ship.locatorSets.FindByName(hConst.LOCATORSET_DISPLAY_OFFSET) 311 if displayOffset is not None and len(displayOffset.locators) == 1: 312 displayOffsetCurve = trinity.Tr2TranslationAdapter() 313 displayOffsetCurve.value = displayOffset.locators[0][0] 314 displayOffsetCurve.rotationOffset = dock.rotation 315 shipTranslation.curves.append(displayOffsetCurve) 316 ship.translationCurve = shipTranslation 317 ship.rotationCurve = platformRotation 318 ship.modelRotationCurve = trinity.Tr2RotationAdapter() 319 ship.modelTranslationCurve = trinity.Tr2TranslationAdapter() 320 321 def _SpawnANewShipIfThereIsRoom(self, itemID, typeID): 322 groupID = GetGroupID(typeID) 323 if not IsInLookUpTable(groupID): 324 return 325 sizeClass = GetShipSizeClass(groupID) 326 newDock = None 327 if sizeClass > 2: 328 return 329 if sizeClass < 2: 330 emptyDocks = [ dock for dock in self.smallDocks if not dock.isActive ] 331 if len(emptyDocks) > 0: 332 newDock = rnd.choice(emptyDocks) 333 else: 334 emptyDocks = [ dock for dock in self.bigDocks if not dock.isActive ] 335 if len(emptyDocks) > 0: 336 newDock = rnd.choice(emptyDocks) 337 if newDock is None: 338 return 339 model = self.LoadShipModel(itemID, typeID, playerShip=False) 340 if model is None: 341 return 342 newDock.dockedShipItemID = itemID 343 self._ReplaceShipInDock(model, newDock, makeActiveShip=False) 344 self._WaitForShipBoundingBox(model) 345 shipOffset = geo2.QuaternionTransformVector(newDock.rotation, self.GetShipOffset(model, typeID)) 346 self._ConfigureShipTransform(model, shipOffset, newDock) 347 newDock.dockedShip = model 348 newDock.isActive = True 349 if model.boosters is not None: 350 model.boosters.display = True 351 if newDock.dockMultiEffect is not None: 352 newDock.dockMultiEffect.SetParameter('docking_ship', model) 353 newDock.dockMultiEffect.SetControllerVariable('materializeDelay', 0.75) 354 newDock.dockMultiEffect.SetControllerVariable('docked', 1.0) 355 newDock.dockMultiEffect.StartControllers() 356 self.hangarScene.objects.append(model) 357 358 def _RemoveShipIfItsInTheScene(self, itemID, typeID): 359 if self.playerShipItemID == itemID: 360 return False 361 groupID = GetGroupID(typeID) 362 sizeClass = GetShipSizeClass(groupID) 363 if sizeClass < 2: 364 dock = next((dock for dock in self.smallDocks if dock.dockedShipItemID == itemID), None) 365 else: 366 dock = next((dock for dock in self.bigDocks if dock.dockedShipItemID == itemID), None) 367 if dock is None: 368 return False 369 370 def cleanUp(hangarScene, ship, multiEffect): 371 if hangarScene is None: 372 return 373 if ship is not None and ship in hangarScene.objects: 374 hangarScene.objects.remove(ship) 375 if multiEffect is not None and multiEffect in hangarScene.objects: 376 for param in multiEffect.parameters: 377 param.object = None 378 379 multiEffect.bindings.removeAt(-1) 380 hangarScene.objects.remove(multiEffect) 381 382 oldME = dock.dockMultiEffect 383 oldME.SetControllerVariable('materialize', 0.0) 384 oldME.SetControllerVariable('docked', 0.0) 385 dock.childObject.SetControllerVariable('isDocked', 0.0) 386 oldShip = oldME.parameters.FindByName('docking_ship').object 387 dock.dockMultiEffect = None 388 dock.childObject.SetControllerVariable('isDocked', 0.0) 389 dock.childObject.SetControllerVariable('docked', 0.0) 390 dock.dockedShip = None 391 dock.isActive = False 392 dock.dockedShipItemID = 0 393 call_after_simtime_delay(cleanUp, 15.0, self.hangarScene, oldShip, oldME) 394 395 def _FindPLayerShipInADock(self, sizeClass): 396 if sizeClass < 2: 397 dock = next((dock for dock in self.smallDocks if dock.dockedShipItemID == self.playerShipItemID), None) 398 else: 399 dock = next((dock for dock in self.bigDocks if dock.dockedShipItemID == self.playerShipItemID), None) 400 return dock 401 402 def _WaitForShipBoundingBox(self, model): 403 if model is None: 404 return 405 try: 406 counter = 0 407 maxYields = 25 408 while counter < maxYields: 409 modelBB = model.GetLocalBoundingBox() 410 if modelBB[0][0] != 0.0 and modelBB[0][2] != 0.0: 411 return 412 counter = counter + 1 413 blue.synchro.Yield() 414 415 except IndexError: 416 self.log.error('modularHangarShipBehaviour.populateDocksWithInventoryShips: bounding box missconfigured') 417 418 def PrepareFSB(self, vfxMultiEffect): 419 self.playerDock.dockMultiEffect.SetParameter('docking_ship', None) 420 p = self.playerDock.cameraExitPoint 421 self.SetFlightPath(p, p, p, p, p) 422 self.GetCamera().SkipFlight() 423 vfxMultiEffect.SetParameter('activeDock', self.playerDock.childObject) 424 self.playerDock.childObject.SetControllerVariable('isActivePlayerDock', 0.0) 425 self.playerDock.childObject.SetControllerVariable('isDocked', 1.0) 426 self.playerDock.childObject.StartControllers() 427 vfxMultiEffect.StartControllers() 428 for ship in (obj for obj in self.hangarScene.objects if type(obj) == trinity.EveShip2): 429 ship.SetControllerVariable('lightRigOn', 0.0) 430 431 def FinishFSB(self): 432 self.playerDock.dockMultiEffect.SetParameter('docking_ship', self.playerDock.dockedShip) 433 self.playerDock.dockMultiEffect.SetControllerVariable('materialize', 1.0) 434 self.playerDock.dockMultiEffect.SetControllerVariable('_previousState', 1.0) 435 self.playerDock.dockMultiEffect.SetControllerVariable('materializeDelay', 0.0) 436 self.playerDock.dockMultiEffect.StartControllers() 437 self.GetCamera().zoomFactor = 0.2 438 self.GetCamera().zoomTarget = 0.2 439 for ship in (obj for obj in self.hangarScene.objects if type(obj) == trinity.EveShip2): 440 ship.SetControllerVariable('lightRigOn', 1.0) 441 442 def GetActiveDock(self): 443 if self.playerDock is not None: 444 return self.playerDock.childObject 445 446 def PlaceShip(self, itemID, typeID, skipDockingAnimation = False): 447 groupID = GetGroupID(typeID) 448 sizeClass = GetShipSizeClass(groupID) 449 firstDocking = self.playerDock is None 450 foundDock = self._FindPLayerShipInADock(sizeClass) 451 if foundDock is None: 452 if firstDocking: 453 if sizeClass < 2: 454 dock = next((dock for dock in self.smallDocks if dock.isPlayer), None) 455 unusedDock = next((dock for dock in self.bigDocks if dock.isPlayer), None) 456 if unusedDock is not None: 457 unusedDock.isPlayer = False 458 unusedDock.isActive = unusedDock.dockedShipItemID is not 0 459 else: 460 dock = next((dock for dock in self.bigDocks if dock.isPlayer), None) 461 unusedDock = next((dock for dock in self.smallDocks if dock.isPlayer), None) 462 if unusedDock is not None: 463 unusedDock.isPlayer = False 464 unusedDock.isActive = unusedDock.dockedShipItemID is not 0 465 if dock is None: 466 if sizeClass < 2: 467 if self.smallDocks: 468 dock = rnd.choice(self.smallDocks) 469 elif self.bigDocks: 470 dock = rnd.choice(self.bigDocks) 471 elif self.bigDocks: 472 dock = rnd.choice(self.bigDocks) 473 elif self.smallDocks: 474 dock = rnd.choice(self.smallDocks) 475 if dock is None: 476 return 477 dock.dockedShipItemID = self.playerShipItemID 478 model = self.LoadShipModel(itemID, typeID, True) 479 self.playerDock = dock 480 self._ReplaceShipInDock(model, dock) 481 if dock.dockMultiEffect is not None: 482 dock.dockMultiEffect.SetParameter('docking_ship', model) 483 dock.dockMultiEffect.SetParameter('docking_dock', dock.childObject) 484 dock.dockMultiEffect.SetControllerVariable('materialize', 1.0) 485 dock.dockMultiEffect.SetControllerVariable('_previousState', 1.0) 486 dock.dockMultiEffect.SetControllerVariable('materializeDelay', 0.0) 487 dock.dockMultiEffect.SetControllerVariable('docked', 1.0 if skipDockingAnimation else 0.0) 488 dock.dockMultiEffect.StartControllers() 489 if skipDockingAnimation: 490 dock.childObject.SetControllerVariable('isActivePlayerDock', 0.0) 491 dock.childObject.SetControllerVariable('isDocked', 1.0) 492 dock.childObject.StartControllers() 493 call_after_simtime_delay(dock.childObject.SetControllerVariable, 1.0, 'isActivePlayerDock', 1.0) 494 else: 495 try: 496 if sizeClass < 2: 497 emptyDocks = [ dock for dock in self.smallDocks if not dock.isActive ] 498 if len(emptyDocks) > 0: 499 newDock = rnd.choice(emptyDocks) 500 else: 501 nonPlayerDocks = [ dock for dock in self.smallDocks if not dock.isPlayer ] 502 if nonPlayerDocks: 503 newDock = rnd.choice(nonPlayerDocks) 504 else: 505 raise IndexError('No available docks') 506 else: 507 emptyDocks = [ dock for dock in self.bigDocks if not dock.isActive ] 508 if len(emptyDocks) > 0: 509 newDock = rnd.choice(emptyDocks) 510 else: 511 nonPlayerDocks = [ dock for dock in self.bigDocks if not dock.isPlayer ] 512 if nonPlayerDocks: 513 newDock = rnd.choice(nonPlayerDocks) 514 else: 515 raise IndexError('No available docks') 516 except IndexError: 517 if sizeClass < 2: 518 if self.smallDocks: 519 newDock = rnd.choice(self.smallDocks) 520 elif self.bigDocks: 521 newDock = rnd.choice(self.bigDocks) 522 else: 523 return 524 elif self.bigDocks: 525 newDock = rnd.choice(self.bigDocks) 526 elif self.smallDocks: 527 newDock = rnd.choice(self.smallDocks) 528 else: 529 return 530 531 self.playerDock.isPlayer = False 532 newDock.isPlayer = True 533 newDock.dockedShipItemID = itemID 534 oldDock = self.playerDock 535 if oldDock.childObject is not None: 536 oldDock.childObject.SetControllerVariable('isActivePlayerDock', 0.0) 537 model = self.LoadShipModel(itemID, typeID, True) 538 oldShip = newDock.dockedShip 539 oldME = newDock.dockMultiEffect 540 self._WaitForShipBoundingBox(model) 541 self.playerDock = self._ReplaceShipInDock(model, newDock, skipMaterialization=skipDockingAnimation) 542 shipOffset = geo2.QuaternionTransformVector(newDock.rotation, self.GetShipOffset(model, typeID)) 543 if not skipDockingAnimation: 544 self.SetFlightPath(oldDock.cameraExitPoint, oldDock.hallwayPoint, newDock.hallwayPoint, newDock.cameraExitPoint, geo2.Vec3Add(newDock.translation, shipOffset)) 545 dist = geo2.Vec3DistanceSq(oldDock.cameraExitPoint, newDock.cameraExitPoint) 546 if not self.GetCamera().IsPointWithinViewAngle(newDock.translation, 75) and dist > 1000000 or skipDockingAnimation: 547 if oldShip is not None and oldShip in self.hangarScene.objects: 548 self.hangarScene.objects.remove(oldShip) 549 if oldME is not None and oldME in self.hangarScene.objects: 550 self.hangarScene.objects.remove(oldME) 551 newDock.dockMultiEffect.SetParameter('docking_ship', model) 552 newDock.dockMultiEffect.SetParameter('docking_dock', newDock.childObject) 553 newDock.dockMultiEffect.SetControllerVariable('materialize', 1.0) 554 newDock.dockMultiEffect.SetControllerVariable('_previousState', 1.0) 555 newDock.dockMultiEffect.SetControllerVariable('materializeDelay', 0.0) 556 newDock.childObject.SetControllerVariable('isDocked', 1.0 if skipDockingAnimation else 0.0) 557 newDock.childObject.StartControllers() 558 newDock.dockMultiEffect.SetControllerVariable('docked', 1.0 if skipDockingAnimation else 0.0) 559 newDock.dockMultiEffect.StartControllers() 560 else: 561 if foundDock == self.playerDock: 562 if itemID == self.playerDock.dockedShipItemID: 563 if skipDockingAnimation: 564 docker = self.playerDock.dockMultiEffect 565 docker.SetControllerVariable('docked', 1.0 if skipDockingAnimation else 0.0) 566 docker.StartControllers() 567 self.playerDock.childObject.SetControllerVariable('isActivePlayerDock', 0.0) 568 self.playerDock.childObject.SetControllerVariable('isDocked', 1.0) 569 self.playerDock.childObject.StartControllers() 570 call_after_simtime_delay(self.playerDock.childObject.SetControllerVariable, 1.0, 'isActivePlayerDock', 1.0) 571 return self.playerDock.dockedShip 572 model = self.LoadShipModel(itemID, typeID, True) 573 self._ReplaceShipInDock(model, self.playerDock) 574 self._WaitForShipBoundingBox(model) 575 self.shipOffset = geo2.QuaternionTransformVector(self.playerDock.rotation, self.GetShipOffset(model, typeID)) 576 self._ConfigureShipTransform(model, self.shipOffset, self.playerDock) 577 self.playerDock.dockedShip = model 578 self.GetCamera().SetIsChangingSkin() 579 self.GetCamera().SetShip(model, typeID, changingShip=False) 580 self.GetCamera().SetCurrentShipSizeClass(sizeClass) 581 self._AddDetailsToShipModel(itemID, typeID, model, playerShip=True) 582 self.hangarScene.objects.append(model) 583 if self.playerDock.dockMultiEffect is not None: 584 self.playerDock.dockMultiEffect.SetParameter('docking_ship', model) 585 self.playerDock.dockMultiEffect.SetParameter('docking_dock', self.playerDock.childObject) 586 self.playerDock.dockMultiEffect.StartControllers() 587 return model 588 if firstDocking: 589 smalldock = next((dock for dock in self.smallDocks if dock.isPlayer), None) 590 smalldock.isPlayer = False 591 smalldock.isActive = False 592 bigdock = next((dock for dock in self.bigDocks if dock.isPlayer), None) 593 bigdock.isPlayer = False 594 bigdock.isActive = False 595 if foundDock.childObject is not None: 596 foundDock.childObject.SetControllerVariable('isActivePlayerDock', 1.0) 597 if foundDock.dockedShip is not None: 598 foundDock.dockedShip.SetControllerVariable('isActivePlayerDock', 1.0) 599 self.playerDock = foundDock 600 foundDock.isActive = True 601 foundDock.isPlayer = True 602 while foundDock.dockedShip is None: 603 blue.synchro.Yield() 604 605 foundDock.dockMultiEffect.SetControllerVariable('_previousState', 1.0) 606 foundDock.dockMultiEffect.SetControllerVariable('docked', 1.0 if skipDockingAnimation else 0.0) 607 self.GetCamera().SetShip(foundDock.dockedShip, typeID) 608 self.GetCamera().SetCurrentShipSizeClass(sizeClass) 609 foundDock.dockMultiEffect.StartControllers() 610 sm.ScatterEvent('OnHangarGoingToShip', foundDock.dockedShip) 611 self._AddDetailsToShipModel(itemID, typeID, foundDock.dockedShip, playerShip=True) 612 if skipDockingAnimation: 613 foundDock.childObject.SetControllerVariable('isActivePlayerDock', 0.0) 614 foundDock.childObject.SetControllerVariable('isDocked', 1.0) 615 call_after_simtime_delay(foundDock.childObject.SetControllerVariable, 1.0, 'isActivePlayerDock', 1.0) 616 return foundDock.dockedShip 617 if self.playerDock.childObject is not None: 618 self.playerDock.childObject.SetControllerVariable('isActivePlayerDock', 0.0) 619 if self.playerDock.dockedShip is not None: 620 self.playerDock.dockedShip.SetControllerVariable('isActivePlayerDock', 0.0) 621 if foundDock.childObject is not None: 622 foundDock.childObject.SetControllerVariable('isActivePlayerDock', 1.0) 623 if foundDock.dockedShip is not None: 624 foundDock.dockedShip.SetControllerVariable('isActivePlayerDock', 1.0) 625 self.playerDock.isPlayer = False 626 foundDock.isPlayer = True 627 self.GetCamera().SetShip(foundDock.dockedShip, typeID) 628 self.GetCamera().SetCurrentShipSizeClass(sizeClass) 629 shipOffset = geo2.QuaternionTransformVector(foundDock.rotation, self.GetShipOffset(foundDock.dockedShip, typeID)) 630 self.SetFlightPath(self.playerDock.cameraExitPoint, self.playerDock.hallwayPoint, foundDock.hallwayPoint, foundDock.cameraExitPoint, geo2.Vec3Add(foundDock.translation, shipOffset)) 631 self.playerDock = foundDock 632 self._AddDetailsToShipModel(itemID, typeID, foundDock.dockedShip, playerShip=True) 633 sm.ScatterEvent('OnHangarGoingToShip', foundDock.dockedShip) 634 return foundDock.dockedShip 635 if self.playerDock is None or model is None: 636 self.log.error('ModularHangarShipBehaviour.PlaceShip: Dock missconfigured') 637 return 638 self.playerDock.isActive = True 639 self._WaitForShipBoundingBox(model) 640 self.shipOffset = geo2.QuaternionTransformVector(self.playerDock.rotation, self.GetShipOffset(model, typeID)) 641 self._ConfigureShipTransform(model, self.shipOffset, self.playerDock) 642 self.playerDock.dockedShip = model 643 self.GetCamera().SetShip(model, typeID) 644 self.GetCamera().SetCurrentShipSizeClass(sizeClass) 645 if model.boosters is not None: 646 model.boosters.display = True 647 self._AddDetailsToShipModel(itemID, typeID, model, playerShip=True) 648 if self.playerDock.dockMultiEffect is not None: 649 self.playerDock.dockMultiEffect.SetParameter('docking_ship', model) 650 self.playerDock.dockMultiEffect.SetParameter('docking_dock', self.playerDock.childObject) 651 self.playerDock.dockMultiEffect.StartControllers() 652 sm.ScatterEvent('OnHangarGoingToShip', model) 653 self.hangarScene.objects.append(model) 654 return model 655 656 def GetShipOffset(self, model, typeID): 657 if model is None: 658 return (0.0, 0.0, 0.0) 659 localBB = model.GetLocalBoundingBox() 660 height = abs(localBB[0][0]) 661 width = abs(localBB[0][2]) 662 groupID = GetGroupID(typeID) 663 sizeClass = GetShipSizeClass(groupID) 664 if sizeClass < 2: 665 shipOffset = hConst.SMALL_PLATFORM_SHIP_PLACEMENT_OFFSET 666 return (0.0, shipOffset[2] + shipOffset[3] * height, shipOffset[0] + shipOffset[1] * width) 667 shipOffset = hConst.MEDIUM_PLATFORM_SHIP_PLACEMENT_OFFSET 668 return (0.0, shipOffset[2] + shipOffset[3] * height, shipOffset[0] + shipOffset[1] * width) 669 670 def GetShipCenter(self, model, typeID): 671 translation = model.translationCurve.currentValue if model.translationCurve is not None else None 672 modelTranslation = model.translationCurve.currentValue if model.translationCurve is not None else None 673 return geo2.Vec3Add(translation or (0.0, 0.0, 0.0), modelTranslation or (0.0, 0.0, 0.0)) 674 675 def GetAnimEndPosition(self): 676 return (0.0, 0.0, 0.0) 677 678 def GetAnimStartPosition(self): 679 return (0.0, 0.0, 0.0) 680 681 def _GetSizeClass(self, ship): 682 assignedGroup = GetShipSizeClass(ship.groupID) 683 if assignedGroup is None: 684 return 1 685 return assignedGroup 686 687 def _GetDockingMultieffect(self): 688 return blue.resMan.LoadObject(GetGraphicFile(self.dockingEffectGraphicID)) 689 690 def populateDocksWithInventoryShips(self, ships, scene, hangar): 691 rnd.shuffle(ships) 692 bigShips = [] 693 smallShips = [] 694 capitalShips = [] 695 for ship in ships: 696 sizeClass = self._GetSizeClass(ship) 697 if sizeClass < 2: 698 smallShips.append(ship) 699 elif sizeClass < 3: 700 bigShips.append(ship) 701 else: 702 capitalShips.append(ship) 703 704 if self.smallDocks: 705 smallDock = rnd.choice(self.smallDocks) 706 smallDock.isPlayer = True 707 smallDock.isActive = True 708 if self.bigDocks: 709 bigDock = rnd.choice(self.bigDocks) 710 bigDock.isPlayer = True 711 bigDock.isActive = True 712 713 def _placeShipInDock(ship, dock): 714 multiEffect = self._GetDockingMultieffect() 715 if multiEffect is None: 716 return self.log.error('modularHangarShipBehaviour.populateDocksWithInventoryShips: MultiEffect broken') 717 multiEffect.SetParameter('docking_dock', dock.childObject) 718 try: 719 curveSet = multiEffect.curveSets.FindByName('docking_cs') 720 exitPoint = curveSet.curves.FindByName('exit_point') 721 exitPoint.value = dock.relativeMEExitPoint 722 except AttributeError: 723 self.log.error('modularHangarShipBehaviour.populateDocksWithInventoryShips: MultiEffect Attributes broken') 724 725 dock.dockMultiEffect = multiEffect 726 scene.objects.append(multiEffect) 727 model = self.LoadShipModel(ship.itemID, ship.typeID, False) 728 self._WaitForShipBoundingBox(model) 729 shipOffset = geo2.QuaternionTransformVector(dock.rotation, self.GetShipOffset(model, ship.typeID)) 730 self._ConfigureShipTransform(model, shipOffset, dock) 731 scene.objects.append(model) 732 dock.dockedShip = model 733 dock.dockMultiEffect.SetParameter('docking_ship', model) 734 dock.dockMultiEffect.SetControllerVariable('_previousState', 1.0) 735 dock.dockMultiEffect.SetControllerVariable('docked', 1.0) 736 dock.childObject.SetControllerVariable('isDocked', 1.0) 737 dock.childObject.StartControllers() 738 if ship.itemID != self.playerShipItemID: 739 dock.dockMultiEffect.StartControllers() 740 dock.dockMultiEffect.name = dock.dockMultiEffect.name + '_' + model.name 741 742 for ship in smallShips: 743 if sum((d.isActive is False for d in self.smallDocks)) == 0: 744 break 745 if ship.itemID == self.playerShipItemID: 746 for smallDock in self.smallDocks: 747 if smallDock.isPlayer: 748 dock = smallDock 749 750 else: 751 dock = rnd.choice([ dock for dock in self.smallDocks if not dock.isActive ]) 752 dock.isActive = True 753 dock.dockedShipItemID = ship.itemID 754 if dock.isPlayer: 755 _placeShipInDock(ship, dock) 756 else: 757 uthread.new(_placeShipInDock, ship, dock) 758 759 for ship in bigShips: 760 if sum((d.isActive is False for d in self.bigDocks)) == 0: 761 break 762 if ship.itemID == self.playerShipItemID: 763 for bigDock in self.bigDocks: 764 if bigDock.isPlayer: 765 dock = bigDock 766 767 else: 768 dock = rnd.choice([ dock for dock in self.bigDocks if not dock.isActive ]) 769 dock.isActive = True 770 dock.dockedShipItemID = ship.itemID 771 if dock.isPlayer: 772 _placeShipInDock(ship, dock) 773 else: 774 uthread.new(_placeShipInDock, ship, dock) 775 776 def _LoadAndPlaceCapitalShip(ship): 777 positionLocators = self.GetLocatorsFromSet(hangar, hConst.LOCATORSET_CAPITAL_SHIP) 778 if len(positionLocators) != 1: 779 self.log.info('ModularHangarShipBehaviour.populateDocksWithInventoryShips: capital locator missing') 780 return 781 model = self.LoadShipModel(ship.itemID, ship.typeID, False) 782 if model is None: 783 return 784 self._WaitForShipBoundingBox(model) 785 position = positionLocators[0][0] 786 rotation = positionLocators[0][1] 787 shipTranslation = trinity.Tr2TranslationAdapter() 788 shipBBOffset = self.GetShipOffset(model, ship.typeID) 789 shipTranslation.value = geo2.Vec3Add(position, shipBBOffset) 790 shipRotation = trinity.Tr2CurveConstant() 791 shipRotation.value = rotation 792 model.translationCurve = shipTranslation 793 model.rotationCurve = shipRotation 794 scene.objects.append(model) 795 796 if len(capitalShips) > 0: 797 ship = rnd.choice(capitalShips) 798 uthread.new(_LoadAndPlaceCapitalShip, ship) 799 self.isInitialized = True 800 801 def SetFlightPath(self, exit1, hallway1, hallway2, exit2, dockPos): 802 self.flightPath['exit1'] = exit1 803 self.flightPath['exit2'] = exit2 804 self.flightPath['hallway1'] = hallway1 805 self.flightPath['hallway2'] = hallway2 806 self.GetCamera().SetFlightValueMap(exit1, hallway1, hallway2, exit2, dockPos) 807 808 def UpdateStructureState(self, hangarViewState, hangarModel): 809 try: 810 if hangarViewState.upkeepState is not None: 811 hangarModel.SetControllerVariable('upkeepState', hangarViewState.upkeepState - 1 or 0) 812 if hangarViewState.operatingState is not None: 813 if hangarViewState.operatingState == 102: 814 operatingState = 0 815 else: 816 operatingState = hangarViewState.operatingState - 109 817 hangarModel.SetControllerVariable('operatingState', operatingState) 818 hangarModel.SetControllerVariable('hangarShieldDamage', hangarViewState.damageState[0] or 1.0) 819 hangarModel.SetControllerVariable('hangarArmorDamage', hangarViewState.damageState[1] or 1.0) 820 hangarModel.SetControllerVariable('hangarHullDamage', hangarViewState.damageState[2] or 1.0) 821 if hangarViewState.timerProgress is not None and type(hangarViewState.timerProgress) == float: 822 timerProgress = 1 + math.floor(hangarViewState.timerProgress * 15) or 0 823 hangarModel.SetControllerVariable('timerProgress', timerProgress) 824 hangarModel.SetControllerVariable('isRepairing', float(hangarViewState.timerIsProgressing) or 0) 825 hangarModel.SetControllerVariable('isDamaged', float(hangarViewState.timerIsPaused) or 0) 826 timeRemainingSec = GetSecondsUntilSimTime(hangarViewState.timerEndAt or 0) 827 hangarModel.SetControllerVariable('remainingTime', timeRemainingSec or 0) 828 except TypeError: 829 self.log.error('modularHangarBehaviours.UpdateStructureState hangarViewState attribute error') 830 831 def UpdateUndockStatus(self, isUndocking): 832 dock = self._GetPlayerDock() 833 if dock is not None and dock.dockMultiEffect is not None: 834 dock.dockMultiEffect.SetControllerVariable('docked', 1.0 - isUndocking) 835 836 def _ReplaceShipInDock(self, model, dock, skipCleanup = False, makeActiveShip = True, skipMaterialization = False): 837 838 def cleanUp(hangarScene, ship, multiEffect): 839 for param in multiEffect.parameters: 840 param.object = None 841 842 multiEffect.bindings.removeAt(-1) 843 if ship is not None and ship in hangarScene.objects: 844 hangarScene.objects.remove(ship) 845 if multiEffect is not None and multiEffect in hangarScene.objects: 846 hangarScene.objects.remove(multiEffect) 847 848 if self.playerDock is None: 849 return 850 multiEffect = self._GetDockingMultieffect() 851 multiEffect.name = multiEffect.name + '_' + model.name 852 if dock.dockMultiEffect is None: 853 if multiEffect is None: 854 return self.log.error('modularHangarShipBehaviour._ReplaceShipInDock: MultiEffect broken') 855 multiEffect.SetParameter('docking_dock', dock.childObject) 856 curveSet = multiEffect.curveSets.FindByName('docking_cs') 857 exitPoint = curveSet.curves.FindByName('exit_point') 858 exitPoint.value = dock.relativeMEExitPoint 859 else: 860 newExit = multiEffect.curveSets.FindByName('docking_cs').curves.FindByName('exit_point') 861 oldExit = dock.dockMultiEffect.curveSets.FindByName('docking_cs').curves.FindByName('exit_point') 862 newExit.value = oldExit.value 863 oldME = dock.dockMultiEffect 864 multiEffect.SetParameter('docking_dock', dock.childObject) 865 oldME.SetControllerVariable('materialize', 0.0) 866 if skipMaterialization: 867 oldME.SetControllerVariable('_previousState', 0.0) 868 oldME.StartControllers() 869 oldShip = oldME.parameters.FindByName('docking_ship').object 870 if not skipCleanup: 871 call_after_simtime_delay(cleanUp, 15.0, self.hangarScene, oldShip, oldME) 872 dock.dockMultiEffect = multiEffect 873 self.hangarScene.objects.append(multiEffect) 874 multiEffect.SetControllerVariable('materialize', 1.0) 875 multiEffect.SetControllerVariable('_previousState', 1.0 if skipMaterialization else 0.0) 876 multiEffect.SetControllerVariable('docked', 1.0) 877 multiEffect.SetControllerVariable('materializeDelay', 2.75) 878 if dock.childObject is not None and makeActiveShip: 879 call_after_simtime_delay(dock.childObject.SetControllerVariable, 0.1, 'isActivePlayerDock', 1.0) 880 return dock 881 882 def AnimateShipEntry(self, newModel, typeID, scene = None, duration = 5.0): 883 pass 884 885 def UpdateActiveShipIDs(self, typeID, itemID): 886 self.playerShipItemID = itemID 887 self.playerShipTypeID = typeID 888 889 def OnShipCosmeticsChanged(self, ship_id, cosmetics_types): 890 if self.smallDocks: 891 for each in (dock for dock in self.smallDocks): 892 if each.dockedShip is not None: 893 enabledCosmetics = sm.GetService('cosmeticsSvc').get_enabled_ship_cosmetics(each.dockedShipItemID, forceRefresh=False) 894 uthread.new(self.cosmeticsLoader.SetCosmeticsOnShip, each.dockedShip, enabledCosmetics) 895 896 if self.bigDocks: 897 for each in (dock for dock in self.bigDocks): 898 if each.dockedShip is not None: 899 enabledCosmetics = sm.GetService('cosmeticsSvc').get_enabled_ship_cosmetics(each.dockedShipItemID, forceRefresh=False) 900 uthread.new(self.cosmeticsLoader.SetCosmeticsOnShip, each.dockedShip, enabledCosmetics) 901 902 def OnSessionChanged(self, _isremote, _session, change): 903 if 'corpid' or 'allianceid' in change: 904 enabledCosmetics = sm.GetService('cosmeticsSvc').get_enabled_ship_cosmetics(session.shipid) 905 self.OnShipCosmeticsChanged(session.shipid, enabledCosmetics) 906 907 def _AddDetailsToShipModel(self, itemID, typeID, model, playerShip = False, skipSetupAnimation = False): 908 try: 909 if model is None: 910 return 911 if playerShip: 912 self.SetShipDamage(itemID, model) 913 self.FitTurrets(itemID, typeID, model) 914 self.SetShipKillCounter(itemID, model) 915 self.SetShipDirtLevel(itemID, model) 916 if not skipSetupAnimation: 917 self.SetupShipAnimation(model, typeID, itemID) 918 enabledCosmetics = sm.GetService('cosmeticsSvc').get_enabled_ship_cosmetics(itemID, forceRefresh=True) 919 if enabledCosmetics is not None: 920 uthread.new(self.cosmeticsLoader.SetCosmeticsOnShip, model, enabledCosmetics) 921 except RuntimeError: 922 self.log.error('modularHangarBehaviours._AddDetailsToShipModel failed to get dogmaItem') 923 924 def LoadShipModel(self, itemID, typeID, playerShip = False, skipSetupAnimation = False): 925 model = self._LoadSOFShipModel(itemID, typeID) 926 if model is not None: 927 model.name = str(itemID) 928 if playerShip: 929 self.playerShipItemID = itemID 930 self.playerShipTypeID = typeID 931 if hasattr(model, 'boosters') and model.boosters is not None: 932 model.boosters.display = True 933 self._AddDetailsToShipModel(itemID, typeID, model, playerShip=playerShip, skipSetupAnimation=skipSetupAnimation) 934 self.SetInHangarVariables(model) 935 return model 936 937 def OnShipsRepaired(self, itemIDs): 938 for each in (dock for dock in self.smallDocks if dock.dockedShipItemID in itemIDs): 939 each.dockMultiEffect.SetControllerVariable('isRepairing', 1.0) 940 941 for each in (dock for dock in self.bigDocks if dock.dockedShipItemID in itemIDs): 942 each.dockMultiEffect.SetControllerVariable('isRepairing', 1.0) 943 944 def ProcessSkinChange(self, newModel): 945 if self.playerDock is not None and self.playerDock.dockMultiEffect is not None: 946 self.playerDock.dockedShip = newModel 947 else: 948 return 949 if newModel.boosters is not None: 950 newModel.boosters.display = True 951 self.GetCamera().SetIsChangingSkin() 952 self.GetCamera().SetShip(newModel, self.playerShipTypeID, changingShip=False) 953 self._AddDetailsToShipModel(self.playerShipItemID, self.playerShipTypeID, newModel, playerShip=True) 954 self.playerDock.dockMultiEffect.SetParameter('docking_ship', newModel) 955 self.playerDock.dockMultiEffect.SetControllerVariable('materialize', 1.0) 956 self.playerDock.dockMultiEffect.SetControllerVariable('materializeDelay', 0.0) 957 self.playerDock.dockMultiEffect.SetControllerVariable('_previousState', 1.0) 958 self.playerDock.dockMultiEffect.SetControllerVariable('skinChange', 1.0) 959 self.playerDock.dockMultiEffect.SetControllerVariable('docked', 1.0) 960 newModel.StartControllers() 961 for curveSet in self.playerDock.dockMultiEffect.curveSets: 962 curveSet.Play() 963 964 for controller in self.playerDock.dockMultiEffect.controllers: 965 controller.Start() 966 967 skin_state = sm.GetService('cosmeticsSvc').GetAppliedSkinStateForCurrentSession(self.playerShipItemID) 968 if skin_state is not None and skin_state.skin_type == ShipSkinType.FIRST_PARTY_SKIN: 969 self._activeSkinID = sm.GetService('cosmeticsSvc').GetFirstPartySkinObjectForCurrentSession(skin_state.skin_data.skin_id) 970 971 def ProcessCamera(self, camera, newModel, typeID): 972 print('process camera called with newModel typeID: ', typeID) 973 974 def _shipRequiresBigDock(self, ship): 975 pass 976 977 978 class ModularHangarDroneBehaviour(BaseHangarShipDroneBehaviour): 979 980 def SetRepairDroneCount(self, boundingRadius): 981 count = int(math.ceil(boundingRadius / 60.0)) 982 if self.repairDroneBehaviourGroup: 983 self.repairDroneBehaviourGroup.SetCount(count)