turrets.py (14805B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\environment\effects\turrets.py 2 import trinity 3 from eve.client.script.environment.effects.GenericEffect import GenericEffect, STOP_REASON_DEFAULT 4 from evetypes import GetGraphicID 5 from fighters import ABILITY_SLOT_ID_KEY 6 import evegraphics.settings as gfxsettings 7 import uthread 8 import collections 9 import random 10 import blue 11 import geo2 12 from fsdBuiltData.common.graphicIDs import GetControllerVariableOverrides 13 from fsdBuiltData.client.effects import GetSourceDamageDelay, GetSourceDamageDuration, GetSourceDamageSize, GetTargetDamageSize, GetTargetDamageDuration, GetTargetDamageDelay 14 15 class StandardWeapon(GenericEffect): 16 __guid__ = 'effects.StandardWeapon' 17 18 def __init__(self, trigger, *args): 19 self.ballIDs = [trigger.shipID, trigger.targetID] 20 self.gfx = None 21 self.gfxModel = None 22 self.turrets = [] 23 if trigger.graphicInfo is not None and ABILITY_SLOT_ID_KEY in trigger.graphicInfo: 24 self.moduleID = trigger.graphicInfo[ABILITY_SLOT_ID_KEY] 25 else: 26 self.moduleID = trigger.moduleID 27 self.otherTypeID = trigger.otherTypeID 28 self.fxSequencer = sm.GetService('FxSequencer') 29 self.controllerVariableOverrides = {} 30 if self.otherTypeID is not None: 31 ammo_gid = GetGraphicID(self.otherTypeID) 32 self.controllerVariableOverrides = GetControllerVariableOverrides(ammo_gid) or {} 33 34 def Prepare(self): 35 pass 36 37 def SetupTurrets(self): 38 if not gfxsettings.Get(gfxsettings.UI_TURRETS_ENABLED): 39 return False 40 shipBall = self.GetEffectShipBall() 41 targetBall = self.GetEffectTargetBall() 42 if targetBall is None: 43 return False 44 if shipBall is None: 45 return False 46 shipID = self.GetEffectShipID() 47 if not hasattr(shipBall, 'fitted'): 48 self.fxSequencer.LogError('%s: %s Turrets: Error! can not fit turrets. No fitted attribute ' % (self.__guid__, shipID)) 49 return False 50 shipBall.FitHardpoints(blocking=True) 51 if not shipBall.fitted: 52 return False 53 if shipBall.modules is None: 54 return False 55 self.PopulateTurrets(shipBall) 56 if len(self.turrets) < 1: 57 self.fxSequencer.LogError('StandardWeapon: Turret not fitted on shipID will retry', shipID) 58 return False 59 return True 60 61 def Shoot(self, shipBall, targetID): 62 for turret in self.turrets: 63 turret.StartControllers() 64 for name, value in self.controllerVariableOverrides.iteritems(): 65 turret.SetControllerVariable(name, value) 66 67 turret.SetTarget(targetID) 68 turret.StartShooting() 69 70 def Start(self, duration): 71 if self.SetupTurrets(): 72 uthread.worker('FxSequencer::ShootTurrets', self.Shoot, self.GetEffectShipBall(), self.GetEffectTargetID()) 73 74 def PopulateTurrets(self, shipBall): 75 if len(self.turrets) != 0 or shipBall is None: 76 return 77 shipBall.PrepareForFiring() 78 self.turrets = shipBall.modules.get(self.moduleID) 79 if not isinstance(self.turrets, collections.Iterable): 80 if self.turrets is None: 81 self.turrets = [] 82 else: 83 self.turrets = [self.turrets] 84 self.SetAmmoColor() 85 self.SetDestSpaceObject() 86 self.SetSourceSpaceObject() 87 88 def SetAmmoColor(self): 89 if self.otherTypeID is None: 90 return 91 for turret in self.turrets: 92 turret.SetAmmoColorByTypeID(self.otherTypeID) 93 94 def SetDestSpaceObject(self): 95 targetBall = self.GetEffectTargetBall() 96 if targetBall is None: 97 return 98 for turret in self.turrets: 99 turret.SetDestSpaceObject(targetBall.model) 100 101 def SetSourceSpaceObject(self): 102 sourceBall = self.GetEffectShipBall() 103 if sourceBall is None: 104 return 105 for turret in self.turrets: 106 turret.SetSourceSpaceObject(sourceBall.model) 107 108 def Stop(self, reason = STOP_REASON_DEFAULT): 109 for turret in self.turrets: 110 turret.StopShooting() 111 turret.shooting = 0 112 113 for turret in self.turrets: 114 turret.SetSourceSpaceObject(None) 115 turret.SetDestSpaceObject(None) 116 117 self.turrets = [] 118 119 def _RestTurrets(self): 120 for turret in self.turrets: 121 turret.Rest() 122 turret.shooting = 0 123 124 def Repeat(self, duration): 125 if len(self.turrets) < 1: 126 shipBall = self.GetEffectShipBall() 127 if shipBall is None: 128 return 129 self.PopulateTurrets(shipBall) 130 if len(self.turrets) < 1: 131 return 132 shipID = self.ballIDs[0] 133 shipBall = self.fxSequencer.GetBall(shipID) 134 targetID = self.ballIDs[1] 135 targetBall = self.fxSequencer.GetBall(targetID) 136 if targetBall is None or shipBall is None: 137 self._RestTurrets() 138 return 139 shipBall.PrepareForFiring() 140 uthread.worker('FxSequencer::ShootTurrets', self.Shoot, shipID, targetID) 141 142 143 class CloudMining(StandardWeapon): 144 __guid__ = 'effects.CloudMining' 145 146 def SetAmmoColor(self): 147 targetBall = self.GetEffectTargetBall() 148 targetModel = getattr(targetBall, 'model', None) 149 color = (1.0, 1.0, 1.0, 1.0) 150 emitters = targetModel.Find('trinity.EveEmitterStatic') 151 if len(emitters): 152 if len(emitters[0].particleData): 153 color = emitters[0].particleData[0].color 154 for turret in self.turrets: 155 if hasattr(turret, 'SetAmmoColor'): 156 turret.SetAmmoColor(color) 157 158 159 class MissileLaunch(GenericEffect): 160 __guid__ = 'effects.MissileLaunch' 161 162 def __init__(self, trigger, *args): 163 self.ballIDs = [trigger.shipID, trigger.targetID] 164 self.gfx = None 165 self.gfxModel = None 166 self.moduleID = trigger.moduleID 167 self.otherTypeID = trigger.otherTypeID 168 self.fxSequencer = sm.GetService('FxSequencer') 169 170 def Prepare(self): 171 pass 172 173 def Shoot(self, targetID): 174 if getattr(self, 'turret', None) is not None: 175 self.turret.SetTarget(targetID) 176 177 def Start(self, duration): 178 if not gfxsettings.Get(gfxsettings.UI_TURRETS_ENABLED): 179 return 180 shipID = self.ballIDs[0] 181 shipBall = self.fxSequencer.GetBall(shipID) 182 targetID = self.ballIDs[1] 183 targetBall = self.fxSequencer.GetBall(targetID) 184 if targetBall is None: 185 return 186 if shipBall is None: 187 return 188 if not hasattr(shipBall, 'fitted'): 189 return 190 shipBall.FitHardpoints(blocking=True) 191 if not shipBall.fitted: 192 return 193 if shipBall.modules is None: 194 return 195 self.turret = shipBall.modules.get(self.moduleID) 196 if self.moduleID == shipID and 0 in shipBall.modules: 197 self.turret = shipBall.modules.get(0) 198 if not self.turret: 199 self.fxSequencer.LogError('MissileLaunch: Turret not fitted on shipID', shipID, self.moduleID) 200 return 201 uthread.worker('FxSequencer::ShootTurrets', self.Shoot, targetID) 202 203 def SetAmmoColor(self): 204 pass 205 206 def Stop(self, reason = STOP_REASON_DEFAULT): 207 if getattr(self, 'turret', None) is None: 208 return 209 self.turret.StopShooting() 210 self.turret.shooting = 0 211 self.turret = None 212 213 def Repeat(self, duration): 214 if getattr(self, 'turret', None) is None: 215 return 216 shipID = self.ballIDs[0] 217 shipBall = self.fxSequencer.GetBall(shipID) 218 targetID = self.ballIDs[1] 219 targetBall = self.fxSequencer.GetBall(targetID) 220 if targetBall is None: 221 self.turret.Rest() 222 self.turret.shooting = 0 223 return 224 if shipBall is None: 225 self.turret.Rest() 226 self.turret.shooting = 0 227 return 228 if shipBall == targetBall: 229 return 230 uthread.worker('FxSequencer::ShootTurrets', self.Shoot, targetID) 231 232 233 class ChainWeaponEffect(StandardWeapon): 234 __guid__ = 'effects.ChainWeaponEffect' 235 236 def __init__(self, trigger, effect = None, graphicFile = None): 237 super(ChainWeaponEffect, self).__init__(trigger, effect, graphicFile) 238 self.duration = trigger.duration 239 self.graphicFile = graphicFile 240 self.effects = [] 241 self.damageThreads = [] 242 self.startTime = trigger.startTime 243 self.sourceDamageSize = GetSourceDamageSize(trigger.guid) 244 self.sourceDamageDuration = GetSourceDamageDuration(trigger.guid) 245 self.sourceDamageDelay = GetSourceDamageDelay(trigger.guid) 246 self.targetDamageSize = GetTargetDamageSize(trigger.guid) 247 self.targetDamageDuration = GetTargetDamageDuration(trigger.guid) 248 self.targetDamageDelay = GetTargetDamageDelay(trigger.guid) 249 self.controllerVariableOverrides = {} 250 if trigger.moduleTypeID is not None: 251 ammo_gid = GetGraphicID(trigger.moduleTypeID) 252 self.controllerVariableOverrides = GetControllerVariableOverrides(ammo_gid) or {} 253 self.targets = [] 254 try: 255 self.targets = trigger.graphicInfo['targets'] 256 except KeyError: 257 self.fxSequencer.LogError("ChainWeaponEffect: No 'targets' in graphic info... no additional targets used") 258 259 def _add_effect(self, source_curve, target_curve, jump_index = 0): 260 if source_curve is None or target_curve is None: 261 return 262 gfx = trinity.Load(self.graphicFile) 263 gfx.source = source_curve 264 gfx.dest = target_curve 265 gfx.SetControllerVariable('jumpNumber', jump_index) 266 self.AddToScene(gfx) 267 return gfx 268 269 def _get_damage_locator_curve(self, source_id, target_id): 270 target_ball = self.fxSequencer.GetBall(target_id) 271 if target_ball is None: 272 return 273 target_model = target_ball.model 274 if target_model is not None: 275 dest = trinity.EveLocalPositionCurve(trinity.EveLocalPositionBehavior.damageLocator) 276 dest.parent = target_model 277 dest.alignPositionCurve = self.fxSequencer.GetBall(source_id) 278 return dest 279 return target_ball 280 281 def _add_turret_to_target_effect(self, turret, target_id): 282 source = trinity.EveLocalPositionCurve(trinity.EveLocalPositionBehavior.activeTurret) 283 source.turretSetObject = turret.turretSets[0] 284 source.muzzleIndex = 0 285 return self._add_effect(source, self._get_damage_locator_curve(self.GetEffectShipID(), target_id)) 286 287 def _add_target_to_target_effect(self, source_id, target_id, jump_index): 288 if source_id == target_id: 289 self.fxSequencer.LogError('ChainWeaponEffect: Trying to create a stretch between the same object %s' % source_id) 290 return None 291 source_curve = self._get_damage_locator_curve(target_id, source_id) 292 target_curve = self._get_damage_locator_curve(source_id, target_id) 293 return self._add_effect(source_curve, target_curve, jump_index) 294 295 def setup_firing_effects(self): 296 self.effects = [] 297 for turret in self.turrets: 298 e = self._add_turret_to_target_effect(turret, self.GetEffectTargetID()) 299 if e is not None: 300 self.effects.append(e) 301 302 last_target = self.GetEffectTargetID() 303 for index, target in enumerate(self.targets): 304 e = self._add_target_to_target_effect(last_target, target, index + 1) 305 if e is not None: 306 self.effects.append(e) 307 last_target = target 308 309 def remove_stretch_effect(self): 310 for gfx in self.effects: 311 self.RemoveFromScene(gfx) 312 313 for t in self.damageThreads: 314 if t is not None and t.alive: 315 t.kill() 316 317 self.damageThreads = [] 318 self.effects = [] 319 320 def Start(self, duration): 321 if not self.SetupTurrets(): 322 return 323 uthread.worker('FxSequencer::ShootTurrets', self.Shoot, self.GetEffectShipID(), self.GetEffectTargetID()) 324 325 def Repeat(self, duration): 326 super(ChainWeaponEffect, self).Repeat(duration) 327 self.remove_stretch_effect() 328 329 def Stop(self, reason = STOP_REASON_DEFAULT): 330 super(ChainWeaponEffect, self).Stop(reason) 331 self.remove_stretch_effect() 332 333 def Shoot(self, ship_id, target_id): 334 self.setup_firing_effects() 335 for turret in self.turrets: 336 turret.StartControllers() 337 for name, value in self.controllerVariableOverrides.iteritems(): 338 turret.SetControllerVariable(name, value) 339 340 turret.SetTarget(target_id) 341 turret.StartShooting() 342 343 delay = 0 344 for effect in self.effects: 345 for name, value in self.controllerVariableOverrides.iteritems(): 346 effect.SetControllerVariable(name, value) 347 348 effect.StartFiring(delay) 349 self.damageThreads.append(uthread.new(self._apply_damage, self.sourceDamageDelay + delay, self.sourceDamageSize, self.sourceDamageDuration, effect, False)) 350 self.damageThreads.append(uthread.new(self._apply_damage, self.targetDamageDelay + delay, self.targetDamageSize, self.targetDamageDuration, effect, True)) 351 delay += 0.3 * random.random() 352 353 def _apply_damage(self, delay, size, duration, stretch_effect, applyOnTarget): 354 blue.synchro.SleepSim(delay * 1000) 355 source = stretch_effect.source 356 target = stretch_effect.dest 357 source_pos = source.GetVectorAt(blue.os.GetSimTime()) 358 source_pos = (source_pos.x, source_pos.y, source_pos.z) 359 target_pos = target.GetVectorAt(blue.os.GetSimTime()) 360 target_pos = (target_pos.x, target_pos.y, target_pos.z) 361 if not applyOnTarget: 362 if not isinstance(source, trinity.EveLocalPositionCurve) or source.parent is None: 363 return 364 if not hasattr(source.parent, 'CreateImpact'): 365 return 366 direction = geo2.Vec3Direction(target_pos, source_pos) 367 source.parent.CreateImpact(source.damageLocatorIndex, direction, duration, size) 368 elif target is not None and getattr(target, 'parent', None) is not None: 369 if not isinstance(target, trinity.EveLocalPositionCurve) or target.parent is None: 370 return 371 if not hasattr(target.parent, 'CreateImpact'): 372 return 373 direction = geo2.Vec3Direction(source_pos, target_pos) 374 target.parent.CreateImpact(target.damageLocatorIndex, direction, duration, size)