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

Jump.py (29719B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\environment\effects\Jump.py
      2 import logging
      3 import random
      4 import blue
      5 import carbon.common.script.util.mathCommon as mathCommon
      6 import carbonui.const as uiconst
      7 import evecamera
      8 import evecamera.shaker as shaker
      9 import evefisfx.jumptransitioncamera as transitioncam
     10 import geo2
     11 import inventorycommon.const as invconst
     12 import trinity
     13 import uthread
     14 from carbon.common.script.util.exceptionEater import ExceptionEater
     15 from carbonui.uicore import uicore
     16 from eve.client.script.environment.effects.GenericEffect import GenericEffect, ShipEffect, STOP_REASON_DEFAULT
     17 from eve.client.script.ui.shared.infoPanels.const import infoPanelConst
     18 from eve.client.script.ui.view.viewStateConst import ViewState
     19 from eve.common.script.sys.idCheckers import IsAbyssalSpaceSystem
     20 from eve.common.script.sys.idCheckers import IsTriglavianSystem
     21 from fsdBuiltData.common.graphicIDs import GetGraphicFile
     22 logger = logging.getLogger(__name__)
     23 
     24 class JumpTransitionTunnel(object):
     25     __guid__ = 'effects.JumpTransitionTunnel'
     26 
     27     def __init__(self, tunnelEffect):
     28         self.tunnelEffect = tunnelEffect
     29         self.destinationSceneApplied = False
     30         self.startCamDurationS = 1.0
     31         self.endCamDurationS = 1.0
     32         self.camOffsetStart = 1000000
     33         self.camOffsetEnd = 500000
     34         self.initToStartDelay = 850
     35         self.normDir = (0, 0, 1)
     36         self.effect = None
     37         self.effectRoot = None
     38         self.initCS = None
     39         self.startCS = None
     40         self.stopCS = None
     41         self.mainCS = None
     42         self.shakeDampCurve = None
     43         self.shakeScaleOut = None
     44         self.shakeScaleIn = None
     45         self.randomSoundNumber = 0
     46         self.cameraLookAnimation = None
     47         self.fxSequencer = sm.GetService('FxSequencer')
     48 
     49     def _FindCurveSets(self, model):
     50         self.initCS = None
     51         self.startCS = None
     52         self.stopCS = None
     53         self.mainCS = None
     54         for each in model.curveSets:
     55             if each.name == 'init':
     56                 self.initCS = each
     57             elif each.name == 'start':
     58                 self.startCS = each
     59             elif each.name == 'stop':
     60                 self.stopCS = each
     61             elif each.name == 'valuePropagation':
     62 
     63                 def propValue(*args):
     64                     source, dest = args
     65                     dest.value = source.value
     66 
     67                 each.bindings[2].copyValueCallable = propValue
     68             elif each.name == 'main':
     69                 self.mainCS = each
     70 
     71     def SetScene(self, scene):
     72         self.scene = scene
     73         scene.warpTunnel = self.effectRoot
     74 
     75     def _ApplyTexturePath(self, effect, name, path):
     76         for each in effect.resources:
     77             if each.name == name:
     78                 each.resourcePath = path
     79 
     80     def _CreateCameraShakeCurves(self):
     81         shakeScaleOut = trinity.Tr2CurveScalar()
     82         shakeScaleOut.AddKey(0.0, 0.125, trinity.Tr2CurveInterpolation.LINEAR)
     83         shakeScaleOut.AddKey(0.5, 4.0, trinity.Tr2CurveInterpolation.LINEAR)
     84         shakeScaleOut.AddKey(2.5, 1.0, trinity.Tr2CurveInterpolation.LINEAR)
     85         shakeScaleIn = trinity.Tr2CurveScalar()
     86         shakeScaleIn.AddKey(0.0, 1.0, trinity.Tr2CurveInterpolation.LINEAR)
     87         shakeScaleIn.AddKey(0.4, 2.0, trinity.Tr2CurveInterpolation.LINEAR)
     88         shakeScaleIn.AddKey(0.6, 4.0, trinity.Tr2CurveInterpolation.LINEAR)
     89         shakeScaleIn.AddKey(0.8, 1.0, trinity.Tr2CurveInterpolation.LINEAR)
     90         shakeScaleIn.AddKey(1.1, 0.0, trinity.Tr2CurveInterpolation.LINEAR)
     91         shakeDampCurve = trinity.TriPerlinCurve()
     92         shakeDampCurve.offset = 0.07
     93         shakeDampCurve.scale = 1
     94         shakeDampCurve.alpha = 0.75
     95         shakeDampCurve.speed = 4
     96         shakeDampCurve.N = 4
     97         self.shakeJumpInit = shaker.ShakeBehavior('JumpInit')
     98         self.shakeJumpInit.noiseScale = 0.125
     99         self.shakeJumpInit.dampCurve = shakeDampCurve
    100         self.shakeJumpOut = shaker.ShakeBehavior('JumpOut')
    101         self.shakeJumpOut.scaleCurve = shakeScaleOut
    102         self.shakeJumpOut.dampCurve = shakeDampCurve
    103         self.shakeJumpIn = shaker.ShakeBehavior('JumpIn')
    104         self.shakeJumpIn.scaleCurve = shakeScaleIn
    105         self.shakeJumpIn.dampCurve = shakeDampCurve
    106 
    107     def Prepare(self, shipBall, destSystem = None):
    108         self.shipBall = shipBall
    109         self.ending = False
    110         self.effectRoot = trinity.EveRootTransform()
    111         self.effect = blue.resMan.LoadObject(self.tunnelEffect)
    112         self.dust = self.effect.children.FindByName('Dust')
    113         self.dust.display = True
    114         self.effectRoot.children.append(self.effect)
    115         self._FindCurveSets(self.effect)
    116         sceneMan = sm.GetService('sceneManager')
    117         self.camera = sceneMan.SetPrimaryCamera(evecamera.CAM_JUMP)
    118         transition = sm.GetService('viewState').GetTransitionByName('inflight', 'inflight')
    119         transition.SetTransitionEffect(self)
    120         self.transition = transition
    121         sceneManager = sm.GetService('sceneManager')
    122         if destSystem is not None:
    123             destNebulaPath = sceneManager.GetNebulaPathForSystem(destSystem)
    124             self._ApplyTexturePath(self.effect.mesh.transparentAreas[0].effect, 'NebulaMap', destNebulaPath)
    125         self._CreateCameraShakeCurves()
    126 
    127     def Start(self):
    128         uthread.new(self._DelayedStart)
    129 
    130     def _PlayInitSequence(self):
    131         self.StartGateEffectAudio()
    132         blue.synchro.SleepSim(850)
    133         if self.initCS is not None:
    134             self.initCS.Play()
    135             self.StartWarpTransitionAudio()
    136         blue.synchro.SleepSim(1500)
    137         self.GetCamera().shakeController.DoCameraShake(self.shakeJumpInit)
    138 
    139     def GetCamera(self):
    140         return sm.GetService('sceneManager').GetOrCreateCamera(evecamera.CAM_JUMP)
    141 
    142     def _PlayTunnelSequence(self):
    143         if self.ending:
    144             self.fxSequencer.LogWarn('Jump Transition: Trying to play tunnel start sequence while ending.')
    145             return
    146         normDir = geo2.QuaternionTransformVector(self.effectRoot.rotation, (0, 0, 1))
    147         self.normDir = normDir
    148         camera = self.GetCamera()
    149         camera.shakeController.DoCameraShake(self.shakeJumpOut)
    150         if self.initCS is not None:
    151             self.initCS.Stop()
    152         if self.startCS is not None:
    153             self.startCS.Play()
    154         camera.animationController.Schedule(transitioncam.OutFOV(self.startCamDurationS))
    155         blue.synchro.SleepSim(500)
    156 
    157     def _PlayMidTransitionCurves(self):
    158         self.transition.ApplyDestinationScene()
    159         self.destinationSceneApplied = True
    160         if self.mainCS is not None:
    161             self.mainCS.Play()
    162             self.StopWarpTransitionAudio()
    163 
    164     def _DelayedStart(self):
    165         with ExceptionEater('JumpTransitionTunnelStart'):
    166             self.DoCameraLookAnimation()
    167             self._PlayInitSequence()
    168             blue.synchro.SleepSim(self.initToStartDelay)
    169             self.FadeUIOut()
    170             self._PlayTunnelSequence()
    171             self._PlayMidTransitionCurves()
    172 
    173     def Stop(self):
    174         self._EarlyCleanup()
    175         self.ending = True
    176         if self.cameraLookAnimation is not None:
    177             self.cameraLookAnimation.Stop()
    178         camera = self.GetCamera()
    179         camera.shakeController.EndCameraShake('JumpIn')
    180         sm.GetService('viewState').GetView(ViewState.Space).ActivatePrimaryCamera()
    181         with ExceptionEater('JumpTransitionTunnelEnd'):
    182             if not self.destinationSceneApplied:
    183                 self.transition.ApplyDestinationScene()
    184             camera = self.GetCamera()
    185             anim = camera.animationController
    186             offset = geo2.Vec3Scale(self.normDir, -self.camOffsetEnd)
    187             anim.Schedule(transitioncam.InFOV(self.endCamDurationS))
    188             camera.shakeController.DoCameraShake(self.shakeJumpIn)
    189         if self.startCS is not None:
    190             self.startCS.Stop()
    191         if self.mainCS is not None:
    192             self.mainCS.Stop()
    193         if self.stopCS is not None:
    194             self.stopCS.Play()
    195         if self.dust is not None:
    196             self.dust.display = False
    197         self.FadeUIIn()
    198         uthread.new(self.BlinkSystemName)
    199         uthread.new(self._DelayedCleanup)
    200         self.cameraLookAnimation.OnJumpDone()
    201 
    202     def _EarlyCleanup(self):
    203         pass
    204 
    205     def _DelayedCleanup(self):
    206         blue.synchro.SleepSim(2000)
    207         if self.stopCS is not None:
    208             self.stopCS.Stop()
    209         if self.scene.warpTunnel == self.effectRoot:
    210             self.scene.warpTunnel = None
    211         self.effect = None
    212         self.effectRoot = None
    213         self.dust = None
    214 
    215     def DoCameraLookAnimation(self):
    216         if self.cameraLookAnimation is not None:
    217             self.cameraLookAnimation.Start()
    218 
    219     def BlinkSystemName(self):
    220         blue.synchro.Sleep(1000)
    221         infoPanelSvc = sm.GetService('infoPanel')
    222         panel = infoPanelSvc.GetPanelByTypeID(infoPanelConst.PANEL_LOCATION_INFO)
    223         if panel is not None:
    224             uicore.animations.FadeOut(panel.headerLabelCont, loops=4, duration=0.5, curveType=uiconst.ANIM_WAVE)
    225 
    226     def GetUIToFade(self):
    227         toFade = []
    228         from eve.client.script.ui.inflight.overview.overviewWindowUtil import GetOverviewWndIfOpen
    229         overview = GetOverviewWndIfOpen()
    230         if overview is not None:
    231             try:
    232                 toFade.append(overview.GetScrollContent())
    233             except:
    234                 self.fxSequencer.LogWarn('Failed to get overview contents to fade while jumping')
    235 
    236         return toFade
    237 
    238     def FadeUIOut(self):
    239         if self.ending:
    240             self.fxSequencer.LogWarn('Jump Transition: Trying to fade out ui while ending.')
    241             return
    242         uicore.animations.FadeOut(uicore.layer.bracket, duration=1)
    243         objs = self.GetUIToFade()
    244         for obj in objs:
    245             uicore.animations.FadeOut(obj, duration=1)
    246 
    247         uicore.layer.bracket.opacity = 0.0
    248         if not self.ending:
    249             for obj in objs:
    250                 obj.display = False
    251 
    252     def FadeUIIn(self):
    253         uicore.animations.FadeIn(uicore.layer.bracket, duration=1)
    254         objs = self.GetUIToFade()
    255         for obj in objs:
    256             obj.display = True
    257             uicore.animations.FadeIn(obj, duration=1, sleep=True)
    258 
    259         uicore.layer.bracket.opacity = 1.0
    260         for obj in objs:
    261             obj.opacity = 1.0
    262             obj.display = True
    263 
    264     def StartWarpTransitionAudio(self):
    265         eventName = 'transition_jump_play_%02d' % self.randomSoundNumber
    266         sm.GetService('audio').SendUIEvent(eventName)
    267 
    268     def StartGateEffectAudio(self):
    269         self.randomSoundNumber = random.randint(1, 10)
    270         eventName = 'jumpgate_new_play_%02d' % self.randomSoundNumber
    271         sm.GetService('audio').SendUIEvent(eventName)
    272 
    273     def StopWarpTransitionAudio(self):
    274         eventName = 'transition_jump_arrival_play_%02d' % self.randomSoundNumber
    275         sm.GetService('audio').SendUIEvent(eventName)
    276 
    277 
    278 class JumpTransitionGate(JumpTransitionTunnel):
    279     __guid__ = 'effects.JumpTransitionGate'
    280 
    281     def __init__(self, tunnelEffect):
    282         JumpTransitionTunnel.__init__(self, tunnelEffect)
    283 
    284     def Prepare(self, shipBall, stargateID, stargateBall):
    285         destStargate, destSystem = sm.GetService('michelle').GetBallpark().GetInvItem(stargateID).jumps[0]
    286         JumpTransitionTunnel.Prepare(self, shipBall, destSystem)
    287         model = stargateBall.GetModel()
    288         if model is not None:
    289             self.effectRoot.rotation = model.rotationCurve.value
    290             gateSize = model.boundingSphereRadius
    291         else:
    292             gateSize = 2500
    293         self.transition.InitializeGateTransition(destSystem, destStargate)
    294         finalTranslation = self.shipBall.radius * 10
    295         self.cameraLookAnimation = transitioncam.LookAnimation(self.camera, self.effectRoot.rotation, startFocusID=stargateID, endFocusID=destStargate, startTranslation=gateSize * 3, endTranslation=finalTranslation)
    296 
    297 
    298 class JumpTransitionShipCaster(JumpTransitionGate):
    299     __guid__ = 'effects.JumpShipCaster'
    300 
    301 
    302 class JumpTransitionCyno(JumpTransitionTunnel):
    303     __guid__ = 'effects.JumpTransitionCyno'
    304 
    305     def __init__(self, tunnelEffect, gateID = None):
    306         JumpTransitionTunnel.__init__(self, tunnelEffect)
    307         self.gateID = gateID
    308 
    309     def Prepare(self, shipBall, destSystemID, rotation):
    310         JumpTransitionTunnel.Prepare(self, shipBall, destSystemID)
    311         self.effectRoot.rotation = rotation
    312         self.transition.InitializeCynoTransition(destSystemID)
    313         self.initToStartDelay = 0
    314         if self.gateID is not None:
    315             model = self.fxSequencer.GetBall(self.gateID).GetModel()
    316             if model is None:
    317                 radius = 7000
    318             else:
    319                 radius = model.boundingSphereRadius
    320             self.cameraLookAnimation = transitioncam.LookAnimation(self.camera, self.effectRoot.rotation, startFocusID=self.gateID, startTranslation=5 * radius)
    321         else:
    322             self.cameraLookAnimation = transitioncam.LookAnimation(self.camera, self.effectRoot.rotation)
    323 
    324 
    325 class JumpTransitionWormhole(object):
    326     __guid__ = 'effects.JumpTransitionWormhole'
    327 
    328     def __init__(self):
    329         self.graphicInfo = None
    330         self.resPath = 'res:/fisfx/jump/wormholes/transition.red'
    331         self.model = None
    332         self.scene = None
    333         self.startCS = None
    334         self.stopCS = None
    335         self.midCS = None
    336         self.triglavianCS = None
    337         self.mainSequenceFinished = False
    338 
    339     def SetScene(self, scene):
    340         if self.model is None:
    341             return
    342         if self.scene is not None:
    343             self.scene.objects.fremove(self.model)
    344         scene.objects.append(self.model)
    345         self.scene = scene
    346 
    347     def Prepare(self, wormholeItem, destNebulaPath, srcNebulaPath, graphicInfo):
    348         if self.resPath is not None:
    349             self.model = trinity.Load(self.resPath)
    350         transition = sm.GetService('viewState').GetTransitionByName('inflight', 'inflight')
    351         transition.InitializeWormholeTransition(GetGraphicFile(wormholeItem.nebulaType))
    352         self.transition = transition
    353         self.graphicInfo = graphicInfo
    354         cubeParams = self.model.Find('trinity.TriTextureParameter')
    355         for cube in cubeParams:
    356             if cube.name == 'SourceNebulaMap':
    357                 cube.resourcePath = srcNebulaPath
    358             elif cube.name == 'ReflectionMap':
    359                 cube.resourcePath = destNebulaPath
    360 
    361         for each in self.model.curveSets:
    362             if each.name == 'start':
    363                 self.startCS = each
    364             elif each.name == 'stop':
    365                 self.stopCS = each
    366             elif each.name == 'middle':
    367                 self.midCS = each
    368             elif each.name == 'destination_tspace':
    369                 self.triglavianCS = each
    370 
    371         transition.SetTransitionEffect(self)
    372         self.itemID = wormholeItem.itemID
    373         sceneMan = sm.GetService('sceneManager')
    374         self.camera = sceneMan.SetPrimaryCamera(evecamera.CAM_JUMP)
    375 
    376     def _PlayMidCurves(self):
    377         if self.triglavianCS is not None and IsTriglavianSystem(self.graphicInfo[0]):
    378             self.triglavianCS.Play()
    379         blue.synchro.Sleep(500)
    380         if self.startCS is not None:
    381             self.startCS.Play()
    382         blue.synchro.Sleep(1000)
    383         self.transition.ApplyDestinationScene()
    384         if self.midCS is not None:
    385             self.midCS.Play()
    386         self.mainSequenceFinished = True
    387 
    388     def GetCamera(self):
    389         return sm.GetService('sceneManager').GetActiveSpaceCamera()
    390 
    391     def Start(self):
    392         camera = self.GetCamera()
    393         camera.LookAt(self.itemID, force=True)
    394         uthread.new(self._PlayMidCurves)
    395         sm.GetService('audio').SendUIEvent('worldobject_wormhole_travel_play')
    396 
    397     def Abort(self):
    398         self.transition.Abort()
    399 
    400         def _waitForFinish():
    401             while not self.mainSequenceFinished:
    402                 blue.synchro.Yield()
    403 
    404             self.Stop()
    405 
    406         uthread.new(_waitForFinish)
    407 
    408     def Stop(self, reason = STOP_REASON_DEFAULT):
    409         uthread.new(self.BlinkSystemName)
    410         if self.model is None:
    411             return
    412         uthread.new(self._DelayedStop)
    413 
    414     def _DelayedStop(self):
    415         if self.startCS is not None:
    416             self.startCS.Stop()
    417         if self.stopCS is not None:
    418             self.stopCS.Play()
    419         blue.synchro.SleepSim(500)
    420         sm.GetService('viewState').GetView(ViewState.Space).ActivatePrimaryCamera()
    421         blue.synchro.SleepSim(1500)
    422         if self.scene is not None:
    423             self.scene.objects.fremove(self.model)
    424             self.scene = None
    425         self.model = None
    426 
    427     def BlinkSystemName(self):
    428         blue.synchro.Sleep(1000)
    429         infoPanelSvc = sm.GetService('infoPanel')
    430         panel = infoPanelSvc.GetPanelByTypeID(infoPanelConst.PANEL_LOCATION_INFO)
    431         uicore.animations.FadeOut(panel.headerLabelCont, loops=4, duration=0.5, curveType=uiconst.ANIM_WAVE)
    432 
    433     def FadeOut(self, obj):
    434         uicore.animations.FadeOut(obj, duration=1)
    435 
    436     def FadeIn(self, obj):
    437         uicore.animations.FadeIn(obj, duration=1)
    438 
    439 
    440 class JumpTransitionAbyssal(JumpTransitionTunnel):
    441     __guid__ = 'effects.JumpTransitionAbyssal'
    442 
    443     def __init__(self, tunnelEffect):
    444         JumpTransitionTunnel.__init__(self, tunnelEffect)
    445 
    446     def Prepare(self, shipBall, destSolarSystemID, beaconID, beaconBall, beaconModel, nebulaGraphicID = None):
    447         JumpTransitionTunnel.Prepare(self, shipBall)
    448         self.transition.InitializeAbyssalTransition(destSolarSystemID, nebulaGraphicID)
    449         self.cameraLookAnimation = transitioncam.AbyssalLookAnimation(self.camera, beaconModel.boundingSphereRadius, self.effectRoot, startFocusID=beaconID)
    450         self.DoCameraLookAnimation()
    451 
    452     def _DelayedStart(self):
    453         with ExceptionEater('JumpTransitionTunnelStart'):
    454             self.FreezeEnvironments(True)
    455             self._PlayInitSequence()
    456             blue.synchro.SleepSim(self.initToStartDelay)
    457             self.FadeUIOut()
    458             self._PlayTunnelSequence()
    459             self._PlayMidTransitionCurves()
    460             self.ClearEnvironments()
    461 
    462     def _EarlyCleanup(self):
    463         if self.stopCS is not None:
    464             self.stopCS.Stop()
    465         try:
    466             self.scene.objects.remove(self.effectRoot)
    467         except:
    468             pass
    469 
    470         self.effect = None
    471         self.effectRoot = None
    472         self.dust = None
    473 
    474     def _DelayedCleanup(self):
    475         pass
    476 
    477     def Stop(self):
    478         scene = self.fxSequencer.GetScene()
    479         tunnel = self.scene.warpTunnel
    480         self.scene.warpTunnel = None
    481         scene.objects.append(tunnel)
    482         blue.pyos.synchro.SleepSim(2000)
    483         self.FreezeEnvironments(False)
    484         blue.pyos.synchro.SleepSim(500)
    485         JumpTransitionTunnel.Stop(self)
    486 
    487     def FreezeEnvironments(self, frozen):
    488         sm.GetService('environment').FreezeEnvironments(frozen)
    489 
    490     def ClearEnvironments(self):
    491         sm.GetService('environment').ClearAllEnvironments()
    492 
    493 
    494 class JumpTransitionAbyssalGate(JumpTransitionAbyssal):
    495     __guid__ = 'effects.JumpTransitionAbyssalGate'
    496 
    497     def Prepare(self, shipBall, destSolarSystemID, gateID, gateBall, gateModel, nebulaGraphicID = None):
    498         JumpTransitionTunnel.Prepare(self, shipBall)
    499         self.transition.InitializeAbyssalTransition(destSolarSystemID, nebulaGraphicID if IsAbyssalSpaceSystem(destSolarSystemID) else None)
    500         rotation = gateModel.rotationCurve.value if gateModel.rotationCurve is not None else geo2.QuaternionIdentity()
    501         distance = gateModel.boundingSphereRadius
    502         self.effectRoot.rotation = rotation
    503         self.cameraLookAnimation = transitioncam.AbyssalGateLookAnimation(self.camera, distance * 3, rotation, gateID)
    504         self.DoCameraLookAnimation()
    505 
    506 
    507 class JumpTransitionAbyssalBetween(JumpTransitionAbyssal):
    508     __guid__ = 'effects.JumpTransitionAbyssalGate'
    509 
    510     def Prepare(self, shipBall, gateID, gateBall, gateModel):
    511         JumpTransitionTunnel.Prepare(self, shipBall)
    512         rotation = gateModel.rotationCurve.value if gateModel.rotationCurve is not None else geo2.QuaternionIdentity()
    513         distance = gateModel.boundingSphereRadius
    514         self.effectRoot.rotation = rotation
    515         self.cameraLookAnimation = transitioncam.AbyssalGateLookAnimation(self.camera, distance * 3, rotation, gateID)
    516         self.DoCameraLookAnimation()
    517 
    518 
    519 class JumpDriveIn(ShipEffect):
    520     __guid__ = 'effects.JumpDriveIn'
    521 
    522     def Start(self, duration):
    523         shipID = self.ballIDs[0]
    524         shipBall = self.fxSequencer.GetBall(shipID)
    525         if shipBall is None:
    526             self.fxSequencer.LogError(self.__guid__, ' could not find a ball')
    527             return
    528         ShipEffect.Start(self, duration)
    529 
    530     def DelayedHide(self, shipBall, delay):
    531         blue.pyos.synchro.SleepSim(delay)
    532         if shipBall is not None and shipBall.model is not None:
    533             shipBall.model.display = False
    534 
    535 
    536 class JumpDriveInBO(JumpDriveIn):
    537     __guid__ = 'effects.JumpDriveInBO'
    538 
    539 
    540 class JumpDriveOut(JumpDriveIn):
    541     __guid__ = 'effects.JumpDriveOut'
    542 
    543     def Start(self, duration):
    544         shipID = self.ballIDs[0]
    545         gateID = self.ballIDs[1]
    546         shipBall = self.fxSequencer.GetBall(shipID)
    547         here = sm.GetService('map').GetItem(session.solarsystemid2)
    548         there = sm.GetService('map').GetItem(self.graphicInfo[0])
    549         yaw, pitch = mathCommon.GetYawAndPitchAnglesRad((here.x, here.y, here.z), (there.x, there.y, there.z))
    550         quat = geo2.QuaternionRotationSetYawPitchRoll(yaw, pitch, 0)
    551         self.gfxModel.rotation = quat
    552         if session.shipid == shipID:
    553             self.playerEffect = JumpTransitionCyno(self.secondaryGraphicFile, gateID)
    554             self.playerEffect.Prepare(shipBall, self.graphicInfo[0], quat)
    555             self.playerEffect.SetScene(self.fxSequencer.GetScene())
    556             self.playerEffect.Start()
    557         ShipEffect.Start(self, duration)
    558         uthread.new(self.DelayedHide, shipBall, 180)
    559 
    560 
    561 class JumpDriveOutBO(JumpDriveOut):
    562     __guid__ = 'effects.JumpDriveOutBO'
    563 
    564 
    565 class JumpIn(JumpDriveIn):
    566     __guid__ = 'effects.JumpIn'
    567 
    568     def Start(self, duration):
    569         scaling = self.gfxModel.scaling
    570         self.gfxModel.scaling = (scaling[0] * 0.005, scaling[1] * 0.005, scaling[2] * 0.005)
    571         JumpDriveIn.Start(self, duration)
    572 
    573 
    574 class JumpOut(ShipEffect):
    575     __guid__ = 'effects.JumpOut'
    576 
    577     def Start(self, duration):
    578         shipID = self.ballIDs[0]
    579         shipBall = self.fxSequencer.GetBall(shipID)
    580         uthread.new(self.DelayedHide, shipBall)
    581         targetID = self.ballIDs[1]
    582         targetBall = self.fxSequencer.GetBall(targetID)
    583         if session.shipid == shipID:
    584             if hasattr(shipBall, 'KillBooster'):
    585                 shipBall.KillBooster()
    586             self.playerEffect = JumpTransitionGate(self.secondaryGraphicFile)
    587             self.playerEffect.Prepare(shipBall, targetID, targetBall)
    588             self.playerEffect.SetScene(self.fxSequencer.GetScene())
    589             self.playerEffect.Start()
    590 
    591     def DelayedHide(self, shipBall):
    592         blue.pyos.synchro.SleepSim(880)
    593         self.fxSequencer.OnSpecialFX(shipBall.id, None, None, None, None, 'effects.Uncloak', 0, 0, 0)
    594         if shipBall is not None and shipBall.model is not None:
    595             shipBall.model.display = False
    596 
    597 
    598 class JumpOutWormhole(JumpDriveIn):
    599     __guid__ = 'effects.JumpOutWormhole'
    600 
    601     def Start(self, duration):
    602         shipID = self.ballIDs[0]
    603         shipBall = self.fxSequencer.GetBall(shipID)
    604         if getattr(shipBall, 'model', None) is not None:
    605             self.fxSequencer.OnSpecialFX(shipID, None, None, None, None, 'effects.CloakRegardless', 0, 1, 0, -1, None)
    606         uthread.new(self.DelayedHide, shipBall, 2000)
    607         wormholeID = self.ballIDs[1]
    608         wormholeBall = self.fxSequencer.GetBall(wormholeID)
    609         if session.shipid == shipID:
    610             if hasattr(shipBall, 'KillBooster'):
    611                 shipBall.KillBooster()
    612             scene = self.fxSequencer.GetScene()
    613             self.playerEffect = JumpTransitionWormhole()
    614             srcNebula = scene.envMapResPath
    615             targetNebula = getattr(wormholeBall, 'targetNebulaPath', None)
    616             wormholeItem = self.fxSequencer.GetItem(wormholeID)
    617             self.playerEffect.Prepare(wormholeItem, targetNebula, srcNebula, self.graphicInfo)
    618             self.playerEffect.SetScene(scene)
    619             self.playerEffect.Start()
    620         self.PlayNamedAnimations(wormholeBall.model, 'Activate')
    621 
    622     def Stop(self, reason = STOP_REASON_DEFAULT):
    623         shipID = self.ballIDs[0]
    624         shipBall = self.fxSequencer.GetBall(shipID)
    625         if shipBall is not None and shipBall.model is not None:
    626             shipBall.model.display = True
    627         if self.gfx is not None:
    628             JumpDriveIn.Stop(self, reason)
    629 
    630 
    631 class JumpOutAbyssal(JumpOut):
    632     __guid__ = 'effects.JumpOutAbyssal'
    633 
    634     def Start(self, duration):
    635         shipID = self.ballIDs[0]
    636         shipBall = self.fxSequencer.GetBall(shipID)
    637         uthread.new(self.DelayedHide, shipBall)
    638         targetID = self.ballIDs[1]
    639         targetBall = self.fxSequencer.GetBall(targetID)
    640         targetModel = targetBall.GetModel()
    641         targetType = targetBall.typeID
    642         player = session.shipid == shipID
    643         if player:
    644             if hasattr(shipBall, 'KillBooster'):
    645                 shipBall.KillBooster()
    646         logger.debug('JumpOutAbyssal.Start graphicInfo=%s', self.graphicInfo)
    647         if targetType in (invconst.typeKnownToAbyssalBeacon, invconst.typeKnownToAbyssalSuspectBeacon):
    648             self.RemoveFromScene(targetModel)
    649             if player:
    650                 uthread.new(self.DelayedJumpTunnel, shipBall, targetID, targetBall, targetModel)
    651             else:
    652                 uthread.new(self.DelayedTearTrace, targetBall)
    653             self.fxSequencer.OnSpecialFX(targetID, None, None, None, None, 'effects.AbyssalSpaceTear', 0, 1, 0)
    654         elif player:
    655             uthread.new(self.DelayedJumpTunnelGate, shipBall, targetID, targetBall, targetModel)
    656             self.PlayActivationCurve(targetModel)
    657 
    658     def PlayActivationCurve(self, model):
    659         self.PlayNamedChildAnimations(model, 'Activation')
    660 
    661     def DelayedTearTrace(self, ball):
    662         blue.pyos.synchro.SleepSim(10000)
    663         model = ball.GetModel()
    664         if model is not None:
    665             self.AddToScene(model)
    666 
    667     def DelayedJumpTunnel(self, shipBall, targetID, targetBall, targetModel):
    668         self.playerEffect = JumpTransitionAbyssal(self.secondaryGraphicFile)
    669         self.StartEffect(shipBall, targetID, targetBall, targetModel)
    670 
    671     def DelayedJumpTunnelGate(self, shipBall, targetID, targetBall, targetModel):
    672         self.playerEffect = JumpTransitionAbyssalGate(self.secondaryGraphicFile)
    673         self.StartEffect(shipBall, targetID, targetBall, targetModel)
    674 
    675     def StartEffect(self, shipBall, targetID, targetBall, targetModel):
    676         self.playerEffect.Prepare(shipBall, self._GetDestinationSolarSystemID(), targetID, targetBall, targetModel, nebulaGraphicID=self._GetNebulaGraphicID())
    677         self.playerEffect.SetScene(self.fxSequencer.GetScene())
    678         blue.pyos.synchro.SleepSim(6000)
    679         self.playerEffect.Start()
    680 
    681     def _GetDestinationSolarSystemID(self):
    682         return self.graphicInfo[0]
    683 
    684     def _GetNebulaGraphicID(self):
    685         return self.graphicInfo[1]
    686 
    687 
    688 class JumpOutAbyssalBetween(JumpOutAbyssal):
    689     __guid__ = 'effects.JumpOutAbyssalBetween'
    690 
    691     def Start(self, duration):
    692         shipID = self.ballIDs[0]
    693         shipBall = self.fxSequencer.GetBall(shipID)
    694         shipModel = shipBall.GetModel()
    695         if session.shipid != shipID:
    696             return
    697         uthread.new(self.DelayedHide, shipBall)
    698         targetID = self.ballIDs[1]
    699         targetBall = self.fxSequencer.GetBall(targetID)
    700         targetModel = targetBall.GetModel()
    701         targetType = targetBall.typeID
    702         if hasattr(shipBall, 'KillBooster'):
    703             shipBall.KillBooster()
    704         uthread.new(self.DelayedJumpTunnelBetween, shipBall, shipModel, targetID, targetBall, targetModel)
    705         self.PlayActivationCurve(targetModel)
    706 
    707     def DelayedJumpTunnelBetween(self, shipBall, shipModel, targetID, targetBall, targetModel):
    708         self.playerEffect = JumpTransitionAbyssalBetween(self.secondaryGraphicFile)
    709         self.playerEffect.Prepare(shipBall, targetID, targetBall, targetModel)
    710         self.playerEffect.SetScene(self.fxSequencer.GetScene())
    711         self.playerEffect.Start()
    712         blue.pyos.synchro.SleepSim(5000)
    713         shipModel.display = True
    714         self.playerEffect.Stop()
    715 
    716 
    717 class GateActivity(GenericEffect):
    718     __guid__ = 'effects.GateActivity'
    719 
    720     def Prepare(self):
    721         gateBall = self.GetEffectShipBall()
    722         self.gfx = gateBall.model
    723 
    724     def Start(self, duration):
    725         gateID = self.ballIDs[0]
    726         gateBall = self.fxSequencer.GetBall(gateID)
    727         if gateBall is None:
    728             self.fxSequencer.LogError('GateActivity could not find a gate ball')
    729             return
    730         if gateBall.model is None:
    731             self.fxSequencer.LogError('GateActivity could not find a gate ball')
    732             return
    733         gateBall.Activate()
    734         gateBall.JumpArrival()
    735 
    736 
    737 class WormholeActivity(GenericEffect):
    738     __guid__ = 'effects.WormholeActivity'
    739 
    740     def Start(self, duration):
    741         wormholeID = self.ballIDs[0]
    742         wormholeBall = self.fxSequencer.GetBall(wormholeID)
    743         if wormholeBall is None:
    744             self.fxSequencer.LogError('WormholeActivity could not find a wormhole ball')
    745             return
    746         if wormholeBall.model is None:
    747             self.fxSequencer.LogError('WormholeActivity could not find a wormhole ball')
    748             return
    749         self.PlayNamedAnimations(wormholeBall.model, 'Activate')