skillTooltipController.py (11090B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\tooltip\skillTooltipController.py 2 import characterskills.client 3 import clonegrade 4 import evetypes 5 import localization 6 from carbonui.uicore import uicore 7 from eve.client.script.ui.control import primaryButton 8 from eve.client.script.ui.shared.cloneGrade import ORIGIN_SKILLREQUIREMENTSTOOLTIP 9 from eve.client.script.ui.shared.info import infoConst 10 from eve.client.script.ui.shared.neocom import skillConst 11 from inventorycommon import typeHelpers 12 from omega.client.clone_grade_svc import get_clone_grade_svc 13 14 def service_dependency(name, injected = None): 15 if injected is not None: 16 return injected 17 return sm.GetService(name) 18 19 20 class SkillTooltipController(object): 21 22 def __init__(self, type_id, info_service = None, market_utils_service = None, queue_service = None, skill_service = None): 23 self.type_id = type_id 24 self._info_service = service_dependency('info', info_service) 25 self._market_utils_service = service_dependency('marketutils', market_utils_service) 26 self._queue_service = service_dependency('skillqueue', queue_service) 27 self._skill_service = service_dependency('skills', skill_service) 28 29 @property 30 def description(self): 31 return evetypes.GetDescription(self.type_id) 32 33 @property 34 def estimated_market_price(self): 35 return typeHelpers.GetAveragePrice(self.type_id) 36 37 @property 38 def has_rare_missing_requirements(self): 39 return any((not skill.is_available_for_purchase for skill in self.missing_requirements)) 40 41 @property 42 def is_available_for_purchase(self): 43 return characterskills.client.is_available_for_purchase(self.type_id) 44 45 @property 46 def is_grandfathered(self): 47 return self.points > 0 and self.untrained_requirements 48 49 @property 50 def is_injected(self): 51 return self._skill_service.IsSkillInjected(self.type_id) 52 53 @property 54 def is_next_level_omega_restricted(self): 55 if get_clone_grade_svc().is_omega_with_grace_period(): 56 return False 57 if self.points == 0 and self.is_omega_restricted_by_requirements: 58 return True 59 if self.level_including_queued == 5: 60 return False 61 next_level = self.level_including_queued + 1 62 return get_clone_grade_svc().is_skill_level_restricted(self.type_id, next_level) 63 64 @property 65 def is_rare(self): 66 return not self.is_available_for_purchase 67 68 @property 69 def is_omega_restricted(self): 70 return self.level_max == 0 or self.level_max < self.level or self.is_next_level_omega_restricted 71 72 @property 73 def is_omega_restricted_by_requirements(self): 74 if get_clone_grade_svc().is_omega_with_grace_period(): 75 return False 76 return get_clone_grade_svc().is_requirements_restricted(self.type_id) 77 78 @property 79 def is_trainable(self): 80 if not self.is_injected: 81 return False 82 if self.level == 5: 83 return False 84 if self.is_next_level_omega_restricted: 85 return False 86 if self.is_grandfathered: 87 return True 88 if self.missing_requirements: 89 return False 90 return True 91 92 @property 93 def is_queued(self): 94 return self._queue_service.IsSkillInQueue(self.type_id) 95 96 def could_be_trained(self, skillLevel): 97 if self.level == 5: 98 return False 99 if self.level >= skillLevel: 100 return False 101 if self.is_next_level_omega_restricted: 102 return False 103 return True 104 105 @property 106 def level(self): 107 skill = self._get_skill_including_lapsed() 108 if skill: 109 return skill.trainedSkillLevel or 0 110 return 0 111 112 @property 113 def effective_level(self): 114 skill = self._get_skill_including_lapsed() 115 if skill: 116 return skill.effectiveSkillLevel or 0 117 return 0 118 119 @property 120 def trained_level(self): 121 skill = self._get_skill_including_lapsed() 122 if skill: 123 return skill.trainedSkillLevel or 0 124 return 0 125 126 @property 127 def virtual_level(self): 128 skill = self._get_skill_including_lapsed() 129 if skill: 130 return skill.virtualSkillLevel or 0 131 return 0 132 133 @property 134 def level_including_queued(self): 135 return self._skill_service.MySkillLevelIncludingQueued(self.type_id) 136 137 @property 138 def level_max(self): 139 return get_clone_grade_svc().get_max_skill_level(self.type_id) 140 141 @property 142 def missing_requirements(self): 143 return filter(lambda skill: not skill.is_injected, self.untrained_requirements) 144 145 @property 146 def points(self): 147 skill = self._get_skill_including_lapsed() 148 if skill: 149 return skill.trainedSkillPoints or 0 150 return 0 151 152 @property 153 def price(self): 154 if not self.is_available_for_purchase: 155 return None 156 return characterskills.client.get_direct_purchase_price(self.type_id) 157 158 @property 159 def rank(self): 160 return self._skill_service.GetSkillRank(self.type_id) 161 162 @property 163 def requirements_training_time(self): 164 return self._skill_service.GetSkillTrainingTimeLeftToUseType(self.type_id, includeBoosters=False) 165 166 @property 167 def training_rate(self): 168 return self._skill_service.GetSkillpointsPerMinute(self.type_id) 169 170 @property 171 def untrained_requirements(self): 172 return [ RequiredSkillTooltipController(type_id, level) for type_id, level in self._get_untrained_required_skills() ] 173 174 def buy(self): 175 return self._skill_service.PurchaseSkills([self.type_id]) 176 177 def buy_with_requirements(self): 178 type_ids = [] 179 if not self.is_grandfathered: 180 type_ids.extend((skill.type_id for skill in self.missing_requirements)) 181 if not self.is_injected: 182 type_ids.append(self.type_id) 183 if not type_ids: 184 return 185 return self._skill_service.PurchaseSkills(type_ids) 186 187 def get_time_until_trained(self, level = None): 188 if not self.is_queued: 189 return 190 if level is None: 191 level = self.level_including_queued 192 training_time, _, _ = self._queue_service.GetTrainingLengthOfSkill(self.type_id, self.level_including_queued) 193 return training_time 194 195 def get_training_time_to_level(self, level): 196 return long(sm.GetService('skills').GetTrainingTimeLeftForSkillLevels({self.type_id: level}, includeBoosters=True)) 197 198 def train(self, skillLevel = None): 199 self._queue_service.AddSkillAndRequirementsToQueue(self.type_id) 200 201 def train_to_level(self, skillLevel): 202 self._queue_service.AddSkillAndRequirementsToQueue(self.type_id, skillLevel) 203 204 def view_market_details(self): 205 self._market_utils_service.ShowMarketDetails(self.type_id, None) 206 207 def view_requirements(self): 208 self._info_service.ShowInfo(typeID=self.type_id, selectTabType=infoConst.TAB_REQUIREMENTS) 209 210 def _get_skill(self): 211 return self._skill_service.GetSkill(self.type_id) 212 213 def _get_skill_including_lapsed(self): 214 return self._skill_service.GetSkillIncludingLapsed(self.type_id) 215 216 def _get_untrained_required_skills(self): 217 return self._skill_service.GetSkillsMissingToUseItemRecursiveList(self.type_id) 218 219 220 class RequiredSkillTooltipController(SkillTooltipController): 221 222 def __init__(self, type_id, required_level): 223 super(RequiredSkillTooltipController, self).__init__(type_id) 224 self.required_level = required_level 225 226 227 class SkillPrimaryActionController(primaryButton.PrimaryButtonController): 228 229 def __init__(self, skill, skillLevel = None): 230 self.skill = skill 231 self.skillLevel = skillLevel 232 self.skill_service = service_dependency('skills') 233 super(SkillPrimaryActionController, self).__init__() 234 235 @property 236 def default_is_enabled(self): 237 if self.need_omega_upgrade: 238 return True 239 if self.skill.is_grandfathered: 240 return True 241 if not self.skill.is_injected and self.skill.is_rare: 242 return False 243 if self.skill.has_rare_missing_requirements: 244 return False 245 return True 246 247 @property 248 def default_label(self): 249 if self.need_omega_upgrade: 250 return localization.GetByLabel('UI/CloneState/Upgrade') 251 if self.need_to_buy_skills: 252 return localization.GetByLabel('UI/Skills/BuyAndTrain') 253 if self.skill.is_trainable: 254 skillLevel = self.skillLevel or self.skill.level_including_queued + 1 255 return localization.GetByLabel('UI/Skills/TrainLevel', level=skillLevel) 256 257 @property 258 def default_style(self): 259 if not self.default_is_enabled: 260 color = (1.0, 1.0, 1.0, 0.5) 261 elif self.need_omega_upgrade: 262 color = clonegrade.COLOR_OMEGA_BG 263 else: 264 color = skillConst.COLOR_SKILL_2 265 return primaryButton.FixedColorStyle(base_color=color) 266 267 @property 268 def error_message(self): 269 are_requirements_available = all((skill.is_available_for_purchase for skill in self.skill.missing_requirements)) 270 need_rare_requirements = self.skill.missing_requirements and not are_requirements_available 271 is_skill_available = self.skill.is_available_for_purchase 272 need_rare_skill = not self.skill.is_injected and not is_skill_available 273 if need_rare_skill and need_rare_requirements: 274 return localization.GetByLabel('UI/Skills/ErrorRareSkillAndRequirements') 275 elif need_rare_skill: 276 return localization.GetByLabel('UI/Skills/ErrorRareSkill') 277 elif need_rare_requirements: 278 return localization.GetByLabel('UI/Skills/ErrorRareRequirements') 279 else: 280 return None 281 282 @property 283 def need_to_buy_skills(self): 284 return not self.skill.is_injected or not self.skill.is_grandfathered and self.skill.missing_requirements 285 286 @property 287 def need_omega_upgrade(self): 288 return self.skill.is_omega_restricted 289 290 def buy_and_train(self, skillLevel = None): 291 with self.arrow_animated(): 292 if self.need_to_buy_skills: 293 missing_skills = [] 294 missing_skills.extend((skill.type_id for skill in self.skill.missing_requirements)) 295 missing_skills.append(self.skill.type_id) 296 bought_skills = self.skill.buy_with_requirements() 297 if not bought_skills: 298 return 299 self.skill_service.WaitUntilSkillsAreAvailable(missing_skills) 300 if skillLevel: 301 self.skill.train_to_level(skillLevel) 302 else: 303 self.skill.train() 304 305 def on_clicked(self): 306 if self.need_omega_upgrade: 307 self.upgrade() 308 else: 309 self.buy_and_train(self.skillLevel) 310 311 def upgrade(self): 312 uicore.cmd.OpenCloneUpgradeWindow(origin=ORIGIN_SKILLREQUIREMENTSTOOLTIP, reason=self.skill.type_id)