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

baseHangarBehaviours.py (13797B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\view\hangarBehaviours\baseHangarBehaviours.py
      2 from __future__ import absolute_import
      3 import evetypes
      4 import trinity
      5 import logging
      6 import geo2
      7 import uthread2
      8 from cosmetics.common.ships.skins.static_data.skin_type import ShipSkinType
      9 from fsdBuiltData.common.graphicIDs import GetSofFactionName
     10 from inventorycommon.util import GetSubSystemTypeIDs
     11 import evegraphics.utils as gfxutils
     12 from eve.common.script.net import eveMoniker
     13 from eveSpaceObject.spaceobjanimation import SetShipAnimationStance, TriggerDefaultStates
     14 from eve.client.script.ui.inflight.shipstance import get_ship_stance
     15 from eve.client.script.environment.model.turretSet import TurretSet
     16 from eve.client.script.environment.sofService import GetSofService
     17 from eve.client.script.environment.spaceObject.cosmeticsManager import CosmeticsManager
     18 from evegraphics.CosmeticsLoader import CosmeticsLoader
     19 from . import modularHangarBehavioursConstants as hConst
     20 log = logging.getLogger(__name__)
     21 
     22 class BaseHangarShipBehaviour(object):
     23     MIN_SHIP_BOBBING_TIME = 10
     24     MAX_SHIP_BOBBING_TIME = 300
     25     MIN_SHIP_BOBBING_HALF_DISTANCE = 100
     26 
     27     def __init__(self):
     28         self._activeMaterialSetID = None
     29         self._activeSkinID = None
     30         self.log = log
     31         self.shipAnchorPoint = (0.0, 0.0, 0.0)
     32         self.shipSwitchingInProcess = False
     33         self.turretSets = {}
     34         self.cosmeticsLoader = CosmeticsLoader((CosmeticsLoader.ALLIANCE, CosmeticsLoader.CORP))
     35 
     36     def LoadShipModel(self, itemID, typeID):
     37         self.shipSwitchingInProcess = True
     38         model = self._LoadSOFShipModel(itemID, typeID)
     39         model.name = str(itemID)
     40         model.FreezeHighDetailMesh()
     41         self.SetShipDirtLevel(itemID, model)
     42         self.SetShipKillCounter(itemID, model)
     43         self.SetupShipAnimation(model, typeID, itemID)
     44         self.SetShipDamage(itemID, model)
     45         self.FitTurrets(itemID, typeID, model)
     46         self.SetInHangarVariables(model)
     47         self.shipSwitchingInProcess = False
     48         return model
     49 
     50     def CleanScene(self):
     51         self.turretSets = None
     52 
     53     def _LoadSOFShipModel(self, itemID, typeID):
     54         self._activeSkinID = None
     55         self._activeMaterialSetID = None
     56         skin_state = self.GetShipSkinState(itemID, typeID)
     57         if skin_state:
     58             if skin_state.skin_type == ShipSkinType.THIRD_PARTY_SKIN:
     59                 thirdPartyDNA = CosmeticsManager.CreateSOFDNAfromSkinState(skin_state, typeID)
     60                 ship = GetSofService().spaceObjectFactory.BuildFromDNA(thirdPartyDNA)
     61                 CosmeticsManager.UpdatePatternProjectionParametersFromSkinState(skin_state, ship, typeID)
     62                 blend_mode = skin_state.skin_data.slot_layout.pattern_blend_mode
     63                 if blend_mode is not None:
     64                     CosmeticsManager.SetBlendMode(ship, blendMode=blend_mode)
     65                 return ship
     66             if skin_state.skin_type == ShipSkinType.FIRST_PARTY_SKIN:
     67                 self._activeSkinID = skin_state.skin_data.skin_id
     68                 self._activeMaterialSetID = sm.GetService('cosmeticsSvc').GetFirstPartySkinMaterialSetID(self._activeSkinID)
     69             elif skin_state.skin_type == ShipSkinType.NO_SKIN:
     70                 pass
     71         shipDna = gfxutils.BuildSOFDNAFromTypeID(typeID, materialSetID=self._activeMaterialSetID, multiHullTypeIDList=GetSubSystemTypeIDs(itemID, typeID))
     72         if shipDna is None:
     73             self.log.error('%s._LoadSOFShip(itemID = %s, typeID = %s): Trying to show a SOF ship that is not in the SOF' % (self, itemID, typeID))
     74             return
     75         return GetSofService().spaceObjectFactory.BuildFromDNA(shipDna)
     76 
     77     def SetupShipAnimation(self, model, typeID, itemID):
     78         if model is None:
     79             return
     80         if not evetypes.Exists(typeID):
     81             return
     82         SetShipAnimationStance(model, get_ship_stance(itemID, typeID))
     83         TriggerDefaultStates(model)
     84 
     85     def SetShipDirtLevel(self, itemID, model):
     86         dirtTimeStamp = eveMoniker.GetShipAccess().GetDirtTimestamp(itemID)
     87         dirtLevel = gfxutils.CalcDirtLevelFromAge(dirtTimeStamp)
     88         model.dirtLevel = dirtLevel
     89 
     90     def SetShipKillCounter(self, itemID, model):
     91         killCounter = sm.RemoteSvc('shipKillCounter').GetItemKillCountPlayer(itemID)
     92         model.displayKillCounterValue = min(killCounter, 999)
     93 
     94     def SetShipDamage(self, itemID, model, steps = 1, duration = 0.1):
     95         dogmaLocation = sm.GetService('clientDogmaIM').GetDogmaLocation()
     96         dogmaLocation.LoadItem(itemID)
     97         shipState = dogmaLocation.GetDamageStateEx(itemID)
     98         if shipState is None:
     99             self.log.error('%s.SetShipDamage(itemID = %s, model = %s): Got no shipstate from dogma', self, itemID, model)
    100             return False
    101         shieldState, armorState, hullState = shipState
    102         if isinstance(shieldState, tuple):
    103             shieldState = shieldState[0]
    104         if model is not None:
    105             if model.impactOverlay is not None:
    106                 damage = model.impactOverlay.hullDamageFactor
    107                 if damage > 0.1 and armorState > 0.99 and hullState > 0.99:
    108                     uthread2.start_tasklet(self.ImpactUpdateThread, model)
    109                     return True
    110             model.SetImpactDamageState(shieldState, armorState, hullState, True)
    111         return False
    112 
    113     def ImpactUpdateThread(self, model):
    114         if model.impactOverlay is None:
    115             self.log.error('ImpactUpdateThread: impactOverlay not initialized on hull')
    116             return
    117         overlay = model.impactOverlay
    118         originalHullDamageState = overlay.GetLastDamageState()
    119         hullProgress = originalHullDamageState[2]
    120         armorProgress = originalHullDamageState[1]
    121         shieldState = originalHullDamageState[0]
    122         initialProgress = hullProgress + armorProgress
    123         stepSize = (2.0 - initialProgress) / hConst.REPAIR_DRONES_REPAIR_DURATION
    124         uthread2.sleep(hConst.REPAIR_DRONES_START_DELAY)
    125         overlay.hullRepairing.fading = hConst.REPAIR_DRONE_HULL_REPAIR_EFFECT_SPEED[0]
    126         overlay.armorRepairing.fading = hConst.REPAIR_DRONE_ARMOR_REPAIR_EFFECT_SPEED[0]
    127         while hullProgress < 1.0:
    128             if model is None:
    129                 return
    130             model.SetImpactDamageState(shieldState, armorProgress, min(hullProgress, 1.0), True)
    131             uthread2.sleep(1.0)
    132             hullProgress += stepSize
    133 
    134         overlay.hullRepairing.fading = hConst.REPAIR_DRONE_HULL_REPAIR_EFFECT_SPEED[1]
    135         overlay.armorRepairing.fading = hConst.REPAIR_DRONE_ARMOR_REPAIR_EFFECT_SPEED[1]
    136         while armorProgress < 0.8:
    137             if model is None:
    138                 return
    139             model.SetImpactDamageState(1.0, armorProgress, 1.0, True)
    140             uthread2.sleep(1.0)
    141             armorProgress += stepSize
    142 
    143         overlay.armorRepairing.fading = hConst.REPAIR_DRONE_ARMOR_REPAIR_EFFECT_SPEED[2]
    144         while armorProgress < 1.0:
    145             if model is None:
    146                 return
    147             model.SetImpactDamageState(1.0, armorProgress, 1.0, True)
    148             uthread2.sleep(1.0)
    149             armorProgress += stepSize
    150 
    151         model.SetImpactDamageState(1.0, 1.0, 1.0, True)
    152 
    153     def FitTurrets(self, itemID, typeID, model):
    154         graphicID = evetypes.GetGraphicID(typeID)
    155         sofFactionName = GetSofFactionName(graphicID)
    156         self.turretSets = TurretSet.FitTurrets(itemID, model, sofFactionName)
    157         self._SetHighLodForTurrets(model)
    158 
    159     def SetInHangarVariables(self, model):
    160         if model is None:
    161             return
    162         model.SetControllerVariable('inHangar', 1.0)
    163 
    164     def UpdateTurretState(self, dogmaItem):
    165         if dogmaItem.itemID not in self.turretSets:
    166             return
    167         turret = self.turretSets[dogmaItem.itemID]
    168         if dogmaItem.IsOnline():
    169             turret.Online()
    170         else:
    171             turret.Offline()
    172 
    173     def _SetHighLodForTurrets(self, model):
    174         for turretSet in model.turretSets:
    175             turretSet.FreezeHighDetailLOD()
    176 
    177     def GetShipSkinState(self, itemID, typeID):
    178         return sm.GetService('cosmeticsSvc').GetAppliedSkinState(session.charid, itemID)
    179 
    180     def ShouldSwitchSkin(self, skinID):
    181         return skinID != getattr(self._activeSkinID, 'skinID', None) and not self.shipSwitchingInProcess
    182 
    183     def GetLocatorsFromSet(self, model, locatorSetName):
    184         if model is None:
    185             return []
    186         return model.GetTransformedLocatorsFromSet(locatorSetName)
    187 
    188     def SetAnchorPoint(self, hangarModel, hangarScene):
    189         raise NotImplementedError("%s does not implement 'SetAnchorPoint'", self)
    190 
    191     def PlaceShip(self, model, typeID):
    192         raise NotImplementedError("%s does not implement 'PlaceShip'", self)
    193 
    194     def GetShipCenter(self, model, typeID):
    195         raise NotImplementedError("%s does not implement 'GetShipCenter'", self)
    196 
    197     def AnimateShipEntry(self, model, typeID, scene = None, duration = 5.0):
    198         self.PlaceShip(model, typeID)
    199 
    200     def AnimateReflectionProbeEntry(self, reflectionProbe, duration = 5.0):
    201         self.PlaceReflectionProbe(reflectionProbe)
    202 
    203     def PlaceReflectionProbe(self, reflectionProbe):
    204         if reflectionProbe:
    205             reflectionProbe.lockPosition = True
    206             reflectionProbe.position = self.shipAnchorPoint
    207 
    208     def ApplyShipBobbing(self, model, initialPosition, deltaPosition, cycleLengthInSec):
    209         curve = trinity.Tr2CurveVector3()
    210         topPosition = geo2.Vec3Add(initialPosition, deltaPosition)
    211         bottomPosition = geo2.Vec3Subtract(initialPosition, deltaPosition)
    212         curve.AddKey(0.0, initialPosition, trinity.Tr2CurveInterpolation.HERMITE)
    213         curve.AddKey(0.25 * cycleLengthInSec, bottomPosition, trinity.Tr2CurveInterpolation.HERMITE)
    214         curve.AddKey(0.75 * cycleLengthInSec, topPosition, trinity.Tr2CurveInterpolation.HERMITE)
    215         curve.AddKey(1.0 * cycleLengthInSec, initialPosition, trinity.Tr2CurveInterpolation.HERMITE)
    216         curve.x.extrapolationAfter = trinity.Tr2CurveExtrapolation.CYCLE
    217         curve.y.extrapolationAfter = trinity.Tr2CurveExtrapolation.CYCLE
    218         curve.z.extrapolationAfter = trinity.Tr2CurveExtrapolation.CYCLE
    219         model.modelTranslationCurve = trinity.Tr2TranslationAdapter()
    220         model.modelTranslationCurve.curve = curve
    221 
    222 
    223 class BaseHangarShipDroneBehaviour(object):
    224 
    225     def __init__(self):
    226         self.dronesActive = False
    227         self.seekTargetBehaviourData = None
    228         self.collisionAvoidanceBehaviourData = None
    229         self.repairDroneBehaviourGroup = None
    230         self.hasEllipsoid = False
    231 
    232     def Setup(self, hangarModel, shipModel):
    233         self.repairDroneBehaviourGroup = self.GetRepairDroneBehaviourGroup(hangarModel)
    234         self.seekTargetBehaviourData = self.GetSeekTargetData(self.repairDroneBehaviourGroup)
    235         self.collisionAvoidanceBehaviourData = self.GetCollisionAvoidanceData(hangarModel)
    236         if self.seekTargetBehaviourData:
    237             self.seekTargetBehaviourData.ResetBehavior()
    238         self.SetRepairDroneCount(shipModel.boundingSphereRadius)
    239         self.dronesActive = False
    240 
    241     def SplitBoundingBox(self):
    242         if self.seekTargetBehaviourData:
    243             self.seekTargetBehaviourData.SplitBoundingBox()
    244 
    245     def GetSeekTargetData(self, repairDroneBehaviourGroup):
    246         behavior = repairDroneBehaviourGroup.Find('trinity.SeekTarget')
    247         for data in behavior:
    248             return data
    249 
    250     def GetCollisionAvoidanceData(self, hangarModel):
    251         behavior = hangarModel.Find('trinity.CollisionAvoidance')
    252         for data in behavior:
    253             return data
    254 
    255     def GetRepairDroneBehaviourGroup(self, hangarModel):
    256         behaviorGroups = hangarModel.Find('trinity.BehaviorGroup')
    257         for each in behaviorGroups:
    258             if each.name == 'RepairDrone':
    259                 return each
    260 
    261     def GetShipArmorImpactLifeTime(self, shipModel):
    262         return shipModel.impactOverlay.GetArmorImpactLifeTime()
    263 
    264     def GetDronesActive(self):
    265         return self.dronesActive
    266 
    267     def SetDronesActive(self, value):
    268         self.dronesActive = value
    269         self.seekTargetBehaviourData.SetupShipRepair()
    270 
    271     def SetTarget(self, shipModel):
    272         self.seekTargetBehaviourData.SetTarget(shipModel)
    273 
    274     def SetExit(self):
    275         if self.seekTargetBehaviourData:
    276             self.seekTargetBehaviourData.SetExit(True)
    277         self.dronesActive = False
    278 
    279     def StartRepairDroneSequence(self, itemID, shipModel, shipBehaviour):
    280         self.SetEllipsoidVolume(shipModel)
    281         self.SetTarget(shipModel)
    282         if shipModel.boundingSphereRadius >= 2250:
    283             self.SplitBoundingBox()
    284         sec = self.GetShipArmorImpactLifeTime(shipModel)
    285         if self.seekTargetBehaviourData:
    286             self.seekTargetBehaviourData.SetTotalRepairTime(sec)
    287         self.seekTargetBehaviourData.onFirstDroneArrivedCallback = lambda : self.StartEffectAndTimer(itemID, shipModel, shipBehaviour)
    288 
    289     def StartEffectAndTimer(self, itemID, shipModel, shipBehaviour):
    290         shipBehaviour.SetShipDamage(itemID, shipModel)
    291 
    292     def SetRepairDroneCount(self, boundingRadius):
    293         raise NotImplementedError("%s does not implement 'SetCount'", self)
    294 
    295     def SetEllipsoidVolume(self, shipModel):
    296         if self.collisionAvoidanceBehaviourData and self.seekTargetBehaviourData:
    297             volume = trinity.EveEllipsoidVolume()
    298             scale = 1.5
    299             volume.shape = (shipModel.shapeEllipsoidRadius[0] * scale, shipModel.shapeEllipsoidRadius[1] * scale, shipModel.shapeEllipsoidRadius[2] * scale)
    300             volume.innerShape = shipModel.shapeEllipsoidRadius
    301             volume.position = shipModel.translationCurve.value
    302             self.collisionAvoidanceBehaviourData.exclusionVolumes[0] = volume
    303             self.hasEllipsoid = True