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

target.py (14352B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\objectives\client\objective_task\target.py
      2 import evetypes
      3 import localization
      4 import logging
      5 import threadutils
      6 import uthread2
      7 from carbon.common.script.util.format import FmtDist
      8 from carbonui.uicore import uicore
      9 import eve.client.script.parklife.states as states
     10 import log
     11 from objectives.client.objective_task.base import ObjectiveTask, ObjectiveTaskGroup
     12 from objectives.client.objective_task.generic import ProgressTask, ValueRangeTask
     13 from objectives.client.ui.objective_task_widget import ProgressBarTaskWidget
     14 from objectives.common.util import value_as_set
     15 logger = logging.getLogger('objectives')
     16 
     17 class TargetTask(ObjectiveTask):
     18     objective_task_content_id = 24
     19 
     20     def __init__(self, target = None, **kwargs):
     21         self._slim_item = None
     22         self._target = None
     23         self._slim_item_tasklet = None
     24         self._use_custom_title = bool(kwargs.get('title'))
     25         super(TargetTask, self).__init__(hidden=(not self._use_custom_title), **kwargs)
     26         self.target = target
     27 
     28     def get_values(self):
     29         result = super(TargetTask, self).get_values()
     30         result['slim_item'] = self._slim_item
     31         result['item_id'] = self.item_id
     32         result['type_id'] = self.type_id
     33         result['dungeon_object_id'] = self.dungeon_object_id
     34         return result
     35 
     36     @property
     37     def target(self):
     38         return self._target
     39 
     40     @target.setter
     41     def target(self, value):
     42         if self._target == value:
     43             return
     44         self._target = value
     45         self._slim_item = None
     46         if isinstance(self._target, dict):
     47             if self.type_id:
     48                 self._set_target_title(evetypes.GetName(self.type_id))
     49                 self.update()
     50         else:
     51             self._slim_item = self._target
     52         if self._slim_item_tasklet:
     53             self._slim_item_tasklet.kill()
     54         if self._target:
     55             self._slim_item_tasklet = uthread2.start_tasklet(self._initialize_slim_item)
     56 
     57     @property
     58     def item_id(self):
     59         if self._slim_item:
     60             return self._slim_item.itemID
     61         if self._target:
     62             return self._target.get('item_id', None)
     63 
     64     @property
     65     def type_id(self):
     66         if self._slim_item:
     67             return self._slim_item.typeID
     68         if self._target:
     69             return self._target.get('type_id', None)
     70 
     71     @property
     72     def group_id(self):
     73         if self._slim_item:
     74             return self._slim_item.groupID
     75         if self._target:
     76             return self._target.get('group_id', None)
     77 
     78     @property
     79     def dungeon_object_id(self):
     80         if self._slim_item:
     81             return getattr(self._slim_item, 'dunObjectID', None)
     82         if self._target:
     83             return self._target.get('dungeon_object_id', None)
     84 
     85     def _set_target_title(self, value):
     86         if self._use_custom_title:
     87             return
     88         if self._title == value:
     89             return
     90         self._title = value
     91         self.hidden = not bool(self._title)
     92 
     93     def _initialize_slim_item(self):
     94         while not self._slim_item:
     95             if self.item_id:
     96                 self._slim_item = sm.GetService('michelle').GetItem(self.item_id)
     97             elif self.type_id or self.group_id or self.dungeon_object_id:
     98                 self._find_target()
     99             if not self._slim_item:
    100                 uthread2.sleep(0.5)
    101 
    102         title = None
    103         if self._slim_item.nameID:
    104             title = localization.GetByMessageID(self._slim_item.nameID)
    105         elif self._slim_item.charID:
    106             try:
    107                 character_info = cfg.eveowners.Get(self._slim_item.charID)
    108                 title = character_info.name
    109             except KeyError:
    110                 pass
    111 
    112         if not title:
    113             title = evetypes.GetName(self.type_id)
    114         self._slim_item_tasklet = None
    115         self._set_target_title(title)
    116         self._set_target_highlight()
    117         self._slim_item_initialized()
    118         self.update()
    119 
    120     def _find_target(self):
    121         if self.dungeon_object_id:
    122             from nodegraph.client.getters.object import GetDungeonObject
    123             dungeon_object = GetDungeonObject(dungeon_object_id=self.dungeon_object_id).get_values()
    124             if dungeon_object:
    125                 self._slim_item = dungeon_object['slim_item']
    126         else:
    127             from nodegraph.client.getters.object import FindClosestObject
    128             target = FindClosestObject(type_id=self.type_id, group_id=self.group_id).get_values()
    129             if target and 'slim_item' in target:
    130                 self._slim_item = target['slim_item']
    131 
    132     def _set_target_highlight(self):
    133         from nodegraph.client.actions.highlights import HighlightSpaceObject
    134         self.highlight = HighlightSpaceObject(item_id=self.item_id)
    135 
    136     def _slim_item_initialized(self):
    137         pass
    138 
    139     def mouse_down(self, ui_widget):
    140         item_id = self.item_id
    141         sm.GetService('stateSvc').SetState(item_id, states.selected, 1)
    142         sm.GetService('menu').TacticalItemClicked(item_id)
    143         sm.GetService('menu').TryExpandActionMenu(item_id, ui_widget)
    144 
    145     def click(self):
    146         camera = sm.GetService('sceneManager').GetActiveSpaceCamera()
    147         if camera:
    148             camera.Track(self.item_id)
    149 
    150     def double_click(self, *args):
    151         if uicore.cmd.IsSomeCombatCommandLoaded():
    152             return
    153         if self._slim_item:
    154             sm.GetService('menu').Activate(self._slim_item)
    155 
    156     def get_context_menu(self):
    157         return sm.GetService('menu').CelestialMenu(self.item_id)
    158 
    159     def _stop(self):
    160         if self._slim_item_tasklet:
    161             self._slim_item_tasklet.kill()
    162             self._slim_item_tasklet = None
    163 
    164     @staticmethod
    165     def get_custom_task_id(target):
    166         try:
    167             if isinstance(target, dict):
    168                 return target.get('item_id') or target.get('dungeon_object_id') or target.get('type_id') or target.get('group_id') or None
    169             return target.itemID
    170         except:
    171             log.LogException()
    172             return None
    173 
    174 
    175 class TargetsTaskGroup(ObjectiveTaskGroup):
    176     TASK = TargetTask
    177     KEY = 'targets'
    178     objective_task_content_id = None
    179 
    180     def __init__(self, targets = None, **kwargs):
    181         super(TargetsTaskGroup, self).__init__(**kwargs)
    182         self._update_targets(targets)
    183 
    184     def update_value(self, key, value):
    185         super(TargetsTaskGroup, self).update_value(key, value)
    186         if key == self.KEY:
    187             self._update_targets(value)
    188 
    189     def _update_targets(self, targets):
    190         self.clear_tasks()
    191         if targets is None:
    192             targets = []
    193         elif not isinstance(targets, list):
    194             targets = [targets]
    195         for target in targets:
    196             self._add_target(target, start_task=False)
    197 
    198         self.all_tasks_added()
    199 
    200     def _get_task_by_item_id(self, item_id):
    201         if item_id in self.tasks:
    202             return self.tasks[item_id]
    203         for task in self.tasks.itervalues():
    204             if task.item_id == item_id:
    205                 return task
    206 
    207     def _add_target(self, target, start_task = False):
    208         task_id = self.TASK.get_custom_task_id(target)
    209         self.add_task(task_id=task_id, target=target, start_task=start_task)
    210 
    211 
    212 class BaseTargetsTask(ObjectiveTaskGroup):
    213     objective_task_content_id = None
    214     TASK = TargetTask
    215     __notifyevents__ = ['OnBallAdded', 'DoBallRemove']
    216 
    217     def start(self):
    218         self.clear_tasks()
    219         if self._is_active:
    220             self.update()
    221         else:
    222             super(BaseTargetsTask, self).start()
    223 
    224     def _start(self):
    225         super(BaseTargetsTask, self)._start()
    226         self._find_targets()
    227 
    228     def OnBallAdded(self, slim_item):
    229         if self._validate_target(slim_item):
    230             self._add_target(slim_item)
    231 
    232     def DoBallRemove(self, ball, *args, **kwargs):
    233         if ball is not None:
    234             self.remove_task(task_id=ball.id)
    235 
    236     def _find_targets(self):
    237         ballpark = sm.GetService('michelle').GetBallpark()
    238         if not ballpark:
    239             return
    240         for ball_id in ballpark.balls.iterkeys():
    241             if ball_id == session.shipid:
    242                 continue
    243             slim_item = ballpark.GetInvItem(ball_id)
    244             if slim_item and self._validate_target(slim_item):
    245                 self._add_target(slim_item, start_task=False)
    246 
    247         self.all_tasks_added()
    248 
    249     def _validate_target(self, slim_item):
    250         return True
    251 
    252     def _add_target(self, slim_item, start_task = True):
    253         self.add_task(task_id=slim_item.itemID, target=slim_item, start_task=start_task)
    254 
    255 
    256 class TargetsTask(BaseTargetsTask):
    257 
    258     def __init__(self, type_ids = None, group_ids = None, type_list_id = None, objective_target_groups = None, item_ids = None, dungeon_object_ids = None, *args, **kwargs):
    259         self._item_ids = value_as_set(item_ids)
    260         self._dungeon_object_ids = value_as_set(dungeon_object_ids)
    261         self._objective_target_groups = value_as_set(objective_target_groups)
    262         self._type_ids = value_as_set(type_ids)
    263         self._group_ids = value_as_set(group_ids)
    264         self._type_list_id = None
    265         self._type_ids_from_type_list = set()
    266         if type_list_id:
    267             self._update_type_list()
    268         super(TargetsTask, self).__init__(*args, **kwargs)
    269 
    270     @property
    271     def item_ids(self):
    272         return self._item_ids
    273 
    274     @item_ids.setter
    275     def item_ids(self, value):
    276         if self._item_ids == value:
    277             return
    278         self._item_ids = value_as_set(value)
    279         self._parameter_updated()
    280 
    281     @property
    282     def dungeon_object_ids(self):
    283         return self._dungeon_object_ids
    284 
    285     @dungeon_object_ids.setter
    286     def dungeon_object_ids(self, value):
    287         if self._dungeon_object_ids == value:
    288             return
    289         self._dungeon_object_ids = value_as_set(value)
    290         self._parameter_updated()
    291 
    292     @property
    293     def type_ids(self):
    294         return self._type_ids
    295 
    296     @type_ids.setter
    297     def type_ids(self, value):
    298         if self._type_ids == value:
    299             return
    300         self._type_ids = value_as_set(value)
    301         self._parameter_updated()
    302 
    303     @property
    304     def group_ids(self):
    305         return self._group_ids
    306 
    307     @group_ids.setter
    308     def group_ids(self, value):
    309         if self._group_ids == value:
    310             return
    311         self._group_ids = value_as_set(value)
    312         self._parameter_updated()
    313 
    314     @property
    315     def objective_target_groups(self):
    316         return self._objective_target_groups
    317 
    318     @objective_target_groups.setter
    319     def objective_target_groups(self, value):
    320         if self._objective_target_groups == value:
    321             return
    322         self._objective_target_groups = value_as_set(value)
    323         self._parameter_updated()
    324 
    325     @property
    326     def type_list_id(self):
    327         return self._type_list_id
    328 
    329     @type_list_id.setter
    330     def type_list_id(self, value):
    331         if self._type_list_id == value:
    332             return
    333         self._type_list_id = value
    334         self._update_type_list()
    335         self._parameter_updated()
    336 
    337     def _update_type_list(self):
    338         if not self._type_list_id:
    339             self._type_ids_from_type_list.clear()
    340         else:
    341             try:
    342                 type_ids = evetypes.GetTypeIDsByListID(self._type_list_id)
    343             except Exception as e:
    344                 logger.exception('%s: Failed to get type list', self.__class__.__name__)
    345                 return
    346 
    347             self._type_ids_from_type_list = set(type_ids)
    348 
    349     @uthread2.debounce(0.1)
    350     def _parameter_updated(self):
    351         self.clear_tasks()
    352         if self.is_active:
    353             self._find_targets()
    354             self.update()
    355 
    356     def _validate_target(self, slim_item):
    357         if self._objective_target_groups and getattr(slim_item, 'objectiveTargetGroup', None) in self._objective_target_groups:
    358             return True
    359         if self._type_ids and getattr(slim_item, 'typeID', None) in self._type_ids:
    360             return True
    361         if self._group_ids and getattr(slim_item, 'groupID', None) in self._group_ids:
    362             return True
    363         if self._type_ids_from_type_list and getattr(slim_item, 'typeID', None) in self._type_ids_from_type_list:
    364             return True
    365         if self._item_ids and getattr(slim_item, 'itemID', None) in self._item_ids:
    366             return True
    367         if self._dungeon_object_ids and getattr(slim_item, 'dunObjectID', None) in self._dungeon_object_ids:
    368             return True
    369         return False
    370 
    371 
    372 class GetWithinRangeTask(TargetTask):
    373     objective_task_content_id = 7
    374     WIDGET = ProgressBarTaskWidget
    375 
    376     def __init__(self, distance = 500, **kwargs):
    377         self._distance = distance
    378         self._target_ball = None
    379         self._max_distance = distance + 1
    380         self._distance_to_target = self._max_distance
    381         super(GetWithinRangeTask, self).__init__(**kwargs)
    382 
    383     @property
    384     def distance(self):
    385         return self._distance
    386 
    387     @distance.setter
    388     def distance(self, value):
    389         if self._distance == value:
    390             return
    391         self._distance = value
    392         self._max_distance = max(self._max_distance, self._distance + 1)
    393         self.update()
    394 
    395     def _slim_item_initialized(self):
    396         super(GetWithinRangeTask, self)._slim_item_initialized()
    397         ballpark = sm.GetService('michelle').GetBallpark()
    398         self._target_ball = ballpark.GetBall(self.item_id)
    399         self._update_distance_routine()
    400 
    401     @threadutils.threaded
    402     def _update_distance_routine(self):
    403         while self.is_active:
    404             value = max(0, self._target_ball.surfaceDist - self.distance)
    405             if self._distance_to_target != value:
    406                 self._distance_to_target = value
    407                 self._max_distance = max(self._max_distance, self._distance_to_target)
    408                 self.update()
    409                 self.completed = self._distance_to_target == 0
    410             uthread2.sleep(1)
    411 
    412     @property
    413     def progress(self):
    414         return 1.0 - min(self._distance_to_target / float(self._max_distance), 1.0)
    415 
    416     @property
    417     def value(self):
    418         return FmtDist(self._distance_to_target, 0)
    419 
    420 
    421 class TargetWithProgressTask(TargetTask, ProgressTask):
    422     objective_task_content_id = 32
    423     WIDGET = ProgressBarTaskWidget
    424 
    425 
    426 class TargetWithValueRangeTask(TargetTask, ValueRangeTask):
    427     objective_task_content_id = 43
    428     WIDGET = ProgressBarTaskWidget