superWeapon.py (17392B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\environment\effects\superWeapon.py 2 import random 3 import geo2 4 import blue 5 from dogma.const import attributeDamageDelayDuration 6 from eve.common.lib import appConst 7 import trinity 8 import uthread 9 import uthread2 10 import evetypes 11 import log 12 from eve.client.script.environment.effects.stretchEffect import StretchEffect 13 from eve.client.script.environment.effects.GenericEffect import GetBoundingBox, STOP_REASON_DEFAULT 14 15 def GetClosestLocatorIndex(sourceModel, targetModel, locatorSetName): 16 targetModelWorldPos = targetModel.modelWorldPosition 17 return sourceModel.GetCloseLocatorIndex(targetModelWorldPos, locatorSetName) 18 19 20 def GetSecondaryIndices(model, locatorSetName, mainIndex): 21 locatorCount = model.GetLocatorCount(locatorSetName) 22 return [ x for x in xrange(locatorCount) if x != mainIndex ] 23 24 25 def AmarrTitanSetup(superWeapon, effect): 26 sourceBall = superWeapon.GetEffectShipBall() 27 targetBall = superWeapon.GetEffectTargetBall() 28 sourceModel = getattr(sourceBall, 'model', None) 29 targetModel = getattr(targetBall, 'model', None) 30 if sourceModel is None or targetModel is None: 31 return False 32 sideLocatorIndex = GetClosestLocatorIndex(sourceModel, targetModel, superWeapon.data['locatorSetName']) 33 locatorSetNames = {0: 'doomsday_left_side', 34 1: 'doomsday_center', 35 2: 'doomsday_right_side'} 36 if sideLocatorIndex == -1: 37 return False 38 locatorSetName = locatorSetNames[sideLocatorIndex] 39 firingDirection = sideLocatorIndex - 1 40 mainStretchLocatorIndex = GetClosestLocatorIndex(sourceModel, targetModel, locatorSetName) 41 secondaryIndices = GetSecondaryIndices(sourceModel, locatorSetName, mainStretchLocatorIndex) 42 if mainStretchLocatorIndex == -1: 43 return False 44 SetControllerVariable(sourceModel, 'FiringDirection', firingDirection) 45 superWeapon.sourceLocation.locatorSetName = locatorSetName 46 superWeapon.sourceLocation.locatorIndex = mainStretchLocatorIndex 47 if len(secondaryIndices) >= 2: 48 secondStretchEffect = superWeapon.RecycleOrLoad(superWeapon.secondaryGraphicFile) 49 thirdStretchEffect = superWeapon.RecycleOrLoad(superWeapon.secondaryGraphicFile) 50 if secondStretchEffect is None: 51 log.LogError('secondaryGraphicFile not found: ' + str(superWeapon.secondaryGraphicFile)) 52 return False 53 if thirdStretchEffect is None: 54 log.LogError('secondaryGraphicFile not found: ' + str(superWeapon.secondaryGraphicFile)) 55 return False 56 secondStretchEffect = superWeapon.CreateSourceSequencer(secondStretchEffect) 57 thirdStretchEffect = superWeapon.CreateSourceSequencer(thirdStretchEffect) 58 secondSourceLocation = CreateSourceLocation(superWeapon.startLocation, sourceBall, targetBall, secondaryIndices[0], locatorSetName) 59 thirdSourceLocation = CreateSourceLocation(superWeapon.startLocation, sourceBall, targetBall, secondaryIndices[1], locatorSetName) 60 secondStretchEffect.source.functions.append(secondSourceLocation) 61 thirdStretchEffect.source.functions.append(thirdSourceLocation) 62 superWeapon.additionalEffects.append(secondStretchEffect) 63 superWeapon.additionalEffects.append(thirdStretchEffect) 64 effect.stretchObject.scaling = ObjectScaleXY(list(effect.stretchObject.scaling), 0.5) 65 effect.sourceObject.scaling = ObjectScaleXY(list(effect.sourceObject.scaling), 0.5) 66 return True 67 68 69 def ObjectScaleXY(object, value): 70 object[0] = value 71 object[1] = value 72 return object 73 74 75 def CreateSourceLocation(startLocation, sourceBall, targetBall, index, locatorSetName): 76 sourceLocation = trinity.EveLocalPositionCurve(startLocation) 77 sourceLocation.parent = sourceBall.model 78 sourceLocation.locatorIndex = index 79 sourceLocation.locatorSetName = locatorSetName 80 return sourceLocation 81 82 83 def SetControllerVariable(model, variable, value): 84 if model is not None: 85 for c in model.effectChildren: 86 if c.name == 'Amarr_Doomsday_Controller': 87 c.SetControllerVariable(variable, value) 88 89 90 effectData = {'effects.SuperWeaponCaldari': {'count': 32, 91 'maxDelay': 2600, 92 'delayUntilShipHit': 10000}, 93 'effects.SuperWeaponMinmatar': {'count': 32, 94 'maxDelay': 4000, 95 'delayUntilShipHit': 1000, 96 'delayBeforeEffect': 3000, 97 'doomsday': True, 98 'doomsdayFaction': 0}, 99 'effects.SuperWeaponAmarr': {'count': 1, 100 'maxDelay': 0, 101 'delayUntilShipHit': 2200, 102 'delayBeforeEffect': 6000, 103 'startLocation': trinity.EveLocalPositionBehavior.nearestFiringLocator, 104 'locatorSetName': 'doomsday_firing', 105 'additionalSetup': AmarrTitanSetup, 106 'doomsday': True}, 107 'effects.SuperWeaponGallente': {'count': 1, 108 'maxDelay': 0, 109 'delayUntilShipHit': 4833, 110 'startLocation': trinity.EveLocalPositionBehavior.nearestBounds, 111 'doomsday': True, 112 'doomsdayFaction': 1}, 113 'effects.TurboLaser': {'count': 1, 114 'maxDelay': 0, 115 'delayUntilShipHit': 2500, 116 'impactMassFraction': 0.5, 117 'startLocation': trinity.EveLocalPositionBehavior.nearestBounds, 118 'destLocation': trinity.EveLocalPositionBehavior.nearestBounds}, 119 'effects.SuperWeaponLanceAmarr': {'count': 1, 120 'maxDelay': 0, 121 'delayUntilShipHit': 2200, 122 'delayBeforeEffect': 6000, 123 'startLocation': trinity.EveLocalPositionBehavior.nearestBounds, 124 'destLocation': trinity.EveLocalPositionBehavior.nearestBounds}, 125 'effects.SuperWeaponLanceCaldari': {'count': 1, 126 'maxDelay': 0, 127 'delayUntilShipHit': 2200, 128 'delayBeforeEffect': 6000, 129 'startLocation': trinity.EveLocalPositionBehavior.nearestBounds, 130 'destLocation': trinity.EveLocalPositionBehavior.nearestBounds}, 131 'effects.SuperWeaponLanceGallente': {'count': 1, 132 'maxDelay': 0, 133 'delayUntilShipHit': 2200, 134 'delayBeforeEffect': 6000, 135 'startLocation': trinity.EveLocalPositionBehavior.nearestBounds, 136 'destLocation': trinity.EveLocalPositionBehavior.nearestBounds}, 137 'effects.SuperWeaponLanceMinmatar': {'count': 1, 138 'maxDelay': 0, 139 'delayUntilShipHit': 2200, 140 'delayBeforeEffect': 6000, 141 'startLocation': trinity.EveLocalPositionBehavior.nearestBounds, 142 'destLocation': trinity.EveLocalPositionBehavior.nearestBounds}} 143 144 class SuperWeapon(StretchEffect): 145 146 def __init__(self, trigger, effect = None, graphicFile = None): 147 StretchEffect.__init__(self, trigger, effect, graphicFile) 148 self.data = effectData[trigger.guid] 149 self.isDoomsday = self.data.get('doomsday', False) 150 self.doomsdayFaction = self.data.get('doomsdayFaction', 1) 151 self.projectileCount = self.data['count'] 152 self.maxDelay = self.data['maxDelay'] 153 self.delayUntilShipHit = self.data['delayUntilShipHit'] 154 self.delayBeforeEffect = self.data.get('delayBeforeEffect', 0) 155 try: 156 self.delayUntilDamageApplied = self.fxSequencer.GetTypeAttribute(trigger.moduleTypeID, attributeDamageDelayDuration) 157 except evetypes.TypeNotFoundException: 158 log.LogError("Module type not found: '%s'" % trigger.moduleTypeID) 159 self.delayUntilDamageApplied = 9000 160 161 self.impactMassFraction = self.data.get('impactMassFraction', 1.0) 162 self.startLocation = self.data.get('startLocation', trinity.EveLocalPositionBehavior.damageLocator) 163 self.destLocation = self.data.get('destLocation', trinity.EveLocalPositionBehavior.damageLocator) 164 self.additionalSetup = self.data.get('additionalSetup', None) 165 self.sourceLocation = trinity.EveLocalPositionCurve(self.startLocation) 166 self.additionalEffects = [] 167 168 def CreateSourceSequencer(self, effect): 169 effect.source = trinity.TriVectorSequencer() 170 effect.source.operator = 1 171 return effect 172 173 def CreateDestSequencer(self, effect): 174 effect.dest = trinity.TriVectorSequencer() 175 effect.dest.operator = 1 176 return effect 177 178 def IsTargetStillValid(self): 179 targetBall = self.GetEffectTargetBall() 180 return targetBall is not None and targetBall.model is not None 181 182 def Prepare(self): 183 pass 184 185 def StartIndividual(self, sourceBall, targetBall, rotation, direction): 186 effect = self.RecycleOrLoad(self.graphicFile) 187 if effect is None: 188 log.LogError('effect not found: ' + str(self.graphicFile)) 189 return 190 effect = self.CreateSourceSequencer(effect) 191 self.sourceLocation.parent = sourceBall.model 192 self.sourceLocation.parentPositionCurve = sourceBall 193 self.sourceLocation.parentRotationCurve = sourceBall 194 self.sourceLocation.alignPositionCurve = targetBall 195 sourceScale = GetBoundingBox(sourceBall, scale=1.2) 196 self.sourceLocation.boundingSize = sourceScale 197 successfulAdditionalSetup = False 198 if self.additionalSetup is not None: 199 successfulAdditionalSetup = self.additionalSetup(self, effect) 200 effect.source.functions.append(self.sourceLocation) 201 sourceOffsetCurve = trinity.Tr2CurveVector3() 202 if self.projectileCount > 1: 203 offset = (random.gauss(0.0, 1000.0), random.gauss(0.0, 1000.0), random.gauss(0.0, 700.0) - 2000.0) 204 else: 205 offset = (0, 0, -self.sourceOffset) 206 offset = geo2.QuaternionTransformVector(rotation, offset) 207 sourceOffsetCurve.AddKey(0, offset) 208 effect.source.functions.append(sourceOffsetCurve) 209 effect = self.CreateDestSequencer(effect) 210 destLocation = trinity.EveLocalPositionCurve(self.destLocation) 211 destLocation.parent = targetBall.model 212 destLocation.alignPositionCurve = sourceBall 213 destLocation.parentPositionCurve = targetBall 214 destLocation.parentRotationCurve = targetBall 215 targetScale = GetBoundingBox(targetBall, scale=1.2) 216 destLocation.boundingSize = targetScale 217 effect.dest.functions.append(destLocation) 218 for additionalEffect in self.additionalEffects or []: 219 additionalEffect = self.CreateDestSequencer(additionalEffect) 220 additionalEffect.dest.functions.append(destLocation) 221 222 destOffsetCurve = trinity.Tr2CurveVector3() 223 if self.projectileCount > 1: 224 offset = (random.gauss(0.0, 1000.0), random.gauss(0.0, 1000.0), random.gauss(0.0, 700.0) + 500.0) 225 else: 226 offset = (0, 0, self.destinationOffset) 227 offset = geo2.QuaternionTransformVector(rotation, offset) 228 destOffsetCurve.AddKey(0, offset) 229 effect.dest.functions.append(destOffsetCurve) 230 if successfulAdditionalSetup or self.additionalSetup is None and self.isDoomsday: 231 if sourceBall.model is not None and hasattr(sourceBall.model, 'SetControllerVariable'): 232 sourceBall.model.SetControllerVariable('InDoomsdayFiringMode', 1.0) 233 sourceBall.model.SetControllerVariable('doomsdayFaction', self.doomsdayFaction) 234 blue.synchro.SleepSim(self.delayBeforeEffect) 235 delay = random.random() * self.maxDelay 236 blue.synchro.SleepSim(delay) 237 self.AddToScene(effect) 238 for additionalEffect in self.additionalEffects or []: 239 self.AddToScene(additionalEffect) 240 additionalEffect.Start() 241 242 effect.Start() 243 blue.synchro.SleepSim(self.delayUntilShipHit) 244 if self.IsTargetStillValid() and self.delayUntilDamageApplied is not None: 245 impactMass = targetBall.mass * targetBall.model.boundingSphereRadius * self.impactMassFraction / (250.0 * self.projectileCount) 246 targetShip = self.GetEffectTargetBall() 247 targetShip.ApplyTorqueAtPosition(effect.dest.value, direction, impactMass) 248 impactDirection = geo2.Vec3Scale(direction, -1.0) 249 if self.projectileCount == 1: 250 impactScale = 16.0 * self.impactMassFraction 251 else: 252 impactScale = 8.0 * self.impactMassFraction 253 damageDuration = self.delayUntilDamageApplied - self.delayUntilShipHit + 500 254 targetBall.model.CreateImpact(destLocation.damageLocatorIndex, impactDirection, damageDuration * 0.001, impactScale) 255 blue.synchro.SleepSim(damageDuration) 256 if self.projectileCount == 1 and self.IsTargetStillValid() and self.delayUntilDamageApplied is not None: 257 targetBall.model.CreateImpact(destLocation.damageLocatorIndex, impactDirection, 3, impactScale) 258 sleepTime = effect.curveSets[0].GetMaxCurveDuration() 259 blue.synchro.SleepSim(sleepTime * 1000) 260 self.RemoveFromScene(effect) 261 for additionalEffect in self.additionalEffects or []: 262 self.RemoveFromScene(additionalEffect) 263 264 if successfulAdditionalSetup or self.additionalSetup is None and self.isDoomsday: 265 if sourceBall.model is not None and hasattr(sourceBall.model, 'SetControllerVariable'): 266 sourceBall.model.SetControllerVariable('InDoomsdayFiringMode', 0.0) 267 self.sourceLocation.parent = None 268 self.sourceLocation.alignPositionCurve = None 269 destLocation.parent = None 270 destLocation.alignPositionCurve = None 271 272 def Start(self, duration): 273 sourceBall = self.GetEffectShipBall() 274 targetBall = self.GetEffectTargetBall() 275 sourcePos = sourceBall.GetVectorAt(blue.os.GetSimTime()) 276 sourcePos = (sourcePos.x, sourcePos.y, sourcePos.z) 277 targetPos = targetBall.GetVectorAt(blue.os.GetSimTime()) 278 targetPos = (targetPos.x, targetPos.y, targetPos.z) 279 direction = geo2.Vec3Direction(sourcePos, targetPos) 280 rotation = geo2.QuaternionRotationArc((0, 0, 1), direction) 281 direction = geo2.Vec3Scale(direction, -1.0) 282 for x in range(self.projectileCount): 283 uthread.new(self.StartIndividual, sourceBall, targetBall, rotation, direction) 284 285 def Stop(self, reason = STOP_REASON_DEFAULT): 286 pass 287 288 def ScaleEffectAudioEmitters(self): 289 pass 290 291 292 class SlashWeapon(StretchEffect): 293 294 def __init__(self, trigger, *args): 295 StretchEffect.__init__(self, trigger, *args) 296 self.startTargetOffset = trigger.graphicInfo.startTargetOffset 297 self.endTargetOffset = trigger.graphicInfo.endTargetOffset 298 self.durationSeconds = trigger.graphicInfo.duration / 1000.0 299 300 def Prepare(self): 301 shipBall = self.GetEffectShipBall() 302 self.gfx = self.RecycleOrLoad(self.graphicFile) 303 if self.gfx is None: 304 log.LogError('effect not found: ' + str(self.graphicFile)) 305 return 306 self.gfx.dest = trinity.EveRemotePositionCurve() 307 self.gfx.dest.startPositionCurve = shipBall 308 self.gfx.dest.offsetDir1 = self.startTargetOffset 309 self.gfx.dest.offsetDir2 = self.endTargetOffset 310 self.gfx.dest.sweepTime = self.durationSeconds 311 sourceBehavior = trinity.EveLocalPositionBehavior.nearestBounds 312 self.gfx.source = trinity.EveLocalPositionCurve(sourceBehavior) 313 self.gfx.source.offset = self.sourceOffset 314 self.gfx.source.parentPositionCurve = shipBall 315 self.gfx.source.parentRotationCurve = shipBall 316 self.gfx.source.alignPositionCurve = self.gfx.dest 317 self.gfx.source.boundingSize = GetBoundingBox(shipBall, scale=1.2) 318 self.AddToScene(self.gfx) 319 320 def Start(self, duration): 321 StretchEffect.Start(self, duration) 322 323 def Stop(self, reason = STOP_REASON_DEFAULT): 324 if self.gfx is None: 325 return 326 self.RemoveFromScene(self.gfx) 327 self.gfx.source.parentPositionCurve = None 328 self.gfx.source.parentRotationCurve = None 329 self.gfx.source.alignPositionCurve = None 330 self.gfx.dest.startPositionCurve = None 331 self.gfx = None 332 self.gfxModel = None 333 334 335 class DirectionalWeapon(SlashWeapon): 336 337 def __init__(self, trigger, *args): 338 StretchEffect.__init__(self, trigger, *args) 339 self.startTargetOffset = trigger.graphicInfo.targetOffset 340 self.endTargetOffset = trigger.graphicInfo.targetOffset 341 self.durationSeconds = trigger.graphicInfo.duration / 1000.0