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

ballparks.py (15705B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\behaviors\monitors\ballparks.py
      2 import logging
      3 import uthread2
      4 from ballpark.messenger.const import MESSAGE_INVULNERABILITY_CANCELED, MESSAGE_ON_BUBBLE_PROXIMITY_ENTERED
      5 from ballpark.messenger.const import MESSAGE_ON_BALLPARK_ITEM_DESTROY
      6 from ballpark.messenger.const import MESSAGE_ON_ITEM_REMOVED_FROM_PARK, MESSAGE_ON_PROXIMITY
      7 from behaviors import status
      8 from behaviors.groups.mixin import GroupTaskMixin
      9 from behaviors.tasks import Task
     10 from behaviors.utility.ballparks import is_ball_cloaked
     11 from behaviors.utility.blackboards import update_blackboard_set_if_changed
     12 from behaviors.utility.components import get_proximity_sensors, get_proximity_sensor
     13 from ccpProfile import TimedFunction
     14 from npcs.server.tags import get_behavior_sensor_tags
     15 logger = logging.getLogger(__name__)
     16 PROXIMITY_EVENT = 'DoBubbleProximity'
     17 
     18 class BubbleChangedMonitor(Task):
     19 
     20     @TimedFunction('behaviors::monitors::ballparks::BubbleChangedMonitor::OnEnter')
     21     def OnEnter(self):
     22         self.bubbleId = self.GetBubbleId()
     23         self.GetServiceManager().RegisterForNotifyEvent(self, PROXIMITY_EVENT)
     24         self.context.ballpark.SetBubbleEvents(self.bubbleId, True)
     25         self.SetStatusToSuccess()
     26 
     27     def GetBubbleId(self):
     28         if getattr(self.attributes, 'bubbleIdAddress', None) is None:
     29             return self.context.myBall.newBubbleId
     30         else:
     31             return self.GetLastBlackboardValue(self.attributes.bubbleIdAddress)
     32 
     33     def CleanUp(self):
     34         if not self.IsInvalid():
     35             self.GetServiceManager().UnregisterForNotifyEvent(self, PROXIMITY_EVENT)
     36             self.context.ballpark.SetBubbleEvents(self.bubbleId, False)
     37             self.bubbleId = None
     38         self.SetStatusToInvalid()
     39 
     40     @TimedFunction('behaviors::monitors::ballparks::BubbleChangedMonitor::DoBubbleProximity')
     41     def DoBubbleProximity(self, solarSystemId, bubbleId, ballId, isEntering):
     42         if self.IsInvalid():
     43             return
     44         if bubbleId == self.bubbleId:
     45             self.behaviorTree.RequestReset(requestedBy=self)
     46 
     47     def GetServiceManager(self):
     48         return sm
     49 
     50 
     51 class BallEnteredOrLeftBubbleGroupMonitor(Task, GroupTaskMixin):
     52 
     53     @TimedFunction('behaviors::monitors::ballparks::BallEnteredOrLeftBubbleGroupMonitor::OnEnter')
     54     def OnEnter(self):
     55         self.bubbleIdSet = self.GetMemberBubbleSet()
     56         self.GetServiceManager().RegisterForNotifyEvent(self, PROXIMITY_EVENT)
     57         for bubbleId in self.bubbleIdSet:
     58             self.context.ballpark.SetBubbleEvents(bubbleId, True)
     59 
     60         self.SetStatusToSuccess()
     61 
     62     def CleanUp(self):
     63         if not self.IsInvalid():
     64             self.GetServiceManager().UnregisterForNotifyEvent(self, PROXIMITY_EVENT)
     65             for bubbleId in self.bubbleIdSet:
     66                 self.context.ballpark.SetBubbleEvents(bubbleId, False)
     67 
     68         self.SetStatusToInvalid()
     69 
     70     @TimedFunction('behaviors::monitors::ballparks::BallEnteredOrLeftBubbleGroupMonitor::DoBubbleProximity')
     71     def DoBubbleProximity(self, solarSystemId, bubbleId, ballId, isEntering):
     72         if self.IsInvalid():
     73             return
     74         if bubbleId in self.bubbleIdSet:
     75             self.behaviorTree.RequestReset(requestedBy=self)
     76 
     77     def GetServiceManager(self):
     78         return sm
     79 
     80 
     81 class TargetChangingBubbleMonitor(BubbleChangedMonitor):
     82 
     83     def DoBubbleProximity(self, solarSystemId, bubbleId, ballId, isEntering):
     84         if self.IsInvalid():
     85             return
     86         if bubbleId != self.bubbleId:
     87             return
     88         if isEntering != self.attributes.resetOnEnter:
     89             return
     90         targetId = self.GetLastBlackboardValue(self.attributes.targetAddress)
     91         if ballId != targetId:
     92             return
     93         logger.debug('Target %s is %s my bubble', ballId, 'entering' if isEntering else 'leaving')
     94         self.behaviorTree.RequestReset(requestedBy=self)
     95 
     96 
     97 class TargetWithOwnerEnteredBubbleMonitor(Task):
     98 
     99     def __init__(self, attributes = None):
    100         super(TargetWithOwnerEnteredBubbleMonitor, self).__init__(attributes)
    101         self.bubbleIdSet = None
    102 
    103     @TimedFunction('behaviors::monitors::ballparks::TargetWithOwnerEnteredBubbleMonitor::OnEnter')
    104     def OnEnter(self):
    105         self.bubbleIdSet = None
    106         if self.attributes.ownerIds:
    107             self.bubbleIdSet = self.GetBubbleIdSet()
    108             self.bubbleIdSet.update(self.GetBubbleIdSet())
    109             self.SubscribeToBubbleEnter()
    110         self.SetStatusToSuccess()
    111 
    112     def CleanUp(self):
    113         if not self.IsInvalid() and self.attributes.ownerIds:
    114             self.UnsubscribeFromBubbleEnter()
    115         self.SetStatusToInvalid()
    116 
    117     def SubscribeToBubbleEnter(self):
    118         for bubbleId in self.bubbleIdSet:
    119             self.SubscribeBubbleProximityEntered(bubbleId)
    120             self.context.ballpark.SetBubbleEvents(bubbleId, True)
    121 
    122     def SubscribeBubbleProximityEntered(self, bubbleId):
    123         messenger = self.GetEventMessenger()
    124         messenger.SubscribeBubble(bubbleId, MESSAGE_ON_BUBBLE_PROXIMITY_ENTERED, self.OnBubbleEntered)
    125 
    126     def UnsubscribeFromBubbleEnter(self):
    127         if self.bubbleIdSet is None:
    128             return
    129         for bubbleId in self.bubbleIdSet:
    130             self.UnsubscribeBubbleProximityEntered(bubbleId)
    131             self.context.ballpark.SetBubbleEvents(bubbleId, False)
    132 
    133         self.bubbleIdSet = None
    134 
    135     def UnsubscribeBubbleProximityEntered(self, bubbleId):
    136         messenger = self.GetEventMessenger()
    137         messenger.UnsubscribeBubble(bubbleId, MESSAGE_ON_BUBBLE_PROXIMITY_ENTERED, self.OnBubbleEntered)
    138 
    139     @TimedFunction('behaviors::monitors::ballparks::TargetWithOwnerEnteredBubbleMonitor::OnBubbleEntered')
    140     def OnBubbleEntered(self, ballId):
    141         if self.IsInvalid():
    142             return
    143         ballpark = self.context.ballpark
    144         slimItem = ballpark.slims.get(ballId)
    145         if slimItem and slimItem.ownerID not in self.attributes.ownerIds:
    146             return
    147         logger.debug('Target %s with owner %s is entering bubble %s', ballId, slimItem.ownerID, ballpark.balls[ballId].newBubbleId)
    148         targetSet = self.GetLastBlackboardValue(self.attributes.targetSetAddress) or set()
    149         if ballId not in targetSet:
    150             targetSet.add(ballId)
    151             self.SendBlackboardValue(self.attributes.targetSetAddress, targetSet)
    152 
    153     def GetBubbleIdSet(self):
    154         return {self.context.myBall.newBubbleId}
    155 
    156 
    157 class TargetsWithOwnerEnteredBubbleMonitor(TargetWithOwnerEnteredBubbleMonitor, GroupTaskMixin):
    158 
    159     def GetBubbleIdSet(self):
    160         return self.GetMemberBubbleSet()
    161 
    162 
    163 class TargetLeavingParkMonitor(Task):
    164 
    165     @TimedFunction('behaviors::monitors::ballparks::TargetLeavingParkMonitor::OnEnter')
    166     def OnEnter(self):
    167         self.targetId = self.GetLastBlackboardValue(self.attributes.targetAddress)
    168         self.context.ballpark.eventMessenger.SubscribeItem(self.targetId, MESSAGE_ON_ITEM_REMOVED_FROM_PARK, self._OnItemLeavingPark)
    169         self.status = status.TaskSuccessStatus
    170 
    171     def CleanUp(self):
    172         if not self.IsInvalid():
    173             self.SetStatusToInvalid()
    174             self.context.ballpark.eventMessenger.UnsubscribeItem(self.targetId, MESSAGE_ON_ITEM_REMOVED_FROM_PARK, self._OnItemLeavingPark)
    175 
    176     def _OnItemLeavingPark(self, itemId):
    177         targetId = self.GetLastBlackboardValue(self.attributes.targetAddress)
    178         if itemId != targetId:
    179             return
    180         if self.attributes.clearValue:
    181             self.SendBlackboardValue(self.attributes.targetAddress, None)
    182         self.behaviorTree.RequestReset(requestedBy=self)
    183 
    184 
    185 class MonitorProximitySensors(Task):
    186 
    187     def __init__(self, attributes = None):
    188         super(MonitorProximitySensors, self).__init__(attributes)
    189         self.proximitySensorIds = set()
    190         self.bubbleIdSet = None
    191         self.tags = set()
    192 
    193     @TimedFunction('behaviors::monitors::ballparks::MonitorProximitySensors::OnEnter')
    194     def OnEnter(self):
    195         self._SetTags()
    196         self.proximitySensorIds.clear()
    197         super(MonitorProximitySensors, self).OnEnter()
    198         self.SetBubbleIdSet(self.GetBubbleIdSet())
    199         proximitySensors = self.FindProximitySensorsForBubbleSet()
    200         itemIds = self.FindItemsInSensorRange(proximitySensors)
    201         self.ClassifyItems(itemIds)
    202         self.SubscribeToProximitySensor(proximitySensors)
    203         self.SetStatusToSuccess()
    204 
    205     def _SetTags(self):
    206         tags = getattr(self.attributes, 'tags', None) or []
    207         self.tags = get_behavior_sensor_tags(self.context, tags)
    208 
    209     def ClassifyItems(self, itemIds):
    210         update_blackboard_set_if_changed(self, itemIds, self.attributes.objectListAddress)
    211 
    212     def CleanUp(self):
    213         if not self.IsInvalid():
    214             self.UnsubscribeProximitySensors()
    215         super(MonitorProximitySensors, self).CleanUp()
    216 
    217     def UnsubscribeProximitySensors(self):
    218         for itemId in self.proximitySensorIds:
    219             self.UnsubscribeItem(itemId, MESSAGE_ON_PROXIMITY, self.OnProximityDetected)
    220 
    221         self.proximitySensorIds.clear()
    222 
    223     @TimedFunction('behaviors::monitors::ballparks::MonitorProximitySensors::FindItemsInSensorRange')
    224     def FindItemsInSensorRange(self, proximitySensors):
    225         itemIds = set()
    226         for component in proximitySensors:
    227             for itemId in component.GetBallIdsInRange():
    228                 if self.IsValidTarget(itemId):
    229                     itemIds.add(itemId)
    230 
    231         return itemIds
    232 
    233     @TimedFunction('behaviors::monitors::ballparks::MonitorProximitySensors::FindProximitySensorsInBubble')
    234     def FindProximitySensorsForBubbleSet(self):
    235         proximitySensorComponents = []
    236         for component in self.GetProximitySensors():
    237             if self.InSameBubble(component.GetBubbleId()):
    238                 proximitySensorComponents.append(component)
    239 
    240         return proximitySensorComponents
    241 
    242     def SubscribeToProximitySensor(self, proximitySensors):
    243         for sensor in proximitySensors:
    244             self.proximitySensorIds.add(sensor.itemID)
    245             self.SubscribeItem(sensor.itemID, MESSAGE_ON_PROXIMITY, self.OnProximityDetected)
    246 
    247     @TimedFunction('behaviors::monitors::ballparks::MonitorProximitySensors::GetProximitySensors')
    248     def GetProximitySensors(self):
    249         return get_proximity_sensors(self, *self.tags)
    250 
    251     def IsValidTarget(self, itemId):
    252         slim = self.context.ballpark.slims.get(itemId)
    253         if not slim:
    254             return False
    255         if self.attributes.includedCategories and slim.categoryID not in self.attributes.includedCategories:
    256             return False
    257         if self.attributes.excludedGroups and slim.groupID in self.attributes.excludedGroups:
    258             return False
    259         if self.attributes.validOwnerIds and slim.ownerID not in self.attributes.validOwnerIds:
    260             return False
    261         if self.attributes.invalidOwnerIds and slim.ownerID in self.attributes.invalidOwnerIds:
    262             return False
    263         if is_ball_cloaked(self, itemId):
    264             return False
    265         return True
    266 
    267     def OnProximityDetected(self, ballId, isEntering):
    268         uthread2.start_tasklet(self._OnProximityDetected, ballId, isEntering)
    269 
    270     def _OnProximityDetected(self, ballId, isEntering):
    271         if self.IsInvalid():
    272             return
    273         if isEntering and self.IsValidTarget(ballId):
    274             self.ClassifyItems({ballId})
    275 
    276     def InSameBubble(self, bubbleId):
    277         return bubbleId in self.bubbleIdSet
    278 
    279     def SetBubbleIdSet(self, bubbleIdSet):
    280         self.bubbleIdSet = bubbleIdSet
    281 
    282     def GetBubbleIdSet(self):
    283         return {self.context.myBall.newBubbleId}
    284 
    285 
    286 class MonitorProximitySensorsForGroupMembers(MonitorProximitySensors, GroupTaskMixin):
    287 
    288     def GetBubbleIdSet(self):
    289         return self.GetMemberBubbleSet()
    290 
    291 
    292 class MonitorSpecificProximitySensor(MonitorProximitySensors):
    293 
    294     @TimedFunction('behaviors::monitors::ballparks::MonitorSpecificProximitySensor::GetProximitySensors')
    295     def GetProximitySensors(self):
    296         proximitySensorId = self.GetLastBlackboardValue(self.attributes.proximitySensorAddress)
    297         if proximitySensorId and self.context.ballpark.HasBall(proximitySensorId):
    298             proximitySensor = get_proximity_sensor(self, proximitySensorId)
    299             return [proximitySensor]
    300         return []
    301 
    302 
    303 class MonitorSpecificProximitySensorForGroupMembers(MonitorSpecificProximitySensor, GroupTaskMixin):
    304 
    305     def GetBubbleIdSet(self):
    306         return self.GetMemberBubbleSet()
    307 
    308 
    309 class MonitorInvulnerabilityCanceledInBubble(Task):
    310 
    311     def __init__(self, attributes = None):
    312         super(MonitorInvulnerabilityCanceledInBubble, self).__init__(attributes)
    313         self.bubbleIdSet = None
    314 
    315     @TimedFunction('behaviors::monitors::ballparks::MonitorInvulnerabilityCanceledInBubble::OnEnter')
    316     def OnEnter(self):
    317         self.SubscribeToInvulnerabilityCanceledInBubbles()
    318         self.SetStatusToSuccess()
    319 
    320     def SubscribeToInvulnerabilityCanceledInBubbles(self):
    321         self.bubbleIdSet = self.GetBubbleIds()
    322         messenger = self.GetEventMessenger()
    323         for bubbleId in self.bubbleIdSet:
    324             messenger.SubscribeBubble(bubbleId, MESSAGE_INVULNERABILITY_CANCELED, self.OnInvulnerabilityCanceled)
    325 
    326     def UnsubscribeToInvulnerabilityCanceledInBubbles(self):
    327         messenger = self.GetEventMessenger()
    328         for bubbleId in self.bubbleIdSet:
    329             messenger.UnsubscribeBubble(bubbleId, MESSAGE_INVULNERABILITY_CANCELED, self.OnInvulnerabilityCanceled)
    330 
    331         self.bubbleIdSet = None
    332 
    333     def GetBubbleIds(self):
    334         return {self.context.myBall.newBubbleId}
    335 
    336     @TimedFunction('behaviors::monitors::ballparks::MonitorInvulnerabilityCanceledInBubble::OnInvulnerabilityCanceled')
    337     def OnInvulnerabilityCanceled(self, itemId, isCompleted, reason):
    338         if self.IsInvalid():
    339             return
    340         if not self.IsValidTarget(itemId):
    341             return
    342         logger.debug('Invulnerability canceled isCompleted=%s reason=%s', isCompleted, reason)
    343         self.behaviorTree.RequestReset(requestedBy=self)
    344 
    345     def IsValidTarget(self, itemId):
    346         if self.attributes.targetIdListAddress is None:
    347             return True
    348         targetIdList = self.GetLastBlackboardValue(self.attributes.targetIdListAddress)
    349         if targetIdList and itemId in targetIdList:
    350             return True
    351         return False
    352 
    353     def CleanUp(self):
    354         if not self.IsInvalid():
    355             self.UnsubscribeToInvulnerabilityCanceledInBubbles()
    356         super(MonitorInvulnerabilityCanceledInBubble, self).CleanUp()
    357 
    358 
    359 class MonitorInvulnerabilityCanceledInGroupBubbles(MonitorInvulnerabilityCanceledInBubble, GroupTaskMixin):
    360 
    361     def GetBubbleIds(self):
    362         return self.GetMemberBubbleSet()
    363 
    364 
    365 class ClearBlackboardChannelOnItemExplosion(Task):
    366 
    367     @TimedFunction('behaviors::monitors::ballparks::MonitorItemExplosion::OnEnter')
    368     def OnEnter(self):
    369         self.SetStatusToSuccess()
    370         item_id = self.GetLastBlackboardValue(self.attributes.itemIdAddress)
    371         if self.context.ballpark.HasBall(item_id):
    372             self.item_id = item_id
    373             self.SubscribeItem(item_id, MESSAGE_ON_BALLPARK_ITEM_DESTROY, self._clear_black_board_channel_on_explosion)
    374         else:
    375             self.item_id = None
    376 
    377     def _clear_black_board_channel_on_explosion(self, exploding_item_id):
    378         if exploding_item_id == self.item_id:
    379             self.SendBlackboardValue(self.attributes.blackBoardChannelAddress, None)
    380             self.behaviorTree.RequestReset(self)
    381 
    382     def CleanUp(self):
    383         if not self.IsInvalid() and self.item_id is not None:
    384             self.UnsubscribeItem(self.item_id, MESSAGE_ON_BALLPARK_ITEM_DESTROY, self._clear_black_board_channel_on_explosion)
    385         self.SetStatusToInvalid()