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

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