skill_requirement.py (14798B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\tooltip\skill_requirement.py 2 import carbonui.uiconst as uiconst 3 import eveicon 4 import evetypes 5 import localization 6 from carbon.common.script.util.format import IntToRoman 7 from carbonui import TextColor, Align, ButtonStyle, Density, ButtonFrameType 8 from carbonui.text.styles import TextBody 9 from carbonui.control.button import Button 10 from carbonui.primitives.container import Container 11 from carbonui.primitives.containerAutoSize import ContainerAutoSize 12 from carbonui.primitives.layoutGrid import LayoutGrid, LayoutGridRow 13 from carbonui.primitives.sprite import Sprite 14 from carbonui.uicore import uicore 15 from carbonui.util.color import Color 16 from clonegrade import COLOR_OMEGA_ORANGE, COLOR_OMEGA_DARK_BG 17 from eve.client.script.ui.control.infoIcon import WarningGlyphIcon 18 from eve.client.script.ui.control.skillBar.skillBar import SkillBar 19 from eve.client.script.ui.shared.cloneGrade import ORIGIN_SKILLREQ_PANEL 20 from eve.client.script.ui.shared.inventory.invSettings import show_training_details 21 from eve.client.script.ui.shared.neocom import skillConst 22 from eve.client.script.ui.shared.tooltip.itemObject import ItemObject 23 from eve.client.script.ui.shared.tooltip.skillBtns import SkillActionContainer 24 from eveservices.menu import GetMenuService 25 from localization.formatters.timeIntervalFormatters import TIME_CATEGORY_MINUTE, FormatTimeIntervalShortWritten 26 from omega.client.clone_grade_svc import get_clone_grade_svc 27 from skills.client.skillController import SkillController 28 from utillib import KeyVal 29 from inventorycommon import const 30 31 class RequiredSkillRow(LayoutGridRow): 32 default_state = uiconst.UI_NORMAL 33 isDragObject = True 34 __notifyevents__ = ['OnSkillQueueRefreshed'] 35 36 def ApplyAttributes(self, attributes): 37 super(RequiredSkillRow, self).ApplyAttributes(attributes) 38 self.typeID = attributes.typeID 39 self.level = attributes.level 40 text = localization.GetByLabel('UI/InfoWindow/RequiredSkillNameAndLevel', skill=self.typeID, level=IntToRoman(self.level), levelColor=Color(*skillConst.COLOR_SKILL_1).GetHex()) 41 label = TextBody(align=uiconst.CENTERLEFT, text=text, padRight=15) 42 self.AddCell(label) 43 texturePath, hint = self._GetTexturePathAndHint() 44 Sprite(name='skillbookStatus', parent=label.parent, align=uiconst.CENTERRIGHT, pos=(-16, 0, 16, 16), texturePath=texturePath, color=TextColor.WARNING, hint=hint) 45 self.bar = SkillBar(align=uiconst.CENTERRIGHT, state=uiconst.UI_DISABLED, skillID=self.typeID, requiredLevel=self.level) 46 self.AddCell(self.bar, cellPadding=(24, 6, 0, 0)) 47 sm.RegisterNotify(self) 48 49 def Close(self): 50 super(RequiredSkillRow, self).Close() 51 sm.UnregisterNotify(self) 52 53 def _GetTexturePathAndHint(self): 54 texturePath = hint = '' 55 skillController = SkillController(self.typeID) 56 if not skillController.IsInjected(): 57 if skillController.IsSkillAvailableForPurchase(): 58 texturePath = eveicon.skill_book 59 hint = localization.GetByLabel('UI/SkillQueue/SkillBookMissing') 60 else: 61 texturePath = 'res:/ui/Texture/classes/Skills/RareSkillBookNotInjected.png' 62 hint = localization.GetByLabel('UI/SkillQueue/RareSkillBookMissing') 63 elif skillController.GetMyLevel() < self.level: 64 texturePath = None 65 hint = localization.GetByLabel('UI/InfoWindow/SkillNotTrainedToRequiredLevel') 66 return (texturePath, hint) 67 68 def GetMenu(self): 69 return GetMenuService().GetMenuForSkill(self.typeID) 70 71 def OnClick(self): 72 sm.GetService('info').ShowInfo(self.typeID) 73 74 def GetDragData(self): 75 data = KeyVal(__guid__='uicls.GenericDraggableForTypeID', typeID=self.typeID, label=evetypes.GetName(self.typeID)) 76 return (data,) 77 78 def OnSkillQueueRefreshed(self): 79 self.bar.Refresh() 80 81 82 class AlphaTrainingTimeContainer(ContainerAutoSize): 83 default_name = 'AlphaTrainingCnt' 84 default_align = Align.TOTOP 85 default_alignMode = Align.TOTOP 86 default_bgColor = COLOR_OMEGA_DARK_BG 87 88 def ApplyAttributes(self, attributes): 89 self.isOmegaRestricted = attributes.isOmegaRestricted 90 self.alphaTime = attributes.alphaTime 91 self.omegaTime = attributes.omegaTime 92 self.activityText = attributes.activityText 93 self.omega_button = None 94 super(AlphaTrainingTimeContainer, self).ApplyAttributes(attributes) 95 self.on_click_callback = attributes.get('on_click', None) 96 content = ContainerAutoSize(parent=self, align=Align.TOTOP, alignMode=Align.TOTOP, padding=10, clipChildren=True) 97 top_container = ContainerAutoSize(parent=content, align=Align.TOTOP, alignMode=Align.CENTERLEFT, padBottom=4) 98 TextBody(parent=top_container, align=uiconst.CENTERLEFT, text=localization.GetByLabel('Tooltips/SkillPlanner/TrainingTime'), color=TextColor.SECONDARY, autoFadeSides=True) 99 alpha_time_container = ContainerAutoSize(parent=content, align=Align.TOTOP, alignMode=Align.CENTERLEFT, padBottom=4) 100 Sprite(parent=alpha_time_container, align=Align.CENTERLEFT, width=16, height=16, texturePath=eveicon.alpha) 101 TextBody(parent=alpha_time_container, align=Align.CENTERLEFT, text=self._get_time_formatted(self.alphaTime), color=TextColor.HIGHLIGHT if not self.isOmegaRestricted else TextColor.SECONDARY, padLeft=24, autoFadeSides=True) 102 omega_time_container = ContainerAutoSize(parent=content, align=Align.TOTOP, alignMode=Align.CENTERLEFT) 103 Sprite(parent=omega_time_container, align=Align.CENTERLEFT, width=16, height=16, texturePath=eveicon.omega) 104 TextBody(parent=omega_time_container, align=uiconst.CENTERLEFT, text=self._get_time_formatted(self.omegaTime), color=COLOR_OMEGA_ORANGE, padLeft=24, autoFadeSides=True) 105 if self.isOmegaRestricted: 106 omega_warning_container = ContainerAutoSize(parent=content, align=Align.TOTOP, alignMode=Align.CENTERLEFT, padTop=4) 107 WarningGlyphIcon(parent=omega_warning_container, align=Align.CENTERLEFT, height=18, width=18) 108 TextBody(parent=omega_warning_container, align=Align.CENTERLEFT, color=TextColor.HIGHLIGHT, text=localization.GetByLabel('Tooltips/SkillPlanner/OmegaCloneStateRequiredForActivity', doActivity=self.activityText), padLeft=24, autoFadeSides=True) 109 Button(parent=content, align=Align.TOTOP, label=localization.GetByLabel('UI/CloneState/Upgrade'), texturePath=eveicon.omega, style=ButtonStyle.MONETIZATION, func=self.on_omega_button_click, density=Density.COMPACT, frame_type=ButtonFrameType.CUT_BOTTOM_LEFT_RIGHT, padTop=8) 110 111 def _get_time_formatted(self, time): 112 if time: 113 return FormatTimeIntervalShortWritten(time, showTo=TIME_CATEGORY_MINUTE) 114 return localization.GetByLabel('Tooltips/SkillPlanner/TrainingComplete') 115 116 def _get_background_color(self): 117 return COLOR_OMEGA_DARK_BG 118 119 def on_omega_button_click(self, *args): 120 uicore.cmd.OpenCloneUpgradeWindow(origin=ORIGIN_SKILLREQ_PANEL) 121 if self.on_click_callback: 122 self.on_click_callback() 123 124 125 class AlphaTrainingTimeRow(LayoutGridRow): 126 default_state = uiconst.UI_NORMAL 127 isDragObject = False 128 _OMEGA_RESTRICTED_HEIGHT = 30 129 _CONTENT_HEIGHT = 80 130 131 def ApplyAttributes(self, attributes): 132 super(AlphaTrainingTimeRow, self).ApplyAttributes(attributes) 133 self.isOmegaRestricted = attributes.get('isOmegaRestricted', False) 134 self.alphaTime = attributes.get('alphaTime', None) 135 self.omegaTime = attributes.get('omegaTime', None) 136 self.activityText = attributes.get('activityText', '') 137 on_click = attributes.get('on_click', None) 138 self.outer_container = AlphaTrainingTimeContainer(isOmegaRestricted=self.isOmegaRestricted, alphaTime=self.alphaTime, omegaTime=self.omegaTime, activityText=self.activityText, on_click=on_click) 139 self.AddCell(cellObject=self.outer_container, colSpan=self.columns, cellPadding=(0, 10, 0, 0)) 140 141 def _get_height(self): 142 if self.isOmegaRestricted: 143 return self._CONTENT_HEIGHT + self._OMEGA_RESTRICTED_HEIGHT + 5 144 return self._CONTENT_HEIGHT 145 146 def _get_background_color(self): 147 return COLOR_OMEGA_DARK_BG 148 149 150 class OmegaTrainingTimeContainer(ContainerAutoSize): 151 default_name = 'OmegaTrainingCnt' 152 default_align = Align.TOTOP 153 default_alignMode = Align.TOTOP 154 default_bgColor = (0.1, 0.1, 0.1, 0.7) 155 156 def ApplyAttributes(self, attributes): 157 super(OmegaTrainingTimeContainer, self).ApplyAttributes(attributes) 158 omegaTime = attributes.get('omegaTime', None) 159 TextBody(parent=self, align=uiconst.TOTOP, text=localization.GetByLabel('Tooltips/SkillPlanner/OmegaTrainingTime'), color=TextColor.SECONDARY, maxLines=1, padding=(10, 5, 10, 0)) 160 TextBody(parent=self, align=uiconst.TOTOP, text=FormatTimeIntervalShortWritten(omegaTime, showTo=TIME_CATEGORY_MINUTE), color=TextColor.HIGHLIGHT, padding=(10, 0, 10, 5)) 161 162 163 class OmegaTrainingTimeRow(LayoutGridRow): 164 default_state = uiconst.UI_NORMAL 165 isDragObject = False 166 167 def ApplyAttributes(self, attributes): 168 super(OmegaTrainingTimeRow, self).ApplyAttributes(attributes) 169 self.omegaTime = attributes.get('omegaTime', None) 170 self.content = OmegaTrainingTimeContainer(omegaTime=self.omegaTime) 171 self.AddCell(cellObject=self.content, colSpan=self.columns, cellPadding=(0, 10, 0, 0)) 172 173 174 def AddSkillActionAndRequirementsForType(grid, typeID, item = None, origin = None): 175 skillSvc = sm.GetService('skills') 176 missingSkills = skillSvc.GetTopLevelSkillsMissingToUseItem(typeID) 177 if not missingSkills: 178 return 179 allMissingSkills = skillSvc.GetSkillsMissingToUseItemRecursiveList(typeID) 180 totalMissingSkillLevels = skillSvc.GetTotalMissingSkillLevelsToUseItem(typeID) 181 missingSkillbooks = skillSvc.GetMissingSkillBooksFromList(allMissingSkills) 182 showTrainingDetails = ShouldShowTrainingDetails() 183 AddSkillRequirements(grid, allMissingSkills, missingSkillbooks, totalMissingSkillLevels, showTrainingDetails) 184 if showTrainingDetails: 185 AddTrainingTimeForType(grid, typeID, item) 186 AddSkillAction(grid, typeID, item) 187 188 189 def ShouldShowTrainingDetails(): 190 isOmega = get_clone_grade_svc().is_omega_with_grace_period() 191 if not isOmega: 192 return True 193 if show_training_details.get(): 194 return True 195 return False 196 197 198 def AddSkillRequirementLabel(grid, allMissingSkillsCount, missingSkillBooksCount, totalMissingSkillLevels): 199 labelCnt = ContainerAutoSize(align=uiconst.CENTERLEFT, minWidth=270, height=25, bgColor=(0.2, 0.2, 0.2, 0)) 200 spriteCnt = Container(parent=labelCnt, align=uiconst.TOLEFT, width=20) 201 Sprite(parent=spriteCnt, align=uiconst.TOPLEFT, width=16, height=16, texturePath=eveicon.skill_book, color=TextColor.NORMAL if not missingSkillBooksCount else TextColor.WARNING) 202 TextBody(parent=labelCnt, align=uiconst.TOLEFT, text=localization.GetByLabel('Tooltips/SkillPlanner/SkillsAndSkillLevels', numSkills=allMissingSkillsCount, numLevels=totalMissingSkillLevels), color=skillConst.COLOR_SKILL_1) 203 if missingSkillBooksCount > 0: 204 TextBody(parent=labelCnt, align=uiconst.TOLEFT, text=localization.GetByLabel('Tooltips/SkillPlanner/MissingSkillBooks', numMissingBooks=missingSkillBooksCount), color=TextColor.WARNING) 205 grid.AddRow(rowObjects=[labelCnt], cellPadding=(0, 5, 0, 0)) 206 207 208 def AddSkillRequirements(grid, allMissingSkills, missingSkillbooks, totalMissingSkillLevels, showTrainingDetails = True): 209 missingSkillBooksCount = len(missingSkillbooks) 210 allMissingSkillsCount = len(allMissingSkills) 211 AddSkillRequirementLabel(grid, allMissingSkillsCount, missingSkillBooksCount, totalMissingSkillLevels) 212 if showTrainingDetails: 213 for skillID, level in allMissingSkills: 214 grid.AddRow(rowClass=RequiredSkillRow, typeID=skillID, level=level, cellPadding=(0, 8, 0, 0)) 215 216 217 def AddTrainingTimeForType(grid, typeID, item = None, on_click = None): 218 isOmega = get_clone_grade_svc().is_omega_with_grace_period() 219 isOmegaRestricted = ItemObject(typeID, item).NeedsOmegaUpgrade() 220 totalTime = long(sm.GetService('skills').GetSkillTrainingTimeLeftToUseType(typeID, includeBoosters=False)) 221 if isOmega and totalTime > 0: 222 AddTrainingTime(grid, isOmega, isOmegaRestricted, trainingTime=totalTime, on_click=on_click) 223 elif totalTime > 0 or isOmegaRestricted: 224 AddTrainingTime(grid, isOmega, isOmegaRestricted, trainingTime=totalTime, activityText=GetActivityTextForType(typeID), on_click=on_click) 225 226 227 def AddTrainingTime(grid, isOmega, isOmegaRestricted, trainingTime = None, activityText = None, minWidth = 380, on_click = None): 228 if isOmega: 229 grid.AddRow(rowClass=OmegaTrainingTimeRow, isOmega=True, omegaTime=trainingTime) 230 return 231 if trainingTime > 0: 232 grid.AddRow(rowClass=AlphaTrainingTimeRow, isOmegaRestricted=isOmegaRestricted, alphaTime=trainingTime, omegaTime=trainingTime / 2, activityText=activityText, on_click=on_click) 233 elif isOmegaRestricted: 234 grid.AddRow(rowClass=AlphaTrainingTimeRow, isOmegaRestricted=isOmegaRestricted, alphaTime=None, omegaTime=None, activityText=activityText, on_click=on_click) 235 grid.AddCell(Container(align=uiconst.CENTERTOP, width=minWidth), colSpan=grid.columns) 236 237 238 def AddSkillAction(grid, typeID, item = None, on_click_callback = None): 239 itemObject = ItemObject(typeID, item) 240 if itemObject.NeedsOmegaUpgrade(): 241 return 242 if not sm.GetService('skills').IsSkillRequirementMet(typeID): 243 btnGroup = SkillActionContainer(align=uiconst.TOTOP, typeID=typeID, item=item, on_click=on_click_callback) 244 grid.AddCell(cellObject=btnGroup, colSpan=grid.columns, cellPadding=(0, 10, 0, 0)) 245 246 247 def AddSkillActionForList(grid, requiredSkills, missingSkills = None, on_click_callback = None, minWidth = None, skillPlanName = None): 248 btnGroup = SkillActionContainer(align=uiconst.TOTOP, requiredSkills=requiredSkills, missingSkills=missingSkills, on_click=on_click_callback, skillPlanName=skillPlanName) 249 grid.AddCell(cellObject=btnGroup, colSpan=grid.columns, cellPadding=(0, 10, 0, 0)) 250 if minWidth: 251 grid.AddCell(Container(align=uiconst.CENTERTOP, width=minWidth), colSpan=grid.columns) 252 253 254 def GetActivityTextForType(typeID): 255 if evetypes.GetCategoryID(typeID) == const.categoryShip: 256 return localization.GetByLabel('Tooltips/SkillPlanner/ActivityFlyShip') 257 if evetypes.GetCategoryID(typeID) == const.categorySkill: 258 return localization.GetByLabel('Tooltips/SkillPlanner/ActivityTrainSkill') 259 return localization.GetByLabel('Tooltips/SkillPlanner/ActivityUseModule')