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

lpOfferEntry.py (19059B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\station\loyaltyPointStore\lpOfferEntry.py
      2 import evetypes
      3 import localization
      4 import logging
      5 import trinity
      6 import uthread
      7 import utillib
      8 from carbonui import uiconst
      9 from carbonui.control.button import Button
     10 from carbonui.button.const import HEIGHT_NORMAL
     11 from carbonui.control.scrollentries import SE_BaseClassCore
     12 from carbonui.control.singlelineedits.singleLineEditInteger import SingleLineEditInteger
     13 from carbonui.primitives.container import Container
     14 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     15 from carbonui.primitives.sprite import Sprite
     16 from carbonui.uicore import uicore
     17 from carbonui.util.color import Color
     18 from signals import Signal
     19 from dogma import const as dogmaconst
     20 from eve.client.script.ui.control import eveIcon
     21 from eve.client.script.ui.control.eveIcon import OwnerIcon
     22 from eve.client.script.ui.control.infoIcon import InfoIcon
     23 from eve.client.script.ui.control.utilMenu import ExpandedUtilMenu
     24 from shipcosmetics.common.const import CosmeticsType
     25 from cosmetics.common.cosmeticsConst import BACKGROUND_PATH_BY_TYPE
     26 from shipcosmetics.client.licensegateway.licenseSignals import on_ship_cosmetics_license_change
     27 from eve.client.script.ui.station.loyaltyPointStore.lpLabels import LPStoreEntryLabel
     28 from eve.client.script.ui.station.loyaltyPointStore.lpUtil import GetItemText
     29 from eve.client.script.ui.station.lpstoreRequirement import getContainerName, getLabelName
     30 from eve.common.lib import appConst
     31 from inventorycommon import const as invconst
     32 from localization import GetByLabel
     33 logger = logging.getLogger(__name__)
     34 
     35 class LPOfferEntry(SE_BaseClassCore):
     36     __guid__ = 'listentry.LPOffer'
     37     iconSize = 64
     38     iconMargin = 2
     39     lineHeight = 1
     40     labelMargin = 6
     41     entryHeight = 88
     42 
     43     def ApplyAttributes(self, attributes):
     44         self.godma = sm.GetService('godma')
     45         self.lpSvc = sm.GetService('lpstore')
     46         self.node = attributes.node
     47         self.typeID = self.node.typeID
     48         self.qty = self.node.Get('qty', 1)
     49         self.reqItems = self.node.Get('reqItems', [])
     50         self.lootItems = self.node.Get('lootItems', [])
     51         self.lpOfferRequirementColumns = self.lpSvc.GetRequirements(self.node.corpID)
     52         self.requiredStandings = self.node.Get('requiredStandings', None)
     53         SE_BaseClassCore.ApplyAttributes(self, attributes)
     54         self.amountEdit = None
     55         self._AddRewardColumn()
     56         self._AddRequirementColumns()
     57         if self.requiredStandings:
     58             self._AddStandingsColumn()
     59         self.AddBuyButton()
     60 
     61     def _AddRewardColumn(self):
     62         self.sr.rewardParent = Container(parent=self, name='rewardParent', align=uiconst.TOLEFT, state=uiconst.UI_PICKCHILDREN)
     63         self.sr.rewardIconParent = Container(parent=self.sr.rewardParent, name='rewardIconParent', align=uiconst.TOLEFT, width=self.entryHeight, padright=self.labelMargin)
     64         self.sr.rewardInfoIcon = InfoIcon(parent=self.sr.rewardIconParent, align=uiconst.TOPRIGHT, left=10, top=10)
     65         self.CreateIcon()
     66         self.AddRewardLabel()
     67 
     68     def CreateIcon(self):
     69         self.sr.icon = eveIcon.Icon(name='logoIcon', parent=self.sr.rewardIconParent, size=self.iconSize, ignoreSize=True, align=uiconst.CENTER, state=uiconst.UI_DISABLED)
     70 
     71     def _AddRequirementColumns(self):
     72         for requirement in self.lpOfferRequirementColumns:
     73             self._AddRequirementColumn(requirement)
     74 
     75     def _AddRequirementColumn(self, requirement):
     76         parentContainerName = getContainerName(requirement)
     77         labelName = getLabelName(requirement)
     78         notFulfilledHintPath = requirement.notFulfilledHintPath
     79         parentContainer = Container(name=parentContainerName, parent=self, state=uiconst.UI_PICKCHILDREN, align=uiconst.TOLEFT, clipChildren=True)
     80         label = LPStoreEntryLabel(parent=parentContainer, name=labelName, left=self.labelMargin, align=uiconst.CENTERLEFT, color=self.GetRowContentTint(), opacity=0.7 if self.node.isOwned else 1.0)
     81         self.sr[labelName] = label
     82         if notFulfilledHintPath:
     83             self.sr[labelName].hint = localization.GetByLabel(notFulfilledHintPath)
     84 
     85     def GetRowContentTint(self):
     86         return LPStoreEntryLabel.default_color
     87 
     88     def _AddStandingsColumn(self):
     89         ownerID = self.requiredStandings['ownerID']
     90         standingsValue = self.requiredStandings['value']
     91         container = Container(name='requiredStandingsParent', parent=self, align=uiconst.TOLEFT, clipChildren=True)
     92         standingsLabel = LPStoreEntryLabel(parent=container, name='requiredStandingsLabel', state=uiconst.UI_NORMAL, align=uiconst.CENTERLEFT, left=self.labelMargin, text=u'{:6.2f}'.format(standingsValue))
     93         standingsLabel.hint = localization.GetByLabel('UI/Standings/Restricted', from_id=ownerID, to_id=session.charid, required_standing=standingsValue, current_standing=sm.GetService('standing').GetStandingWithSkillBonus(ownerID, session.charid))
     94         if not self.lpSvc.IsStandingsFulfilled(self.node):
     95             standingsLabel.color = Color.RED
     96         OwnerIcon(parent=container, name='requiredStandingsIcon', align=uiconst.CENTERLEFT, left=standingsLabel.width + 8, size=36, width=36, height=36, ownerID=ownerID)
     97 
     98     def AddRewardLabel(self):
     99         self.sr.rewardLabel = LPStoreEntryLabel(parent=self.sr.rewardParent, align=uiconst.TOTOP, padTop=4, maxLines=3)
    100 
    101     def AddBuyButton(self):
    102         buyBtnCont = Container(parent=self.sr.rewardParent, name='buyBtnCont', state=uiconst.UI_PICKCHILDREN, align=uiconst.TOTOP, height=HEIGHT_NORMAL, padTop=4)
    103         self.sr.buyBtn = Button(name='buyBtn', parent=buyBtnCont, label=localization.GetByLabel('UI/VirtualGoodsStore/Buttons/Buy'), align=uiconst.TOLEFT, func=self.OnBuyBtn)
    104 
    105     def OnBuyBtn(self, *_args):
    106         self.utilMenu = ExpandedUtilMenu(parent=uicore.layer.utilmenu, controller=self.sr.buyBtn, menuAlign=uiconst.TOPLEFT, GetUtilMenu=self.GetUtilMenu)
    107 
    108     def GetUtilMenu(self, menuParent):
    109         cont = ContainerAutoSize(parent=menuParent, align=uiconst.TOTOP, padding=appConst.defaultPadding)
    110         cont.GetEntryWidth = lambda mc = cont: 80
    111         self.amountEdit = SingleLineEditInteger(name='amountEdit', parent=cont, align=uiconst.TOTOP, minValue=1, maxValue=appConst.maxLoyaltyStoreBulkOffers, setvalue=1, label=localization.GetByLabel('UI/Common/Amount'), padding=(5, 10, 5, 0), OnReturn=self.Buy)
    112         Button(name='buyButton', parent=cont, align=uiconst.TOTOP, label=localization.GetByLabel('UI/LPStore/Accept'), func=self.Buy, padding=(5, 5, 5, 5))
    113         uicore.registry.SetFocus(self.amountEdit)
    114 
    115     def Buy(self, *_args):
    116         accepted = self.lpSvc.AcceptOffer(self.node, self.amountEdit.GetValue())
    117         if accepted == uiconst.ID_YES and self.utilMenu:
    118             self.utilMenu.Close()
    119 
    120     def Startup(self, *etc):
    121         pass
    122 
    123     def Load(self, data):
    124         uthread.pool('lpStore::LPOfferEntry.Load_Thread', self.Load_Thread, data)
    125 
    126     def Load_Thread(self, data):
    127         abstractInfo = None
    128         isCopy = False
    129         if evetypes.GetCategoryID(data.typeID) == appConst.categoryBlueprint:
    130             bpData = sm.GetService('blueprintSvc').GetBlueprintTypeCopy(typeID=data.typeID, runsRemaining=data.qty, original=False)
    131             abstractInfo = utillib.KeyVal(bpData=bpData)
    132             isCopy = True
    133         self.sr.rewardInfoIcon.OnClick = (sm.GetService('info').ShowInfo,
    134          data.typeID,
    135          None,
    136          abstractInfo)
    137         self.LoadIcon(data.typeID, isCopy)
    138         self.sr.rewardLabel.SetText(GetItemText(data.typeID, data.Get('qty', 1)))
    139         self._LoadRequirementColumns(data)
    140         self.CheckCanAcceptOffer(data)
    141         self.CreateTooltipPanel()
    142 
    143     def CreateTooltipPanel(self):
    144         self.LoadTooltipPanel = self.LoadRewardTooltipPanel
    145 
    146     def LoadIcon(self, typeID, isCopy):
    147         self.sr.icon.LoadIconByTypeID(typeID=typeID, size=64, ignoreSize=True, isCopy=isCopy)
    148 
    149     def CheckCanAcceptOffer(self, data):
    150         if self.lpSvc.CanAcceptOffer(data):
    151             self.sr.buyBtn.state = uiconst.UI_NORMAL
    152         else:
    153             self.sr.buyBtn.state = uiconst.UI_HIDDEN
    154             self.sr.icon.spriteEffect = trinity.TR2_SFX_SOFTLIGHT
    155             self.sr.icon.SetRGBA(1, 0, 0, 1)
    156             self.sr.icon.saturation = 0.1
    157 
    158     def _GetRewardCostHint(self):
    159         requirements = {}
    160         for requirementColumn in self.lpOfferRequirementColumns:
    161             costLabelPath = requirementColumn.costLabelPath
    162             if costLabelPath:
    163                 costName = requirementColumn.name
    164                 costNameText = localization.GetByLabel(costLabelPath)
    165                 costLabel = getLabelName(requirementColumn)
    166                 costLabelText = self.sr[costLabel].text
    167                 requirements[costName] = costNameText
    168                 requirements[costLabel] = costLabelText
    169 
    170         return localization.GetByLabel('UI/LPStore/HintRewardCost', rewardLabel=self.sr.rewardLabel.text, **requirements)
    171 
    172     def GetValidSlotForType(self, typeID):
    173         return self.godma.GetPowerEffectForType(typeID)
    174 
    175     def _GetTooltipItemTypeSortPriority(self, typeID):
    176         categoryID = evetypes.GetCategoryID(typeID)
    177         if categoryID == invconst.categoryShip:
    178             priority = 1
    179         elif categoryID == invconst.categoryShipSkin:
    180             priority = 2
    181         elif categoryID == invconst.categoryModule:
    182             slotType = self.GetValidSlotForType(typeID)
    183             if slotType == dogmaconst.effectHiPower:
    184                 priority = 3
    185             elif slotType == dogmaconst.effectMedPower:
    186                 priority = 4
    187             elif slotType == dogmaconst.effectLoPower:
    188                 priority = 5
    189             else:
    190                 priority = 6
    191         elif categoryID == invconst.categoryDrone:
    192             priority = 7
    193         elif categoryID == invconst.categoryCharge:
    194             priority = 8
    195         else:
    196             priority = 9
    197         return priority
    198 
    199     def _CompareTooltipEntries(self, itemAndQuantity, otherItemAndQuantity):
    200         itemTypeID, _ = itemAndQuantity
    201         priority = self._GetTooltipItemTypeSortPriority(itemTypeID)
    202         otherItemTypeID, _ = otherItemAndQuantity
    203         otherPriority = self._GetTooltipItemTypeSortPriority(otherItemTypeID)
    204         return priority - otherPriority
    205 
    206     def LoadRewardTooltipPanel(self, tooltipPanel, *_args):
    207         tooltipPanel.LoadGeneric3ColumnTemplate()
    208         tooltipPanel.state = uiconst.UI_NORMAL
    209         tooltipPanel.cellSpacing = 2
    210         icon = eveIcon.Icon(parent=tooltipPanel, size=32, ignoreSize=True, align=uiconst.CENTER, state=uiconst.UI_DISABLED)
    211         icon.LoadIconByTypeID(typeID=self.typeID, isCopy=True)
    212         tooltipPanel.AddLabelMedium(text=GetItemText(self.typeID, self.qty), align=uiconst.CENTERLEFT)
    213         tooltipPanel.AddInfoIcon(self.typeID, align=uiconst.CENTERRIGHT)
    214         items = []
    215         isReqItems = False
    216         if len(self.reqItems):
    217             isReqItems = True
    218             tooltipPanel.AddDivider()
    219             tooltipPanel.AddLabelSmall(text=localization.GetByLabel('UI/LPStore/RequiredItems'), colSpan=3)
    220             items = self.reqItems
    221         elif len(self.lootItems):
    222             tooltipPanel.AddDivider()
    223             tooltipPanel.AddLabelSmall(text=localization.GetByLabel('UI/Inventory/Filters/CritContains'), colSpan=3)
    224             items = self.lootItems
    225         items = sorted(items, cmp=self._CompareTooltipEntries)
    226         for typeID, qty in items:
    227             eveIcon.Icon(parent=tooltipPanel, size=24, ignoreSize=True, align=uiconst.CENTER, state=uiconst.UI_DISABLED, typeID=typeID)
    228             if not isReqItems:
    229                 qty = evetypes.GetPortionSize(typeID) * qty
    230             itemLabel = tooltipPanel.AddLabelMedium(text=GetItemText(typeID, qty, checkIsBlueprint=False), align=uiconst.CENTERLEFT)
    231             tooltipPanel.AddInfoIcon(typeID, align=uiconst.CENTERRIGHT)
    232             if isReqItems and not self.lpSvc.HaveItem(typeID, qty):
    233                 itemLabel.color = Color.RED
    234 
    235     def _LoadRequirementColumns(self, data):
    236         for requirementColumn in self.lpOfferRequirementColumns:
    237             self._LoadRequirementColumn(data, requirementColumn)
    238 
    239     def _LoadRequirementColumn(self, data, requirementColumn):
    240         requirementName = requirementColumn.name
    241         cost = data.Get(requirementName, 0)
    242         labelName = getLabelName(requirementColumn)
    243         amountName = requirementColumn.amountName
    244         amount = requirementColumn.formatAmount(cost)
    245         amountHintPath = requirementColumn.amountHintPath
    246         amountText = amount
    247         if amountHintPath:
    248             keywords = {amountName: amount}
    249             amountText = localization.GetByLabel(amountHintPath, **keywords)
    250         self.sr[labelName].SetText(amountText)
    251         if not requirementColumn.checkAmount(cost):
    252             self.sr[labelName].color = Color.RED
    253 
    254     def OnColumnResize(self, newCols):
    255         for container, width in zip(self.children[:], newCols):
    256             container.width = width
    257 
    258         self.sr.rewardLabel.width = self.sr.rewardParent.width - self.sr.rewardIconParent.width - self.sr.rewardLabel.left - self.labelMargin
    259 
    260     def GetHeight(self, node, _width):
    261         node.height = LPOfferEntry.entryHeight
    262         return node.height
    263 
    264 
    265 on_cosmetic_license_purchase_failed = Signal('on_cosmetic_license_purchase_failed')
    266 
    267 class CosmeticLogoLPOfferEntry(LPOfferEntry):
    268 
    269     def ApplyAttributes(self, attributes):
    270         super(CosmeticLogoLPOfferEntry, self).ApplyAttributes(attributes)
    271         self._showHilite = not self.node.isOwned
    272         on_ship_cosmetics_license_change.connect(self.OnLicenseStatusChanged)
    273 
    274     def _UpdateStatus(self):
    275         self._showHilite = not self.node.isOwned
    276         for requirement in self.lpOfferRequirementColumns:
    277             labelName = getLabelName(requirement)
    278             self.sr[labelName].opacity = 0.7 if self.node.isOwned else 1.0
    279             self.sr[labelName].color = self.GetRowContentTint()
    280 
    281         if self.sr.rewardlabel:
    282             self.sr.rewardLabel.opacity = 0.7 if self.node.isOwned else 1.0
    283             self.sr.rewardLabel.color = self.GetRowContentTint()
    284         self.offerCont.Flush()
    285         self.AddBuyButton()
    286         if self.sr and self.sr.icon:
    287             self.sr.icon.color = self.GetRowContentTint()
    288             if self.node:
    289                 self.sr.icon.opacity = 0.7 if self.node.isOwned else 1.0
    290 
    291     def AddRewardLabel(self):
    292         rewardLabelContainer = Container(name='rewardLabelContainer', parent=self.sr.rewardParent, align=uiconst.TOALL)
    293         self.sr.rewardLabel = LPStoreEntryLabel(parent=rewardLabelContainer, align=uiconst.CENTERLEFT, padTop=4, maxLines=3, color=self.GetRowContentTint(), opacity=0.7 if self.node.isOwned else 1.0)
    294 
    295     def AddBuyButton(self):
    296         self.offerCont = Container(name='buyButtonParent', parent=self, align=uiconst.TOLEFT, clipChildren=True)
    297         if self.node.isOwned:
    298             rewardAquiredCont = Container(name='rewardAquiredCont', parent=self.offerCont, align=uiconst.TOLEFT, padRight=20)
    299             labelCont = Container(name='labelCont', parent=rewardAquiredCont, align=uiconst.TOLEFT)
    300             rewardAquiredLabel = LPStoreEntryLabel(name='rewardAquiredLabel', parent=labelCont, align=uiconst.CENTER, text=GetByLabel('UI/ShipCosmetics/RewardAcquired'), color=self.GetRowContentTint(), opacity=0.9 if self.node.isOwned else 1.0)
    301             labelWidth, labelHeight = rewardAquiredLabel.GetSize()
    302             labelCont.SetSize(labelWidth, labelHeight)
    303             tickCont = Container(name='tickCont', parent=rewardAquiredCont, align=uiconst.TORIGHT)
    304             rewardAquiredTick = Sprite(name='rewardAquiredTick', parent=tickCont, align=uiconst.CENTER, texturePath='res:/UI/Texture/classes/SkillPlan/completedIcon.png', width=34, height=34)
    305             tickWidth, tickHeight = rewardAquiredTick.GetSize()
    306             tickCont.SetSize(tickWidth, tickHeight)
    307             rewardAquiredWidth = labelWidth + tickWidth
    308             rewardAquiredHeight = labelHeight + tickHeight
    309             rewardAquiredCont.SetSize(rewardAquiredWidth, rewardAquiredHeight)
    310         else:
    311             self.sr.buyBtn = Button(name='buyBtn', parent=self.offerCont, label=localization.GetByLabel('UI/VirtualGoodsStore/Buttons/Buy'), align=uiconst.CENTERLEFT, padLeft=8, func=self.OnBuyBtn)
    312 
    313     def GetRowContentTint(self):
    314         if self.node.isOwned:
    315             return Color.HextoRGBA('#8DC169')
    316         return (1.0, 1.0, 1.0, 1.0)
    317 
    318     def CreateTooltipPanel(self):
    319         pass
    320 
    321     def CreateIcon(self):
    322         self.sr.icon = None
    323 
    324     def LoadIcon(self, typeID, isCopy):
    325         self.sr.icon = Sprite(name='logoIcon', parent=self.sr.rewardIconParent, align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath=self.GetIconTexturePath(), color=self.GetRowContentTint(), opacity=0.7 if self.node.isOwned else 1.0)
    326         self.sr.icon.width = self.iconSize
    327         self.sr.icon.height = self.iconSize
    328 
    329     def CheckCanAcceptOffer(self, data):
    330         if self.sr.buyBtn:
    331             if self.node.isOwned:
    332                 self.sr.buyBtn.state = uiconst.UI_HIDDEN
    333                 self.sr.buyBtn.disable(animate=False)
    334             elif self.lpSvc.CanAcceptOffer(data):
    335                 self.sr.buyBtn.state = uiconst.UI_NORMAL
    336                 self.sr.buyBtn.enable(animate=False)
    337             else:
    338                 self.sr.buyBtn.state = uiconst.UI_DISABLED
    339                 self.sr.buyBtn.disable(animate=False)
    340         self.sr.icon.color = self.GetRowContentTint()
    341         self.sr.icon.opacity = 0.7 if self.node.isOwned else 1.0
    342 
    343     def GetIconTexturePath(self):
    344         return None
    345 
    346     def OnBuyBtn(self, *_args):
    347         ok = uiconst.ID_NO
    348         try:
    349             ok = self.lpSvc.AcceptOffer(self.node, 1)
    350         except RuntimeError as ex:
    351             logger.exception('Could not complete LP Store purchase: %s' % ex)
    352             on_cosmetic_license_purchase_failed()
    353 
    354         if ok == uiconst.ID_NO:
    355             on_cosmetic_license_purchase_failed()
    356 
    357     def OnLicenseStatusChanged(self, licenseID, enable):
    358         licenseData = sm.GetService('cosmeticsLicenseSvc').get_by_ship_license_type_id(self.node.typeID)
    359         if licenseData and licenseData.licenseID == licenseID:
    360             self.node.isOwned = enable
    361             self._UpdateStatus()
    362 
    363     def OnColumnResize(self, newCols):
    364         super(CosmeticLogoLPOfferEntry, self).OnColumnResize(newCols)
    365 
    366 
    367 class AllianceLogoLPOfferEntry(CosmeticLogoLPOfferEntry):
    368 
    369     def ApplyAttributes(self, attributes):
    370         super(AllianceLogoLPOfferEntry, self).ApplyAttributes(attributes)
    371 
    372     def GetIconTexturePath(self):
    373         return BACKGROUND_PATH_BY_TYPE.get(CosmeticsType.ALLIANCE_LOGO, '')
    374 
    375 
    376 class CorporationLogoLPOfferEntry(CosmeticLogoLPOfferEntry):
    377 
    378     def ApplyAttributes(self, attributes):
    379         super(CorporationLogoLPOfferEntry, self).ApplyAttributes(attributes)
    380 
    381     def GetIconTexturePath(self):
    382         return BACKGROUND_PATH_BY_TYPE.get(CosmeticsType.CORPORATION_LOGO, '')