def AddEntry(self, info): confirmOnDblClick = self.minChoices == self.maxChoices == 1 if self.listtype in ('character', 'corporation', 'alliance', 'faction', 'owner'): name, itemID, typeID = info typeExists = False if typeID: typeExists = evetypes.Exists(typeID) if not typeExists: owner = cfg.eveowners.GetIfExists(itemID) if owner: typeExists = evetypes.Exists(owner.typeID) if typeExists: charID = itemID if util.IsCharacter(charID) and util.IsNPC(charID): entryType = 'AgentEntry' else: entryType = 'User' return (40, listentry.Get(entryType, {'charID': charID, 'OnDblClick': self.DblClickEntry, 'OnClick': self.ClickEntry, 'dblconfirm': confirmOnDblClick, 'charIndex': name})) else: if self.listtype in ('pickStation',): data = info data.confirmOnDblClick = confirmOnDblClick data.OnDblClick = self.DblClickEntry data.OnClick = self.ClickEntry return (32, listentry.Get('Generic', data=data)) if self.listtype == 'generic': name, listvalue = info data = util.KeyVal() data.confirmOnDblClick = confirmOnDblClick data.label = name data.listvalue = info data.OnDblClick = self.DblClickEntry data.OnClick = self.ClickEntry return (32, listentry.Get('Generic', data=data)) name, itemID, typeID = info data = util.KeyVal() data.confirmOnDblClick = confirmOnDblClick data.label = name data.itemID = itemID data.typeID = typeID data.listvalue = [name, itemID, typeID] data.isStation = self.listtype == 'station' data.getIcon = self.listtype == 'item' data.OnDblClick = self.DblClickEntry data.OnClick = self.ClickEntry return (24, listentry.Get('Generic', data=data))
def GetStandardLinkHint(self, url): if url.startswith('showinfo'): parsedArgs = BaseLink().ParseShowInfo(url[9:]) if not parsedArgs: return localization.GetByLabel('UI/Commands/ShowInfo') typeID, itemID, data = parsedArgs if evetypes.Exists(typeID): if evetypes.GetCategoryID(typeID) == const.categorySkill: hintText = localization.GetByLabel('UI/Common/ShowTypeInfo', groupName=evetypes.GetCategoryName(typeID)) else: hintText = localization.GetByLabel('UI/Common/ShowTypeInfo', groupName=evetypes.GetGroupName(typeID)) else: hintText = localization.GetByLabel('UI/Common/ShowInfo') return hintText if url.startswith('podGuideLink'): podGuideID = int(url[len('podGuideLink:'):]) return localization.GetByMessageID(GetTermShortText(podGuideID)) if url.startswith('accessGroup'): return '' for k, v in HINTLABELS.iteritems(): if url.startswith('%s:' % k): if v is None: return v return localization.GetByLabel(v) return url
def GetShipsAndGroups(self, filterTextLower, fittings): fittingsByGroupID = defaultdict(list) fittingsByGroupAndRaceIDs = defaultdict(lambda: defaultdict(set)) if not fittings: shipGroups, shipsByGroupID, shipsByGroupAndRaceIDs = self.GetAllShipGroupsAndShipsByGroupID( filterTextLower) else: shipGroups = set() shipsByGroupID = defaultdict(set) shipsByGroupAndRaceIDs = defaultdict(lambda: defaultdict(set)) for fittingID, fitting in fittings.iteritems(): shipTypeID = fitting.shipTypeID if not evetypes.Exists(shipTypeID): log.LogError( 'Ship in stored fittings does not exist, shipID=%s, fittingID=%s' % (shipTypeID, fittingID)) continue groupID = evetypes.GetGroupID(shipTypeID) fittingsByGroupID[groupID].append(fitting) groupName = evetypes.GetGroupName(shipTypeID) shipGroups.add((groupName, groupID)) raceID = evetypes.GetRaceID(shipTypeID) shipsByGroupAndRaceIDs[groupID][raceID].add(shipTypeID) fittingsByGroupAndRaceIDs[groupID][raceID].add(fitting) return (fittingsByGroupID, shipsByGroupID, shipGroups, shipsByGroupAndRaceIDs, fittingsByGroupAndRaceIDs)
def GetShipGroupSubContent(self, nodedata, *args): scrolllist = [] fittingsByType = defaultdict(list) fittingNumByTypeID = nodedata.fittingNumByTypeID for fitting in nodedata.fittings: shipTypeID = fitting.shipTypeID if not evetypes.Exists(shipTypeID): log.LogError( 'Ship in stored fittings does not exist, shipID=%s, fittingID=%s' % (shipTypeID, fitting.fittingID)) continue fittingsByType[shipTypeID].append(fitting) allShips = nodedata.allShips for typeID in allShips: typeName = evetypes.GetName(typeID) numPersonal = fittingNumByTypeID[typeID][False] numCorp = fittingNumByTypeID[typeID][True] fittingsForType = fittingsByType.get(typeID, []) entry = self.GetShipTypeGroup(typeID, typeName, fittingsForType, numPersonal, numCorp) scrolllist.append((typeName, entry)) scrolllist = SortListOfTuples(scrolllist) return scrolllist
def GetShipGroupSubContent(self, nodedata, *args): scrolllist = [] fittingsByType = {} shipTypes = [] for fitting in nodedata.fittings: shipTypeID = fitting.shipTypeID if not evetypes.Exists(shipTypeID): log.LogError( 'Ship in stored fittings does not exist, shipID=%s, fittingID=%s' % (shipTypeID, fitting.fittingID)) continue if shipTypeID not in fittingsByType: fittingsByType[shipTypeID] = [] fittingsByType[shipTypeID].append(fitting) typeName = evetypes.GetName(shipTypeID) if (typeName, shipTypeID) not in shipTypes: shipTypes.append((typeName, shipTypeID)) shipTypes.sort() for typeName, typeID in shipTypes: data = util.KeyVal() data.GetSubContent = self.GetFittingSubContent data.label = typeName data.groupItems = fittingsByType[typeID] data.fittings = fittingsByType[typeID] data.id = ('fittingMgmtScrollWndType', typeName) data.sublevel = 1 data.showicon = 'hide' data.state = 'locked' scrolllist.append(listentry.Get('Group', data=data)) return scrolllist
def DrawFittings(self, *args): scrolllist = [] fittings = self.fittingSvc.GetFittings(self.ownerID).items() self.EnableExportButton(len(fittings) > 0) maxFittings = None if self.ownerID == session.charid: maxFittings = const.maxCharFittings elif self.ownerID == session.corpid: maxFittings = const.maxCorpFittings fittingsByGroupID = {} shipGroups = [] if self.wordFilter is not None: for fittingID, fitting in fittings[:]: if self.wordFilter.lower() not in fitting.name.lower(): fittings.remove((fittingID, fitting)) hideRight = True for fittingID, fitting in fittings: if self.fitting is not None and self.fitting.fittingID == fittingID: hideRight = False shipTypeID = fitting.shipTypeID if not evetypes.Exists(shipTypeID): log.LogError( 'Ship in stored fittings does not exist, shipID=%s, fittingID=%s' % (shipTypeID, fittingID)) continue groupID = evetypes.GetGroupID(shipTypeID) if groupID not in fittingsByGroupID: fittingsByGroupID[groupID] = [] fittingsByGroupID[groupID].append(fitting) groupName = evetypes.GetGroupNameByGroup(groupID) if (groupName, groupID) not in shipGroups: shipGroups.append((groupName, groupID)) if len(fittings) == 0 and self.wordFilter is not None: data = {'label': localization.GetByLabel('UI/Common/NothingFound')} scrolllist.append(listentry.Get('Generic', data)) if hideRight is None: self.HideRightPanel() shipGroups.sort() if maxFittings is not None: label = localization.GetByLabel( 'UI/Fitting/FittingWindow/FittingManagement/FittingsListHeader', numFittings=len(fittings), maxFittings=maxFittings) scrolllist.append(listentry.Get('Header', {'label': label})) for groupName, groupID in shipGroups: data = { 'GetSubContent': self.GetShipGroupSubContent, 'label': groupName, 'fittings': fittingsByGroupID[groupID], 'groupItems': fittingsByGroupID[groupID], 'id': ('fittingMgmtScrollWndGroup', groupName), 'showicon': 'hide', 'state': 'locked', 'BlockOpenWindow': 1 } scrolllist.append(listentry.Get('Group', data)) self.sr.scroll.Load(contentList=scrolllist, scrolltotop=0)
def VerifyFitting(self, fitting): if fitting.name.find('@@') != -1 or fitting.description.find('@@') != -1: raise UserError('InvalidFittingInvalidCharacter') if fitting.shipTypeID is None: raise UserError('InvalidFittingDataTypeID', {'typeName': fitting.shipTypeID}) shipTypeName = evetypes.GetNameOrNone(fitting.shipTypeID) if shipTypeName is None: raise UserError('InvalidFittingDataTypeID', {'typeName': fitting.shipTypeID}) if evetypes.GetCategoryID(fitting.shipTypeID) not in (const.categoryShip, const.categoryStructure): raise UserError('InvalidFittingDataShipNotShip', {'typeName': shipTypeName}) if len(fitting.fitData) == 0: raise UserError('ParseFittingFittingDataEmpty') for typeID, flag, qty in fitting.fitData: if not evetypes.Exists(typeID): raise UserError('InvalidFittingDataTypeID', {'typeID': typeID}) try: int(flag) except TypeError: raise UserError('InvalidFittingDataInvalidFlag', {'type': typeID}) if not (IsShipFittingFlag(flag) or flag in (const.flagDroneBay, const.flagCargo, const.flagFighterBay)): raise UserError('InvalidFittingDataInvalidFlag', {'type': typeID}) try: int(qty) except TypeError: raise UserError('InvalidFittingDataInvalidQuantity', {'type': typeID}) if qty == 0: raise UserError('InvalidFittingDataInvalidQuantity', {'type': typeID}) return True
def GetLineInfo(self, line): parts = SplitAndStrip(line, CHARGE_SEPARATOR) typeName = parts[0] if len(parts) > 1: chargeName = parts[1].strip().lower() else: chargeName = None parts = SplitAndStrip(typeName, MULTIPLIER_SEPARATOR) typeName = parts[0] if len(parts) > 1: numItems = int(parts[1]) else: numItems = 1 if typeName: typeName = typeName.lower() typeID = self.nameAndTypesDict.get(typeName, None) chargeTypeID = self.nameAndTypesDict.get(chargeName, None) isEmpty = True slotLocation = None if typeName in emptySlotDict: slotLocation = emptySlotDict[typeName] elif typeID: slotLocation = self.GetSlot(typeID) isEmpty = False if typeID is None and chargeTypeID is None and slotLocation is None: return categoryID = None capacity = None chargeVolume = None if evetypes.Exists(typeID): categoryID = evetypes.GetCategoryID(typeID) capacity = evetypes.GetCapacity(typeID) if evetypes.Exists(chargeTypeID): chargeVolume = evetypes.GetVolume(chargeTypeID) info = { 'typeName': typeName, 'typeID': typeID, 'categoryID': categoryID, 'capacity': capacity, 'numItems': numItems, 'chargeName': chargeName, 'chargeTypeID': chargeTypeID, 'chargeVolume': chargeVolume, 'slotLocation': slotLocation, 'isEmpty': isEmpty } return info
def ContainsTypeInGivenCollections(typeIDs, checkFunc): for typeID in typeIDs: if not evetypes.Exists(typeID): continue if checkFunc(typeID): return True return False
def GetMenu(self, *args): if isinstance(self.sr.node.invtype, tuple): typeID = self.sr.node.invtype[0] else: typeID = self.sr.node.invtype groupID = evetypes.GetGroupID(typeID) catID = evetypes.GetCategoryIDByGroup(groupID) graphicID = evetypes.GetGraphicID(typeID) graphicFileMenu = [] if evetypes.Exists(typeID) and evetypes.GetGraphicID( typeID) is not None: graphic = GetGraphic(evetypes.GetGraphicID(typeID)) if graphic is not None: graphicFile = GetGraphicFile(graphic) graphicFileMenu = [ [ 'Copy graphicID (%s)' % graphicID, lambda *x: blue.pyos.SetClipboardData(str(graphicID)), () ], [ 'Copy graphicFile (%s)' % graphicFile, lambda *x: blue.pyos.SetClipboardData(graphicFile), () ] ] averagePrice = inventorycommon.typeHelpers.GetAveragePrice(typeID) if averagePrice is None: averagePrice = 'n/a' else: averagePrice = util.FmtISK(averagePrice) menu = [[ 'Preview', lambda *x: uthread.new( sm.StartService('preview').PreviewType, typeID), () ]] menu += graphicFileMenu menu += [[ 'Copy typeID (%s)' % typeID, lambda *x: blue.pyos.SetClipboardData(str(typeID)), () ], [ 'Copy groupID (%s)' % groupID, lambda *x: blue.pyos.SetClipboardData(str(groupID)), () ], [ 'Copy categoryID (%s)' % catID, lambda *x: blue.pyos.SetClipboardData(str(catID)), () ], [ 'Average price: %s' % averagePrice, lambda *x: blue.pyos.SetClipboardData(averagePrice), () ], [ 'View market details', lambda *x: uthread.new( sm.StartService('marketutils').ShowMarketDetails, typeID, None), () ], None] menu += sm.GetService('menu').GetGMTypeMenu(typeID) return menu
def SetupShipAnimation(self, model, typeID, itemID): if model is None: return if not evetypes.Exists(typeID): return animationStates = GetAnimationStates(typeID) LoadAnimationStates(animationStates, cfg.graphicStates, model, trinity) if model.animationSequencer is not None: model.animationSequencer.GoToState('normal') SetShipAnimationStance(model, get_ship_stance(itemID, typeID))
def PrefetchGraphicsForModules(modules): prefetch_set = set() for moduleID, typeID, slot, isOnline in modules: if evetypes.Exists(typeID) and evetypes.GetGroupID(typeID) not in const.turretModuleGroups: continue turretPath = inventorycommon.typeHelpers.GetGraphicFile(typeID) if turretPath: prefetch_set.add(turretPath) remotefilecache.prefetch_files(prefetch_set)
def BuildSOFDNAFromTypeID(typeID, materialSetID=None): if typeID is None: return if not evetypes.Exists(typeID): return if materialSetID is None: materialSetID = evetypes.GetSofMaterialSetIDOrNone(typeID) sofBuildClass = evetypes.GetSofBuildClassOrNone(typeID) return BuildSOFDNAFromGraphicID(evetypes.GetGraphicID(typeID), materialSetID=materialSetID, sofBuildClass=sofBuildClass)
def __init__(self, typeID = -1, quantity = 0, expireDateTime = 0, stationID = 0, tokenID = 0, massTokenID = 0): self.typeID = typeID self.quantity = quantity self.expireDateTime = expireDateTime self.stationID = stationID self.tokenID = tokenID self.massTokenID = massTokenID self.typeName = None self.portionSize = None if evetypes.Exists(typeID): self.typeName = evetypes.GetName(typeID) self.portionSize = evetypes.GetPortionSize(typeID)
def SanitizedTypeID(typeID): try: typeID = int(typeID) except: log.LogError('Unable to convert typeID into an integer!') return if typeID is None: return if not evetypes.Exists(typeID): return return typeID
def GetSearchResults(conditions, itemRowset, searchtype): stations = defaultdict(list) itemsByContainerID = defaultdict(set) allContainersByItemIDs = {} failedTypeCheck = set() containerGroups = set([ const.groupSecureCargoContainer, const.groupAuditLogSecureContainer, const.groupFreightContainer, const.groupCargoContainer ]) containerTypesIDs = set([const.typeAssetSafetyWrap]) containerFlags = (const.flagNone, const.flagLocked, const.flagUnlocked) LogNotice('Asset search - find containers') for item in itemRowset: if item.groupID in containerGroups or item.typeID in containerTypesIDs: allContainersByItemIDs[item.itemID] = item def AddStationIDToFakeRow(locationID, row): containerItem = allContainersByItemIDs.get(locationID) if containerItem: stationID = containerItem.locationID elif row.flagID in (const.flagHangar, const.flagAssetSafety): stationID = locationID else: return setattr(row, 'stationID', stationID) LogNotice('Asset Search - start search') for item in itemRowset: typeID = item.typeID if not evetypes.Exists(typeID): continue if item.stacksize == 0: continue if searchtype: if typeID in failedTypeCheck: continue elif not MatchesTypeChecks(typeID, evetypes.GetGroupID(typeID), evetypes.GetCategoryID(typeID), searchtype): failedTypeCheck.add(typeID) continue AddStationIDToFakeRow(item.locationID, item) else: AddStationIDToFakeRow(item.locationID, item) if not MatchesSearchCriteria(item, conditions): continue if item.locationID in allContainersByItemIDs: itemsByContainerID[item.locationID].add(item) else: stations[item.locationID].append(item) LogNotice('Asset Search - Searching done') return (allContainersByItemIDs, itemsByContainerID, stations)
def IsPreviewable(typeID): if not evetypes.Exists(typeID): return False else: if IsApparel(typeID): return True if IsShipSkin(typeID): return True if evetypes.GetGraphicID(typeID) is None: return False return evetypes.GetCategoryID( typeID) in const.previewCategories or evetypes.GetGroupID( typeID) in const.previewGroups
def SetupAnimation(self, model, shipItem): if model is None: return if not evetypes.Exists(shipItem.typeID): return animationStates = inventorycommon.typeHelpers.GetAnimationStates( shipItem.typeID) spaceobjanimation.LoadAnimationStates(animationStates, cfg.graphicStates, model, trinity) if model.animationSequencer is not None: model.animationSequencer.GoToState('normal') spaceobjanimation.SetShipAnimationStance( model, shipstance.get_ship_stance(shipItem.itemID, shipItem.typeID))
def OnOrbitalStrikeDamage(self, request, report): for damage in report or []: typeID = damage.get('typeID') if not evetypes.Exists(typeID): continue elif evetypes.GetGroupID(typeID) == const.groupInfantryDropsuit and damage.get('characterName') is not None: name = damage.get('characterName') else: name = evetypes.GetName(typeID) target = sm.GetService('bracket').DisplayName(util.KeyVal(charID=damage.get('characterID'), corpID=damage.get('corporationID'), typeID=typeID, itemID=request['planetID'], allianceID=None), name) sm.GetService('logger').AddCombatMessage('AttackHits', {'isBanked': request['count'] > 1, 'hitQualityText': '', 'weapon': request['moduleTypeID'], 'splash': '', 'attackType': 'me', 'damage': damage['shieldDamage'] + damage['armorDamage'], 'target': target}) blue.pyos.synchro.SleepWallclock(1200)
def GetModuleLists(self): test = {} groups = dict.fromkeys([ groupID for groupID in evetypes.GetGroupIDsByCategory(const.categoryModule) ]) for k in cfg.invmetatypesByParent.iterkeys(): rowset = cfg.invmetatypesByParent[k] for row in rowset: if row.metaGroupID == 2: typeID = row.typeID if evetypes.Exists(typeID) and evetypes.GetMarketGroupID( typeID) and evetypes.GetCategoryID( typeID) == const.categoryModule: test[evetypes.GetGroupID(typeID)] = typeID for typeID in evetypes.Iterate(): groupID = evetypes.GetGroupID(typeID) if groupID not in test and groupID in groups: if not cfg.invmetatypesByParent.has_key(typeID): if evetypes.GetMarketGroupID(typeID): test[groupID] = typeID targeted = [] activated = [] passive = [] for typeID in test.values(): effects = [ cfg.dgmeffects.Get(row.effectID) for row in cfg.dgmtypeeffects.get(typeID, []) ] effectCategories = [ eff.effectCategory for eff in effects if eff.effectName != 'online' ] if const.dgmEffTarget in effectCategories: targeted.append((typeID, effects)) elif const.dgmEffActivation in effectCategories: activated.append((typeID, effects)) else: passive.append((typeID, effects)) return (targeted, activated, passive)
def GetPinGraphicsClassForType(self, typeID): if not evetypes.Exists(typeID): raise RuntimeError('Unable to find inventory type for typeID', typeID) groupID = evetypes.GetGroupID(typeID) if groupID == const.groupCommandPins: return CommandCenterPin if groupID == const.groupExtractorPins: return ExtractorPin if groupID == const.groupProcessPins: return ProcessorPin if groupID == const.groupSpaceportPins: return LaunchpadPin if groupID == const.groupStoragePins: return StorageFacilityPin if groupID == const.groupExtractionControlUnitPins: return EcuPin raise RuntimeError( 'Unable to resolve UI container class for pin of type', typeID)
def ReloadShipModel(self, throttle = False, animate = True): if self.destroyed: return with self._reloadLock: if throttle: newModel = self.CreateActiveShipModelThrottled() else: newModel = self.CreateActiveShipModel() if not newModel: return newModel.FreezeHighDetailMesh() trinity.WaitForResourceLoads() self.AddToScene(newModel) if animate: self.AnimEntry() if isinstance(self.controller.dogmaLocation.GetCurrentShipID(), basestring): _ApplyIsisEffect(newModel, isSkinned=False) grid = trinity.Load('res:/dx9/model/UI/ScanGrid.red') grid.scaling = (4, 4, 4) self.scene.objects.append(grid) camera = self.camera rad = newModel.GetBoundingSphereRadius() minZoom = rad + camera.nearClip alpha = camera.fov / 2.0 maxZoom = min(self.backClip - rad, rad * (1 / math.tan(alpha)) * 2) oldZoomDistance = self.minZoom + (self.maxZoom - self.minZoom) * self.zoom defaultZoom = minZoom / (maxZoom - minZoom) self.SetMinMaxZoom(minZoom, maxZoom) if animate or oldZoomDistance < minZoom or oldZoomDistance > maxZoom: self.SetZoom(defaultZoom) shipTypeID = self.controller.GetTypeID() stanceBtnControllerClass = self.controller.GetStanceBtnControllerClass() stanceID = stanceBtnControllerClass().get_ship_stance(self.controller.GetItemID(), shipTypeID) animationStates = [] if evetypes.Exists(shipTypeID): animationStates = inventorycommon.typeHelpers.GetAnimationStates(shipTypeID) spaceobjanimation.LoadAnimationStates(animationStates, cfg.graphicStates, newModel, trinity) if newModel.animationSequencer is not None: newModel.animationSequencer.GoToState('normal') spaceobjanimation.SetShipAnimationStance(newModel, stanceID) if not self.controller.IsSimulated(): self.UpdateHardpoints(newModel)
def FitTurret(model, turretTypeID, locatorID, turretFaction = None, count = 1, online = True, checkSettings = True): if not evetypes.Exists(turretTypeID): return if checkSettings and not gfxsettings.Get(gfxsettings.UI_TURRETS_ENABLED): return groupID = evetypes.GetGroupID(turretTypeID) if model is None: log.LogError('FitTurret() called with NoneType, so there is no model to fit the turret to!') return if groupID not in const.turretModuleGroups: return newTurretSet = None graphicID = evetypes.GetGraphicID(turretTypeID) if graphicID is not None: newTurretSet = TurretSet.AddTurretToModel(model, graphicID, turretFaction, locatorID, count) if newTurretSet is None: return if not online: newTurretSet.Offline() newTurretSet.turretTypeID = turretTypeID newTurretSet.turretGroupID = groupID return newTurretSet
def GetPinEntityType(typeID): if not evetypes.Exists(typeID): raise RuntimeError( 'Unable to locate inventory type object for type ID', typeID) from eve.common.script.planet.entities.storagePin import StoragePin from eve.common.script.planet.entities.ecuPin import EcuPin from eve.common.script.planet.entities.spaceportPin import SpaceportPin from eve.common.script.planet.entities.processPin import ProcessPin from eve.common.script.planet.entities.extractorPin import ExtractorPin from eve.common.script.planet.entities.commandPin import CommandPin groupID = evetypes.GetGroupID(typeID) if groupID == const.groupCommandPins: return CommandPin if groupID == const.groupExtractorPins: return ExtractorPin if groupID == const.groupProcessPins: return ProcessPin if groupID == const.groupSpaceportPins: return SpaceportPin if groupID == const.groupStoragePins: return StoragePin if groupID == const.groupExtractionControlUnitPins: return EcuPin
def Profile_LoadInternal(self, name): profile = {} INSIDERDIR = sm.GetService('insider').GetInsiderDir() try: for line in open(os.path.join(INSIDERDIR, '%s.skills' % name), 'r'): line = filter(lambda x: x in '0123456789. ', line).split() typeID = 0 level = 5 for part in line: part = int(float(part)) if part < 6 and part > 0: level = part elif evetypes.Exists(part): typeID = part if typeID: profile[typeID] = level except IOError: return None return profile
def IsPlaceable(typeID): if not evetypes.Exists(typeID): return False return evetypes.GetCategoryID(typeID) == const.categoryPlaceables
def IsBlueprint(typeID): if not evetypes.Exists(typeID): return False return evetypes.GetCategoryID(typeID) == const.categoryBlueprint
def IsApparel(typeID): if not evetypes.Exists(typeID): return False return evetypes.GetCategoryID(typeID) == const.categoryApparel
def IsShipSkin(typeID): if not evetypes.Exists(typeID): return False return evetypes.GetGroupID(typeID) == const.groupShipSkins
def IsShip(typeID): if not evetypes.Exists(typeID): return False return evetypes.GetCategoryID(typeID) == const.categoryShip