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

effects.py (12421B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\behaviors\actions\effects.py
      2 import logging
      3 import random
      4 from ballpark.messenger.const import MESSAGE_ON_EFFECT_STOPPED
      5 from behaviors import status
      6 from behaviors.tasks import Task
      7 from behaviors.utility.ballparks import get_slim_item, get_ship_balls_in_bubble
      8 from behaviors.utility.dogmatic import type_has_effect, try_stop_effect, get_default_effect_id_for_type
      9 from ccpProfile import TimedFunction
     10 from dogma.const import attributeRateOfFire
     11 from eveexceptions import UserError
     12 from behaviors.exceptions import BehaviorAuthoringException
     13 logger = logging.getLogger(__name__)
     14 TARGET_ATTACK_GRAPHIC_EFFECT = 'effects.Laser'
     15 
     16 class PlayOneShotStretchEffectAction(Task):
     17 
     18     @TimedFunction('behaviors::actions::effects::PlayOneShotStretchEffectAction::OnEnter')
     19     def OnEnter(self):
     20         sourceId = self._GetEffectSourceId()
     21         targetId = self.GetLastBlackboardValue(self.attributes.effectTargetAddress)
     22         if sourceId is None or targetId is None:
     23             self.status = status.TaskFailureStatus
     24         else:
     25             sfx = self.context.ballpark.specialEffects
     26             moduleId = None
     27             if getattr(self.attributes, 'useEntityAsModule', False):
     28                 moduleId = sourceId
     29             sfx.StartStretchEffect(sourceId, targetId, self.attributes.effectName, self._GetEffectDuration(), 1, moduleId)
     30             self.status = status.TaskSuccessStatus
     31 
     32     def _GetEffectSourceId(self):
     33         if self.HasAttribute('effectSourceAddress'):
     34             return self.GetLastBlackboardValue(self.attributes.effectSourceAddress)
     35         return self.context.myItemId
     36 
     37     def _GetEffectDuration(self):
     38         if self.HasAttribute('effectDurationAddress'):
     39             return self.GetLastBlackboardValue(self.attributes.effectDurationAddress)
     40         return self.attributes.effectDuration
     41 
     42 
     43 class PlayOneShotTargetedShipEffectAction(Task):
     44 
     45     @TimedFunction('behaviors::actions::effects::PlayOneShotTargetedShipEffectAction::OnEnter')
     46     def OnEnter(self):
     47         targetId = self.GetLastBlackboardValue(self.attributes.effectTargetAddress)
     48         if targetId is None:
     49             self.status = status.TaskFailureStatus
     50         else:
     51             sfx = self.context.ballpark.specialEffects
     52             sfx.StartShipEffect(targetId, self.attributes.effectName, self.attributes.effectDuration, 1)
     53             self.status = status.TaskSuccessStatus
     54 
     55 
     56 class PlayOneShotShipEffectAction(Task):
     57 
     58     @TimedFunction('behaviors::actions::effects::PlayOneShotShipEffectAction::OnEnter')
     59     def OnEnter(self):
     60         ballId = self.context.myItemId
     61         if getattr(self.attributes, 'effectTargetAddress', None):
     62             ballId = self.GetLastBlackboardValue(self.attributes.effectTargetAddress)
     63         sfx = self.context.ballpark.specialEffects
     64         sfx.StartShipEffect(ballId, self.attributes.effectName, self.attributes.effectDuration, 1, graphicInfo=getattr(self.attributes, 'graphicInfo', None))
     65         self.status = status.TaskSuccessStatus
     66 
     67 
     68 class PlayStretchEffectAction(Task):
     69 
     70     def OnEnter(self):
     71         self.SetStatusToFailed()
     72         targetId = self.GetLastBlackboardValue(self.attributes.effectTargetAddress)
     73         graphicInfoAddress = self.attributes.graphicInfoAddress
     74         if graphicInfoAddress:
     75             graphicInfo = self.GetLastBlackboardValue(graphicInfoAddress)
     76         else:
     77             graphicInfo = None
     78         repeats = self.attributes.effectRepeats
     79         if targetId is not None:
     80             sfx = self.context.ballpark.specialEffects
     81             moduleId = None
     82             if getattr(self.attributes, 'useEntityAsModule', False):
     83                 moduleId = self.context.myItemId
     84             sfx.StartStretchEffect(self.context.myItemId, targetId, self.attributes.effectName, self.get_effect_duration(), repeats, moduleId, graphicInfo=graphicInfo)
     85             self.SetStatusToSuccess()
     86 
     87     def get_effect_duration(self):
     88         if self.HasAttribute('effectDurationRandomVariance'):
     89             variance = self.attributes.effectDurationRandomVariance
     90             if variance > 0:
     91                 difference = random.random() * variance - variance * 0.5
     92                 return self.attributes.effectDuration + difference
     93         return self.attributes.effectDuration
     94 
     95 
     96 class StopStretchEffectAction(Task):
     97 
     98     def OnEnter(self):
     99         self.SetStatusToFailed()
    100         targetId = self.GetLastBlackboardValue(self.attributes.effectTargetAddress)
    101         if targetId is not None:
    102             sfx = self.context.ballpark.specialEffects
    103             moduleId = None
    104             if getattr(self.attributes, 'useEntityAsModule', False):
    105                 moduleId = self.context.myItemId
    106             sfx.StopStretchEffect(self.context.myItemId, targetId, self.attributes.effectName, moduleId)
    107             self.SetStatusToSuccess()
    108 
    109 
    110 class SetDogmaAttributeValue(Task):
    111 
    112     def OnEnter(self):
    113         value = self._GetValue()
    114         self.context.dogmaLM.SetAttributeValue(self.context.myItemId, self.attributes.attributeId, value)
    115         self.SetStatusToSuccess()
    116 
    117     def _GetValue(self):
    118         if self.attributes.valueAddress:
    119             return self.GetLastBlackboardValue(self.attributes.valueAddress)
    120         if self.attributes.value is not None:
    121             return self.attributes.value
    122         raise BehaviorAuthoringException('BehaviorID: %s has no value defined for task: %s', self.behaviorTree.GetBehaviorId(), type(self).__name__)
    123 
    124 
    125 class SendDogmaAttributeValueAsMessage(Task):
    126 
    127     def OnEnter(self):
    128         attributeValue = self.context.dogmaLM.GetAttributeValue(self.context.myItemId, self.attributes.attributeId)
    129         if self.attributes.scalarValueAddress is not None:
    130             scalar = self.GetLastBlackboardValue(self.attributes.scalarValueAddress)
    131         else:
    132             scalar = getattr(self.attributes, 'scalar', None) or 1.0
    133         self.SendBlackboardValue(self.attributes.valueAddress, attributeValue * scalar)
    134         self.SetStatusToSuccess()
    135 
    136 
    137 class ResetDogmaAttributeValue(Task):
    138 
    139     @TimedFunction('behaviors::actions::effects::ResetDogmaAttributeValue::OnEnter')
    140     def OnEnter(self):
    141         typeValue = self.context.dogmaLM.dogmaStaticMgr.GetTypeAttribute2(self.context.mySlimItem.typeID, self.attributes.attributeId)
    142         self.context.dogmaLM.SetAttributeValue(self.context.myItemId, self.attributes.attributeId, typeValue)
    143         self.status = status.TaskSuccessStatus
    144 
    145 
    146 class ActivateTargetedEffect(Task):
    147 
    148     @TimedFunction('behaviors::actions::effects::ActivateTargetedEffect::OnEnter')
    149     def OnEnter(self):
    150         selectedTarget = self.GetLastBlackboardValue(self.attributes.selectedTargetAddress)
    151         self.SetStatusToSuccess()
    152         item = self.context.ballpark.inventory2.GetItem(self.context.myItemId)
    153         if selectedTarget:
    154             if self.context.dogmaLM.dogmaStaticMgr.TypeHasEffect(item.typeID, self.attributes.effectId):
    155                 self.TryActivateEffect(item.ownerID, selectedTarget)
    156 
    157     @TimedFunction('behaviors::actions::effects::ActivateTargetedEffect::TryActivateEffect')
    158     def TryActivateEffect(self, ownerID, targetID):
    159         try:
    160             self.context.dogmaLM.ActivateWithContext(ownerID, self.context.myItemId, self.attributes.effectId, targetid=targetID, repeat=self.attributes.repeats)
    161             self.StartMonitoringEffectStoppedIfRequired()
    162             logger.debug('ActivateTargetedEffect: %s: start attacking target %s with effect %s', self.context.myItemId, targetID, self.attributes.effectId)
    163         except (UserError,) as e:
    164             if e.msg == 'EffectAlreadyActive2':
    165                 self.StartMonitoringEffectStoppedIfRequired()
    166                 logger.debug('ActivateTargetedEffect: %s: effect already active', self.context.myItemId)
    167             else:
    168                 logger.debug('ActivateTargetedEffect: %s: failed to activate on target %s with effect %s: %s', self.context.myItemId, targetID, self.attributes.effectId, e)
    169 
    170     def CleanUp(self):
    171         if self.IsInvalid():
    172             return
    173         self.StopMonitoringEffectStopped()
    174         self.SetStatusToInvalid()
    175 
    176     def StartMonitoringEffectStopped(self):
    177         self.SubscribeItem(self.context.myItemId, MESSAGE_ON_EFFECT_STOPPED, self.OnStopEffect)
    178 
    179     def StopMonitoringEffectStopped(self):
    180         self.UnsubscribeItem(self.context.myItemId, MESSAGE_ON_EFFECT_STOPPED, self.OnStopEffect)
    181 
    182     def StartMonitoringEffectStoppedIfRequired(self):
    183         if self.attributes.shouldResetBehaviorOnEffectStopped:
    184             self.StartMonitoringEffectStopped()
    185 
    186     def OnStopEffect(self, effectId):
    187         if self.IsInvalid():
    188             return
    189         if effectId == self.attributes.effectId:
    190             self.behaviorTree.RequestReset(requestedBy=self)
    191 
    192 
    193 class ActivateEffect(Task):
    194 
    195     def OnEnter(self):
    196         self.SetStatusToSuccess()
    197         item = self.context.ballpark.inventory2.GetItem(self.context.myItemId)
    198         self.TryActivateEffect(item.ownerID)
    199 
    200     def TryActivateEffect(self, ownerID):
    201         effect_id = self.GetEffectId()
    202         try:
    203             self.context.dogmaLM.ActivateWithContext(ownerID, self.context.myItemId, effectID=effect_id, repeat=self.GetRepeats(), context=self.GetContext())
    204             logger.debug('ActivateEffect: %s: start attacking effect %s', self.context.myItemId, effect_id)
    205         except (UserError,) as e:
    206             logger.debug('ActivateEffect: %s: failed to activate effect %s: %s', self.context.myItemId, effect_id, e)
    207 
    208     def GetContext(self):
    209         return getattr(self.attributes, 'contextDict', None)
    210 
    211     def GetEffectId(self):
    212         return self.attributes.effectId
    213 
    214     def GetRepeats(self):
    215         return self.attributes.repeats
    216 
    217 
    218 class ActivateDefaultEffect(ActivateEffect):
    219 
    220     def GetEffectId(self):
    221         return get_default_effect_id_for_type(self, self.context.mySlimItem.typeID)
    222 
    223 
    224 class MockTargetAttack(Task):
    225 
    226     def OnEnter(self):
    227         self.SetStatusToFailed()
    228         targetId = self.GetLastBlackboardValue(self.attributes.targetIdAddress)
    229         if targetId is not None:
    230             duration = self.context.dogmaLM.GetAttributeValue(self.context.myItemId, attributeRateOfFire)
    231             sfx = self.context.ballpark.specialEffects
    232             sfx.StartStretchEffect(self.context.myItemId, targetId, TARGET_ATTACK_GRAPHIC_EFFECT, duration, 99, self.context.myItemId)
    233             self.SetStatusToSuccess()
    234 
    235 
    236 class StopMockTargetAttack(Task):
    237 
    238     def OnEnter(self):
    239         self.SetStatusToFailed()
    240         targetId = self.GetLastBlackboardValue(self.attributes.targetIdAddress)
    241         if targetId is not None:
    242             sfx = self.context.ballpark.specialEffects
    243             sfx.StopStretchEffect(self.context.myItemId, targetId, TARGET_ATTACK_GRAPHIC_EFFECT, self.context.myItemId)
    244             self.SetStatusToSuccess()
    245 
    246 
    247 class SendDogmaEffectIdAsMessage(Task):
    248 
    249     def OnEnter(self):
    250         self.SendBlackboardValue(self.attributes.effectIdAddress, self.attributes.effectId)
    251         self.SetStatusToSuccess()
    252 
    253 
    254 class StopEffect(Task):
    255 
    256     @TimedFunction('behaviors::actions::effects::StopEffect::OnEnter')
    257     def OnEnter(self):
    258         self.SetStatusToFailed()
    259         effect_id = self._get_effect_id()
    260         if not effect_id:
    261             logger.warn('Behavior=%s does not have effect=%s authored for task=%s', self.behaviorTree.GetBehaviorId(), effect_id)
    262             return
    263         if not type_has_effect(self, self.context.mySlimItem.typeID, effect_id):
    264             logger.warn('Behavior=%s entity=%s is missing effect=%s', self.behaviorTree.GetBehaviorId(), self.context.mySlimItem.typeID, effect_id)
    265             return
    266         self.SetStatusToSuccess()
    267         self._stop_effect(effect_id)
    268 
    269     def _get_effect_id(self):
    270         return self.attributes.effectId
    271 
    272     def _stop_effect(self, effect_id):
    273         try_stop_effect(self, effect_id, forced=self._is_stop_forced())
    274 
    275     def _is_stop_forced(self):
    276         return self.attributes.forcedStop
    277 
    278 
    279 class ReplaceNebulaForPlayersInBubble(Task):
    280 
    281     def OnEnter(self):
    282         self.SetStatusToSuccess()
    283         nebula_path = 'res:/dx9/scene/abyssal/ad01_a_cube.dds'
    284         for ball_id in get_ship_balls_in_bubble(self, self.context.myBall.newBubbleId):
    285             slim_item = get_slim_item(self, ball_id)
    286             sm.GetService('machoNet').SinglecastByCharID(slim_item.charID, 'OnReplaceNebula', nebula_path)