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

celestialCheckers.py (79484B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\menucheckers\celestialCheckers.py
      2 import evetypes
      3 import inventorycommon.const as invConst
      4 from stargate.client.localGates import FindLocalJumpGateForDestinationPath
      5 from eve.common.script.util.inventoryFlagsCommon import ShouldAllowAdd
      6 import eve.common.lib.appConst as appConst
      7 import dogma.const as dogmaConst
      8 from caching import Memoize
      9 from globalConfig.getFunctions import IsContentComplianceControlSystemActive
     10 from spacecomponents.client.components import linkWithShip, towGameObjective, filamentSpoolup
     11 from spacecomponents.common import componentConst
     12 from structures import STATE_UNKNOWN, OFFLINE_STATES, ALL_UPKEEP_STATES, UPKEEP_STATE_LOW_POWER, TYPES_THAT_NEVER_GO_ABANDONED
     13 from evetypes import GetGroupID, GetCategoryID, IsUpwellStargate, GetGroupNameByGroup
     14 from eveuniverse.security import is_low_sec_or_higher_solar_system
     15 from menucheckers.baseCheckers import _BaseItemChecker
     16 from menucheckers.decorators import decorated_checker, explain_failure_with, needs_ballpark_item
     17 from eve.common.script.sys import idCheckers
     18 from eve.common.script.sys.idCheckers import IsDeprecatedStation, IsNPC, IsStation, IsCharacter, IsSolarSystem, IsTriglavianSystem
     19 from brennivin.itertoolsext import Bundle
     20 from spacecomponents.common.helper import HasItemTrader, HasScoopComponent, IsActiveComponent, HasCargoBayComponent, HasMicroJumpDriverComponent, HasLinkWithShipComponent, HasUnderConstructionComponent, HasTowGameObjectiveComponent, HasPhaseStabilizerComponent, HasJumpBridgeComponent
     21 from spacecomponents.common.components.fitting import IsShipWithinFittingRange, HasFittingComponent
     22 from spacecomponents.common.components.bookmark import IsTypeBookmarkable
     23 from eve.client.script.parklife.states import gbEnemySpotted, selectedForNavigation
     24 from moonmining.miningBeacons import GetMiningBeaconPositionForMoon
     25 
     26 @Memoize
     27 def _GetTypesWithRestrictedRenaming():
     28     return evetypes.GetTypeIDsByListID(evetypes.TYPE_LIST_RESTRICTED_RENAMING)
     29 
     30 
     31 @decorated_checker
     32 
     33 class CelestialChecker(_BaseItemChecker):
     34 
     35     def __init__(self, item, cfg, sessionInfo = None, serviceManager = None):
     36         self.cfg = cfg
     37         if isinstance(item, tuple):
     38             typeID = item[1]
     39             item = Bundle(itemID=item[0], typeID=typeID, groupID=GetGroupID(typeID), categoryID=GetCategoryID(typeID))
     40         super(CelestialChecker, self).__init__(item, sessionInfo, serviceManager)
     41         if self.IsSpecificItem():
     42             self.item.ownerID = self._TryDetermineOwnerID()
     43             self.item.locationID = self._TryDetermineLocationID()
     44         self.isMultiSelection = False
     45 
     46     def _TryDetermineOwnerID(self):
     47         if getattr(self.item, 'ownerID', None) is not None:
     48             return self.item.ownerID
     49         itemID = self.item.itemID
     50         if self.item.typeID == appConst.typeSystem or itemID <= appConst.minStation or IsCharacter(itemID):
     51             return appConst.ownerSystem
     52         if IsStation(itemID):
     53             return cfg.stations.Get(itemID).ownerID
     54         if self.item.categoryID == invConst.categoryStructure:
     55             try:
     56                 return self.sm.GetService('structureDirectory').GetStructureInfo(self.item.itemID).ownerID
     57             except AttributeError:
     58                 pass
     59 
     60     def _TryDetermineLocationID(self):
     61         if getattr(self.item, 'locationID', None) is not None:
     62             return self.item.locationID
     63         try:
     64             locItem = cfg.evelocations.Get(self.item.itemID)
     65             if locItem and locItem.solarSystemID:
     66                 return locItem.solarSystemID
     67         except Exception:
     68             pass
     69 
     70         if self.getDistanceToActiveShip() is not None:
     71             return self.session.solarsystemid
     72         try:
     73             return self.sm.StartService('map').GetItem(self.item.itemID).locationID
     74         except Exception:
     75             self.item.locationID = None
     76 
     77     @needs_ballpark_item
     78     def OfferAbandonCargo(self):
     79         if not self.IsCargoContainer():
     80             return False
     81         if not self.GetBallpark().HaveLootRight(self.item.itemID):
     82             return False
     83         if self.IsPlanetaryLaunchContainer():
     84             return False
     85         return True
     86 
     87     @needs_ballpark_item
     88     def OfferAbandonWreck(self):
     89         if not self.IsWreck():
     90             return False
     91         if not self.GetBallpark().HaveLootRight(self.item.itemID):
     92             return False
     93         if self.GetBallpark().IsAbandoned(self.item.itemID):
     94             return False
     95         return True
     96 
     97     @needs_ballpark_item
     98     def OfferAbortSelfDestructStructure(self):
     99         if not (self.IsSovereigntyClaimMarker() or self.IsInfrastructureHub()):
    100             return False
    101         if not self.IsOwnedByMyCorp():
    102             return False
    103         if not self.IsWithinConfigRange():
    104             return False
    105         if not self.session.IsCorpDirector():
    106             return False
    107         if not self.IsSelfDestructing():
    108             return False
    109         return True
    110 
    111     def OfferAbortSelfDestructShip(self):
    112         if not self.IsMyActiveShip():
    113             return False
    114         return self.IsSelfDestructing()
    115 
    116     @needs_ballpark_item
    117     def OfferAccessCustomOfficePoco(self):
    118         if self.IsOrbitalSkyhook():
    119             return False
    120         return self.IsCustomsOffice()
    121 
    122     @needs_ballpark_item
    123     def OfferAccessCustomOfficeSkyhook(self):
    124         if not self.IsOrbitalSkyhook():
    125             return False
    126         if not IsActiveComponent(self.GetBallpark().componentRegistry, self.item.typeID, self.item.itemID):
    127             return False
    128         return True
    129 
    130     @needs_ballpark_item
    131     def OfferAccessMoonMaterialBay(self):
    132         if not self.IsAutoMoonMiner():
    133             return False
    134         if self.session.IsPilotDocked():
    135             return False
    136         if not IsActiveComponent(self.GetBallpark().componentRegistry, self.item.typeID, self.item.itemID):
    137             return False
    138         if not self.IsWithinInventoryAccessRange():
    139             return False
    140         return True
    141 
    142     def OfferAccessHangarTransfer(self):
    143         if self.session.IsPilotDocked():
    144             return False
    145         if self.session.isPilotCloaked():
    146             return False
    147         if not self.IsStructureOnline():
    148             return False
    149         if self.hasPilotWeaponsTimer():
    150             return False
    151         if self.IsOwnedByNPC():
    152             return False
    153         solarSystemID = self.session.solarsystemid2
    154         if solarSystemID and is_low_sec_or_higher_solar_system(solarSystemID) and self.session.isPilotCriminal():
    155             return False
    156         dist = self.getDistanceToActiveShip()
    157         return dist is not None and dist < self.godma.GetTypeAttribute(self.item.typeID, const.attributeCargoDeliverRange, -1)
    158 
    159     def OfferAccessAutoMoonMinerDetails(self):
    160         if not idCheckers.IsAutoMoonMiner(self.item.typeID):
    161             return False
    162         if not self.IsStructureInSpace():
    163             return False
    164         if not self.item.itemID or not self.item.ownerID:
    165             return False
    166         return True
    167 
    168     @needs_ballpark_item
    169     def OfferAccessOrbitalSkyhookOffice(self):
    170         if not self.IsOrbitalSkyhook():
    171             return False
    172         if not self.IsWithinConfigRange():
    173             return False
    174         return True
    175 
    176     @needs_ballpark_item
    177     def OfferAccessMercenaryDen(self):
    178         if not self.IsMercenaryDen():
    179             return False
    180         if not self.IsOwnedByMe():
    181             return False
    182         if self.session.isPilotWarping():
    183             return False
    184         if self.session.isPilotCloaked():
    185             return False
    186         if self.isInApproachRange(self.getDistanceToActiveShip()):
    187             return True
    188         return False
    189 
    190     @needs_ballpark_item
    191     def OfferAccessPOSActiveCrystal(self):
    192         if not self.IsLaserSentry():
    193             return False
    194         if not self.IsAnchorable():
    195             return False
    196         if not self.IsWithinConfigRange():
    197             return False
    198         if not self.IsOwnedByMeMyCorpOrAlliance():
    199             return False
    200         if self.IsFree():
    201             return False
    202         return True
    203 
    204     @needs_ballpark_item
    205     def OfferAccessPOSAmmo(self):
    206         if not self.IsAnchorable():
    207             return False
    208         if not self.IsWithinConfigRange():
    209             return False
    210         if not self.IsOwnedByMeMyCorpOrAlliance():
    211             return False
    212         if self.IsFree():
    213             return False
    214         if not self.IsSentry():
    215             return False
    216         return True
    217 
    218     @needs_ballpark_item
    219     def OfferAccessPOSCompression(self):
    220         if not self.IsCompressionArray():
    221             return False
    222         if not self.IsWithinTransferRange():
    223             return False
    224         return True
    225 
    226     @needs_ballpark_item
    227     def OfferAccessPOSCrystalStorage(self):
    228         return self.OfferAccessPOSActiveCrystal()
    229 
    230     @needs_ballpark_item
    231     def OfferAccessPOSFuelBay(self):
    232         if not self.IsControlTower():
    233             return False
    234         if not self.IsAnchorable():
    235             return False
    236         if not self.IsWithinConfigRange():
    237             return False
    238         if not self.IsOwnedByMeMyCorpOrAlliance():
    239             return False
    240         if self.IsFree():
    241             return False
    242         return True
    243 
    244     @needs_ballpark_item
    245     def OfferAccessPOSRefinery(self):
    246         if not self.IsReprocessingArray():
    247             return False
    248         if not self.IsWithinTransferRange():
    249             return False
    250         if self.IsFree():
    251             return False
    252         return True
    253 
    254     @needs_ballpark_item
    255     def OfferAccessPOSStorage(self):
    256         if not (self.IsAssemblyArray() or self.IsMobileLaboratory() or self.IsCorpHangarArray() or self.IsPersonalHangarArray() or self.IsSilo() or self.IsReactor()):
    257             return False
    258         if not self.IsAnchorable():
    259             return False
    260         if not self.IsWithinConfigRange():
    261             return False
    262         if not self.IsOwnedByMeMyCorpOrAlliance():
    263             return False
    264         if self.IsFree():
    265             return False
    266         return True
    267 
    268     @needs_ballpark_item
    269     def OfferAccessPOSStrontiumBay(self):
    270         return self.OfferAccessPOSFuelBay()
    271 
    272     @needs_ballpark_item
    273     def OfferAccessPOSVessels(self):
    274         if not self.IsPOSMaintainanceArray():
    275             return False
    276         if not self.IsAnchorable():
    277             return False
    278         if self.IsFree():
    279             return False
    280         if not self.IsWithinTransferRange():
    281             return False
    282         if not self.IsOwnedByMeMyCorpOrAlliance():
    283             return False
    284         return True
    285 
    286     @needs_ballpark_item
    287     def OfferAccessShippingUnit(self):
    288         if not self.IsMobileShippingUnit():
    289             return False
    290         return getattr(self.item, 'timerInfo', None) is None
    291 
    292     @needs_ballpark_item
    293     def OfferActivateAutopilot(self):
    294         if self.session.IsPilotInStructure():
    295             return False
    296         if not self.IsMyActiveShip():
    297             return False
    298         if self.IsNotOnAutoPilot():
    299             return True
    300         return False
    301 
    302     @needs_ballpark_item
    303     def OfferActivateGate(self):
    304         if not self.IsWarpGate():
    305             return False
    306         if self.session.isPilotWarping():
    307             return False
    308         return True
    309 
    310     @needs_ballpark_item
    311     def OfferActivateJumpBridge(self):
    312         if not self.session.IsPilotInShipInSpace():
    313             return False
    314         if self.session.isPilotWarping() and not self.isPilotWarpingToMe():
    315             return False
    316         if not self.IsConnectedJumpBridgeStructure():
    317             return False
    318         if not self.IsStructureOnline():
    319             return False
    320         shipItem = self.session.getActiveShipGodmaItem()
    321         from jumpbridge.client import jumpBridge
    322         jumpBridgeComponent = jumpBridge.GetJumpBridgeComponent(self.GetBallpark(), self.item.itemID)
    323         if not jumpBridgeComponent or not jumpBridgeComponent.IsAccessibleByShip(shipItem):
    324             return False
    325         return True
    326 
    327     @needs_ballpark_item
    328     def OfferActivateJumpBridgeDisabled(self):
    329         if not self.session.IsPilotInShipInSpace():
    330             return False
    331         if not self.IsConnectedJumpBridgeStructure():
    332             return False
    333         if not self.IsStructureOnline():
    334             return False
    335         return True
    336 
    337     @needs_ballpark_item
    338     def OfferActivateMicroJumpDrive(self):
    339         if self.IsDead():
    340             return False
    341         if not IsActiveComponent(self.GetBallpark().componentRegistry, self.item.typeID, self.item.itemID):
    342             return False
    343         return HasMicroJumpDriverComponent(self.item.typeID)
    344 
    345     @needs_ballpark_item
    346     def OfferActivatRandomTraceGate(self):
    347         if not self.IsRandomTraceJumpGate():
    348             return False
    349         if not self.IsOwnedByMe():
    350             return False
    351         if self.session.isPilotWarping():
    352             return False
    353         if not self.IsComponentActive():
    354             return False
    355         failureReason = filamentSpoolup.GetErrorForRandomJumpTraceGate()
    356         if failureReason is not None:
    357             self.failure_label = failureReason
    358             return False
    359         return True
    360 
    361     @needs_ballpark_item
    362     def OfferLinkWithShip(self, checkLinkState = True):
    363         if not self.GetBallpark().GetBall(self.item.itemID):
    364             return False
    365         if self.session.isPilotWarping():
    366             return False
    367         if self.session.isPilotCloaked():
    368             return False
    369         if self.IsDead():
    370             return False
    371         if not IsActiveComponent(self.GetBallpark().componentRegistry, self.item.typeID, self.item.itemID):
    372             return False
    373         if not HasLinkWithShipComponent(self.item.typeID):
    374             return False
    375         if checkLinkState and not linkWithShip.IsAccessibleByCharacter(self.GetBallpark(), self.item):
    376             return False
    377         return True
    378 
    379     @needs_ballpark_item
    380     def OfferConnectToPhaseStabilizer(self):
    381         ballpark = self.GetBallpark()
    382         if not ballpark.GetBall(self.item.itemID):
    383             return False
    384         if self.session.isPilotWarping():
    385             return False
    386         if self.session.isPilotCloaked():
    387             return False
    388         if self.IsDead():
    389             return False
    390         if not HasPhaseStabilizerComponent(self.item.typeID):
    391             return False
    392         shipItem = self.session.getActiveShipGodmaItem()
    393         from spacecomponents.client.components import phaseStabilizer
    394         phaseStabilizerComponent = phaseStabilizer.GetPhaseStabilizerComponent(ballpark, self.item.itemID)
    395         if not phaseStabilizerComponent.IsAccessibleByMyShip(ballpark, shipItem.itemID, shipItem.typeID):
    396             return False
    397         if phaseStabilizerComponent.nearestPhaseableID is None:
    398             return False
    399         if not phaseStabilizerComponent.phaseableIsAvailable:
    400             return False
    401         return True
    402 
    403     @needs_ballpark_item
    404     def OfferTowableMenu(self):
    405         if not HasTowGameObjectiveComponent(self.item.typeID):
    406             return False
    407         if not self.session.IsPilotInShipInSpace():
    408             return False
    409         if not self.GetBallpark().GetBall(self.item.itemID):
    410             return False
    411         if self.session.isPilotWarping():
    412             return False
    413         if self.session.isPilotCloaked():
    414             return False
    415         if self.IsDead():
    416             return False
    417         shipItem = self.session.getActiveShipGodmaItem()
    418         warFactionID = self.session.GetWarFactionID()
    419         failureReason = towGameObjective.GetFailureReason(self.GetBallpark(), self.item, self.session.charid, shipItem, warFactionID)
    420         if failureReason is not None:
    421             self.failure_label = failureReason
    422             return False
    423         return True
    424 
    425     def OfferAddFirstWaypoint(self):
    426         if not self.IsStargate():
    427             return False
    428         if self.isWaypoint():
    429             return False
    430         return bool(self.GetJumpInfo())
    431 
    432     def OfferAddWaypoint(self):
    433         if not self.CanBeWaypoint():
    434             return False
    435         if self.isWaypoint():
    436             return False
    437         return True
    438 
    439     @needs_ballpark_item
    440     def OfferAlignTo(self):
    441         if self.OfferApproachObject():
    442             return False
    443         if not self.IsPilotFlyingInSameSystem():
    444             return False
    445         if self.IsActiveShip():
    446             return False
    447         if not self.session.IsPilotInShipInSpace():
    448             return False
    449         if not self.session.isInWarpRange(self.getDistanceToActiveShip()):
    450             return False
    451         if self.session.isPilotWarping():
    452             return False
    453         if self.IsStructure():
    454             return True
    455         if self.IsFree():
    456             return False
    457         return True
    458 
    459     @needs_ballpark_item
    460     def OfferAnchorOrbital(self):
    461         if not (self.IsOrbital() or self.IsPlanetaryCustomsOffice()):
    462             return False
    463         if self.IsOrbitalSkyhook():
    464             return False
    465         if not self.IsAnchorable():
    466             return False
    467         if not self.CanAnchorOrbital():
    468             return False
    469         if not self.IsOwnedByMyCorp():
    470             return False
    471         return True
    472 
    473     @needs_ballpark_item
    474     def OfferAnchorPOSObject(self):
    475         if not self.IsAnchorable():
    476             return False
    477         if not self.IsOwnedByMeOrCorp():
    478             return False
    479         if not self.IsFree():
    480             return False
    481         if not self.IsWithinConfigRange():
    482             return False
    483         if not self.GetStateManager().TypeHasEffect(self.item.typeID, dogmaConst.effectAnchorDrop):
    484             return False
    485         return True
    486 
    487     @needs_ballpark_item
    488     def OfferAnchorStructure(self):
    489         if not self.IsPOSStructure():
    490             return False
    491         if not self.IsAnchorable():
    492             return False
    493         if not self.IsWithinConfigRange():
    494             return False
    495         if not self.IsOwnedByMeMyCorpOrAlliance():
    496             return False
    497         if not self.CanAnchorStructure():
    498             return False
    499         return True
    500 
    501     @needs_ballpark_item
    502     def OfferApproachObject(self):
    503         if self.IsPlanetMoonAsteroidBelt():
    504             return False
    505         if not self.IsPilotFlyingInSameSystem() and not self.IsPilotingStructureInSystem():
    506             return False
    507         if self.IsActiveShip():
    508             return False
    509         if self.session.isPilotWarping():
    510             return False
    511         if self.session.IsPilotInShipInSpace() or self.IsPilotControllingStructureWithFightersSelected():
    512             if self.isInApproachRange(self.getDistanceToActiveShip()):
    513                 return True
    514         return False
    515 
    516     @needs_ballpark_item
    517     def OfferAssumeStructureControl(self):
    518         if not self.IsPOSStructure():
    519             return False
    520         if not self.IsAnchorable():
    521             return False
    522         if not self.IsOwnedByMeMyCorpOrAlliance():
    523             return False
    524         if not self.CanAssumeControlOfStructure():
    525             return False
    526         if not self.CanOfflineStructure():
    527             return False
    528         if self.IsSovereigntyStructure():
    529             return False
    530         if self.hasPlanetViewActive():
    531             return False
    532         if self.GetStructureController() is not None:
    533             return False
    534         return True
    535 
    536     def OfferAvoidLocation(self):
    537         if not self.OfferShowLocationOnMap():
    538             return False
    539         if self.isAvoided():
    540             return False
    541         return True
    542 
    543     @needs_ballpark_item
    544     def OfferBoardShip(self):
    545         if not self.IsShip():
    546             return False
    547         if self.IsActiveShip():
    548             return False
    549         if self.IsInteractive():
    550             return False
    551         if self.session.isPilotWarping():
    552             return False
    553         dist = self.getDistanceToActiveShip()
    554         if dist is None:
    555             return False
    556         if dist > appConst.maxBoardingDistance:
    557             return False
    558         if self.session.IsPilotInShipInSpace() or self.session.IsPilotControllingUndockableStructure():
    559             return True
    560         return False
    561 
    562     def OfferBoardPreviousShip(self):
    563         return self.session.IsPilotControllingUndockableStructure()
    564 
    565     @needs_ballpark_item
    566     def OfferBoardStructure(self):
    567         if not self.IsStructure():
    568             return False
    569         if self.IsDockableStructure():
    570             return False
    571         if not self.IsStructureInSpace():
    572             return False
    573         if not self.IsStructureOnline():
    574             return False
    575         if not self.session.IsPilotInShipInSpace():
    576             return False
    577         dist = self.getDistanceToActiveShip()
    578         if dist is None:
    579             return False
    580         if dist > appConst.maxBoardingDistance:
    581             return False
    582         if self.session.IsElevatedPlayer():
    583             return True
    584         return self.sm.GetService('structureControl').MayTakeControl(self.item.itemID)
    585 
    586     def OfferBookmarkLocation(self):
    587         if not self.IsSpecificItem():
    588             return False
    589         if self.IsEntity() or self.IsDrone() or self.IsShip() or self.IsFighter():
    590             return False
    591         if self.IsLandmark():
    592             return False
    593         if IsDeprecatedStation(self.item.typeID):
    594             return False
    595         if not IsTypeBookmarkable(self.item.typeID):
    596             return False
    597         if self.IsSolarsystem() or self.IsConstellation() or self.IsRegion():
    598             return True
    599         if not self.IsInSpace():
    600             return False
    601         return True
    602 
    603     def OfferBroadcastAlignTo(self):
    604         return self.OfferBroadcastWarpTo()
    605 
    606     @needs_ballpark_item
    607     def OfferBroadcastEnemySpotted(self):
    608         if not self.session.IsPilotFleetMember():
    609             return False
    610         return bool(self.sm.GetService('fleet').CurrentFleetBroadcastOnItem(self.item.itemID, gbEnemySpotted))
    611 
    612     @needs_ballpark_item
    613     def OfferBroadcastHealTarget(self):
    614         if not self.IsPilotFlyingInSameSystem():
    615             return False
    616         if not self.session.IsPilotFleetMember():
    617             return False
    618         return self.isInFleetBroadcastRange(self.getDistanceToActiveShip())
    619 
    620     @needs_ballpark_item
    621     def OfferBroadcastJumpTo(self):
    622         if not self.IsPilotFlyingInSameSystem():
    623             return False
    624         if not self.session.IsPilotFleetMember():
    625             return False
    626         if self.IsStargate() or self.IsJumpGate():
    627             return True
    628         return False
    629 
    630     @needs_ballpark_item
    631     def OfferBroadcastTarget(self):
    632         if not self.IsPilotFlyingInSameSystem():
    633             return False
    634         if self.IsActiveShip():
    635             return False
    636         if not self.session.IsPilotFleetMember():
    637             return False
    638         return self.isInFleetBroadcastRange(self.getDistanceToActiveShip())
    639 
    640     def OfferBroadcastTravelTo(self):
    641         if not self.session.IsPilotFleetMember():
    642             return False
    643         if not self.CanBeWaypoint():
    644             return False
    645         if self.IsStation and not IsDeprecatedStation(self.item.typeID):
    646             return True
    647         if self.IsSolarsystem():
    648             return True
    649         return False
    650 
    651     @needs_ballpark_item
    652     def OfferBroadcastWarpTo(self):
    653         if not self.IsPilotFlyingInSameSystem():
    654             return False
    655         if not self.session.IsPilotFleetMember():
    656             return False
    657         if self.IsEntity() or self.IsDrone() or self.IsShip() or self.IsFighter():
    658             return False
    659         if self.IsAbyssEntranceGate():
    660             return False
    661         return True
    662 
    663     @needs_ballpark_item
    664     def OfferPilotMenu(self):
    665         if not self.item.ownerID:
    666             return False
    667         if not self.IsShip():
    668             return False
    669         return True
    670 
    671     def OfferCompareButton(self):
    672         if self.isMultiSelection:
    673             return False
    674         if not self.IsComparible():
    675             return False
    676         if self.IsShip() or self.IsDrone() or self.IsFighter():
    677             return bool(self.GetAttributeDict())
    678         return False
    679 
    680     def OfferConfigureFacility(self):
    681         if not self.IsSpecificItem():
    682             return False
    683         if not self.session.IsStationManager():
    684             return False
    685         if not (self.IsAssemblyArray() or self.IsMobileLaboratory()):
    686             return False
    687         if not self.IsOwnedByMyCorp():
    688             return False
    689         if not self.IsFacility():
    690             return False
    691         return True
    692 
    693     @needs_ballpark_item
    694     def OfferConfigureOrbitalPoco(self):
    695         if not super(CelestialChecker, self).OfferConfigureOrbital():
    696             return False
    697         if self.IsOrbitalSkyhook():
    698             return False
    699         if not self.IsOrbitalAnchored():
    700             return False
    701         return True
    702 
    703     def OfferConfigureOrbitalSkyhook(self):
    704         if not self.IsSpecificItem():
    705             return False
    706         if not super(CelestialChecker, self).OfferConfigureOrbital():
    707             return False
    708         if not self.IsOrbitalSkyhook():
    709             return False
    710         return True
    711 
    712     @needs_ballpark_item
    713     def OfferConfigureShipCloneFacility(self):
    714         if not self.IsShip():
    715             return False
    716         if self.session.IsPilotInStructure():
    717             return False
    718         if not self.IsActiveShip():
    719             return False
    720         if not self.IsCloneCapableShip():
    721             return False
    722         return True
    723 
    724     def OfferCustomsOfficeMenu(self):
    725         if not self.IsPlanet():
    726             return False
    727         if not self.GetBallpark():
    728             return False
    729         return bool(self.GetPocoOrbitals())
    730 
    731     @needs_ballpark_item
    732     def OfferDeactivateAutopilot(self):
    733         if self.session.IsPilotInStructure():
    734             return False
    735         if not self.IsMyActiveShip():
    736             return False
    737         if not self.IsOnAutoPilot():
    738             return False
    739         return True
    740 
    741     def OfferDock(self):
    742         if not self.IsDockable():
    743             return False
    744         if not self.session.IsPilotInShipInSpace():
    745             return False
    746         if self.session.isPilotWarping():
    747             return False
    748         dist = self.getDistanceToActiveShip()
    749         if dist is None:
    750             return
    751         if self.IsStructure() and not self.IsStructureOnline():
    752             return False
    753         return True
    754 
    755     def OfferDroneMenu(self):
    756         if not self.IsDrone():
    757             return False
    758         if not self.IsSpecificItem():
    759             return False
    760         if None in (self.locationID, self.ownerID):
    761             return False
    762         return True
    763 
    764     def OfferEditProfileForStructure(self):
    765         if self.isMultiSelection:
    766             return False
    767         if not self.IsSpecificItem():
    768             return False
    769         if not self.IsStructure():
    770             return False
    771         if not self.session.IsStationManager():
    772             return False
    773         if not self.IsStructureInSpace():
    774             return False
    775         if self.IsFree():
    776             return False
    777         return self.IsStructureOwnedByMyCorp()
    778 
    779     @needs_ballpark_item
    780     def OfferEjectFromShip(self):
    781         if not self.session.IsPilotInShipInSpace():
    782             return False
    783         if not self.IsMyActiveShip():
    784             return False
    785         if self.IsCapsule():
    786             return False
    787         if self.session.isPilotWarping():
    788             return False
    789         return True
    790 
    791     @needs_ballpark_item
    792     def OfferEnterStarbasePassword(self):
    793         if not self.IsShip():
    794             return False
    795         if self.session.IsPilotInStructure():
    796             return False
    797         if not self.IsActiveShip():
    798             return False
    799         return True
    800 
    801     @needs_ballpark_item
    802     def OfferEnterWormhole(self):
    803         if not self.IsWormhole():
    804             return False
    805         if self.session.isPilotWarping():
    806             return False
    807         return True
    808 
    809     def OfferExitPlanetaryProduction(self):
    810         if not self.IsSpecificItem():
    811             return False
    812         if not self.IsPlanet():
    813             return False
    814         return self.getViewedPlanet() == self.item.itemID
    815 
    816     def OfferFindInContracts(self):
    817         if not self.IsPublished():
    818             return False
    819         return True
    820 
    821     def OfferFindPersonalAssets(self):
    822         if self.isMultiSelection:
    823             return False
    824         if not self.IsPublished():
    825             return False
    826         return True
    827 
    828     @needs_ballpark_item
    829     def OfferFleetTagItem(self):
    830         if self.IsActiveShip():
    831             return False
    832         if self.IsPlanetMoonAsteroidBelt():
    833             return False
    834         if not self.session.IsPilotFleetMember():
    835             return False
    836         if not self.session.IsPilotFleetCommander():
    837             return False
    838         return True
    839 
    840     @needs_ballpark_item
    841     def OfferItemTraderAccess(self):
    842         if self.IsDead():
    843             return False
    844         if not IsActiveComponent(self.GetBallpark().componentRegistry, self.item.typeID, self.item.itemID):
    845             return False
    846         return HasItemTrader(self.item.typeID)
    847 
    848     @needs_ballpark_item
    849     def OfferJumpFleetThroughToSystem(self):
    850         if not self.IsPilotFlyingInSameSystem():
    851             return False
    852         if not self.session.IsPilotInShipInSpace():
    853             return False
    854         if self.session.isPilotWarping():
    855             return False
    856         if not self.isInStargateJumpRange(self.getDistanceToActiveShip()):
    857             return False
    858         if not self.session.isPilotInSameFleetAs(self.item.ownerID):
    859             return False
    860         if not self.GetActiveFleetBridge():
    861             return False
    862         return True
    863 
    864     def OfferJumpThroughStargate(self):
    865         if self.GetBallpark() is None:
    866             return False
    867         if not self.IsSpecificItem():
    868             return False
    869         if not self.session.IsPilotInShipInSpace():
    870             return False
    871         solarsystemID = self.GetWaypointSolarsystemID()
    872         if solarsystemID is None:
    873             return False
    874         if solarsystemID in self.sm.GetService('map').GetNeighbors(self.session.solarsystemid):
    875             return True
    876         return False
    877 
    878     def OfferJumpThroughStructureJumpGate(self):
    879         if self.GetBallpark() is None:
    880             return False
    881         if not self.IsSpecificItem():
    882             return False
    883         if not self.session.IsPilotInShipInSpace():
    884             return False
    885         solarsystemID = self.GetWaypointSolarsystemID()
    886         if solarsystemID is None:
    887             return False
    888         if solarsystemID == self.session.solarsystemid:
    889             return False
    890         return self.IsSolarSystemReachableThroughJumpGate(solarsystemID)
    891 
    892     @needs_ballpark_item
    893     def OfferKeepAtRange(self):
    894         if self.IsPlanetMoonAsteroidBelt():
    895             return False
    896         if not self.IsPilotFlyingInSameSystem() and not self.IsPilotingStructureInSystem():
    897             return False
    898         if self.IsActiveShip():
    899             return False
    900         if self.session.isPilotWarping():
    901             return False
    902         if not self.IsValidForKeepAtRange():
    903             return False
    904         if not self.session.IsPilotInShipInSpace() and not self.IsPilotControllingStructureWithFightersSelected():
    905             return False
    906         if self.isInApproachRange(self.getDistanceToActiveShip()):
    907             return True
    908         return False
    909 
    910     @needs_ballpark_item
    911     def OfferLockTarget(self):
    912         if self.IsActiveShip():
    913             return False
    914         if self.IsPlanetMoonAsteroidBelt():
    915             return False
    916         if self.session.IsPilotDockedInStructure():
    917             return False
    918         if self.session.IsPilotDocked() and not self.session.IsPilotControllingStructure():
    919             return False
    920         if not self.IsNotTarget():
    921             return False
    922         if self.IsBeingTargetLocked():
    923             return False
    924         if self.session.IsPilotInCapsule():
    925             return False
    926         if not self.IsWithinTargettingRange():
    927             return False
    928         return True
    929 
    930     @needs_ballpark_item
    931     def OfferLookAtObject(self):
    932         if self.session.isPilotWarping():
    933             return False
    934         if not self.canLookAt():
    935             return False
    936         if self.isLookingAtMe():
    937             return False
    938         if self.IsPlanet():
    939             return False
    940         if self.IsMoon():
    941             return False
    942         return True
    943 
    944     @needs_ballpark_item
    945     def OfferManageControlTower(self):
    946         if not self.IsAnchorable():
    947             return False
    948         if self.IsFree():
    949             return False
    950         if not self.IsControlTower():
    951             return False
    952         if not self.IsOwnedByMeOrCorp():
    953             return False
    954         return True
    955 
    956     @needs_ballpark_item
    957     def OfferMarkWreckNotViewed(self):
    958         return self.IsWreck() and self.IsViewedWreck()
    959 
    960     @needs_ballpark_item
    961     def OfferMarkWreckViewed(self):
    962         return self.IsWreck() and not self.IsViewedWreck()
    963 
    964     def OfferMoonMiningPointMenu(self):
    965         return self.IsMoon()
    966 
    967     @needs_ballpark_item
    968     def OfferMoonMenuOptions(self):
    969         if not self.IsPlanet():
    970             return False
    971         return bool(self.GetMoonsForPlanet())
    972 
    973     @needs_ballpark_item
    974     def OfferOpenCargo(self):
    975         if self.session.IsPilotControllingStructure():
    976             return False
    977         if not self.session.IsPilotInShipInSpace():
    978             return False
    979         if self.session.isPilotWarping():
    980             return False
    981         if not self.IsContainer():
    982             return False
    983         if HasItemTrader(self.item.typeID):
    984             return False
    985         return True
    986 
    987     @needs_ballpark_item
    988     def OfferOpenCargoBay(self):
    989         if not IsActiveComponent(self.GetBallpark().componentRegistry, self.item.typeID, self.item.itemID):
    990             return False
    991         if not HasCargoBayComponent(self.item.typeID):
    992             return False
    993         if HasUnderConstructionComponent(self.item.typeID):
    994             return False
    995         from spacecomponents.client.components import cargobay
    996         return cargobay.IsAccessibleByCharacter(self.item, self.session.charid)
    997 
    998     @needs_ballpark_item
    999     def OfferOpenCargoHold(self):
   1000         if not self.IsShip():
   1001             return False
   1002         if self.session.IsPilotInStructure():
   1003             return False
   1004         if not self.IsActiveShip():
   1005             return False
   1006         if self.IsCapsule():
   1007             return False
   1008         return True
   1009 
   1010     @needs_ballpark_item
   1011     def OfferOpenFleetHangar(self):
   1012         if not self.IsFleetHangarShip():
   1013             return False
   1014         if self.IsActiveShip():
   1015             return True
   1016         if not self.session.IsPilotInShipInSpace():
   1017             return False
   1018         if self.IsOwnedByMe():
   1019             return True
   1020         return self.CanUseShipServices(invConst.flagFleetHangar)
   1021 
   1022     @needs_ballpark_item
   1023     def OfferOpenInfrastructureHubPanel(self):
   1024         return self.IsControlBunker()
   1025 
   1026     @needs_ballpark_item
   1027     def OfferOpenShipMaintenanceBay(self):
   1028         if not self.IsSMBShip():
   1029             return False
   1030         if self.IsActiveShip():
   1031             return True
   1032         if not self.session.IsPilotInShipInSpace():
   1033             return False
   1034         if self.IsOwnedByMe():
   1035             return True
   1036         return self.CanUseShipServices(invConst.flagShipHangar)
   1037 
   1038     @needs_ballpark_item
   1039     def OfferOpenSovFuelDepositWindow(self):
   1040         if not self.IsInfrastructureHub():
   1041             return False
   1042         if self.session.IsPilotControllingStructure():
   1043             return False
   1044         if not self.session.IsPilotInShipInSpace():
   1045             return False
   1046         if self.session.isPilotWarping():
   1047             return False
   1048         if not self.isInTransferRange(self.getDistanceToActiveShip()):
   1049             return False
   1050         hubInfo = sm.GetService('sov').GetInfrastructureHubInfo(self.session.solarsystemid)
   1051         if hubInfo is None:
   1052             return False
   1053         return True
   1054 
   1055     @needs_ballpark_item
   1056     def OfferOpenSovHubConfigWindow(self):
   1057         if not self.IsInfrastructureHub():
   1058             return False
   1059         if not self.IsOwnedByMyCorp():
   1060             return False
   1061         if not self.session.IsStationManager():
   1062             return False
   1063         hubInfo = sm.GetService('sov').GetInfrastructureHubInfo(self.session.solarsystemid)
   1064         if hubInfo is None:
   1065             return False
   1066         return True
   1067 
   1068     @needs_ballpark_item
   1069     def OfferOpenSovSystemCleanup(self):
   1070         if not self.IsInfrastructureHub():
   1071             return False
   1072         if not self.IsOwnedByMyCorp():
   1073             return False
   1074         return bool(sm.GetService('sov').GetStructuresAvailableToCleanUp())
   1075 
   1076     @needs_ballpark_item
   1077     def OfferOpenUnderConstruction(self):
   1078         if self.session.IsPilotControllingStructure():
   1079             return False
   1080         if not self.session.IsPilotInShipInSpace():
   1081             return False
   1082         if self.session.isPilotWarping():
   1083             return False
   1084         if not IsActiveComponent(self.GetBallpark().componentRegistry, self.item.typeID, self.item.itemID):
   1085             return False
   1086         if not HasUnderConstructionComponent(self.item.typeID):
   1087             return False
   1088         if not HasCargoBayComponent(self.item.typeID):
   1089             return False
   1090         from spacecomponents.client.components import cargobay
   1091         return cargobay.IsAccessibleByCharacter(self.item, self.session.charid)
   1092 
   1093     @needs_ballpark_item
   1094     def OfferOpenUpgradeHold(self):
   1095         from eve.common.script.mgt import entityConst
   1096         if not self.IsOrbital():
   1097             return False
   1098         if not self.IsOwnedByMeOrCorp():
   1099             return False
   1100         if not self.IsSpecialMaterialHoldsItem():
   1101             return False
   1102         if not self.IsPilotFlyingInSameSystem():
   1103             return False
   1104         if not self.session.IsPilotInShipInSpace():
   1105             return False
   1106         if getattr(self.item, 'orbitalState', None) != entityConst.STATE_ANCHORED:
   1107             return False
   1108         if not self.isInTransferRange(self.getDistanceToActiveShip()):
   1109             return False
   1110         if self.IsOrbitalConstructionPlatform():
   1111             return True
   1112         if self.session.IsInZeroSec():
   1113             return True
   1114         return False
   1115 
   1116     @needs_ballpark_item
   1117     def OfferOrbitObject(self):
   1118         if self.IsPlanetMoonAsteroidBelt():
   1119             return False
   1120         if not self.IsPilotFlyingInSameSystem() and not self.IsPilotingStructureInSystem():
   1121             return False
   1122         if self.IsActiveShip():
   1123             return False
   1124         if self.session.isPilotWarping():
   1125             return False
   1126         if not self.session.IsPilotInShipInSpace() and not self.IsPilotControllingStructureWithFightersSelected():
   1127             return False
   1128         if self.isInOrbitRange(self.getDistanceToActiveShip()):
   1129             return True
   1130         return False
   1131 
   1132     @needs_ballpark_item
   1133     def OfferOrbitalSkyhook(self):
   1134         if not self.IsPlanet():
   1135             return False
   1136         return bool(self.GetSkyhookOrbitals())
   1137 
   1138     @needs_ballpark_item
   1139     def OfferPutStructureOffline(self):
   1140         if not self.IsPOSStructure():
   1141             return False
   1142         if not self.IsWithinConfigRange():
   1143             return False
   1144         if not self.IsAnchorable():
   1145             return False
   1146         if not self.IsOwnedByMeMyCorpOrAlliance():
   1147             return False
   1148         if not self.CanOfflineStructure():
   1149             return False
   1150         return True
   1151 
   1152     @needs_ballpark_item
   1153     def OfferPutStructureOnline(self):
   1154         if not self.IsPOSStructure():
   1155             return False
   1156         if not self.IsAnchorable():
   1157             return False
   1158         if not self.IsWithinConfigRange():
   1159             return False
   1160         if self.IsSovereigntyDisruptor():
   1161             return True
   1162         if not self.IsOwnedByMeMyCorpOrAlliance():
   1163             return False
   1164         if not self.CanOnlineStructure():
   1165             return False
   1166         return True
   1167 
   1168     @needs_ballpark_item
   1169     def OfferReconnectToLostDrones(self):
   1170         if not self.IsShip():
   1171             return False
   1172         if self.session.IsPilotInStructure():
   1173             return False
   1174         if not self.IsActiveShip():
   1175             return False
   1176         if not self.IsDroneCapableShip():
   1177             return False
   1178         if self.session.isPilotWarping():
   1179             return False
   1180         return True
   1181 
   1182     def OfferReleaseControl(self):
   1183         return self.session.IsPilotControllingStructure()
   1184 
   1185     @needs_ballpark_item
   1186     def OfferRelinquishPOSControl(self):
   1187         if not self.IsPOSStructure():
   1188             return False
   1189         if not self.IsAnchorable():
   1190             return False
   1191         if not self.IsOwnedByMeMyCorpOrAlliance():
   1192             return False
   1193         if not self.CanAssumeControlOfStructure():
   1194             return False
   1195         if not self.CanOfflineStructure():
   1196             return False
   1197         if self.IsSovereigntyStructure():
   1198             return False
   1199         if self.hasPlanetViewActive():
   1200             return False
   1201         if not self.IsControlledByPilot():
   1202             return False
   1203         return True
   1204 
   1205     def OfferToggleOverviewVisibility(self):
   1206         if self.session.IsPilotDocked() and not self.session.IsPilotControllingStructure():
   1207             return False
   1208         if self.IsLandmark():
   1209             return False
   1210         if self.IsIgnoredByOverview():
   1211             return False
   1212         if self.IsSolarsystem() or self.IsConstellation() or self.IsRegion():
   1213             return False
   1214         if sm.GetService('overviewPresetSvc').IsReadOnly():
   1215             return False
   1216         return True
   1217 
   1218     @explain_failure_with('UI/Menusvc/MenuHints/NotLookingAtItem')
   1219     def OfferResetCamera(self):
   1220         if not self.IsSpecificItem():
   1221             return False
   1222         if not self.session.IsPilotInShipInSpace():
   1223             return False
   1224         if self.isLookingAtMe():
   1225             return True
   1226         if self.GetCameraInterest() == self.item.itemID:
   1227             return True
   1228         return False
   1229 
   1230     @needs_ballpark_item
   1231     def OfferSafeLogoff(self):
   1232         if not self.IsShip():
   1233             return False
   1234         if self.session.IsPilotInStructure():
   1235             return False
   1236         if not self.IsActiveShip():
   1237             return False
   1238         if self.session.isPilotWarping():
   1239             return False
   1240         if self.IsLoggingOffSafely():
   1241             return False
   1242         return True
   1243 
   1244     @needs_ballpark_item
   1245     def OfferScoopToCargoHold(self):
   1246         if not self.session.IsPilotInShipInSpace():
   1247             return False
   1248         return self.IsScoopable()
   1249 
   1250     @needs_ballpark_item
   1251     def OfferScoopToFighterBay(self):
   1252         if not self.IsFighter():
   1253             return False
   1254         if not self.OfferScoopToCargoHold():
   1255             return False
   1256         shipItem = self.session.getActiveShipGodmaItem()
   1257         return shipItem and shipItem.fighterCapacity
   1258 
   1259     @needs_ballpark_item
   1260     def OfferScoopToFleetHangar(self):
   1261         if not self.OfferScoopToCargoHold():
   1262             return False
   1263         shipItem = self.session.getActiveShipGodmaItem()
   1264         return shipItem and shipItem.hasFleetHangars
   1265 
   1266     @needs_ballpark_item
   1267     def OfferScoopToInfrastructureHold(self):
   1268         if not self.OfferScoopToCargoHold():
   1269             return False
   1270         if not self.IsAllowedInFlag(invConst.flagColonyResourcesHold):
   1271             return False
   1272         shipItem = self.session.getActiveShipGodmaItem()
   1273         return shipItem and shipItem.specialColonyResourcesHoldCapacity
   1274 
   1275     @needs_ballpark_item
   1276     def OfferScoopToMobileDepot(self):
   1277         if not self.IsMobileDepot():
   1278             return False
   1279         if not self.OfferScoopToCargoHold():
   1280             return False
   1281         shipItem = self.session.getActiveShipGodmaItem()
   1282         return shipItem and shipItem.specialMobileDepotHoldCapacity
   1283 
   1284     @needs_ballpark_item
   1285     def OfferScoopToShipMaintenanceBay(self):
   1286         if not self.IsShip():
   1287             return False
   1288         if self.IsMyActiveShip():
   1289             return False
   1290         if self.IsCapsule():
   1291             return False
   1292         shipItem = self.session.getActiveShipGodmaItem()
   1293         return shipItem and shipItem.hasShipMaintenanceBay
   1294 
   1295     @needs_ballpark_item
   1296     def OfferSelfDestructShip(self):
   1297         if self.session.IsPilotInStructure():
   1298             return False
   1299         if not self.IsMyActiveShip():
   1300             return False
   1301         if self.session.isPilotWarping():
   1302             return False
   1303         if self.IsSelfDestructing():
   1304             return False
   1305         return True
   1306 
   1307     @needs_ballpark_item
   1308     def OfferSelfDestructShipOrPod(self):
   1309         if not (self.IsSovereigntyClaimMarker() or self.IsInfrastructureHub()):
   1310             return False
   1311         if not self.IsOwnedByMyCorp():
   1312             return False
   1313         if not self.IsWithinConfigRange():
   1314             return False
   1315         if not self.session.IsCorpDirector():
   1316             return False
   1317         if self.IsSelfDestructing():
   1318             return False
   1319         return True
   1320 
   1321     def OfferSetAsCameraInterest(self):
   1322         if not self.IsSpecificItem():
   1323             return False
   1324         if self.GetCameraInterest() == self.item.itemID:
   1325             return False
   1326         if not self.IsPilotFlyingInSameSystem():
   1327             return False
   1328         if self.session.IsPilotControllingStructure():
   1329             return True
   1330         if self.session.IsPilotDocked():
   1331             return False
   1332         if self.IsSolarsystem():
   1333             return False
   1334         return True
   1335 
   1336     def OfferSetDestination(self):
   1337         if not self.CanBeWaypoint():
   1338             return False
   1339         if self.session.solarsystemid2 == self.item.itemID:
   1340             return False
   1341         waypoints = self.getWaypoints()
   1342         if waypoints and self.item.itemID == waypoints[-1]:
   1343             return False
   1344         return True
   1345 
   1346     def OfferSetHomeStation(self):
   1347         if not self.IsSpecificItem():
   1348             return False
   1349         if IsDeprecatedStation(self.item.typeID):
   1350             return False
   1351         if self.session.IsPilotInShipInSpace():
   1352             return False
   1353         if self.IsStation():
   1354             stationSolarSystemID = self.GetWaypointSolarsystemID()
   1355             return not IsTriglavianSystem(stationSolarSystemID)
   1356         if self.IsDockableStructure() and self.IsStructureInSpace():
   1357             structureSolarSystemID = self.GetWaypointSolarsystemID()
   1358             return not IsTriglavianSystem(structureSolarSystemID)
   1359         return False
   1360 
   1361     def OfferSetName(self):
   1362         if not self.IsSpecificItem():
   1363             return False
   1364         if self.IsDrone() or self.IsFighter() or self.IsBiomass():
   1365             return False
   1366         if self.IsCynoField():
   1367             return False
   1368         if self.IsOrbital():
   1369             return False
   1370         if self.IsMercenaryDen():
   1371             return False
   1372         if self.IsMobileWarpDisruptor():
   1373             return False
   1374         if self.IsRenamingRestrictedForType():
   1375             return False
   1376         if self.IsOwnedByMe():
   1377             return True
   1378         if not self.IsOwnedByMyCorp():
   1379             return False
   1380         if self.IsSovereigntyStructure():
   1381             return False
   1382         if self.IsStructure():
   1383             if self.IsFree():
   1384                 return False
   1385             if not self.IsStructureInSpace():
   1386                 return False
   1387             if self.session.IsStationManager():
   1388                 return True
   1389         if self.session.IsCorpDirector():
   1390             return True
   1391         if not self.session.IsEquipmentConfigurator():
   1392             return False
   1393         if not self.IsInPilotLocation():
   1394             return False
   1395         if self.IsDeployable() or self.IsSecureContainer() or self.IsStarbase():
   1396             return True
   1397         return False
   1398 
   1399     @needs_ballpark_item
   1400     def OfferSetNewConfigPasswordForContainer(self):
   1401         return super(CelestialChecker, self).OfferSetNewConfigPasswordForContainer()
   1402 
   1403     @needs_ballpark_item
   1404     def OfferSetNewPasswordForContainer(self):
   1405         return super(CelestialChecker, self).OfferSetNewPasswordForContainer()
   1406 
   1407     @needs_ballpark_item
   1408     def OfferSetNewPasswordForForceField(self):
   1409         if not self.IsAnchorable():
   1410             return False
   1411         if self.IsFree():
   1412             return False
   1413         if not self.IsControlTower():
   1414             return False
   1415         if not self.IsOwnedByMeOrCorp():
   1416             return False
   1417         if not self.IsWithinConfigRange():
   1418             return False
   1419         return True
   1420 
   1421     def OfferShowLocationOnMap(self):
   1422         if self.IsKnownSpaceSystem():
   1423             return True
   1424         if self.IsKnownSpaceConstellation():
   1425             return True
   1426         if self.IsKnownSpaceRegion():
   1427             return True
   1428         return False
   1429 
   1430     def OfferSimulateShip(self):
   1431         if self.isMultiSelection:
   1432             return False
   1433         if not self.IsShip():
   1434             return False
   1435         if self.IsSpecificItem():
   1436             return False
   1437         return True
   1438 
   1439     @needs_ballpark_item
   1440     def OfferStargateJump(self):
   1441         if not self.IsStargate():
   1442             return False
   1443         if not self.session.IsPilotInShipInSpace():
   1444             return False
   1445         if not self.IsInPilotLocation():
   1446             return False
   1447         if self.isPilotWarpingToMe() or not self.session.isPilotWarping():
   1448             return True
   1449         return False
   1450 
   1451     def _GetShipcasterComponent(self):
   1452         try:
   1453             if self.IsShipcasterStarterLauncher():
   1454                 return self.GetBallpark().componentRegistry.GetComponentForItem(self.item.itemID, componentConst.STARTER_SHIPCASTER)
   1455             if self.IsShipcasterLauncher():
   1456                 return self.GetBallpark().componentRegistry.GetComponentForItem(self.item.itemID, componentConst.SHIPCASTER_LAUNCHER)
   1457         except KeyError:
   1458             pass
   1459 
   1460     @needs_ballpark_item
   1461     def OfferShipcasterJump(self):
   1462         component = self._GetShipcasterComponent()
   1463         if component is None:
   1464             return False
   1465         if not self.session.IsPilotInShipInSpace():
   1466             return False
   1467         if not self.IsInPilotLocation():
   1468             return False
   1469         if self.session.isPilotWarping():
   1470             return False
   1471         warFactionID = self.session.GetWarFactionID()
   1472         if component.OfferJump(warFactionID):
   1473             return True
   1474         if not self.IsCorrectFactionForShipCaster(component):
   1475             return False
   1476         if self.IsShipcasterCharging(component):
   1477             return False
   1478         if not self.IsValidTargetForShipcaster(component):
   1479             return False
   1480         return self.CanCharacterJumpWithShipcaster(component)
   1481 
   1482     @needs_ballpark_item
   1483     def OfferStartConversation(self):
   1484         if not self.IsSpaceAgent():
   1485             return False
   1486         if not self.IsWithinAgentCommsRange():
   1487             return False
   1488         return True
   1489 
   1490     @needs_ballpark_item
   1491     def OfferStopMyShip(self):
   1492         if not self.IsMyActiveShip():
   1493             return False
   1494         if not self.session.IsPilotInShipInSpace():
   1495             return False
   1496         return True
   1497 
   1498     def OfferStopAvoidingLocation(self):
   1499         if not self.OfferShowLocationOnMap():
   1500             return False
   1501         if self.OfferAvoidLocation():
   1502             return False
   1503         return True
   1504 
   1505     @needs_ballpark_item
   1506     def OfferStoreVessel(self):
   1507         if not self.IsSMBShip():
   1508             return False
   1509         if self.IsActiveShip():
   1510             return False
   1511         if not self.session.IsPilotInShipInSpace():
   1512             return False
   1513         activeShip = self.session.getBall()
   1514         if not activeShip:
   1515             return False
   1516         if GetGroupID(activeShip.typeID) == invConst.groupCapsule:
   1517             return False
   1518         if self.IsOwnedByMe():
   1519             return True
   1520         if not self.CanUseShipServices(invConst.flagShipHangar):
   1521             return False
   1522         return self.getDistanceToActiveShip() < appConst.maxConfigureDistance
   1523 
   1524     @needs_ballpark_item
   1525     def OfferStoreVesselInSMA(self):
   1526         if not self.IsAnchorable():
   1527             return False
   1528         if not self.IsShipMaintainanceArray():
   1529             return False
   1530         if not self.IsWithinConfigRange():
   1531             return False
   1532         if not self.IsOwnedByMeMyCorpOrAlliance():
   1533             return False
   1534         if self.IsFree():
   1535             return False
   1536         shipItem = self.session.getActiveShipGodmaItem()
   1537         return shipItem and shipItem.groupID != invConst.groupCapsule
   1538 
   1539     def OfferStructureMenu(self):
   1540         return self.IsStructure()
   1541 
   1542     def OfferTakeControl(self):
   1543         if not self.IsSpecificItem():
   1544             return False
   1545         if not self.IsStructure():
   1546             return False
   1547         if self.session.IsPilotInShipInSpace():
   1548             return False
   1549         if self.session.IsPilotControllingStructure():
   1550             return False
   1551         if not self.session.IsPilotInStructure():
   1552             return False
   1553         if self.session.structureid == self.item.itemID:
   1554             if self.session.IsElevatedPlayer():
   1555                 return True
   1556             return self.sm.GetService('structureControl').MayTakeControl(self.item.itemID)
   1557         return False
   1558 
   1559     def OfferTransferStructureOwnership(self):
   1560         if not self.IsSpecificItem():
   1561             return False
   1562         if not self.IsStructure():
   1563             return False
   1564         if not self.IsStructureInSpace():
   1565             return False
   1566         if not self.IsStructureOnline():
   1567             return False
   1568         if not self.IsStructureOwnedByMyCorp():
   1569             return False
   1570         if not self.session.IsCorpDirector():
   1571             return False
   1572         return True
   1573 
   1574     @needs_ballpark_item
   1575     def OfferTransferCorporationOwnershipPoco(self):
   1576         if not self.IsOrbital():
   1577             return False
   1578         if self.IsOrbitalSkyhook():
   1579             return False
   1580         if not self.IsOrbitalAnchored():
   1581             return False
   1582         if self.IsOrbitalConstructionPlatform():
   1583             return False
   1584         if not self.IsOwnedByMyCorp():
   1585             return False
   1586         if not self.session.IsCorpDirector():
   1587             return False
   1588         if len(self.GetOrbitalsAtPlanet()) > 1:
   1589             return False
   1590         return True
   1591 
   1592     @needs_ballpark_item
   1593     def OfferTransferCorporationOwnershipSkyhook(self):
   1594         if not self.IsOrbitalSkyhook():
   1595             return False
   1596         if self.IsOrbitalConstructionPlatform():
   1597             return False
   1598         if not self.IsOwnedByMyCorp():
   1599             return False
   1600         if not self.session.IsCorpDirector():
   1601             return False
   1602         if len(self.GetOrbitalsAtPlanet()) > 1:
   1603             return False
   1604         return True
   1605 
   1606     @needs_ballpark_item
   1607     def OfferTransferSovStructureOwnership(self):
   1608         if not (self.IsSovereigntyClaimMarker() or self.IsInfrastructureHub()):
   1609             return False
   1610         if not self.IsOwnedByMyCorp():
   1611             return False
   1612         if not self.session.IsCorpDirector():
   1613             return False
   1614         if not self.IsWithinConfigRange():
   1615             return False
   1616         return True
   1617 
   1618     @needs_ballpark_item
   1619     def OfferUnanchorOrbital(self):
   1620         if not (self.IsOrbital() or self.IsPlanetaryCustomsOffice()):
   1621             return False
   1622         if not self.IsAnchorable():
   1623             return False
   1624         if not self.IsOrbitalAnchored():
   1625             return False
   1626         if not self.CanUnanchorOrbital():
   1627             return False
   1628         if not self.IsOwnedByMyCorp():
   1629             return False
   1630         return True
   1631 
   1632     @needs_ballpark_item
   1633     def OfferUnanchorPOSObject(self):
   1634         if not self.IsAnchorable():
   1635             return False
   1636         if not self.IsWithinConfigRange():
   1637             return False
   1638         if not self.IsOwnedByMeOrCorp():
   1639             return False
   1640         if self.IsFree():
   1641             return False
   1642         if not self.GetStateManager().TypeHasEffect(self.item.typeID, dogmaConst.effectAnchorLift):
   1643             return False
   1644         return True
   1645 
   1646     @needs_ballpark_item
   1647     def OfferUnanchorStructure(self):
   1648         if not self.IsPOSStructure():
   1649             return False
   1650         if not self.IsAnchorable():
   1651             return False
   1652         if not self.IsWithinConfigRange():
   1653             return False
   1654         if not (self.IsOwnedByMeMyCorpOrAlliance() or self.IsOrphanedStructure()):
   1655             return False
   1656         if not self.CanUnanchorStructure():
   1657             return False
   1658         return True
   1659 
   1660     def OfferUndock(self):
   1661         if self.session.IsPilotControllingStructure():
   1662             return False
   1663         if not self.session.IsPilotInStructure():
   1664             return False
   1665         if self.item.itemID == self.session.structureid:
   1666             return True
   1667         return False
   1668 
   1669     @needs_ballpark_item
   1670     def OfferUnlockStructureTarget(self):
   1671         if not self.IsPOSStructure():
   1672             return False
   1673         if self.IsSovereigntyStructure():
   1674             return False
   1675         if not self.IsAnchorable():
   1676             return False
   1677         if not self.IsOwnedByMeMyCorpOrAlliance():
   1678             return False
   1679         if not self.CanAssumeControlOfStructure():
   1680             return False
   1681         if not self.IsControlledByPilot():
   1682             return False
   1683         if self.GetStructureTarget() is None:
   1684             return False
   1685         return True
   1686 
   1687     @needs_ballpark_item
   1688     def OfferUnlockTarget(self):
   1689         return self.IsTarget() and not self.IsBeingTargetLocked()
   1690 
   1691     @needs_ballpark_item
   1692     def OfferCancelLockTarget(self):
   1693         return self.IsBeingTargetLocked()
   1694 
   1695     @needs_ballpark_item
   1696     def OfferUseFittingService(self):
   1697         if not self.session.IsPilotInShipInSpace():
   1698             return False
   1699         if self.session.IsPilotControllingStructure():
   1700             return False
   1701         if not self.IsInPilotLocation():
   1702             return False
   1703         if HasFittingComponent(self.item.typeID):
   1704             if IsShipWithinFittingRange(self.session.getActiveShipGodmaItem(), self.item, self.GetBallpark()):
   1705                 return True
   1706         elif self.IsSMBShip():
   1707             if self.session.isPilotInSameCorpAs(self.item.ownerID) or self.session.isPilotInSameFleetAs(self.item.ownerID):
   1708                 return True
   1709         elif self.IsPOSMaintainanceArray():
   1710             if self.IsFree():
   1711                 return False
   1712             if not self.IsOwnedByMeMyCorpOrAlliance():
   1713                 return False
   1714             if not self.IsWithinConfigRange():
   1715                 return False
   1716             return True
   1717         return False
   1718 
   1719     @needs_ballpark_item
   1720     def OfferViewLog(self):
   1721         return super(CelestialChecker, self).OfferViewLog()
   1722 
   1723     def OfferViewPlanetaryProduction(self):
   1724         if not self.IsSpecificItem():
   1725             return False
   1726         if not self.IsPlanet():
   1727             return False
   1728         return self.getViewedPlanet() != self.item.itemID
   1729 
   1730     def OfferViewTypesMarketDetails(self):
   1731         if self.GetMarketGroup() is None:
   1732             return False
   1733         return True
   1734 
   1735     @needs_ballpark_item
   1736     def OfferWarpTo(self):
   1737         return self._CanWarpToItem()
   1738 
   1739     @needs_ballpark_item
   1740     def OfferWarpToMoonMiningPoint(self):
   1741         if not self.IsMoon():
   1742             return False
   1743         if not self.session.IsPilotInShipInSpace():
   1744             return False
   1745         if not self.IsInPilotLocation():
   1746             return False
   1747         position = self.GetMiningBeaconPosition()
   1748         if not position:
   1749             return False
   1750         if self.session.isPilotWarping():
   1751             return False
   1752         distance = self.getDistanceToActiveShip()
   1753         if not self.session.isInWarpRange(distance):
   1754             return False
   1755         return True
   1756 
   1757     def IsAllowedInFlag(self, flagID):
   1758         return ShouldAllowAdd(flagID, self.item.categoryID, self.item.groupID, self.item.typeID) is None
   1759 
   1760     def isAvoided(self):
   1761         return self.item.itemID in self.sm.GetService('clientPathfinderService').GetAvoidanceItems()
   1762 
   1763     @explain_failure_with('UI/Menusvc/MenuHints/BeingTargeted')
   1764     def IsBeingTargetLocked(self):
   1765         return self.sm.StartService('target').BeingTargeted(self.item.itemID)
   1766 
   1767     @explain_failure_with('UI/Menusvc/MenuHints/NotActive')
   1768     def IsComponentActive(self):
   1769         return IsActiveComponent(self.GetBallpark().componentRegistry, self.item.typeID, self.item.itemID)
   1770 
   1771     def IsConnectedJumpBridgeStructure(self):
   1772         if not IsUpwellStargate(self.item.typeID):
   1773             return False
   1774         if not HasJumpBridgeComponent(self.item.typeID):
   1775             return False
   1776         if not getattr(self.item, 'targetSolarsystemID', None):
   1777             return False
   1778         return True
   1779 
   1780     def IsControlledByPilot(self):
   1781         return self.GetStructureController() == self.session.charid
   1782 
   1783     @explain_failure_with('UI/Menusvc/MenuHints/ShipcasterIncorrectFaction')
   1784     def IsCorrectFactionForShipCaster(self, shipcasterLauncherComponent):
   1785         warFactionID = self.session.GetWarFactionID()
   1786         if warFactionID not in shipcasterLauncherComponent.validFactionIDsForUse:
   1787             return False
   1788         if warFactionID == shipcasterLauncherComponent.nextTargetFactionID:
   1789             return True
   1790         return False
   1791 
   1792     def IsDead(self):
   1793         ball = self.GetBall()
   1794         return ball is None or ball.isMoribund
   1795 
   1796     def IsDockable(self):
   1797         return self.IsStation() or self.IsDockableStructure()
   1798 
   1799     def IsFacility(self):
   1800         return self.sm.GetService('facilitySvc').IsFacility(self.item.itemID)
   1801 
   1802     @explain_failure_with('UI/Menusvc/MenuHints/CantWarpTo')
   1803     def IsFree(self):
   1804         try:
   1805             return self.GetBall().isFree
   1806         except AttributeError:
   1807             return False
   1808 
   1809     @explain_failure_with('UI/Menusvc/MenuHints/NotInApproachRange')
   1810     def isInApproachRange(self, distance):
   1811         return distance is not None and distance < appConst.maxApproachDistance
   1812 
   1813     @staticmethod
   1814     def isInFleetBroadcastRange(distance):
   1815         return distance is not None and distance < appConst.maxFleetBroadcastTargetDistance
   1816 
   1817     @explain_failure_with('UI/Menusvc/MenuHints/NotInOrbitRange')
   1818     def isInOrbitRange(self, distance):
   1819         return distance is not None and distance < appConst.maxApproachDistance
   1820 
   1821     def IsInSpace(self):
   1822         return IsSolarSystem(getattr(self.item, 'locationID', 0))
   1823 
   1824     @explain_failure_with('UI/Menusvc/MenuHints/NotWithingMaxJumpDist')
   1825     def isInStargateJumpRange(self, distance):
   1826         return distance is not None and distance < appConst.maxStargateJumpingDistance
   1827 
   1828     @explain_failure_with('UI/Menusvc/MenuHints/LocationNotInSystem')
   1829     def IsPilotFlyingInSameSystem(self):
   1830         return self.session.IsPilotInShipInSpace() and self.item.locationID == self.session.solarsystemid
   1831 
   1832     @explain_failure_with('UI/Menusvc/MenuHints/LocationNotInSystem')
   1833     def IsPilotingStructureInSystem(self):
   1834         return self.session.IsPilotControllingStructure() and not self.session.IsPilotControllingUndockableStructure() and self.item.locationID == self.session.solarsystemid
   1835 
   1836     @explain_failure_with('UI/Menusvc/MenuHints/ShipAlreadyPiloted')
   1837     def IsInteractive(self):
   1838         ball = self.GetBall()
   1839         return ball and ball.isInteractive
   1840 
   1841     @explain_failure_with('UI/Menusvc/MenuHints/NotInRange')
   1842     def isInTransferRange(self, distance):
   1843         return distance is not None and distance < max(getattr(self.GetStateManager().GetType(self.item.typeID), 'maxOperationalDistance', 0), const.maxCargoContainerTransferDistance)
   1844 
   1845     def IsLoggingOffSafely(self):
   1846         return self.sm.GetService('viewState').SafeLogoffInProgress()
   1847 
   1848     @explain_failure_with('UI/Menusvc/MenuHints/AlreadyLookingAtItem')
   1849     def isLookingAtMe(self):
   1850         return self.sm.GetService('sceneManager').GetActiveSpaceCamera().GetLookAtItemID() == self.item.itemID
   1851 
   1852     def IsPilotControllingStructureWithFightersSelected(self):
   1853         if not self.session.IsPilotControllingStructure():
   1854             return False
   1855         shipItem = self.session.getActiveShipGodmaItem()
   1856         if not shipItem:
   1857             return False
   1858         if not bool(self.godma.GetType(shipItem.typeID).fighterCapacity):
   1859             return False
   1860         selectedItemIDs = set(sm.GetService('stateSvc').GetStatesForFlag(selectedForNavigation))
   1861         if not selectedItemIDs:
   1862             return False
   1863         return bool({f for f in self.sm.GetService('fighters').shipFighterState.GetAllFighterIDsInSpace()} & selectedItemIDs)
   1864 
   1865     @explain_failure_with('UI/Menusvc/MenuHints/AutopilotNotActive')
   1866     def IsOnAutoPilot(self):
   1867         return bool(self.sm.StartService('autoPilot').GetState())
   1868 
   1869     def IsOrbitalAnchored(self):
   1870         from eve.common.script.mgt import entityConst
   1871         return hasattr(self.item, 'orbitalState') and self.item.orbitalState == entityConst.STATE_ANCHORED
   1872 
   1873     def IsOrphanedStructure(self):
   1874         return self.sm.GetService('pwn').StructureIsOrphan(self.item.itemID)
   1875 
   1876     @explain_failure_with('UI/Menusvc/MenuHints/AutopilotActive')
   1877     def IsNotOnAutoPilot(self):
   1878         return not self.IsOnAutoPilot()
   1879 
   1880     @explain_failure_with('UI/Menusvc/MenuHints/Unavailable')
   1881     def IsOwnedByNPC(self):
   1882         return IsNPC(self.item.ownerID)
   1883 
   1884     def isPilotWarpingToMe(self):
   1885         if not self.session.isPilotWarping():
   1886             return False
   1887         try:
   1888             return sm.GetService('space').warpDestinationCache[0] == self.item.itemID
   1889         except Exception:
   1890             return False
   1891 
   1892     @explain_failure_with('UI/Menusvc/MenuHints/BadGroupForAction', groupName=(GetGroupNameByGroup, 'groupID'))
   1893     def IsPlanetMoonAsteroidBelt(self):
   1894         return self.IsPlanet() or self.IsMoon() or self.IsAsteroidBelt()
   1895 
   1896     def IsPOSStructure(self):
   1897         return self.IsStarbase() or self.IsSovereigntyStructure()
   1898 
   1899     def IsScoopable(self):
   1900         if self.IsNonScoopableType():
   1901             return False
   1902         shipItem = self.session.getActiveShipGodmaItem()
   1903         if shipItem is None:
   1904             return False
   1905         if self.IsBiomass() or self.IsDrone():
   1906             return True
   1907         if self.IsStructure() and self.IsFree():
   1908             return True
   1909         if self.IsDead():
   1910             return False
   1911         if HasScoopComponent(self.item.typeID) and IsActiveComponent(self.GetBallpark().componentRegistry, self.item.typeID, self.item.itemID):
   1912             return self.IsOwnedByMe()
   1913         if shipItem.groupID in (invConst.groupFreighter, invConst.groupJumpFreighter):
   1914             if self.IsFreightContainer():
   1915                 return True
   1916             if self.IsAnchorable() and self.IsFree() and not (self.IsSecureAuditLogContainer() or self.IsSecureContainer() or self.IsCargoContainer()):
   1917                 return True
   1918             return False
   1919         if self.IsAnchorable() and self.IsFree():
   1920             return True
   1921         if self.IsCargoContainer() or self.IsFreightContainer():
   1922             return True
   1923         if self.IsFighter() and self.sm.GetService('fighters').shipFighterState.GetFighterInSpaceByID(self.item.itemID) is None:
   1924             return True
   1925         return False
   1926 
   1927     def IsSelfDestructing(self):
   1928         return getattr(self.item, 'selfDestructTime', None) is not None
   1929 
   1930     @explain_failure_with('UI/Menusvc/MenuHints/ShipcasterIsCharging')
   1931     def IsShipcasterCharging(self, shipcasterLauncherComponent):
   1932         return shipcasterLauncherComponent.IsCharging()
   1933 
   1934     def IsSolarSystemReachableThroughJumpGate(self, solarsystemID):
   1935         jumpGateSlimItem = FindLocalJumpGateForDestinationPath(solarsystemID)
   1936         if jumpGateSlimItem:
   1937             return True
   1938         return False
   1939 
   1940     @explain_failure_with('UI/Menusvc/MenuHints/IsNotAnAgent')
   1941     def IsSpaceAgent(self):
   1942         return self.item.groupID in (invConst.groupAgentsinSpace, invConst.groupDestructibleAgentsInSpace) and bool(self.godma.GetType(self.item.typeID).agentID)
   1943 
   1944     def IsSpecialMaterialHoldsItem(self):
   1945         return bool(self.GetStateManager().GetType(self.item.typeID).specialMaterialBayCapacity)
   1946 
   1947     def IsSpecificItem(self):
   1948         return hasattr(self.item, 'itemID') and isinstance(self.item.itemID, (int, long)) and self.item.itemID > 0
   1949 
   1950     def IsStation(self):
   1951         return self.item.groupID == invConst.groupStation
   1952 
   1953     def IsStructureInSpace(self):
   1954         if not self.IsStructure():
   1955             return False
   1956         if not self.IsSpecificItem():
   1957             return False
   1958         structureDirectory = self.sm.GetService('structureDirectory')
   1959         structureInfo = structureDirectory.GetStructureInfo(self.item.itemID)
   1960         if structureInfo is None:
   1961             return False
   1962         if not structureInfo.inSpace:
   1963             return False
   1964         solarsystemID = structureInfo.solarSystemID
   1965         if solarsystemID == self.session.solarsystemid2 and self.session.IsPilotInShipInSpace() or self.session.IsPilotControllingStructure():
   1966             bp = self.GetBallpark()
   1967             if bp:
   1968                 return self.item.itemID in bp.balls
   1969         return True
   1970 
   1971     @explain_failure_with('UI/Menusvc/MenuHints/StructureIsNotOnline')
   1972     def IsStructureOnline(self):
   1973         if not self.IsSpecificItem():
   1974             return False
   1975         if not self.IsStructure():
   1976             return False
   1977         return getattr(self.item, 'state', STATE_UNKNOWN) not in OFFLINE_STATES
   1978 
   1979     def IsStructureInState(self, stateID):
   1980         if not self.IsSpecificItem():
   1981             return False
   1982         if not self.IsStructure():
   1983             return False
   1984         return getattr(self.item, 'state', STATE_UNKNOWN) == stateID
   1985 
   1986     def IsStructureUpkeep(self, upkeepState):
   1987         if upkeepState not in ALL_UPKEEP_STATES:
   1988             raise ValueError('upkeepState must be one of ALL_UPKEEP_STATES')
   1989         if not self.IsSpecificItem():
   1990             return False
   1991         if not self.IsStructure():
   1992             return False
   1993         return getattr(self.item, 'upkeepState', None) == upkeepState
   1994 
   1995     def CanEditAbandonTimer(self):
   1996         return self.IsStructureUpkeep(UPKEEP_STATE_LOW_POWER) and self.item.typeID not in TYPES_THAT_NEVER_GO_ABANDONED
   1997 
   1998     def IsStructureOwnedByMyCorp(self):
   1999         if not self.IsStructure():
   2000             return False
   2001         if not self.IsSpecificItem():
   2002             return False
   2003         structureInfo = self.sm.GetService('structureDirectory').GetStructureInfo(self.item.itemID)
   2004         if not structureInfo:
   2005             return False
   2006         return structureInfo.ownerID == self.session.corpid
   2007 
   2008     @explain_failure_with('UI/Menusvc/MenuHints/NotInTargets')
   2009     def IsTarget(self):
   2010         return self.item.itemID in self.sm.StartService('target').GetTargets()
   2011 
   2012     @explain_failure_with('UI/Menusvc/MenuHints/AlreadyTargeted')
   2013     def IsNotTarget(self):
   2014         return not self.IsTarget()
   2015 
   2016     def IsRandomTraceJumpGate(self):
   2017         return self.item.typeID in [const.typeTriglavianSpaceTrace, const.typeYoiulTrace, const.typeNeedlejackTrace]
   2018 
   2019     def IsRenamingRestrictedForType(self):
   2020         if not IsContentComplianceControlSystemActive(self.sm.GetService('machoNet')):
   2021             return False
   2022         return self.item.typeID in _GetTypesWithRestrictedRenaming()
   2023 
   2024     @explain_failure_with('UI/Menusvc/MenuHints/CannotKeepInRange', groupName=(GetGroupNameByGroup, 'groupID'))
   2025     def IsValidForKeepAtRange(self):
   2026         if self.item.categoryID == const.categoryAsteroid:
   2027             return False
   2028         if self.item.groupID in {invConst.groupHarvestableCloud,
   2029          invConst.groupMiningDrone,
   2030          invConst.groupCargoContainer,
   2031          invConst.groupSecureCargoContainer,
   2032          invConst.groupAuditLogSecureContainer,
   2033          invConst.groupStation,
   2034          invConst.groupStargate,
   2035          invConst.groupFreightContainer,
   2036          invConst.groupWreck}:
   2037             return False
   2038         return True
   2039 
   2040     @explain_failure_with('UI/Menusvc/MenuHints/NotValidTargetForShipcaster')
   2041     def IsValidTargetForShipcaster(self, shipcasterLauncherComponent):
   2042         if shipcasterLauncherComponent.targetSolarsystemID:
   2043             return True
   2044         return False
   2045 
   2046     def IsViewedWreck(self):
   2047         if not self.IsWreck():
   2048             return False
   2049         return self.sm.GetService('wreck').IsViewedWreck(self.item.itemID)
   2050 
   2051     def isWaypoint(self, itemID = None):
   2052         checkID = itemID or self.item.itemID
   2053         return checkID in self.getWaypoints()
   2054 
   2055     @explain_failure_with('UI/Menusvc/MenuHints/NotAccelerationGate')
   2056     def IsWarpGate(self):
   2057         return self.item.groupID == invConst.groupWarpGate or self.IsAbyssEntranceGate()
   2058 
   2059     def IsWithinAgentCommsRange(self):
   2060         dist = self.getDistanceToActiveShip()
   2061         if dist is None:
   2062             return False
   2063         return dist < self.godma.GetType(self.item.typeID).agentCommRange
   2064 
   2065     @explain_failure_with('UI/Menusvc/MenuHints/NotWithinMaxConfigDist')
   2066     def IsWithinConfigRange(self):
   2067         bp = self.GetBallpark()
   2068         if bp is None:
   2069             return False
   2070         try:
   2071             distance = self.GetBall().surfaceDist
   2072         except AttributeError:
   2073             return False
   2074 
   2075         if distance < appConst.maxConfigureDistance:
   2076             return True
   2077         if bp.IsShipInRangeOfStructureControlTower(self.session.shipid, self.item.itemID):
   2078             return True
   2079 
   2080     @explain_failure_with('UI/Menusvc/MenuHints/NotInTargetRange')
   2081     def IsWithinTargettingRange(self):
   2082         dist = self.getDistanceToActiveShip()
   2083         if dist is None:
   2084             return False
   2085         shipItem = self.session.getActiveShipGodmaItem()
   2086         return shipItem and dist < shipItem.maxTargetRange
   2087 
   2088     @explain_failure_with('UI/Menusvc/MenuHints/NotWithinMaxTranferDistance')
   2089     def IsWithinTransferRange(self):
   2090         bp = self.GetBallpark()
   2091         return bp and bp.IsShipInRangeOfStructureControlTower(self.session.shipid, self.item.itemID)
   2092 
   2093     @explain_failure_with('UI/Menusvc/MenuHints/NotWithinMaxTranferDistance')
   2094     def IsWithinInventoryAccessRange(self):
   2095         dist = self.getDistanceToActiveShip()
   2096         if dist is None:
   2097             return False
   2098         return dist < const.maxCargoContainerTransferDistance
   2099 
   2100     def IsWormhole(self):
   2101         return self.item.groupID == invConst.groupWormhole
   2102 
   2103     def IsWreck(self):
   2104         return self.item.groupID == invConst.groupWreck
   2105 
   2106     @explain_failure_with('UI/Menusvc/MenuHints/ShipcasterCantJump')
   2107     def CanCharacterJumpWithShipcaster(self, shipcasterLauncherComponent):
   2108         return shipcasterLauncherComponent.CanCharacterJump(self.session.GetWarFactionID())
   2109 
   2110     @explain_failure_with('UI/Menusvc/MenuHints/OutsideLookingRange')
   2111     def canLookAt(self):
   2112         return self.GetBall() is not None
   2113 
   2114     def CanOfflineStructure(self):
   2115         return self.GetBall() and self.sm.GetService('pwn').CanOfflineStructure(self.item.itemID)
   2116 
   2117     def CanOnlineStructure(self):
   2118         if self.IsDeprecatedPosModule():
   2119             return False
   2120         return self.GetBall() and self.sm.GetService('pwn').CanOnlineStructure(self.item.itemID)
   2121 
   2122     def CanAnchorOrbital(self):
   2123         from eve.common.script.mgt import entityConst
   2124         return hasattr(self.item, 'orbitalState') and self.item.orbitalState in (None, entityConst.STATE_UNANCHORED)
   2125 
   2126     def CanAnchorStructure(self):
   2127         if self.IsDeprecatedPosModule():
   2128             return False
   2129         return self.GetBall() and self.sm.GetService('pwn').CanAnchorStructure(self.item.itemID)
   2130 
   2131     def CanAssumeControlOfStructure(self):
   2132         return self.GetBall() and self.sm.GetService('pwn').CanAssumeControlStructure(self.item.itemID)
   2133 
   2134     def CanBeWaypoint(self):
   2135         if not self.IsSpecificItem():
   2136             return False
   2137         return bool(self.GetWaypointSolarsystemID())
   2138 
   2139     def CanUnanchorOrbital(self):
   2140         return self.GetBall() and self.IsOrbitalConstructionPlatform()
   2141 
   2142     def CanUnanchorStructure(self):
   2143         return self.GetBall() and self.sm.GetService('pwn').CanUnanchorStructure(self.item.itemID)
   2144 
   2145     def CanUseShipServices(self, serviceFlag):
   2146         shipOwner = self.item.ownerID
   2147         inSameCorp = self.session.isPilotInSameCorpAs(shipOwner)
   2148         inSameFleet = self.session.isPilotInSameFleetAs(shipOwner)
   2149         if not (inSameCorp or inSameFleet):
   2150             return False
   2151         config = self.GetShipConfig(self.item.itemID)
   2152         if serviceFlag == invConst.flagFleetHangar and config['FleetHangar_AllowCorpAccess'] and inSameCorp or config['FleetHangar_AllowFleetAccess'] and inSameFleet:
   2153             return True
   2154         if serviceFlag == invConst.flagShipHangar and config['SMB_AllowCorpAccess'] and inSameCorp or config['SMB_AllowFleetAccess'] and inSameFleet:
   2155             return True
   2156         return False
   2157 
   2158     def _CanWarpToItem(self):
   2159         if self.IsActiveShip():
   2160             return False
   2161         if not self.IsInPilotLocation():
   2162             return False
   2163         if self.session.isPilotWarping():
   2164             return False
   2165         if not self.session.isInWarpRange(self.getDistanceToActiveShip()):
   2166             return False
   2167         if not self.IsPilotFlyingInSameSystem():
   2168             return False
   2169         if self.IsAsteroid():
   2170             return True
   2171         if self.IsStructure():
   2172             return True
   2173         if self.IsOrbital():
   2174             return True
   2175         if self.ShouldNotTreatBookmarkAsSolarSystem():
   2176             return True
   2177         if self.IsShip() and self.session.isPilotInSameFleetAs(self.item.ownerID):
   2178             return True
   2179         if not self.IsFree():
   2180             return True
   2181         return False
   2182 
   2183     def GetActiveFleetBridge(self):
   2184         return self.sm.GetService('fleet').GetActiveBridgeForShip(self.item.itemID)
   2185 
   2186     def GetAttributeDict(self):
   2187         return self.sm.GetService('info').GetAttributeDictForType(self.item.typeID)
   2188 
   2189     def GetBall(self):
   2190         if not self.IsSpecificItem():
   2191             return None
   2192         return self.session.getBall(self.item.itemID)
   2193 
   2194     def GetCameraInterest(self):
   2195         activeCamera = self.sm.GetService('sceneManager').GetActiveSpaceCamera()
   2196         if activeCamera:
   2197             return activeCamera.GetTrackItemID()
   2198 
   2199     def GetJumpInfo(self):
   2200         return getattr(self.item, 'jumps', [None])[0]
   2201 
   2202     @explain_failure_with('UI/Moonmining/MoonHasNoMiningPoint')
   2203     def GetMiningBeaconPosition(self):
   2204         return GetMiningBeaconPositionForMoon(self.item.itemID)
   2205 
   2206     def GetMoonsForPlanet(self):
   2207         return self.sm.GetService('map').GetPlanetMoonsInPlayerSystem(self.item.itemID)
   2208 
   2209     def GetOrbitalsAtPlanet(self):
   2210         return list(self.sm.GetService('planetInfo').GetOrbitalsAtPlanet(self.item.itemID))
   2211 
   2212     def GetPocoOrbitals(self):
   2213         return list(self.sm.GetService('planetInfo').GetPocosForPlanet(self.item.itemID))
   2214 
   2215     def GetSkyhookOrbitals(self):
   2216         return list(self.sm.GetService('planetInfo').GetSkyhooksAtPlanet(self.item.itemID))
   2217 
   2218     def GetShipConfig(self, shipID):
   2219         return self.sm.GetService('shipConfig').GetShipConfig(shipID)
   2220 
   2221     def GetStructureController(self):
   2222         return getattr(self.item, 'controllerID', None)
   2223 
   2224     def GetStructureTarget(self):
   2225         ball = self.GetBall()
   2226         if ball:
   2227             return self.sm.GetService('pwn').GetCurrentTarget(self.item.itemID)
   2228 
   2229     def GetWaypointSolarsystemID(self):
   2230         if self.IsSolarsystem():
   2231             return self.item.itemID
   2232         if self.IsStation() and not IsDeprecatedStation(self.item.typeID):
   2233             return self.cfg.stations.Get(self.item.itemID).solarSystemID
   2234         if self.IsStructure():
   2235             try:
   2236                 structureInfo = self.cfg.evelocations.Get(self.item.itemID)
   2237                 if structureInfo.solarSystemID:
   2238                     return structureInfo.solarSystemID
   2239             except (KeyError, ValueError):
   2240                 pass
   2241 
   2242             structureInfo = self.sm.GetService('structureDirectory').GetStructureInfo(self.item.itemID)
   2243             if structureInfo and structureInfo.inSpace:
   2244                 return structureInfo.solarSystemID
   2245 
   2246     def getWaypoints(self):
   2247         return self.sm.GetService('starmap').GetWaypoints()