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

component.py (13705B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\cosmetics\common\ships\skins\static_data\component.py
      2 from evetypes import TypeNotFoundException
      3 import chroma
      4 import logging
      5 import sys
      6 import evetypes
      7 from itertoolsext.Enum import Enum
      8 from cosmetics.common.ships.skins.static_data.ntc import ntc
      9 from cosmetics.common.ships.skins.static_data.component_finish import get_finish_from_fsd
     10 from cosmetics.common.ships.skins.live_data.component_license_type import ComponentLicenseType
     11 from cosmetics.common.ships.skins.static_data.component_point_value import ComponentPointValuesTable
     12 from inventorycommon.const import groupShipSkinDesignComponents
     13 from localization import GetByMessageID
     14 from fsdBuiltData.common.base import BuiltDataLoader
     15 from cosmetics.common.ships.skins.static_data.component_category import get_category_from_fsd, ComponentCategory
     16 from cosmetics.common.ships.skins.static_data.component_rarity import get_rarity_from_fsd, ComponentRarityLevel
     17 from cosmetics.common.ships.skins.static_data.slot_name import SlotID
     18 COMPONENT_ITEM_INFINITE_USES_GRANTED = -1
     19 try:
     20     import ship_skin_design_componentsLoader
     21 except ImportError:
     22     ship_skin_design_componentsLoader = None
     23 
     24 try:
     25     import ship_skin_design_components_post_processLoader
     26 except ImportError:
     27     ship_skin_design_components_post_processLoader = None
     28 
     29 log = logging.getLogger(__name__)
     30 
     31 class ComponentsPostProcessDataLoader(BuiltDataLoader):
     32     __resBuiltFile__ = 'res:/staticdata/ship_skin_design_components_post_process.fsdbinary'
     33     __clientAutobuildBuiltFile__ = 'eve/autobuild/staticData/client/ship_skin_design_components_post_process.fsdbinary'
     34     __serverAutobuildBuiltFile__ = 'eve/autobuild/staticData/server/ship_skin_design_components_post_process.fsdbinary'
     35     __loader__ = ship_skin_design_components_post_processLoader
     36 
     37     @classmethod
     38     def get_hex_color_by_id(cls, component_id):
     39         components_post_process_data = cls.GetData()
     40         if not components_post_process_data:
     41             log.error('GetData() returned None in ComponentsPostProcessDataLoader.get_hex_color_by_id')
     42             return
     43         component_color_hex = components_post_process_data.get(component_id, None)
     44         if component_color_hex is None:
     45             log.error('component id %s not found in ComponentsPostProcessDataLoader' % component_id)
     46         return component_color_hex
     47 
     48 
     49 class ComponentsDataLoader(BuiltDataLoader):
     50     __resBuiltFile__ = 'res:/staticdata/ship_skin_design_components.fsdbinary'
     51     __clientAutobuildBuiltFile__ = 'eve/autobuild/staticData/client/ship_skin_design_components.fsdbinary'
     52     __serverAutobuildBuiltFile__ = 'eve/autobuild/staticData/server/ship_skin_design_components.fsdbinary'
     53     __loader__ = ship_skin_design_componentsLoader
     54     _components_by_id = None
     55     _is_initialized = False
     56 
     57     @classmethod
     58     def ReloadDataFromDisk(cls):
     59         cls._components_by_id = None
     60         cls._is_initialized = False
     61 
     62     @classmethod
     63     def get_component_data(cls, component_id):
     64         cls._check_init_components_by_id()
     65         return cls._components_by_id.get(component_id, None)
     66 
     67     @classmethod
     68     def get_components_data(cls, category_filter = None, slot_internal_name_filter = None):
     69         cls._check_init_components_by_id()
     70         result = {}
     71         for component_id, component_data in cls._components_by_id.items():
     72             if (category_filter is None or component_data.category in category_filter) and (slot_internal_name_filter is None or slot_internal_name_filter not in component_data.disallowed_slot_ids):
     73                 result[component_id] = component_data
     74 
     75         return result
     76 
     77     @classmethod
     78     def load_components_data(cls):
     79         cls._check_init_components_by_id()
     80 
     81     @classmethod
     82     def _check_init_components_by_id(cls):
     83         if cls._is_initialized:
     84             return
     85         log.info('SKIN COMPONENT LICENSES MANAGEMENT - Start loading component data')
     86         cls._components_by_id = {}
     87         components_data = ComponentsDataLoader.GetData()
     88         if not components_data:
     89             log.info('SKIN COMPONENT LICENSES MANAGEMENT - Component data unavailable, will try again later')
     90             return
     91         for component_id, component_data in components_data.items():
     92             cls._components_by_id[component_id] = ComponentData.build_from_fsd(component_id, component_data, ComponentPointValuesTable())
     93 
     94         cls._is_initialized = True
     95         log.info('SKIN COMPONENT LICENSES MANAGEMENT - Finished loading component data')
     96 
     97     @classmethod
     98     def ReloadDataFromDisk(cls):
     99         super(ComponentsDataLoader, cls).ReloadDataFromDisk()
    100         cls._components_by_id = None
    101 
    102     @classmethod
    103     def get_component_for_component_type(cls, component_type_id):
    104         try:
    105             group_id = evetypes.GetGroupID(component_type_id)
    106         except TypeNotFoundException:
    107             return None
    108 
    109         if group_id != groupShipSkinDesignComponents:
    110             log.warning('type id %s must be of group %s to be matched to a ship skin component' % (component_type_id, groupShipSkinDesignComponents))
    111         components = cls.get_components_data()
    112         for component_id, component_data in components.items():
    113             item_data = component_data.component_item_data_by_type_id.get(component_type_id)
    114             if item_data:
    115                 return component_data
    116 
    117         log.warning('could not match type id %s to any component id' % component_type_id)
    118 
    119     @classmethod
    120     def get_component_item_for_component_type(cls, component_type_id):
    121         component_data = cls.get_component_for_component_type(component_type_id)
    122         if component_data:
    123             item_data = component_data.component_item_data_by_type_id.get(component_type_id)
    124             return item_data
    125 
    126 
    127 class ComponentData(object):
    128 
    129     def __init__(self, component_id, internal_name, name_id, description_id, origin_event_id, category, rarity, finish, resource_file_path, icon_file_path, disallowed_slot_ids, associated_type_ids, sequence_binder_type_id, sequence_binder_required_amount, points_value, projection_type_uv, published):
    130         self._color_shade_sort_index = sys.maxint
    131         log.info('ComponentData init  - component_id: {component_id} name_id: {name_id} icon_file_path: {icon_file_path}'.format(component_id=component_id, name_id=name_id, icon_file_path=icon_file_path))
    132         component_color_hex = ComponentsPostProcessDataLoader.get_hex_color_by_id(component_id)
    133         if component_color_hex is None:
    134             log.warning('None returned by get_hex_color_by_id for component_id: {component_id} name_id: {name_id} icon_file_path: {icon_file_path} ComponentData init  - resource_file_path: {resource_file_path}'.format(component_id=component_id, name_id=name_id, resource_file_path=resource_file_path, icon_file_path=icon_file_path))
    135         else:
    136             color_shade_name = ntc.shade_name_from_hex(component_color_hex)
    137             color_order_list = ['Red',
    138              'Orange',
    139              'Yellow',
    140              'Green',
    141              'Blue',
    142              'Violet',
    143              'Brown',
    144              'Black',
    145              'Grey',
    146              'White']
    147             self._color_shade_sort_index = color_order_list.index(color_shade_name)
    148             apply_secondary_hue_sort = True
    149             if apply_secondary_hue_sort:
    150                 hue, s, l = chroma.hex_to_hsl(component_color_hex)
    151                 self._color_shade_sort_index *= 1000
    152                 self._color_shade_sort_index += int(float(hue) * 360.0)
    153             log.info('color_shade_name: {color_shade_name} color_shade_sort_index: {color_shade_sort_index} ComponentData init - component_id: {component_id} name_id: {name_id} resource_file_path: {resource_file_path}'.format(component_id=component_id, name_id=name_id, resource_file_path=resource_file_path, color_shade_name=color_shade_name, color_shade_sort_index=self._color_shade_sort_index))
    154         self._component_id = component_id
    155         self._internal_name = internal_name
    156         self._name_id = name_id
    157         self._description_id = description_id
    158         self._origin_event_id = origin_event_id
    159         self._category = category
    160         self._rarity = rarity
    161         self._finish = finish
    162         self._resource_file_path = resource_file_path
    163         self._icon_file_path = icon_file_path
    164         self._disallowed_slot_ids = disallowed_slot_ids
    165         self._component_item_data_by_type_id = associated_type_ids
    166         self._sequence_binder_type_id = sequence_binder_type_id
    167         self._sequence_binder_required_amount = sequence_binder_required_amount
    168         self._points_value = points_value
    169         self._projection_type_uv = projection_type_uv
    170         self._published = published
    171 
    172     @property
    173     def color_shade_sort_index(self):
    174         return self._color_shade_sort_index
    175 
    176     @property
    177     def component_id(self):
    178         return self._component_id
    179 
    180     @property
    181     def internal_name(self):
    182         return self._internal_name
    183 
    184     @property
    185     def name(self):
    186         return GetByMessageID(self._name_id)
    187 
    188     @property
    189     def description(self):
    190         return GetByMessageID(self._description_id)
    191 
    192     @property
    193     def origin_event_name(self):
    194         if self._origin_event_id:
    195             return GetByMessageID(self._origin_event_id)
    196 
    197     @property
    198     def category(self):
    199         return self._category
    200 
    201     @property
    202     def rarity(self):
    203         return self._rarity
    204 
    205     @property
    206     def finish(self):
    207         return self._finish
    208 
    209     @property
    210     def resource_file_path(self):
    211         return self._resource_file_path
    212 
    213     @property
    214     def icon_file_path(self):
    215         return self._icon_file_path
    216 
    217     @property
    218     def disallowed_slot_ids(self):
    219         return self._disallowed_slot_ids
    220 
    221     @property
    222     def projection_type_uv(self):
    223         return self._projection_type_uv
    224 
    225     @property
    226     def component_item_data_by_type_id(self):
    227         return self._component_item_data_by_type_id
    228 
    229     @property
    230     def sequence_binder_type_id(self):
    231         return self._sequence_binder_type_id
    232 
    233     @property
    234     def sequence_binder_required_amount(self):
    235         return self._sequence_binder_required_amount
    236 
    237     @property
    238     def published(self):
    239         return self._published
    240 
    241     @property
    242     def points_value(self):
    243         return self._points_value
    244 
    245     def get_license_type(self, type_id):
    246         component_item = self.component_item_data_by_type_id.get(type_id, None)
    247         if component_item:
    248             return component_item.license_type
    249 
    250     def get_item_type(self, license_type):
    251         for type_id, component_item in self.component_item_data_by_type_id.items():
    252             if component_item.license_type == license_type:
    253                 return type_id
    254 
    255     @staticmethod
    256     def build_from_fsd(component_id, fsd_data, points_value_table):
    257         internal_name = fsd_data.internal_name
    258         name_id = fsd_data.name
    259         description_id = fsd_data.description
    260         origin_event_id = fsd_data.origin_event
    261         category = get_category_from_fsd(fsd_data.category)
    262         rarity = get_rarity_from_fsd(fsd_data.rarity)
    263         finish = get_finish_from_fsd(fsd_data.finish)
    264         resource_file_path = fsd_data.resource_file
    265         icon_file_path = fsd_data.icon_file
    266         disallowed_slot_ids = [ x for x in fsd_data.disallowed_slots ]
    267         associated_type_ids = {x.type_id:ComponentItemData(component_id, category, x.type_id, x.license_uses_granted) for x in fsd_data.associated_type_ids}
    268         sequence_binder_type_id = fsd_data.sequence_binder.item_type_id
    269         sequence_binder_required_amount = fsd_data.sequence_binder.count
    270         points_value = points_value_table.get_point_value(category, rarity)
    271         projection_type_uv = [projection_type_from_fsd(fsd_data.projection_type_u), projection_type_from_fsd(fsd_data.projection_type_v)]
    272         published = fsd_data.published
    273         return ComponentData(component_id, internal_name, name_id, description_id, origin_event_id, category, rarity, finish, resource_file_path, icon_file_path, disallowed_slot_ids, associated_type_ids, sequence_binder_type_id, sequence_binder_required_amount, points_value, projection_type_uv, published)
    274 
    275 
    276 class ComponentItemData(object):
    277 
    278     def __init__(self, component_id, category, type_id, license_uses_granted):
    279         self._component_id = component_id
    280         self._category = category
    281         self._type_id = type_id
    282         self._license_uses_granted = license_uses_granted if license_uses_granted > 0 else COMPONENT_ITEM_INFINITE_USES_GRANTED
    283 
    284     @property
    285     def component_id(self):
    286         return self._component_id
    287 
    288     @property
    289     def category(self):
    290         return self._category
    291 
    292     @property
    293     def type_id(self):
    294         return self._type_id
    295 
    296     @property
    297     def license_uses_granted(self):
    298         return self._license_uses_granted
    299 
    300     @property
    301     def license_type(self):
    302         if self._license_uses_granted == COMPONENT_ITEM_INFINITE_USES_GRANTED:
    303             return ComponentLicenseType.UNLIMITED
    304         else:
    305             return ComponentLicenseType.LIMITED
    306 
    307 
    308 @Enum
    309 
    310 class PatternProjectionType(object):
    311     CLAMP = 0
    312     REPEAT = 1
    313     BORDER = 2
    314 
    315 
    316 _PROJECTION_TYPE_FSD_MAPPING = {'Clamp': PatternProjectionType.CLAMP,
    317  'Repeat': PatternProjectionType.REPEAT,
    318  'Border': PatternProjectionType.BORDER}
    319 _PROJECTION_TYPE_TO_FSD_MAPPING = {PatternProjectionType.CLAMP: 'Clamp',
    320  PatternProjectionType.REPEAT: 'Repeat',
    321  PatternProjectionType.BORDER: 'Border'}
    322 
    323 def projection_type_from_fsd(fsd_value):
    324     return _PROJECTION_TYPE_FSD_MAPPING.get(fsd_value, None)
    325 
    326 
    327 def projection_type_to_fsd(value):
    328     return _PROJECTION_TYPE_TO_FSD_MAPPING.get(value, None)