damageSvc.py (10433B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\parklife\damageSvc.py 2 import telemetry 3 import blue 4 import log 5 from carbon.common.script.sys.service import Service 6 SECOND = 10000000 7 8 class DamageService(Service): 9 __guid__ = 'svc.damage' 10 __exportedcalls__ = {'GetTargetLocators': [], 11 'GetDamageLocatorGeneratorTransform': [], 12 'SetLODTargetLevel': [], 13 'SetLocatorCacheTime': [], 14 'GenerateDamageLocators': []} 15 __notifyevents__ = ['DoBallRemove', 'ProcessSessionChange', 'DoBallsRemove'] 16 __dependencies__ = ['michelle'] 17 18 def __init__(self): 19 Service.__init__(self) 20 self.targets = {} 21 self.failedTargets = {} 22 self.targetResultCacheTime = 5000.0 23 self.targetLODLevel = 1 24 self.generatedDamageLocators = 40 25 26 @telemetry.ZONE_METHOD 27 def DoBallsRemove(self, pythonBalls, isRelease): 28 for ball, slimItem, terminal in pythonBalls: 29 self.DoBallRemove(ball, slimItem, terminal) 30 31 def DoBallRemove(self, ball, slimItem, terminal): 32 removeList = [] 33 for key in self.targets: 34 if key[0] == ball.id or key[1] == ball.id: 35 removeList.append(key) 36 37 for key in removeList: 38 del self.targets[key] 39 40 if ball.id in self.failedTargets: 41 del self.failedTargets[ball.id] 42 43 def ProcessSessionChange(self, isremote, session, change): 44 self.targets = {} 45 self.failedTargets = {} 46 47 def SetLODTargetLevel(self, level): 48 pass 49 50 def SetLocatorCacheTime(self, time): 51 pass 52 53 def GetTargetLocators(self, attackerID, targetID, locatorVariance = 1): 54 timer = blue.pyos.taskletTimer.EnterTasklet('DamageService::GetTargetLocators') 55 result = [] 56 try: 57 targetBall = sm.GetService('michelle').GetBall(targetID) 58 targetModel = getattr(targetBall, 'model', None) 59 attackerBall = sm.GetService('michelle').GetBall(attackerID) 60 attackerModel = getattr(attackerBall, 'model', None) 61 if targetBall is None: 62 self.LogError('DamageService::GetTargetLocators cannot find ball of targetID', targetID) 63 return [] 64 if targetModel is None: 65 self.LogError('DamageService::GetTargetLocators target ball has no model', targetID) 66 return [] 67 if attackerBall is None: 68 self.LogError('DamageService::GetTargetLocators cannot find ball of attackerID', attackerID) 69 return [] 70 if attackerModel is None: 71 self.LogError('DamageService::GetTargetLocators attacker ball has no model', attackerID) 72 return [] 73 if (targetID, attackerID) in self.targets: 74 cachedResultTime, cachedResultList = self.targets[targetID, attackerID] 75 if blue.os.TimeDiffInMs(cachedResultTime, blue.os.GetWallclockTimeNow()) < self.targetResultCacheTime: 76 if len(cachedResultList) >= locatorVariance: 77 return cachedResultList[:locatorVariance] 78 if targetID in self.failedTargets: 79 return [targetModel] 80 del self.targets[targetID, attackerID] 81 result = [targetModel] 82 if hasattr(targetModel, 'activeLevel'): 83 if targetModel.activeLevel >= self.targetLODLevel: 84 return [targetModel] 85 self.LogInfo('Regenerating damage locator cache for pair: ', targetID, ' - ', attackerID) 86 targetDamageLocators = getattr(targetBall, 'targets', None) 87 if targetDamageLocators is None or len(targetDamageLocators) == 0: 88 if targetID in self.failedTargets: 89 return [targetModel] 90 self.LogWarn('DamageService::GetTargetLocators must regenerate damage locators', targetID) 91 locators = self.GenerateDamageLocators(targetModel, self.generatedDamageLocators) 92 if len(locators) == 0: 93 self.failedTargets[targetID] = targetModel 94 self.LogError("Couldn't generate damage locators on ", targetModel.name) 95 return [targetModel] 96 targetDamageLocators = locators 97 targetBall.targets = locators 98 closestTargets = [] 99 for targetLocator in targetDamageLocators: 100 closestTargets.append([(targetLocator.worldPosition - attackerModel.worldPosition).Length(), targetLocator]) 101 102 closestTargets.sort() 103 result = [ x[1] for x in closestTargets ] 104 self.targets[targetID, attackerID] = (blue.os.GetWallclockTimeNow(), result) 105 result = result[:locatorVariance] 106 except: 107 log.LogException() 108 finally: 109 blue.pyos.taskletTimer.ReturnFromTasklet(timer) 110 111 return result 112 113 def GetDamageLocatorGeneratorTransformHeirarchy(self, transform): 114 if transform.__typename__ == 'TriLODGroup': 115 if len(transform.children) > 0: 116 return self.GetDamageLocatorGeneratorTransform(transform.children[0], 0) 117 else: 118 self.LogError('DamageService::GetDamageLocatorGeneratorTransformHeirarchy: Passed an empty LODGroup. Not much that can be done here anyway.') 119 return None 120 self.LogError('DamageService::GetDamageLocatorGeneratorTransformHeirarchy: Attempting to generate damage locators on a', transform.__typename__) 121 122 def GetDamageLocatorGeneratorTransform(self, transform, depth = 0): 123 if depth == 0 and not hasattr(transform, 'object'): 124 return 125 if transform.display == 0: 126 return 127 if hasattr(transform, 'object') and transform.object is not None: 128 if transform.object.__typename__ == 'TriModel': 129 if transform.object.vertices != 'res:/Model/Global/locatorObject.tri': 130 if hasattr(transform, 'name'): 131 self.LogWarn('DamageService.GetDamageLocatorGeneratorTransform: Picked:', transform.name) 132 return [transform] 133 if transform.object.__typename__ == 'TriParticleCloud': 134 return [transform] 135 result = None 136 if depth < 3: 137 for child in transform.children: 138 result = self.GetDamageLocatorGeneratorTransform(child, depth + 1) 139 if result is not None: 140 return [transform] + result 141 142 def GenerateDamageLocators(self, rootTransform, generateNumber): 143 timer = blue.pyos.taskletTimer.EnterTasklet('DamageService::GenerateDamageLocators') 144 generatedLocators = [] 145 try: 146 targetTransformHeirarchy = self.GetDamageLocatorGeneratorTransformHeirarchy(rootTransform) 147 if targetTransformHeirarchy is None: 148 self.LogError('DamageService::GenerateDamageLocators: Didnt get anything sensible back from GetDamageLocatorGeneratorTransformHeirarchy') 149 return [] 150 targetTransform = targetTransformHeirarchy[-1] 151 targetTransformHeirarchy = targetTransformHeirarchy[1:] 152 transformCopyList = [] 153 154 def CopyAttributes(tf1, tf2, attributes): 155 for attribute in attributes: 156 if getattr(tf1, attribute, None) is not None: 157 setattr(tf2, attribute, getattr(tf1, attribute).CopyTo()) 158 159 def CheckEmptyTransformation(tf): 160 if tf.__typename__ != 'TriTransform': 161 return True 162 if tf.useCurves: 163 if tf.scalingCurve is not None: 164 return False 165 if tf.rotationCurve is not None: 166 return False 167 if tf.translationCurve is not None: 168 return False 169 if tf.scaling.x != 1.0 or tf.scaling.y != 1.0 or tf.scaling.z != 1.0: 170 return False 171 if tf.translation.x != 0.0 or tf.translation.y != 0.0 or tf.translation.z != 0.0: 172 return False 173 if tf.rotation.x != 0.0 or tf.rotation.y != 0.0 or tf.rotation.z != 0.0 or tf.rotation.w != 1.0: 174 return False 175 return True 176 177 for transformDepthIndex in range(len(targetTransformHeirarchy)): 178 if CheckEmptyTransformation(targetTransformHeirarchy[transformDepthIndex]): 179 continue 180 tfCopy = blue.classes.CreateInstance('trinity.TriTransform') 181 tfCopy.frustrumCull = 0 182 CopyAttributes(targetTransformHeirarchy[transformDepthIndex], tfCopy, ['scalingCurve', 183 'rotationCurve', 184 'translationCurve', 185 'scaling', 186 'rotation', 187 'translation']) 188 if len(transformCopyList) > 0: 189 transformCopyList[-1].children.append(tfCopy) 190 transformCopyList.append(tfCopy) 191 192 if len(transformCopyList) > 0: 193 transformCopyList[0].name = 'Generated Damage Locators' 194 for v in range(generateNumber): 195 pos = targetTransform.RandomSurfacePoint() 196 if not pos: 197 self.LogError('DamageService.GenerateDamageLocators: RandomSurfacePoint generated a None vector') 198 break 199 newDamageLocator = blue.classes.CreateInstance('trinity.TriSplTransform') 200 newDamageLocator.scaling.Scale(0.2) 201 newDamageLocator.name = 'locator_damage_' + str(v) 202 newDamageLocator.translation = pos.CopyTo() 203 targetTransform.children.append(newDamageLocator) 204 if len(transformCopyList) > 0: 205 transformCopyList[-1].children.append(newDamageLocator) 206 generatedLocators.append(newDamageLocator) 207 208 for lodGroup in rootTransform.children[1:]: 209 if len(transformCopyList) > 0: 210 lodGroup.children.append(transformCopyList[0]) 211 else: 212 for newLocator in generatedLocators: 213 lodGroup.children.append(newLocator) 214 215 finally: 216 blue.pyos.taskletTimer.ReturnFromTasklet(timer) 217 218 return generatedLocators