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

entityspawning.py (11928B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\behaviors\actions\entityspawning.py
      2 from ballpark.entities.spawndataforentities import get_spawn_data_for_entities
      3 from ballpark.locationgenerator import GetRandomDeepSpaceLocation
      4 from behaviors.const.blackboardchannels import GUARD_OBJECT_ITEM_ID
      5 from behaviors.groups.mixin import GroupTaskMixin
      6 from behaviors.tasks import Task
      7 from behaviors.utility.awareness import get_spawn_pool_id, get_awareness_config
      8 from behaviors.utility.context import get_extra_context
      9 from behaviors.utility.groups import get_entity_group_member_count
     10 from behaviors.utility.owner import get_owner_id
     11 from behaviors.utility.spawning import EntityGetter, EntityGetterBySpawnlistAndOwner, EntityGetterFromSpawnPointPool
     12 from behaviors.utility.spawning import get_spawn_point_pool_manager
     13 from behaviors.utility.spawning import EntitySpawner, EntitySpawnerWithUndock
     14 from behaviors.utility.spawning import EntitySpawnTableSpawner
     15 from ccpProfile import TimedFunction
     16 from npcs.server.npcspawning.reactivespawn_counters import get_npc_fleet_type
     17 from npcs.server.npcspawning.reactivespawning import ReactiveSpawnConfig
     18 import logging
     19 logger = logging.getLogger(__name__)
     20 
     21 class RegisterSpawnPool(Task):
     22 
     23     @TimedFunction('behaviors::actions::entityspawning::RegisterSpawnPool::OnEnter')
     24     def OnEnter(self):
     25         max_spawn_points = self.attributes.maxSpawnPoints
     26         if not max_spawn_points:
     27             self.SetStatusToFailed()
     28             return
     29         initial_spawn_points = self._get_initial_spawn_points()
     30         spawn_point_pool_id = self._assign_spawn_pool(max_spawn_points, initial_spawn_points)
     31         logger.debug('Registering spawn pool %s', spawn_point_pool_id)
     32         self._post_spawn_point_pool(spawn_point_pool_id)
     33         self.SetStatusToSuccess()
     34 
     35     def _get_initial_spawn_points(self):
     36         return getattr(self.attributes, 'initialSpawnPoints', None)
     37 
     38     def _assign_spawn_pool(self, max_spawn_points, initial_spawn_points):
     39         spawn_point_pool_manager = self._get_spawn_point_pool_manager()
     40         spawn_point_pool_id = spawn_point_pool_manager.register_new_spawn_point_pool(max_spawn_points, initial_spawn_points)
     41         return spawn_point_pool_id
     42 
     43     def _get_spawn_point_pool_manager(self):
     44         return self.context.entityLocation.GetSpawnPoolManager()
     45 
     46     def _post_spawn_point_pool(self, spawn_point_pool_id):
     47         self.SendBlackboardValue(self.attributes.spawnPoolIdAddress, spawn_point_pool_id)
     48 
     49 
     50 class SpawnNewEntities(Task, GroupTaskMixin):
     51 
     52     @TimedFunction('behaviors::actions::entityspawning::SpawnNewEntities::OnEnter')
     53     def OnEnter(self):
     54         self.SetStatusToFailed()
     55         entity_getter = self._get_entity_getter()
     56         entity_spawner = self._get_entity_spawner()
     57         existing_entity_group_id = entity_spawner.get_group_id()
     58         max_npc_count = self._get_max_npc_count_for_group(existing_entity_group_id)
     59         spawn_data_for_entities = entity_getter.get_spawn_data_for_entities(max_npc_count=max_npc_count)
     60         if spawn_data_for_entities:
     61             group, entity_item_ids = entity_spawner.spawn_new_entities(spawn_data_for_entities)
     62             self._update_group(group.GetID(), len(entity_item_ids), existing_entity_group_id)
     63             entity_getter.on_spawn_entities(group.GetID())
     64             self.SetStatusToSuccess()
     65         else:
     66             logger.debug('No entities to spawn. group_id=%s max_npc_count=%s', existing_entity_group_id, max_npc_count)
     67 
     68     def _get_entity_getter(self):
     69         return EntityGetter(self)
     70 
     71     def _get_entity_spawner(self):
     72         return EntitySpawner(self)
     73 
     74     def _update_group(self, entity_group_id, entity_count, existing_entity_group_id):
     75         self._update_reinforcements_for_group(entity_count, existing_entity_group_id)
     76         self._register_entity_group_with_blackboard(entity_group_id)
     77         self._update_group_blackboard_channels(entity_group_id)
     78 
     79     def _update_reinforcements_for_group(self, entity_count, existing_entity_group_id):
     80         if existing_entity_group_id is None:
     81             return
     82         reinforcement_manager = self._get_reinforcement_manager()
     83         reinforced_group = reinforcement_manager.GetReinforcedGroup(existing_entity_group_id)
     84         if not reinforced_group:
     85             return
     86         old_count = reinforced_group.GetFullStrengthCount()
     87         reinforced_group.SetEntityUnitCount(old_count + entity_count)
     88 
     89     def _get_reinforcement_manager(self):
     90         return self.context.entityLocation.reinforcementManager
     91 
     92     def _register_entity_group_with_blackboard(self, entity_group_id):
     93         if not hasattr(self.attributes, 'entityGroupSetAddress') or not self.attributes.spawnNewGroup:
     94             return
     95         entity_groups_set = self.GetLastBlackboardValue(self.attributes.entityGroupSetAddress) or set()
     96         entity_groups_set.add(entity_group_id)
     97         self.SendBlackboardValue(self.attributes.entityGroupSetAddress, entity_groups_set)
     98 
     99     def _update_group_blackboard_channels(self, entity_group_id):
    100         if self.HasAttribute('guardObjectAddress'):
    101             guard_object_item_id = self.GetLastBlackboardValue(self.attributes.guardObjectAddress)
    102             self.GetMessageChannelForGroupId(entity_group_id, GUARD_OBJECT_ITEM_ID[1]).SendMessage(guard_object_item_id)
    103 
    104     def get_spawn_pool_id(self):
    105         if self.HasAttribute('spawnPoolIdAddress'):
    106             return self.GetLastBlackboardValue(self.attributes.spawnPoolIdAddress)
    107 
    108     def get_spawn_table_id(self):
    109         if self.HasAttribute('spawnTableIdAddress'):
    110             return self.GetLastBlackboardValue(self.attributes.spawnTableIdAddress)
    111 
    112     def _get_max_npc_count_for_group(self, group_id):
    113         if not self.HasAttribute('maxNpcCount'):
    114             return
    115         max_npc_count = self.attributes.maxNpcCount
    116         if group_id is not None:
    117             group_count = get_entity_group_member_count(self, group_id)
    118             max_npc_count -= group_count
    119             if max_npc_count < 0:
    120                 max_npc_count = 0
    121         return max_npc_count
    122 
    123     def get_bounty_pay_out_multiplier(self):
    124         return getattr(self.attributes, 'bountyPayOutMultiplier', None)
    125 
    126     def get_behavior_override_id(self):
    127         return getattr(self.attributes, 'behaviorTreeName', None)
    128 
    129     def get_spawn_position(self):
    130         if getattr(self.attributes, 'spawnPositionAddress', None):
    131             return self.GetLastBlackboardValue(self.attributes.spawnPositionAddress)
    132         else:
    133             return GetRandomDeepSpaceLocation(self.context.ballpark.solarsystemID)
    134 
    135     def get_required_npc_tags(self):
    136         return getattr(self.attributes, 'npcTagList', set())
    137 
    138 
    139 class SpawnNewEntitiesBySpawnlistAndOwnerId(SpawnNewEntities):
    140 
    141     def _get_entity_getter(self):
    142         return EntityGetterBySpawnlistAndOwner(self)
    143 
    144 
    145 class SpawnEntitiesFromSpawnTable(SpawnNewEntities):
    146 
    147     def _get_entity_getter(self):
    148         return EntityGetterFromSpawnPointPool(self)
    149 
    150     def _get_entity_spawner(self):
    151         return EntitySpawnTableSpawner(self)
    152 
    153 
    154 class SpawnNewEntitiesAtStructure(SpawnNewEntities):
    155 
    156     def _get_entity_spawner(self):
    157         return EntitySpawnerWithUndock(self)
    158 
    159 
    160 class SpawnNewEntitiesAtStructureBySpawnlistAndOwnerId(SpawnNewEntitiesAtStructure):
    161 
    162     def _get_entity_getter(self):
    163         return EntityGetterBySpawnlistAndOwner(self)
    164 
    165 
    166 class SpawnNewEntitiesAtStructureFromSpawnTable(SpawnNewEntitiesAtStructure):
    167 
    168     def _get_entity_getter(self):
    169         return EntityGetterFromSpawnPointPool(self)
    170 
    171 
    172 class SendSpawnTableIdToBlackboard(Task):
    173 
    174     def OnEnter(self):
    175         self.SendBlackboardValue(self.attributes.npcSpawnTableIdAddress, self.attributes.npcSpawnTableId)
    176         self.SetStatusToSuccess()
    177 
    178 
    179 class SetSpawnPoolAmount(Task):
    180 
    181     def OnEnter(self):
    182         spawn_pool_id = get_spawn_pool_id(self)
    183         spawn_point_pool_manager = get_spawn_point_pool_manager(self)
    184         spawn_point_pool_manager.set_spawn_points(spawn_pool_id, self.attributes.spawnPointAmount)
    185         self.SetStatusToSuccess()
    186 
    187 
    188 class SetSelfEntityRespawn(Task, GroupTaskMixin):
    189 
    190     def OnEnter(self):
    191         entity_types_and_count = [(self.context.mySlimItem.typeID, 1)]
    192         spawn_data_for_entities = get_spawn_data_for_entities(entity_types_and_count, self.context.myBall.GetPosition(), self.attributes.deploymentRangeMeters, self.behaviorTree.GetBehaviorId())
    193         self.context.entityLocation.spawnManager.SetRealItemRespawn(self.context.myEntityGroupId, self.context.mySlimItem.ownerID, spawn_data_for_entities, self.attributes.minRespawnDelaySeconds, self.attributes.maxRespawnDelaySeconds)
    194         self.SetStatusToSuccess()
    195 
    196 
    197 class DisableRespawnGroup(Task, GroupTaskMixin):
    198 
    199     def OnEnter(self):
    200         self.context.entityLocation.behaviorRespawnManager.remove_respawn_group(self.context.myEntityGroupId)
    201         self.SetStatusToSuccess()
    202 
    203 
    204 class SetSpawnTableOnBlackboardByOwner(Task):
    205 
    206     def OnEnter(self):
    207         spawn_table_id = self._get_spawn_table_id()
    208         self.SendBlackboardValue(self.attributes.spawnTableIdAddress, spawn_table_id)
    209         self.SetStatusToSuccess()
    210 
    211     def _get_spawn_table_id(self):
    212         owner_id = get_owner_id(self)
    213         spawn_table_id = self.attributes.ownerToSpawnTableMapping.get(owner_id)
    214         if spawn_table_id is None:
    215             raise ValueError('Unable to find a spawn table id for owner %s' % owner_id)
    216         return spawn_table_id
    217 
    218 
    219 class ReactiveSpawning(Task):
    220 
    221     def OnEnter(self):
    222         self.SetStatusToSuccess()
    223         owner_id = get_owner_id(self)
    224         spawn_config = self._get_spawn_config(owner_id)
    225         reactive_spawn_manager = self.context.entityLocation.reactiveSpawnManager
    226         reactive_spawn_manager.start_spawner(spawn_config)
    227         self._post_spawn_pool_id(spawn_config.spawn_point_pool_id)
    228         reactive_spawn_manager.deregister_when_spawner_is_destroyed(spawn_config, self.context.entityLocation.event_handler_registry)
    229         logger.debug('behavior::entity_spawning::Behavior=%s initialized reactive spawn task with config=%s', self.behaviorTree.GetBehaviorId(), spawn_config)
    230 
    231     def get_member_collection_id(self):
    232         return self.context.myEntityGroupId
    233 
    234     def _get_spawn_config(self, owner_id):
    235         spawn_config = ReactiveSpawnConfig(owner_id, self.get_spawn_table_id(), self.attributes.npcFleetCounterTableId, get_awareness_config(self), initial_point_amount=self.attributes.initialPointAmount, min_point_amount=self.attributes.minPointAmount, max_point_amount=self.attributes.maxPointAmount, extra_context=get_extra_context(self), capped_spawn_points=self.attributes.cappedSpawnPoints, should_spawn_without_threats=self.attributes.spawnWithoutThreats, should_reset_without_threats=self.attributes.resetWithoutThreats, spawn_point_multiplier=self.attributes.spawnPointMultiplier, initial_spawn_npc_fleet_type_id=getattr(self.attributes, 'initialSpawnNpcFleetTypeID', None), min_spawn_interval_seconds=self.attributes.minSpawnIntervalSeconds, max_spawn_interval_seconds=self.attributes.maxSpawnIntervalSeconds, spawner_item_id=self.context.mySlimItem.itemID, bounty_payout_multiplier=self.attributes.bountyPayoutMultiplier, should_match_player_points=self.attributes.shouldMatchPlayerPoints, spawn_point_threshold=self.attributes.spawnPointThreshold)
    236         return spawn_config
    237 
    238     def get_spawn_table_id(self):
    239         return self.GetLastBlackboardValue(self.attributes.spawnTableIdAddress)
    240 
    241     def _post_spawn_pool_id(self, spawn_pool_id):
    242         self.SendBlackboardValue(self.attributes.spawnPoolIdAddress, spawn_pool_id)
    243 
    244     def _has_initial_spawn_npc_fleet_type_id(self):
    245         return hasattr(self.attributes, 'initialSpawnNpcFleetTypeID') and self.attributes.initialSpawnNpcFleetTypeID is not None
    246 
    247     def _get_initial_spawn_npc_fleet_type(self):
    248         return get_npc_fleet_type(self.attributes.initialSpawnNpcFleetTypeID)