skillBtns.py (14265B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\tooltip\skillBtns.py 2 import eveformat 3 import eveicon 4 import uthread2 5 from carbonui.primitives.container import Container 6 from eve.client.script.ui.eveThemeColor import THEME_FOCUSDARK 7 from localization import GetByLabel 8 import inventorycommon.const as invConst 9 from carbonui import ButtonVariant, Density, uiconst, TextColor, AxisAlignment 10 from carbonui.text.styles import TextBody, TextDetail 11 from carbonui.button.group import ButtonSizeMode, ButtonGroup 12 from carbonui.control.button import Button 13 from carbonui.primitives.containerAutoSize import ContainerAutoSize 14 from eve.client.script.ui.shared.neocom import skillConst 15 from eve.client.script.ui.shared.pointerTool import pointerToolConst as pConst 16 from eve.client.script.ui.shared.tooltip.itemObject import ItemObject 17 from eve.client.script.ui.skilltrading.applySkillPointsWindow import ApplySkillPointsWindow 18 from omega.client.clone_grade_svc import get_clone_grade_svc 19 from skills.skillplan.skillPlanTemplate import TypeRequirementSkillPlanTemplate, RequirementListSkillPlanTemplate 20 from skills.skillplan.skillPlanConst import MAX_PERSONAL_PLANS 21 from skills.skillplan.skillPlanService import GetSkillPlanSvc 22 from eve.client.script.ui.skillPlan import skillPlanUtil 23 from eve.client.script.ui.skillPlan.skillPlanConst import BUTTON_GROUP_ID_SKILL_PLANS, BUTTON_GROUP_ID_TOP_LEVEL, PANEL_SKILL_PLANS, PANEL_PERSONAL 24 25 class SkillActionContainer(ContainerAutoSize): 26 default_state = uiconst.UI_NORMAL 27 isDragObject = False 28 29 def ApplyAttributes(self, attributes): 30 super(SkillActionContainer, self).ApplyAttributes(attributes) 31 self.required_skills = attributes.get('requiredSkills', None) 32 self._missing_skills = attributes.get('missingSkills', None) 33 self.type_id = attributes.get('typeID', None) 34 self.item = attributes.get('item', None) 35 self.on_click = attributes.get('on_click', None) 36 self.skill_plan_name = attributes.get('skillPlanName', None) 37 skillSvc = sm.GetService('skills') 38 itemObject = ItemObject(itemTypeID=self.type_id, item=self.item) 39 if not self.required_skills: 40 self.required_skills = skillSvc.GetSkillsMissingToUseItemRecursiveList(self.type_id) 41 if not self._missing_skills: 42 if self.type_id or self.item: 43 self._missing_skills = skillSvc.GetMissingSkillBooksFromList(self.required_skills) 44 else: 45 self._missing_skills = [] 46 is_rare_skill = False 47 has_rare_req = False 48 if len(self._missing_skills) and self.type_id: 49 is_rare_skill = itemObject.IsRareSkill() 50 has_rare_req = itemObject.IsMissingRarePrereqs() 51 all_expanded_skill_requirements = self.GetSkillsMissingToUseItemExpandedList(skillSvc, self.required_skills) 52 expanded_skill_requirements = [ x for x in all_expanded_skill_requirements if x[0] not in self._missing_skills ] 53 required_skill_points = self.GetRequiredSkillPoints(all_expanded_skill_requirements) 54 skill_point_container = Container(parent=self, align=uiconst.TOTOP, height=32, padBottom=8) 55 ApplySkillPointsButton(parent=skill_point_container, align=uiconst.TORIGHT, padLeft=8, on_click=self.on_click, variant=ButtonVariant.GHOST, skillTypeIDsAndLevels=expanded_skill_requirements, offer_injection=len(self._missing_skills) == 0) 56 skill_point_label_container = Container(parent=skill_point_container, align=uiconst.TOALL, bgColor=THEME_FOCUSDARK.rgb + (0.1,)) 57 sp_value_cont = ContainerAutoSize(parent=skill_point_label_container, align=uiconst.TORIGHT) 58 sp_value = TextDetail(parent=sp_value_cont, align=uiconst.CENTERRIGHT, text=eveformat.number(required_skill_points), padRight=12) 59 sp_label_cont = Container(parent=skill_point_label_container, align=uiconst.TOALL, clipChildren=True) 60 sp_label = TextDetail(parent=sp_label_cont, align=uiconst.CENTERLEFT, padLeft=8, text=GetByLabel('UI/Skills/SkillPointsRequired'), color=TextColor.SECONDARY, autoFadeSides=16) 61 btn_group = ButtonGroup(parent=self, align=uiconst.TOTOP, density=Density.NORMAL, button_alignment=AxisAlignment.END, button_size_mode=ButtonSizeMode.DYNAMIC_STRETCH, ignore_overflow=True) 62 if self.type_id: 63 skill_plan_template = TypeRequirementSkillPlanTemplate(self.type_id) 64 else: 65 skill_plan_template = RequirementListSkillPlanTemplate(self.required_skills, self.skill_plan_name) 66 if len(self._missing_skills) > 0: 67 BuyAndTrainButton(parent=btn_group, on_click=self.on_click, requiredSkills=all_expanded_skill_requirements, missingSkills=self._missing_skills, variant=ButtonVariant.NORMAL, isRarePreReqs=has_rare_req, isRareSkill=is_rare_skill, skillPlanTemplate=skill_plan_template) 68 else: 69 AddToQueueButton(parent=btn_group, on_click=self.on_click, requiredSkills=expanded_skill_requirements, variant=ButtonVariant.NORMAL) 70 CreateSkillPlanButton(parent=btn_group, on_click=self.on_click, skillPlanTemplate=skill_plan_template, variant=ButtonVariant.GHOST) 71 72 def GetRequiredSkillPoints(self, skill_ids_and_levels): 73 svc = sm.GetService('skills') 74 return sum(svc.GetSkillPointsRequiredForSkills(skill_ids_and_levels).itervalues()) 75 76 def GetSkillsMissingToUseItemExpandedList(self, skillSvc, requiredSkills): 77 ret = [] 78 for skillTypeID, level in requiredSkills: 79 trainedLevel = skillSvc.GetMyLevel(skillTypeID) 80 if trainedLevel is None: 81 trainedLevel = 0 82 for i in range(level + 1): 83 if i <= 0: 84 continue 85 if i <= trainedLevel: 86 continue 87 ret.append((skillTypeID, i)) 88 89 return ret 90 91 92 class _SkillActionButton(Button): 93 94 def ApplyAttributes(self, attributes): 95 self._isFinished = False 96 super(_SkillActionButton, self).ApplyAttributes(attributes) 97 self.UpdateState() 98 self.func = self.ClickFunc 99 self.on_click = attributes.get('on_click', None) 100 101 def ClickFunc(self, *args): 102 if self.on_click: 103 self.on_click() 104 105 def UpdateState(self): 106 self.UpdateLabel() 107 self.UpdateIcon() 108 109 def UpdateLabel(self): 110 self.label = self._GetText() 111 112 def UpdateIcon(self): 113 self.texturePath = self._GetIcon() 114 115 def _GetIcon(self): 116 return None 117 118 def _GetText(self): 119 return None 120 121 122 class AddToQueueButton(_SkillActionButton): 123 uniqueUiName = pConst.UNIQUE_NAME_ADD_SKILLS_TO_QUEUE_BTN 124 125 def ApplyAttributes(self, attributes): 126 self.requiredSkills = attributes.requiredSkills 127 queueSvc = sm.GetService('skillqueue') 128 allSkillsInQueue = True 129 for skillID, level in self.requiredSkills: 130 if not queueSvc.IsSkillInQueue(skillID): 131 allSkillsInQueue = False 132 break 133 if queueSvc.FindHighestLevelInQueue(skillID) < level: 134 allSkillsInQueue = False 135 break 136 137 attributes.enabled = not allSkillsInQueue 138 attributes.uniqueUiName = self.uniqueUiName 139 super(AddToQueueButton, self).ApplyAttributes(attributes) 140 self._isFinished = allSkillsInQueue 141 self.UpdateLabel() 142 143 def ClickFunc(self, *args): 144 super(AddToQueueButton, self).ClickFunc(*args) 145 self.Disable() 146 try: 147 sm.GetService('skillqueue').AddSkillsToQueue(self.requiredSkills, ignoreAlreadyPresent=True) 148 sm.GetService('skillqueue').CommitTransaction(activate=True) 149 self._isFinished = True 150 except Exception: 151 self.Enable() 152 153 self.UpdateState() 154 155 def _GetText(self): 156 return GetByLabel('UI/Skills/TrainSkills') 157 158 def GetHint(self): 159 if self._isFinished: 160 return GetByLabel('Tooltips/SkillPlanner/AddAllSkillsToQueueButtonFinished') 161 return GetByLabel('Tooltips/SkillPlanner/AddAllSkillsToQueueButton') 162 163 164 class ApplySkillPointsButton(_SkillActionButton): 165 166 def ApplyAttributes(self, attributes): 167 self._offer_injection = attributes.offer_injection 168 super(ApplySkillPointsButton, self).ApplyAttributes(attributes) 169 self.skillTypeIDsAndLevels = attributes.skillTypeIDsAndLevels 170 171 def ClickFunc(self, *args): 172 super(ApplySkillPointsButton, self).ClickFunc(*args) 173 if sm.GetService('skills').GetFreeSkillPoints(): 174 wnd = ApplySkillPointsWindow.GetIfOpen() 175 if wnd: 176 wnd.CloseByUser() 177 uthread2.sleep(0.05) 178 ApplySkillPointsWindow.Open(skillTypeIDsAndLevels=self.skillTypeIDsAndLevels) 179 elif get_clone_grade_svc().is_omega_with_grace_period(): 180 sm.GetService('marketutils').ShowMarketDetails(invConst.typeSkillInjector, None) 181 else: 182 sm.GetService('vgsService').OpenStore(typeIds=[invConst.typeAlphaTrainingInjector]) 183 184 def UpdateState(self): 185 if sm.GetService('skills').GetFreeSkillPoints(): 186 self.hint = GetByLabel('UI/SkillQueue/ApplySkillPoints') 187 self.texturePath = eveicon.add 188 self.enabled = self._offer_injection 189 elif get_clone_grade_svc().is_omega_with_grace_period(): 190 self.hint = GetByLabel('UI/Market/MarketQuote/BuyType', typeID=invConst.typeSkillInjector) 191 self.texturePath = 'res:/UI/Texture/classes/skilltrading/marketSkillinjector.png' 192 self.enabled = True 193 else: 194 self.hint = GetByLabel('UI/Market/MarketQuote/BuyType', typeID=invConst.typeAlphaTrainingInjector) 195 self.texturePath = 'res:/UI/Texture/classes/skilltrading/alphaSkillInjector.png' 196 self.enabled = True 197 198 199 class CreateSkillPlanButton(_SkillActionButton): 200 201 def ApplyAttributes(self, attributes): 202 super(CreateSkillPlanButton, self).ApplyAttributes(attributes) 203 self.skillPlanTemplate = attributes.skillPlanTemplate 204 205 def ClickFunc(self, *args): 206 super(CreateSkillPlanButton, self).ClickFunc(*args) 207 template = self.skillPlanTemplate 208 if not self._CanCreatePlan(): 209 skillPlanUtil.SetPersistedPanelID(BUTTON_GROUP_ID_TOP_LEVEL, PANEL_SKILL_PLANS) 210 skillPlanUtil.SetPersistedPanelID(BUTTON_GROUP_ID_SKILL_PLANS, PANEL_PERSONAL) 211 template = None 212 sm.GetService('cmd').OpenSkillsWindow(forceClose=True, skillPlanTemplate=template) 213 214 def _GetIcon(self): 215 return eveicon.skill_plan 216 217 def GetHint(self): 218 hint = GetByLabel('Tooltips/SkillPlanner/SkillPlanButtonTooltip') 219 numPlans = len(GetSkillPlanSvc().GetAllPersonal()) 220 if self._CanCreatePlan(): 221 return hint 222 else: 223 return u'{}\n\n<color={}>{}</color>'.format(hint, TextColor.WARNING, GetByLabel('UI/SkillPlan/MaximumSkillPlanReached', numPlans=numPlans)) 224 225 def _CanCreatePlan(self): 226 numPlans = len(GetSkillPlanSvc().GetAllPersonal()) 227 return numPlans < MAX_PERSONAL_PLANS 228 229 230 class BuyAndTrainButton(_SkillActionButton): 231 default_name = 'BuyAndTrainButton' 232 233 def ApplyAttributes(self, attributes): 234 super(BuyAndTrainButton, self).ApplyAttributes(attributes) 235 self.requiredSkills = attributes.requiredSkills 236 self.missingSkills = attributes.missingSkills 237 self.isRarePreReqs = attributes.get('isRarePreReqs', False) 238 self.isRareSkill = attributes.get('isRareSkill', False) 239 self.skillPlanTemplate = attributes.get('skillPlanTemplate', None) 240 self._isFinished = False 241 self.skillSvc = sm.GetService('skills') 242 self.func = self.ClickFunc 243 self.UpdateState() 244 245 def IsActive(self): 246 if self._isFinished: 247 return False 248 if self.isRarePreReqs: 249 return False 250 if len(self.missingSkills) == 0: 251 return False 252 return True 253 254 def ClickFunc(self, *args): 255 super(BuyAndTrainButton, self).ClickFunc(*args) 256 self.Disable() 257 try: 258 if self.missingSkills: 259 skills_purchased = self.skillSvc.PurchaseSkills(self.missingSkills, skillPlanTemplate=self.skillPlanTemplate) 260 if skills_purchased: 261 self.skillSvc.WaitUntilSkillsAreAvailable(skills_purchased) 262 if len(skills_purchased) == len(self.missingSkills): 263 self.missingSkills = [] 264 else: 265 self.missingSkills = [ typeID for typeID in self.missingSkills if typeID not in skills_purchased ] 266 else: 267 self.Enable() 268 self.UpdateState() 269 return 270 self._isFinished = not bool(self.missingSkills) 271 if not self._isFinished: 272 self.Enable() 273 skillsToQueue = [ (typeID, level) for typeID, level in self.requiredSkills if typeID not in self.missingSkills ] 274 else: 275 skillsToQueue = self.requiredSkills 276 sm.GetService('skillqueue').AddSkillsToQueue(skillsToQueue, ignoreAlreadyPresent=True) 277 sm.GetService('skillqueue').CommitTransaction(activate=True) 278 except Exception: 279 self.Enable() 280 raise 281 282 self.UpdateState() 283 284 def UpdateState(self): 285 self.UpdateLabel() 286 287 def UpdateLabel(self): 288 self.label = self.GetText() 289 290 def GetColor(self): 291 if self.isRarePreReqs: 292 return (1.0, 1.0, 1.0, 0.5) 293 return skillConst.COLOR_SKILL_2 294 295 def GetText(self): 296 if self._isFinished: 297 pass 298 return GetByLabel('UI/Skills/BuyAndTrain') 299 300 def UpdateIsEnabledByState(self): 301 if self._isFinished or self.isRarePreReqs: 302 self.Disable() 303 else: 304 self.Enable() 305 306 def GetHint(self): 307 if self.isRareSkill: 308 if self.isRarePreReqs: 309 return GetByLabel('UI/Skills/ErrorRareSkillAndRequirements') 310 else: 311 return GetByLabel('UI/Skills/ErrorRareSkill') 312 if self.isRarePreReqs: 313 return GetByLabel('UI/Skills/ErrorRareRequirements')