Warp.py (29604B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\environment\effects\Warp.py 2 from math import cos, pow, sqrt, pi, sin 3 from eve.client.script.environment.effects import warp_signals 4 import random 5 import blue 6 import destiny 7 import evecamera 8 import trinity 9 import geo2 10 import uthread 11 import carbon.common.script.util.logUtil as log 12 import carbon.common.script.util.mathCommon as mathCommon 13 from fsdBuiltData.common.graphicIDs import GetGraphicFile 14 from eve.client.script.environment.effects.GenericEffect import ShipEffect, STOP_REASON_DEFAULT 15 from eve.client.script.parklife.sceneManagerConsts import SYSTEM_WIDE_CLOUD_NAME 16 import eve.client.script.environment.effects.effectConsts as effectconsts 17 import evecamera.shaker as shaker 18 import evegraphics.settings as gfxsettings 19 DYNAMIC_WARP_LIGHT_COLOR = (0.270588219165802, 0.6156862378120422, 1.0, 1.0) 20 STATIC_WARP_LIGHT_COLOR = (0.5647059082984924, 0.9960784316062927, 1.0, 1.0) 21 SMALL_SUN_TYPE_IDS = [3801, 22 3799, 23 45038, 24 3802, 25 45041, 26 3803, 27 45042] 28 29 class Warping(ShipEffect): 30 __guid__ = 'effects.Warping' 31 32 def __init__(self, trigger, effect = None, graphicFile = None): 33 super(Warping, self).__init__(trigger, effect, graphicFile) 34 self.shipball = None 35 self.shipModel = None 36 self.destination = None 37 self.warpSpeedModifier = 1.0 38 self.isLegacyJumpTunnel = True 39 self.systemWideCloud = None 40 41 def Prepare(self): 42 shipID = self.GetEffectShipID() 43 if shipID != session.shipid: 44 self.fxSequencer.OnSpecialFX(shipID, None, None, None, None, 'effects.Warping', 0, 0, 0) 45 self.fxSequencer.OnSpecialFX(shipID, None, None, None, None, 'effects.WarpOut', 0, 1, 0) 46 return 47 if hasattr(cfg.mapSolarSystemContentCache[session.solarsystemid], 'warpTunnelOverwrite'): 48 warpTunnelGID = cfg.mapSolarSystemContentCache[session.solarsystemid].warpTunnelOverwrite 49 if warpTunnelGID > 0: 50 self.graphicFile = GetGraphicFile(warpTunnelGID) 51 self.isLegacyJumpTunnel = False 52 if hasattr(cfg.mapSolarSystemContentCache[session.solarsystemid], 'systemWideCloud'): 53 scene = self.fxSequencer.GetScene() 54 self.systemWideCloud = scene.objects.FindByName(SYSTEM_WIDE_CLOUD_NAME) 55 ShipEffect.Prepare(self) 56 self.AlignToDirection() 57 58 def ModelChangeNotify(self, newModel): 59 if newModel is None: 60 return 61 self.shipModel = newModel 62 for binding in self.curveSet.bindings: 63 binding.sourceObject = self.shipModel.speed 64 65 def Start(self, duration): 66 if self.gfx is None: 67 return 68 self.gfx.display = False 69 self.hasExploded = False 70 self.hasWind = False 71 self.hasMoreCollisions = True 72 self.findNext = True 73 ShipEffect.Start(self, duration) 74 bp = sm.StartService('michelle').GetBallpark() 75 shipID = self.GetEffectShipID() 76 shipBall = bp.GetBall(shipID) 77 self.shipBall = shipBall 78 self.shipModel = getattr(shipBall, 'model', None) 79 self.shipBall.RegisterModelChangeNotification(self.ModelChangeNotify) 80 slimItem = bp.GetInvItem(shipID) 81 self.warpSpeedModifier = sm.StartService('godma').GetTypeAttribute(slimItem.typeID, const.attributeWarpSpeedMultiplier) 82 if self.warpSpeedModifier is None: 83 self.warpSpeedModifier = 1.0 84 egoball = bp.GetBall(bp.ego) 85 self.destination = (egoball.gotoX, egoball.gotoY, egoball.gotoZ) 86 if self.isLegacyJumpTunnel: 87 self.SetupTunnelBindings() 88 self.nextCollision = None 89 self.insideSolid = False 90 self.collisions = [] 91 self.collisions = self.GetWarpCollisions(shipBall) 92 self.ControlFlow('NextCollision') 93 uthread.worker('FxSequencer::WarpEffectLoop', self.WarpLoop, shipBall) 94 95 def AddToScene(self, effect): 96 scene = self.fxSequencer.GetScene() 97 if self.isLegacyJumpTunnel: 98 scene.warpTunnel = effect 99 self._SetupLightingCurves(scene) 100 return 101 scene.objects.append(effect) 102 103 def RemoveFromScene(self, effect): 104 scene = self.fxSequencer.GetScene() 105 if self.isLegacyJumpTunnel: 106 self._RemoveLightingCurves(scene) 107 scene.warpTunnel = None 108 return 109 scene.objects.fremove(effect) 110 111 def _SetupLightingCurves(self, scene): 112 self.lightingCurveSet = trinity.TriCurveSet() 113 self.lights = [] 114 curve = trinity.Tr2CurveScalarExpression() 115 curve.expression = 'input3 - input3 * min(max(input1 - input2, 0), 1)' 116 curve.input1 = 1 117 curve.input2 = 0 118 curve.input3 = gfxsettings.SECONDARY_LIGHTING_INTENSITY 119 self.lightingCurveSet.curves.append(curve) 120 121 def FindBinding(curveSet, binding): 122 cs = [ x for x in self.gfx.curveSets if x.name == curveSet ][0] 123 return [ x for x in cs.bindings if x.name == binding ][0] 124 125 trinity.CreateBinding(self.lightingCurveSet, FindBinding('FadeInCurveSet', 'FadeInBinding').sourceObject, 'value', curve, 'input1') 126 trinity.CreateBinding(self.lightingCurveSet, FindBinding('FadeOutCurveSet', 'FadeOutBindin').sourceObject, 'value', curve, 'input2') 127 trinity.CreateBinding(self.lightingCurveSet, curve, 'currentValue', scene.shLightingManager, 'secondaryIntensity') 128 if scene.shLightingManager: 129 light = self._SetupStaticLight(-1, self.lightingCurveSet) 130 self.lights.append((light, None, None)) 131 scene.shLightingManager.lights.append(light) 132 light = self._SetupStaticLight(1, self.lightingCurveSet) 133 self.lights.append((light, None, None)) 134 scene.shLightingManager.lights.append(light) 135 curve = trinity.Tr2CurveScalarExpression() 136 curve.expression = 'input1 * min(max(input2 + 2 * min(max(min(max(input3, 0), 1) - min(max(input4, 0), 1), 0), 1), 0), 1)' 137 curve.input1 = 1 138 self.lightingCurveSet.curves.append(curve) 139 trinity.CreateBinding(self.lightingCurveSet, FindBinding('_Setup_', 'brightness_tunnel').sourceObject, 'currentValue', curve, 'input1').scale = gfxsettings.SECONDARY_LIGHTING_INTENSITY 140 trinity.CreateBinding(self.lightingCurveSet, FindBinding('SpeedModifier', 'additiveBinding').sourceObject, 'currentValue', curve, 'input2') 141 trinity.CreateBinding(self.lightingCurveSet, FindBinding('FadeInCurveSet', 'FadeInBindingAdditive').sourceObject, 'value', curve, 'input3') 142 trinity.CreateBinding(self.lightingCurveSet, FindBinding('FadeOutCurveSet', 'FadeOutBindingAdditive').sourceObject, 'value', curve, 'input4') 143 trinity.CreateBinding(self.lightingCurveSet, curve, 'currentValue', scene.shLightingManager, 'primaryIntensity').scale = 2 144 self.shLightingManager = scene.shLightingManager 145 scene.curveSets.append(self.lightingCurveSet) 146 self.lightingCurveSet.Play() 147 uthread.new(self._AnimateLights, scene) 148 149 def _AnimateLights(self, scene): 150 while self.lightingCurveSet and scene.shLightingManager: 151 if self.shLightingManager != scene.shLightingManager: 152 self._RemoveLightingCurves(scene) 153 if scene.shLightingManager: 154 self._SetupLightingCurves(scene) 155 return 156 light = self._SetupDynamicLight(self.lightingCurveSet) 157 self.lights.append(light) 158 scene.shLightingManager.lights.append(light[0]) 159 remove = [ i for i, light in enumerate(self.lights) if light[0].position[2] < -5 ] 160 for each in sorted(remove, reverse=True): 161 light, curve, binding = self.lights[each] 162 self.lightingCurveSet.curves.remove(curve) 163 self.lightingCurveSet.bindings.remove(binding) 164 try: 165 scene.shLightingManager.lights.remove(light) 166 except RuntimeError: 167 pass 168 169 del self.lights[each] 170 171 blue.synchro.SleepSim(random.randint(100, 500)) 172 173 def _SetupStaticLight(self, offset, curveSet): 174 light = trinity.Tr2PointLight() 175 light.color = STATIC_WARP_LIGHT_COLOR 176 light.position = (0, 0, offset) 177 curve = trinity.TriPerlinCurve() 178 curve.offset = 0.2 179 curve.scale = 0.2 180 curveSet.curves.append(curve) 181 trinity.CreateBinding(curveSet, curve, 'value', light, 'radius') 182 return light 183 184 def _SetupDynamicLight(self, curveSet): 185 angle = random.random() * 2 * pi 186 light = trinity.Tr2PointLight() 187 light.color = geo2.Vec3Lerp(DYNAMIC_WARP_LIGHT_COLOR, (1, 1, 1, 1), random.random()) 188 light.radius = 0.7 189 light.position = (sin(angle) * 1.5, cos(angle) * 1.5, 2) 190 curve = trinity.Tr2CurveScalar() 191 curve.keys.append((curveSet.scaledTime, 192 2, 193 0, 194 0, 195 0, 196 0, 197 0)) 198 curve.keys.append((curveSet.scaledTime + 8.0 / 20.0, 199 -6, 200 0, 201 0, 202 0, 203 0, 204 0)) 205 curve.OnKeysChanged() 206 curveSet.curves.append(curve) 207 binding = trinity.CreateBinding(curveSet, curve, 'currentValue', light, 'position.z') 208 return (light, curve, binding) 209 210 def _RemoveLightingCurves(self, scene): 211 try: 212 scene.curveSets.remove(self.lightingCurveSet) 213 except (RuntimeError, ValueError): 214 pass 215 216 self.lightingCurveSet = None 217 if self.shLightingManager: 218 self.shLightingManager.primaryIntensity = gfxsettings.SECONDARY_LIGHTING_INTENSITY 219 self.shLightingManager.secondaryIntensity = gfxsettings.SECONDARY_LIGHTING_INTENSITY 220 for each, _, _ in self.lights: 221 try: 222 self.shLightingManager.lights.remove(each) 223 except RuntimeError: 224 pass 225 226 self.lights = [] 227 228 def RecycleOrLoad(self, resPath): 229 return blue.resMan.LoadObject(resPath) 230 231 def ControlFlow(self, event): 232 if event == 'ExitPlanet': 233 scene = self.fxSequencer.GetScene() 234 for each in scene.lensflares: 235 each.display = True 236 237 self.nextCollision[0].display = True 238 self.exitPlanetBinding.scale = 0 239 self.exitPlanetEventCurve.Stop() 240 if self.hasMoreCollisions: 241 self.nextPlanetBinding.scale = 1 242 self.nextPlanetEventCurve.Play() 243 self.nextPlanetBinding.sourceObject.expression = '-input1 / input2' 244 elif event == 'NextCollision': 245 self.nextPlanetBinding.scale = 0 246 self.nextPlanetEventCurve.Stop() 247 res = self.SetupNextCollision() 248 if res == False: 249 self.nextPlanetBinding.scale = 1 250 self.nextPlanetEventCurve.Play() 251 self.nextPlanetBinding.sourceObject.expression = 'input2 / input1' 252 else: 253 self.enterPlanetBinding.scale = 1 254 self.enterPlanetEventCurve.Play() 255 elif event == 'EnterPlanet': 256 scene = self.fxSequencer.GetScene() 257 for each in scene.lensflares: 258 each.display = False 259 260 self.nextCollision[0].display = False 261 if self.nextCollision[0].radius < 450000: 262 delta = 1 263 self.nextCollision = (self.nextCollision[0], delta) 264 self.collisionCurve.input1 = 1.1 * delta / 10000.0 265 self.enterPlanetBinding.scale = 0 266 self.enterPlanetEventCurve.Stop() 267 self.exitPlanetBinding.scale = 1 268 self.exitPlanetEventCurve.Play() 269 270 def SetupTunnelBindings(self): 271 self.curveSet = [ x for x in self.gfx.curveSets if x.name == 'SpeedBinding' ][0] 272 for binding in self.curveSet.bindings: 273 self.speedBinding = binding 274 binding.sourceObject = self.shipModel.speed 275 binding.scale *= 1.0 / (3.0 * const.AU * self.warpSpeedModifier) 276 277 self.curveSet.Play() 278 setup = [ x for x in self.gfx.curveSets if x.name == '_Setup_' ][0] 279 self.setup = setup 280 self.collisionCurve = [ x for x in setup.curves if x.name == '_global' ][0] 281 self.xout = [ x for x in setup.curves if x.name == '_xPointOut' ][0] 282 extra = [ x for x in self.gfx.curveSets if getattr(x, 'name', None) == '_Extra_' ][0] 283 first = [ x for x in self.gfx.curveSets if getattr(x, 'name', None) == '_First_' ][0] 284 self.distanceTracker = first.curves.Find('trinity.Tr2DistanceTracker')[0] 285 self.distanceTraveled = [ x for x in extra.curves if getattr(x, 'name', None) == '_mov' ][0] 286 self.fadeInLength = [ x for x in extra.curves if getattr(x, 'name', None) == '_fadeLength' ][0] 287 self.eventb = [ x for x in self.gfx.curveSets if x.name == 'EventBindings' ][0] 288 eventBindings = [ x for x in self.gfx.curveSets if x.name == 'EventBindings' ][0].bindings 289 for binding in eventBindings: 290 if binding.name == 'enterPlanetBinding': 291 self.enterPlanetBinding = binding 292 elif binding.name == 'exitPlanetBinding': 293 self.exitPlanetBinding = binding 294 elif binding.name == 'nextPlanetBinding': 295 self.nextPlanetBinding = binding 296 297 self.enterPlanetEventCurve = [ x for x in self.gfx.curveSets if x.name == 'enterPlanet' ][0] 298 self.exitPlanetEventCurve = [ x for x in self.gfx.curveSets if x.name == 'exitPlanet' ][0] 299 self.nextPlanetEventCurve = [ x for x in self.gfx.curveSets if x.name == 'nextCollision' ][0] 300 self.enterPlanetBinding.scale = 0 301 self.exitPlanetBinding.scale = 0 302 self.nextPlanetBinding.scale = 0 303 self.enterPlanetEventCurve.Stop() 304 self.exitPlanetEventCurve.Stop() 305 self.nextPlanetEventCurve.Stop() 306 self.exitPlanetEventCurve.curves[0].AddKey(0.0, u'Start') 307 self.exitPlanetEventCurve.curves[0].AddCallableKey(1.0, self.ControlFlow, ('ExitPlanet',)) 308 self.enterPlanetEventCurve.curves[0].AddKey(0.0, u'Start') 309 self.enterPlanetEventCurve.curves[0].AddCallableKey(1.0, self.ControlFlow, ('EnterPlanet',)) 310 self.nextPlanetEventCurve.curves[0].AddKey(0.0, u'Start') 311 self.nextPlanetEventCurve.curves[0].AddCallableKey(1.0, self.ControlFlow, ('NextCollision',)) 312 313 def TeardownTunnelBindings(self): 314 if getattr(self, 'speedBinding', None) is not None: 315 self.speedBinding.sourceObject = self.shipModel.speed 316 if getattr(self, 'distanceTracker', None) is not None: 317 self.distanceTracker.targetObject = None 318 self.distanceTracker = None 319 if getattr(self, 'exitPlanetEventCurve', None) is not None: 320 del self.exitPlanetEventCurve.curves[0] 321 del self.enterPlanetEventCurve.curves[0] 322 del self.nextPlanetEventCurve.curves[0] 323 324 def GetCorrectModelRadius(self, ball): 325 radius = ball.radius 326 if ball in sm.GetService('space').planetManager.suns: 327 radius *= 0.5 328 if ball.typeID in SMALL_SUN_TYPE_IDS: 329 radius *= 0.5 330 return radius 331 332 def CalcEffectiveRadius(self, direction, planetPosition, planetRadius): 333 distToMiddle = geo2.Vec3DotD(planetPosition, direction) 334 if distToMiddle < 0: 335 return None 336 midPoint = geo2.Vec3ScaleD(direction, distToMiddle) 337 distToCenter = geo2.Vec3DistanceD(planetPosition, midPoint) 338 if distToCenter > planetRadius: 339 return None 340 return sqrt(planetRadius * planetRadius - distToCenter * distToCenter) 341 342 def GetDistanceToTarget(self, direction, planetPosition): 343 return geo2.Vec3DotD(planetPosition, direction) 344 345 def GetWarpCollisions(self, ball): 346 space = sm.GetService('space') 347 planets = space.planetManager.planets + space.planetManager.suns 348 destination = self.destination 349 source = (ball.x, ball.y, ball.z) 350 self.direction = geo2.Vec3SubtractD(destination, source) 351 direction = self.direction 352 warpDistance = geo2.Vec3LengthD(direction) 353 normDirection = geo2.Vec3NormalizeD(direction) 354 self.normDirection = normDirection 355 ballpark = sm.GetService('michelle').GetBallpark() 356 collisions = [] 357 for planet in planets: 358 planetBall = ballpark.GetBall(planet.id) 359 if planetBall is None: 360 continue 361 planetPosition = (planetBall.x, planetBall.y, planetBall.z) 362 planetDir = geo2.Vec3SubtractD(planetPosition, source) 363 if geo2.Vec3LengthSqD(self.direction) < geo2.Vec3LengthSqD(planetDir): 364 continue 365 effectiveRadius = self.CalcEffectiveRadius(normDirection, planetDir, self.GetCorrectModelRadius(planetBall)) 366 if effectiveRadius is None: 367 continue 368 collisions.append((planetBall, effectiveRadius)) 369 blue.pyos.BeNice() 370 371 return collisions 372 373 def FindNextCollision(self, destination, candidates, popCollision = True): 374 minDist = None 375 time = blue.os.GetSimTime() 376 position = self.shipBall.GetVectorAt(blue.os.GetSimTime()) 377 position = (position.x, position.y, position.z) 378 nextCollision = None 379 for each in candidates: 380 collisionBall = each[0] 381 collisionCenter = collisionBall.GetVectorAt(time) 382 collisionCenter = (collisionCenter.x, collisionCenter.y, collisionCenter.z) 383 projection = geo2.Vec3DotD(collisionCenter, self.normDirection) 384 if minDist is None or projection < minDist: 385 minDist = projection 386 nextCollision = each 387 388 if nextCollision is not None and popCollision: 389 candidates.remove(nextCollision) 390 return nextCollision 391 392 def SetupNextCollision(self): 393 self.hasMoreCollisions = False 394 self.distanceTracker.direction = self.normDirection 395 time = blue.os.GetSimTime() 396 if self.findNext: 397 lastCollision = self.nextCollision 398 self.nextCollision = self.FindNextCollision(self.destination, self.collisions) 399 if self.nextCollision is None: 400 self.nextCollision = lastCollision 401 if self.nextCollision is None: 402 self.collisionCurve.input1 = 1.0 403 self.fadeInLength.input1 = 0.0 404 self.collisionCurve.input3 = 100000000 405 self.collisionCurve.input3 = 100000000 406 self.distanceTracker.targetObject = None 407 self.distanceTraveled.input1 = 100000000 408 self.distanceTracker.targetPosition = (0, 0, 100000000) 409 self.distanceTracker.direction = (0, 0, -1) 410 return True 411 targetPosition = self.nextCollision[0].GetVectorAt(time) 412 targetPosition = (targetPosition.x, targetPosition.y, targetPosition.z) 413 furtherCollision = self.FindNextCollision(self.destination, self.collisions, False) 414 if furtherCollision is not None: 415 self.hasMoreCollisions = True 416 furtherPosition = furtherCollision[0].GetVectorAt(time) 417 furtherPosition = (furtherPosition.x, furtherPosition.y, furtherPosition.z) 418 length = geo2.Vec3DistanceD(targetPosition, furtherPosition) 419 self.nextPlanetBinding.sourceObject.input2 = length / 2 420 else: 421 targetPosition = self.nextCollision[0].GetVectorAt(time) 422 targetPosition = (targetPosition.x, targetPosition.y, targetPosition.z) 423 distanceToCollision = self.GetDistanceToTarget(self.normDirection, targetPosition) 424 returnValue = True 425 warpSpeed = self.warpSpeedModifier * const.AU 426 if distanceToCollision > warpSpeed: 427 self.findNext = False 428 returnValue = False 429 self.nextPlanetBinding.sourceObject.input2 = warpSpeed 430 else: 431 self.findNext = True 432 delta = self.CalcEffectiveRadius(self.normDirection, targetPosition, self.GetCorrectModelRadius(self.nextCollision[0])) 433 if delta is None: 434 delta = self.nextCollision[0].radius 435 self.nextCollision = (self.nextCollision[0], delta) 436 self.collisionCurve.input1 = 1.1 * delta / 10000.0 437 self.fadeInLength.input1 = 80000 * self.warpSpeedModifier * 3 438 self.collisionCurve.input3 = abs(distanceToCollision) / 10000.0 439 self.distanceTracker.targetObject = self.nextCollision[0] 440 self.distanceTraveled.input1 = abs(distanceToCollision) / 10000.0 441 return returnValue 442 443 def WarpLoop(self, ball): 444 space = sm.GetService('space') 445 michelle = sm.GetService('michelle') 446 space.StartWarpIndication() 447 warpToItemID, warpToTypeID = space.GetWarpDestinationItemIDAndTypeID() 448 sm.ScatterEvent('OnWarpStarted', warpToItemID, warpToTypeID) 449 warp_signals.on_warp_started(warpToItemID) 450 self.shipBall = ball 451 shipID = ball.id 452 hasSentActiveWarpEvent = False 453 hasSentArrivedWarpEvent = False 454 lastSpeed = 0 455 initialWarpDistance = 1.0 456 currentProgress = 0.01 457 warpSpeedMod = 1.0 / (3.0 * const.AU * self.warpSpeedModifier) 458 while ball.mode == destiny.DSTBALL_WARP: 459 if session.shipid != shipID: 460 self.hasExploded = True 461 sm.GetService('space').IndicateCurrentShipManouveringAction() 462 if ball.effectStamp > 0 and not hasSentActiveWarpEvent: 463 sm.ScatterEvent('OnWarpActive', warpToItemID, warpToTypeID) 464 warp_signals.on_warp_activated(warpToItemID) 465 if not self.isLegacyJumpTunnel: 466 self.gfx.SetControllerVariable('TravelTunnelProgress', 0.01) 467 self.gfx.SetControllerVariable('warpSpeedModifier', self.warpSpeedModifier) 468 threshold = const.minWarpDistance * 100.0 469 isShortWarp = geo2.Vec3Distance(michelle.GetMyPosition(), self.destination) < threshold 470 if isShortWarp: 471 self.gfx.SetControllerVariable('shortWarp', 1.0) 472 if self.systemWideCloud: 473 self.systemWideCloud.SetControllerVariable('isWarping', 1.0) 474 hasSentActiveWarpEvent = True 475 initialWarpDistance = geo2.Vec3DistanceSq(michelle.GetMyPosition(), self.destination) 476 self.ShakeCamera(ball) 477 if not self.hasExploded or self.hasWind: 478 if self.isLegacyJumpTunnel: 479 speedFraction = self.shipModel.speed.value * self.curveSet.bindings[0].scale 480 else: 481 speedFraction = self.shipModel.speed.value * warpSpeedMod 482 if not self.hasExploded and speedFraction > 0.005: 483 sm.StartService('audio').SendUIEvent('ship_warp_explosion_play') 484 sm.StartService('audio').SendUIEvent('ship_warp_wind_play') 485 self.hasExploded = True 486 self.hasWind = True 487 sm.ScatterEvent('OnWarpStarted2', warpToItemID, warpToTypeID) 488 elif self.hasWind and speedFraction < 1e-06: 489 sm.ScatterEvent('OnWarpDecelerate', warpToItemID, warpToTypeID) 490 warp_signals.on_warp_deceleration_started(warpToItemID) 491 self.hasWind = False 492 if hasSentActiveWarpEvent and not hasSentArrivedWarpEvent: 493 currentWarpDistance = space.GetWarpDistance() 494 if not self.isLegacyJumpTunnel: 495 if currentProgress > 0.5 and speedFraction < 1e-05: 496 currentProgress = 1.0 497 remainingDistance = geo2.Vec3DistanceSq(michelle.GetMyPosition(), self.destination) 498 distanceTraveled = 1 - remainingDistance / initialWarpDistance 499 currentProgress = max(currentProgress, distanceTraveled) 500 self.gfx.SetControllerVariable('TravelTunnelProgress', currentProgress) 501 if lastSpeed <= self.shipModel.speed.value: 502 lastSpeed = self.shipModel.speed.value 503 elif currentWarpDistance < 10000000: 504 if not self.isLegacyJumpTunnel: 505 self.gfx.SetControllerVariable('TravelTunnelProgress', 1.0) 506 sm.ScatterEvent('OnWarpArrived', warpToItemID, warpToTypeID) 507 if hasSentActiveWarpEvent: 508 warp_signals.on_warp_arrived_at(warpToItemID) 509 hasSentArrivedWarpEvent = True 510 if self.systemWideCloud: 511 self.systemWideCloud.SetControllerVariable('isWarping', 0.0) 512 if self.isLegacyJumpTunnel: 513 blue.synchro.SleepSim(1000) 514 else: 515 blue.synchro.SleepSim(500) 516 if hasattr(self.gfx, 'display'): 517 self.gfx.display = True 518 519 self.EndWarpShake() 520 if not self.isLegacyJumpTunnel: 521 self.gfx.SetControllerVariable('TravelTunnelProgress', 1.0) 522 if self.systemWideCloud: 523 self.systemWideCloud.SetControllerVariable('isWarping', 0.0) 524 sm.StartService('audio').SendUIEvent('ship_warp_wind_stop') 525 sm.StartService('FxSequencer').OnSpecialFX(ball.id, None, None, None, None, 'effects.Warping', 0, 0, 0) 526 sm.ScatterEvent('OnWarpFinished', warpToItemID, warpToTypeID) 527 if hasSentActiveWarpEvent: 528 warp_signals.on_warp_finished(warpToItemID) 529 sm.StartService('space').StopWarpIndication() 530 531 def Stop(self, reason = STOP_REASON_DEFAULT): 532 if self.isLegacyJumpTunnel: 533 self.TeardownTunnelBindings() 534 if self.shipBall is not None: 535 self.shipBall.UnregisterModelChangeNotification(self.ModelChangeNotify) 536 self.shipBall = None 537 self.shipModel = None 538 ShipEffect.Stop(self) 539 540 def ShakeCamera(self, ball): 541 ballpark = sm.GetService('michelle').GetBallpark() 542 if ballpark is None: 543 return 544 speedVector = trinity.TriVector(ball.vx, ball.vy, ball.vz) 545 speed = speedVector.Length() 546 maxSpeed = ballpark.warpSpeed * const.AU - ball.maxVelocity 547 speed = (speed - ball.maxVelocity) / maxSpeed 548 speed = max(0.0, speed) 549 rumbleFactor = 0.5 - 0.5 * cos(6.28 * pow(speed, 0.1)) 550 rumbleFactor = (rumbleFactor - 0.2) / 0.8 551 rumbleFactor = max(rumbleFactor, 0.0) 552 rumbleFactor = pow(rumbleFactor, 0.8) 553 shakeFactor = 0.7 * rumbleFactor 554 cam = self.GetCamera() 555 noisescaleCurve = trinity.Tr2CurveScalar() 556 noisescaleCurve.AddKey(0.0, cam.noiseScale, trinity.Tr2CurveInterpolation.LINEAR) 557 noisescaleCurve.AddKey(0.5, shakeFactor * 2.0, trinity.Tr2CurveInterpolation.LINEAR) 558 noisescaleCurve.AddKey(5.0, 0.0, trinity.Tr2CurveInterpolation.LINEAR) 559 behavior = shaker.ShakeBehavior('Warp') 560 behavior.scaleCurve = noisescaleCurve 561 cam.shakeController.DoCameraShake(behavior) 562 563 def GetCamera(self): 564 return sm.GetService('sceneManager').GetActiveSpaceCamera() 565 566 def EndWarpShake(self): 567 camera = self.GetCamera() 568 camera.shakeController.EndCameraShake('Warp') 569 570 def AlignToDirection(self): 571 ballPark = sm.StartService('michelle').GetBallpark() 572 egoball = ballPark.GetBall(ballPark.ego) 573 direction = [egoball.x - egoball.gotoX, egoball.y - egoball.gotoY, egoball.z - egoball.gotoZ] 574 zaxis = direction 575 if geo2.Vec3LengthSqD(zaxis) > 0.0: 576 zaxis = geo2.Vec3NormalizeD(zaxis) 577 xaxis = geo2.Vec3CrossD((0, 1, 0), zaxis) 578 if geo2.Vec3LengthSqD(xaxis) == 0.0: 579 zaxis = geo2.Vec3AddD(zaxis, mathCommon.RandomVector(0.0001)) 580 zaxis = geo2.Vec3NormalizeD(zaxis) 581 xaxis = geo2.Vec3CrossD((0, 1, 0), zaxis) 582 xaxis = geo2.Vec3NormalizeD(xaxis) 583 yaxis = geo2.Vec3CrossD(zaxis, xaxis) 584 else: 585 self.transformFlags = effectconsts.FX_TF_POSITION_BALL | effectconsts.FX_TF_ROTATION_BALL 586 self.Prepare() 587 return 588 mat = ((xaxis[0], 589 xaxis[1], 590 xaxis[2], 591 0.0), 592 (yaxis[0], 593 yaxis[1], 594 yaxis[2], 595 0.0), 596 (zaxis[0], 597 zaxis[1], 598 zaxis[2], 599 0.0), 600 (0.0, 0.0, 0.0, 1.0)) 601 quat = geo2.QuaternionRotationMatrix(mat) 602 self.gfxModel.rotationCurve = None 603 if self.gfxModel and hasattr(self.gfxModel, 'modelRotationCurve'): 604 self.gfxModel.modelRotationCurve = trinity.Tr2RotationAdapter() 605 self.gfxModel.modelRotationCurve.value = quat 606 self.debugAligned = True 607 if not self.isLegacyJumpTunnel: 608 if self.gfx is not None and self.gfx.modelRotationCurve is not None: 609 vect = geo2.QuaternionRotationGetYawPitchRoll(self.gfx.modelRotationCurve.value) 610 self.gfx.modelRotationCurve.value = geo2.QuaternionRotationSetYawPitchRoll(vect[0], vect[1] + pi, vect[2]) 611 612 def Repeat(self, duration): 613 if self.gfx is None: 614 return 615 ShipEffect.Repeat(self, duration)