mixins.py (32472B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\industry\mixins.py 2 import collections 3 import copy 4 import numbers 5 import blue 6 from caching.memoize import Memoize 7 from carbon.common.script.util.format import DateToBlue, FmtDate 8 from clonegrade.const import CLONE_STATE_ALPHA 9 from eve.client.script.environment.invControllers import POSCorpHangar, StationContainer, StationCorpHangar, StationItems, StructureCorpHangar, StructureItemHangar 10 from eve.common.lib import appConst as const 11 from eve.client.script.ui import eveColor 12 from eve.common.script.sys import idCheckers 13 from eve.common.script.sys.idCheckers import IsStation, flagCorpSAGs, IsShip 14 import evetypes 15 from industry.const import Reference 16 from inventorycommon.util import GetPackagedVolume 17 from localization.formatters.timeIntervalFormatters import FormatTimeInterval 18 import industry 19 import structures 20 import localization 21 import telemetry 22 import inventorycommon.typeHelpers 23 from eve.client.script.ui.shared.inventory.invCommon import CONTAINERGROUPS 24 from industry.const import REACTION_GROUPS 25 from eve.client.script.ui.shared.industry import industryUIConst, GetGroupName, GetProductGroupAndCategory 26 from eve.common.script.util import industryCommon 27 from eve.common.script.util.slimItem import SlimItem 28 from carbonui.util.color import Color 29 from omega.client.clone_grade_svc import get_clone_grade_svc 30 from utillib import KeyVal 31 from eveprefs import boot 32 INSTALLED_TEXT = localization.GetByLabel('UI/Industry/Installed') 33 IMPOUNTED_TEXT = localization.GetByLabel('UI/Corporations/Assets/Impounded') 34 NON_FACILITY_TEXT = localization.GetByLabel('UI/Industry/NonFacility') 35 AVAILABLE_TEXT = localization.GetByLabel('UI/Industry/Available') 36 37 @telemetry.ZONE_METHOD 38 def GetFacilityName(facilityID, typeID = None, solarSystemID = None): 39 return _GetFacilityName(facilityID, typeID, solarSystemID) 40 41 42 @Memoize(0.5) 43 def _GetFacilityName(facilityID, typeID = None, solarSystemID = None): 44 try: 45 name = cfg.evelocations.Get(facilityID).name 46 except (KeyError, AttributeError): 47 name = None 48 if typeID: 49 name = evetypes.GetName(typeID) 50 51 if not idCheckers.IsStation(facilityID) and solarSystemID: 52 if name: 53 if not (typeID and evetypes.GetCategoryID(typeID) == const.categoryStructure): 54 name = localization.GetByLabel('UI/Industry/LocationAndFacility', locationName=cfg.evelocations.Get(solarSystemID).name, facilityName=name) 55 else: 56 name = cfg.evelocations.Get(solarSystemID).name 57 return name 58 59 60 GROUPORDERINDEXES_BY_NUMGROUPS = ((0,), 61 (0, 1), 62 (1, 0, 2), 63 (0, 64 3, 65 2, 66 1), 67 (1, 68 3, 69 0, 70 4, 71 2), 72 (4, 73 2, 74 0, 75 1, 76 3, 77 5)) 78 79 def GetMaterialsByGroups(materialsData): 80 groups = collections.defaultdict(list) 81 for materialData in materialsData: 82 if materialData.IsSelectable(): 83 invGroupID = industryUIConst.GROUP_SELECTABLEITEM 84 elif materialData.IsOptional(): 85 invGroupID = industryUIConst.GROUP_OPTIONALITEM 86 else: 87 typeID = materialData.typeID 88 groupID = evetypes.GetGroupID(typeID) 89 categoryID = evetypes.GetCategoryID(typeID) 90 invGroupID = industryUIConst.GetIndustryGroupID(typeID, groupID, categoryID) 91 groups[invGroupID].append(materialData) 92 93 if not groups: 94 return [] 95 for groupID, materialDataList in groups.iteritems(): 96 materialDataList.sort(key=lambda x: (-IsShip(evetypes.GetCategoryID(x.typeID)) if x.typeID else 0, x.typeID)) 97 98 ret = groups.items() 99 ret.sort(key=lambda groupID_materials: (len(groupID_materials[1]), groupID_materials[0]), reverse=True) 100 numGroups = max(len(ret) - 1, 0) 101 groupOrderIndexes = GROUPORDERINDEXES_BY_NUMGROUPS[numGroups] 102 return [ ret[index] for index in groupOrderIndexes ] 103 104 105 class BlueprintMixin(object): 106 107 def GetItem(self): 108 return SlimItem(itemID=self.blueprintID, typeID=self.blueprintTypeID, ownerID=self.ownerID) 109 110 def GetName(self): 111 return evetypes.GetName(self.blueprintTypeID) 112 113 def GetDescription(self): 114 return evetypes.GetDescription(self.blueprintTypeID) 115 116 def GetEstimatedUnitPrice(self): 117 try: 118 return inventorycommon.typeHelpers.GetAveragePrice(self.blueprintTypeID) or 0.0 119 except KeyError: 120 return 0.0 121 122 def GetLocationName(self): 123 if self.facilityID is None: 124 return self.location.GetLocationName() 125 return self.location.GetName() 126 127 def GetGroupName(self): 128 typeID = self.GetProductOrBlueprintTypeID() 129 return GetGroupName(typeID) 130 131 def GetProductOrBlueprintTypeID(self): 132 productTypeID = self.productTypeID 133 if productTypeID: 134 return productTypeID 135 else: 136 return self.blueprintTypeID 137 138 @telemetry.ZONE_METHOD 139 def GetProductGroupAndCategory(self): 140 typeID = self.GetProductOrBlueprintTypeID() 141 return GetProductGroupAndCategory(typeID) 142 143 def GetDistance(self): 144 if self.facility: 145 return self.facility.distance 146 147 def GetFacilityName(self): 148 if self.facility: 149 return self.facility.GetName() 150 151 def GetFacilityType(self): 152 if self.facility: 153 return self.facility.typeID 154 155 def GetRunsRemainingLabel(self): 156 return str(self.runsRemaining) 157 158 def GetLabel(self): 159 if self.quantity > 1: 160 return '%s x %s' % (self.quantity, self.GetName()) 161 else: 162 return self.GetName() 163 164 def GetAvailabilityText(self): 165 if self.IsInstalled(): 166 return INSTALLED_TEXT 167 if self.IsImpounded(): 168 return IMPOUNTED_TEXT 169 if self.facilityID is None: 170 return NON_FACILITY_TEXT 171 return AVAILABLE_TEXT 172 173 def IsInstalled(self): 174 return self.jobID is not None 175 176 def IsImpounded(self): 177 return bool(self.isImpounded) 178 179 def IsSameBlueprint(self, bpData): 180 if bpData is None: 181 return False 182 if self.blueprintTypeID != bpData.blueprintTypeID: 183 return False 184 if self.blueprintID != bpData.blueprintID: 185 return False 186 if self.locationID != bpData.locationID: 187 return False 188 if self.flagID != bpData.flagID: 189 return False 190 if self.ownerID != bpData.ownerID: 191 return False 192 if self.original != bpData.original: 193 return False 194 return True 195 196 def IsAncientRelic(self): 197 return evetypes.GetCategoryID(self.blueprintTypeID) == const.categoryAncientRelic 198 199 def IsReactionBlueprint(self): 200 return evetypes.GetGroupID(self.blueprintTypeID) in REACTION_GROUPS 201 202 def IsWithinRange(self): 203 if IsStation(self.facilityID): 204 return self.facilityID == session.stationid 205 if session.structureid and self.facilityID == session.structureid: 206 return True 207 if session.solarsystemid: 208 bp = sm.GetService('michelle').GetBallpark() 209 if bp is None: 210 return False 211 slimItem = bp.GetInvItem(self.facilityID) 212 if slimItem and slimItem.categoryID != const.categoryStructure: 213 return True 214 return False 215 216 def GetCopy(self): 217 bpData = sm.GetService('blueprintSvc').GetBlueprintType(self.blueprintTypeID).copy() 218 bpData.original = self.original 219 bpData.materialEfficiency = self.materialEfficiency 220 bpData.timeEfficiency = self.timeEfficiency 221 bpData.runsRemaining = self.runsRemaining 222 return bpData 223 224 def GetDragData(self): 225 dragData = None 226 if self.IsWithinRange(): 227 try: 228 invController = self.location.GetInvController() 229 except TypeError: 230 pass 231 else: 232 item = invController.GetItem(self.blueprintID) 233 if item: 234 return KeyVal(__guid__='xtriui.InvItem', name=self.GetLabel(), item=item, rec=item) 235 236 return KeyVal(__guid__='uicls.GenericDraggableForTypeID', typeID=self.blueprintTypeID, itemID=self.blueprintID, label=self.GetLabel()) 237 238 239 class ActivityMixin(object): 240 241 def GetName(self): 242 return localization.GetByLabel(industryUIConst.ACTIVITY_NAMES.get(self.activityID)) 243 244 def GetHint(self): 245 return self.GetName() 246 247 def GetIcon(self): 248 return industryUIConst.ACTIVITY_ICONS_SMALL[self.activityID] 249 250 def GetTime(self, runs = 1): 251 return FormatTimeInterval(self.time * runs * const.SEC) 252 253 def GetMaterialsByGroups(self): 254 return GetMaterialsByGroups(self.materials) 255 256 def IsOmegaActivity(self): 257 return self.IsClonestateRestricted(CLONE_STATE_ALPHA) 258 259 def IsClonestateRestricted(self, clonestate = None): 260 for skill in self.skills: 261 maxLvl = get_clone_grade_svc().get_max_skill_level(skill.typeID, clonestate) 262 if maxLvl < skill.level: 263 return True 264 265 return False 266 267 268 class FacilityMixin(object): 269 270 def GetName(self): 271 return GetFacilityName(self.facilityID, self.typeID, self.solarSystemID) 272 273 def GetTypeName(self): 274 categoryID = evetypes.GetCategoryID(self.typeID) 275 if categoryID == const.categoryStation: 276 return evetypes.GetCategoryNameByCategory(categoryID) 277 elif categoryID == const.categoryStructure: 278 nameFunc = evetypes.GetName if boot.region == 'optic' else evetypes.GetEnglishName 279 return '%s - %s ' % (nameFunc(self.typeID), evetypes.GetGroupName(self.typeID)) 280 else: 281 return evetypes.GetGroupName(self.typeID) 282 283 def GetFacilityType(self): 284 return self.typeID 285 286 def GetOwnerName(self): 287 try: 288 return cfg.eveowners.Get(self.ownerID).name 289 except KeyError: 290 return '' 291 292 def GetHint(self): 293 return self.GetName() 294 295 def HasFacilityModifiers(self, activityID): 296 for modifier in self.modifiers: 297 if modifier.reference in (Reference.FACILITY, Reference.HULL, Reference.RIG) and modifier.activity == activityID: 298 return True 299 300 if self.rigModifiers: 301 for modifierTypeID, activities in self.rigModifiers.iteritems(): 302 if activityID in activities: 303 return True 304 305 return False 306 307 def GetFacilityModifiersByActivityID(self): 308 ret = collections.defaultdict(list) 309 for modifier in self.modifiers: 310 if modifier.reference in (industry.Reference.FACILITY, industry.Reference.HULL, industry.Reference.RIG) and modifier.groupID is None and modifier.categoryID is None and modifier.invTypeID is None: 311 ret[modifier.activity].append(modifier) 312 313 return ret 314 315 def GetCostIndexByActivityID(self): 316 ret = {} 317 for modifier in self.modifiers: 318 if modifier.reference == industry.Reference.SYSTEM: 319 ret[modifier.activity] = modifier.GetAsSystemCostIndex(modifier.activity) 320 321 return ret 322 323 def GetCostIndex(self, activityID): 324 return self.GetCostIndexByActivityID().get(activityID, 0.0) 325 326 def CanDoActivity(self, activityID, productTypeID): 327 if activityID not in self.activities: 328 return False 329 if evetypes.GetCategoryID(self.GetFacilityType()) == const.categoryStructure: 330 accessKey = structures.services.GetServiceID(activityID, productTypeID) 331 return self.serviceAccess.get(accessKey, None) is not None 332 return True 333 334 def GetServiceTaxes(self): 335 if hasattr(self, 'taxRates'): 336 return self.taxRates.copy() 337 338 def _GetGroupIDs(): 339 if activityID in (industry.MANUFACTURING, industry.REACTION): 340 for groupID in self.activities[activityID]['groups']: 341 yield groupID 342 343 for groupID in evetypes.GetGroupIDsByCategories(self.activities[activityID]['categories']): 344 yield groupID 345 346 else: 347 yield 348 raise StopIteration 349 350 taxRates = collections.OrderedDict() 351 for serviceID in sorted(structures.INDUSTRY_SERVICES): 352 if serviceID in structures.META_SERVICES: 353 continue 354 activityID = structures.GetActivityID(serviceID) 355 if activityID not in self.activities: 356 continue 357 for groupID in _GetGroupIDs(): 358 if structures.GetServiceID(activityID, None, groupID) == serviceID: 359 if isinstance(self.tax, numbers.Number): 360 tax = self.tax * 100 361 else: 362 tax = self.serviceAccess.get(serviceID) 363 if tax is not None: 364 tax *= 100 365 taxRates[serviceID] = tax 366 break 367 368 self.taxRates = taxRates.copy() 369 return taxRates 370 371 372 class SkillMixin(object): 373 374 def GetName(self): 375 return evetypes.GetName(self.typeID) 376 377 def GetHint(self): 378 return localization.GetByLabel('UI/InfoWindow/SkillAndLevel', skill=self.typeID, skillLevel=self.level) 379 380 381 class MaterialMixin(object): 382 383 def GetName(self): 384 return evetypes.GetName(self.typeID) 385 386 def GetDescription(self): 387 return evetypes.GetDescription(self.typeID) 388 389 def GetHint(self): 390 return localization.GetByLabel('UI/Common/QuantityAndItem', item=self.typeID, quantity=self.quantity) 391 392 def GetEstimatedUnitPrice(self): 393 try: 394 return inventorycommon.typeHelpers.GetAveragePrice(self.typeID) or 0.0 395 except KeyError: 396 return 0.0 397 398 def GetPackagedVolume(self): 399 try: 400 return GetPackagedVolume(self.typeID) or 0.0 401 except KeyError: 402 return 0.0 403 404 def IsOptional(self): 405 return bool(self.options) 406 407 def IsSelectable(self): 408 if not self.IsOptional(): 409 return False 410 typeIDs = [ material.typeID for material in self.options ] 411 return None not in typeIDs 412 413 def IsOptionSelected(self): 414 return self.typeID is not None 415 416 417 class JobMixin(object): 418 419 def GetStartDateLabel(self): 420 return FmtDate(DateToBlue(self.startDate), 'ls') 421 422 def GetEndDateLabel(self): 423 return FmtDate(DateToBlue(self.endDate), 'ls') 424 425 def GetJobTimeLeftLabel(self): 426 if self.status == industry.STATUS_UNSUBMITTED: 427 time = self.time.total_seconds() * const.SEC 428 elif self.status == industry.STATUS_INSTALLED: 429 time = DateToBlue(self.endDate) - blue.os.GetWallclockTime() 430 elif self.status == industry.STATUS_PAUSED: 431 time = DateToBlue(self.endDate) - DateToBlue(self.pauseDate) 432 elif self.status == industry.STATUS_READY: 433 time = 0 434 else: 435 return '-' 436 time = long(max(time, 0)) 437 return FormatTimeInterval(time) 438 439 def GetJobStateLabel(self): 440 if self.status <= industry.STATUS_READY: 441 return self.GetJobTimeLeftLabel() 442 elif self.status == industry.STATUS_DELIVERED: 443 if self.activityID == industry.INVENTION: 444 if self.successfulRuns == 0: 445 return '<color=red>%s' % localization.GetByLabel('UI/Industry/JobFailed') 446 else: 447 return localization.GetByLabel('UI/Industry/PartiallySucceeded', numSucceeded=self.successfulRuns, numTotal=self.runs) 448 return localization.GetByLabel('UI/Industry/Succeeded') 449 elif self.status == industry.STATUS_CANCELLED: 450 color = Color.RGBtoHex(*industryUIConst.COLOR_NOTREADY) 451 return '<color=%s>%s' % (color, localization.GetByLabel('UI/Industry/Cancelled')) 452 elif self.status == industry.STATUS_REVERTED: 453 color = Color.RGBtoHex(*industryUIConst.COLOR_NOTREADY) 454 return '<color=%s>%s' % (color, localization.GetByLabel('UI/Industry/Reverted')) 455 else: 456 return '' 457 458 def GetJobProgressRatio(self): 459 if self.status == industry.STATUS_INSTALLED: 460 timeLeft = blue.os.GetWallclockTime() - DateToBlue(self.startDate) 461 totalTime = long(self.time.total_seconds()) * const.SEC 462 return float(timeLeft) / totalTime 463 elif self.status == industry.STATUS_PAUSED: 464 timeLeft = blue.os.GetWallclockTime() - DateToBlue(self.startDate) 465 totalTime = long(self.time.total_seconds()) * const.SEC 466 return float(timeLeft) / totalTime 467 elif self.status > industry.STATUS_COMPLETED: 468 return 1.0 469 else: 470 return 0.0 471 472 def GetProductTypeID(self): 473 if self.product: 474 return self.product.typeID 475 return self.productTypeID 476 477 def GetProductLabel(self): 478 if self.activityID == industry.MANUFACTURING: 479 return self.product.GetName() 480 if self.activityID in (industry.RESEARCH_MATERIAL, industry.RESEARCH_TIME): 481 return localization.GetByLabel('UI/Industry/ResearchedBlueprint') 482 if self.activityID == industry.COPYING: 483 return localization.GetByLabel('UI/Industry/BlueprintCopy') 484 if self.activityID == industry.INVENTION: 485 if self.product: 486 return self.product.GetName() 487 else: 488 return localization.GetByLabel('UI/Industry/NoOutcomeSelected') 489 490 def GetProductAmountLabel(self): 491 if self.activityID in (industry.MANUFACTURING, industry.INVENTION, industry.REACTION): 492 return 'x %s' % self.product.quantity 493 if self.activityID == industry.RESEARCH_MATERIAL: 494 diff = self.product.materialEfficiency - self.blueprint.materialEfficiency 495 return '+%s%%' % diff 496 if self.activityID == industry.RESEARCH_TIME: 497 diff = self.product.timeEfficiency - self.blueprint.timeEfficiency 498 return '+%s%%' % diff 499 if self.activityID == industry.COPYING: 500 return 'x %s' % self.product.quantity 501 502 def GetProductNewBlueprint(self): 503 if isinstance(self.product, industry.Blueprint) and self.product.blueprintID is None: 504 return self.product 505 506 def GetRunsRemainingCaption(self): 507 if self.activityID in (industry.MANUFACTURING, industry.INVENTION): 508 if self.blueprint.original: 509 return localization.GetByLabel('UI/Industry/MaximumRuns') 510 else: 511 return localization.GetByLabel('UI/Industry/RunsRemaining') 512 else: 513 if self.activityID in (industry.RESEARCH_MATERIAL, industry.RESEARCH_TIME): 514 return localization.GetByLabel('UI/Industry/LevelsRemaining') 515 if self.activityID in (industry.COPYING, industry.REACTION): 516 return localization.GetByLabel('UI/Industry/MaximumRuns') 517 518 def GetRunsRemainingLabel(self): 519 remaining = industry.MAX_RUNS_HARD_CAP if self.blueprint.original else self.blueprint.runsRemaining 520 minRemaining = min(remaining, self.maxRuns) 521 if minRemaining is None: 522 return industry.MAX_RUNS_HARD_CAP 523 return minRemaining 524 525 def GetStatusColor(self): 526 if self.status == industry.STATUS_READY: 527 return (1, 1, 1, 1) 528 elif self.status == industry.STATUS_INSTALLED: 529 return (1, 1, 1, 0.7) 530 elif self.status == industry.STATUS_PAUSED: 531 return (1, 0, 0, 0.7) 532 else: 533 return (1, 1, 1, 0.3) 534 535 def GetInstallerName(self): 536 return cfg.eveowners.Get(self.installerID).name 537 538 @telemetry.ZONE_METHOD 539 def GetLocationsInvControllersAndLocations(self): 540 ret = [] 541 for location in self.locations: 542 invController = location.GetInvController() 543 ret.append((invController, location)) 544 545 ret = sorted(ret, key=self._GetSortKey) 546 return ret 547 548 @telemetry.ZONE_METHOD 549 def _GetSortKey(self, data): 550 invController, location = data 551 isContainer = evetypes.GetGroupID(location.typeID) in CONTAINERGROUPS 552 return (location.flagID, isContainer, invController.GetName()) 553 554 def IsInstalled(self): 555 return self.status >= industry.STATUS_INSTALLED 556 557 def HasMultipleProducts(self): 558 return len(self.products) > 1 559 560 def IsProductSelectable(self): 561 return self.activityID == industry.INVENTION and self.HasMultipleProducts() 562 563 def GetGaugeValue(self): 564 maxRuns = self.maxRuns 565 if not maxRuns or maxRuns == industry.MAX_RUNS_HARD_CAP: 566 return 0.0 567 else: 568 return float(self.runs) / maxRuns 569 570 def GetModifierCaption(self, modifierCls): 571 if modifierCls == industry.TimeModifier: 572 return localization.GetByLabel('UI/Industry/ModifierTimeCaption') 573 if modifierCls == industry.CostModifier: 574 return localization.GetByLabel('UI/Industry/ModifierCostCaption') 575 if modifierCls == industry.MaterialModifier: 576 return localization.GetByLabel('UI/Industry/ModifierMaterialCaption') 577 if modifierCls == industry.ProbabilityModifier: 578 return localization.GetByLabel('UI/Industry/ModifierProbabilityCaption') 579 580 def GetModifiers(self, modifierCls): 581 modifiers = {} 582 for modifier in self.input_modifiers: 583 if self._FilterModifiers(modifier, modifierCls): 584 if modifier.reference.value in modifiers: 585 modifiers[modifier.reference.value].amount *= modifier.amount 586 else: 587 modifiers[modifier.reference.value] = copy.copy(modifier) 588 589 return [ modifier for ref, modifier in sorted(modifiers.items()) ] 590 591 def _FilterModifiers(self, modifier, modifierCls): 592 if isinstance(modifier, industry.CostModifier) and modifier.reference == industry.Reference.SYSTEM: 593 return False 594 if isinstance(modifier, industry.CostModifier) and modifier.reference == industry.Reference.CLONE_STATE: 595 return False 596 return isinstance(modifier, modifierCls) 597 598 def GetTimeSkillTypes(self): 599 skills = [] 600 if self.activityID == industry.MANUFACTURING: 601 skills += [const.typeIndustry, const.typeAdvancedIndustry] 602 elif self.activityID == industry.COPYING: 603 skills += [const.typeScience, const.typeAdvancedIndustry] 604 elif self.activityID == industry.RESEARCH_TIME: 605 skills += [const.typeResearch, const.typeAdvancedIndustry] 606 elif self.activityID == industry.RESEARCH_MATERIAL: 607 skills += [const.typeMetallurgy, const.typeAdvancedIndustry] 608 elif self.activityID == industry.INVENTION: 609 skills += [const.typeAdvancedIndustry] 610 godma = sm.GetService('godma') 611 for modifier, attribute, activityID in industryCommon.REQUIRED_SKILL_MODIFIERS: 612 if self.activityID == activityID and modifier == industry.TimeModifier: 613 for skill in self.required_skills: 614 if godma.GetTypeAttribute(skill.typeID, attribute): 615 skills.append(skill.typeID) 616 617 return skills 618 619 def GetMaterialsByGroups(self): 620 if self.IsInstalled(): 621 return [] 622 return GetMaterialsByGroups(self.materials) 623 624 def GetFacilityName(self): 625 try: 626 if self.facility: 627 return self.facility.GetName() 628 primeFacility = self.status < industry.STATUS_COMPLETED 629 return sm.GetService('facilitySvc').GetFacility(self.facilityID, prime=primeFacility).GetName() 630 except KeyError: 631 return GetFacilityName(self.stationID, None, self.solarSystemID) 632 633 def GetFacilityType(self): 634 try: 635 if self.facility: 636 return self.facility.typeID 637 primeFacility = self.status < industry.STATUS_COMPLETED 638 return sm.GetService('facilitySvc').GetFacility(self.facilityID, prime=primeFacility).typeID 639 except KeyError: 640 pass 641 642 def IsPreview(self): 643 return self.blueprintID is None 644 645 def HasError(self, errorID): 646 for errorID2, args in self.errors: 647 if errorID == errorID2: 648 return True 649 650 return False 651 652 def GetCurrentActivity(self): 653 return self.blueprint.activities.get(self.activityID) 654 655 def GetCostWithoutAlphaTax(self): 656 modifiers = [ x for x in self.input_modifiers if x.reference != industry.Reference.CLONE_STATE ] 657 return self._get_cost_for_modifiers(modifiers) 658 659 def GetFacilityTax(self): 660 tax = 0 661 if self.facility and self.facility.tax is not None: 662 tax = self.facility.tax 663 elif self.activity and self.facility: 664 tax = self.activity.activity_tax(self.facility) 665 return int(round(self._get_base_cost() * tax)) 666 667 def GetOutputLocationName(self): 668 try: 669 if self.IsOutputLocationSameAsFacility(): 670 return localization.GetByLabel('UI/Industry/Hangar') 671 if self.outputLocationID: 672 outputName = '' 673 outputLocation = cfg.evelocations.GetIfExists(self.outputLocationID) 674 if outputLocation: 675 name = outputLocation.locationName 676 if name: 677 outputName = name 678 else: 679 outputName = localization.GetByLabel('UI/Inventory/UnnamedContainer') 680 if self.outputFlagID in flagCorpSAGs: 681 divisionName = sm.GetService('corp').GetHangarDivisionNameFromFlagID(self.outputFlagID) 682 if outputName: 683 outputName = '%s (%s)' % (outputName, divisionName) 684 else: 685 outputName = divisionName 686 return outputName 687 except Exception as e: 688 return '' 689 690 def IsOutputLocationSameAsFacility(self): 691 try: 692 if self.facility.facilityID and self.facility.facilityID == self.outputLocationID: 693 return True 694 return False 695 except Exception: 696 return False 697 698 699 class LocationMixin(object): 700 701 def GetName(self): 702 try: 703 return self.GetInvController().GetName() 704 except TypeError: 705 return self.GetLocationName() 706 707 def GetIcon(self): 708 try: 709 return self.GetInvController().GetIconName() 710 except TypeError: 711 try: 712 return inventorycommon.typeHelpers.GetIcon(self.typeID).iconName 713 except AttributeError: 714 return None 715 716 def GetInvController(self): 717 groupID = evetypes.GetGroupID(self.typeID) 718 categoryID = evetypes.GetCategoryID(self.typeID) 719 if groupID in CONTAINERGROUPS: 720 return StationContainer(self.itemID, self.typeID) 721 if self.typeID == const.typeOffice: 722 return StationCorpHangar(self.itemID, const.corpDivisionsByFlag.get(self.flagID)) 723 if groupID in (const.groupAssemblyArray, const.groupMobileLaboratory): 724 return POSCorpHangar(self.itemID, const.corpDivisionsByFlag.get(self.flagID)) 725 if categoryID == const.categoryStructure: 726 if self.flagID == const.flagHangar: 727 return StructureItemHangar(self.itemID) 728 if self.flagID in const.corpDivisionsByFlag: 729 return StructureCorpHangar(self.itemID, const.corpDivisionsByFlag.get(self.flagID)) 730 if categoryID == const.categoryStation: 731 return StationItems(self.itemID) 732 raise TypeError 733 734 def GetLocationName(self): 735 if self.solarSystemID == const.locationAssetSafety or self.typeID == const.typeAssetSafetyWrap: 736 typeName = evetypes.GetName(const.typeAssetSafetyWrap) 737 wraps = [] 738 if self.ownerID == session.charid: 739 wraps = sm.GetService('assetSafety').GetItemsInSafetyForCharacter() 740 elif self.ownerID == session.corpid and self.canView: 741 wraps = sm.GetService('assetSafety').GetItemsInSafetyForCorp() 742 for asw in wraps: 743 if asw['assetWrapID'] == self.itemID: 744 return '%s - %s' % (typeName, asw['wrapName']) 745 746 return typeName 747 if evetypes.GetCategoryID(self.typeID) in (const.categoryStructure, const.categoryStation): 748 return cfg.evelocations.Get(self.itemID).locationName 749 try: 750 locationName = cfg.evelocations.Get(self.itemID).locationName 751 except KeyError: 752 locationName = evetypes.GetName(self.typeID) 753 754 return '%s - %s' % (sm.GetService('map').GetItem(self.solarSystemID).itemName, locationName) 755 756 757 class ModifierMixin(object): 758 759 def GetName(self): 760 if self.reference == industry.Reference.BLUEPRINT: 761 if isinstance(self, industry.TimeModifier): 762 return localization.GetByLabel('UI/Industry/BlueprintTimeEfficiency') 763 if isinstance(self, industry.MaterialModifier): 764 return localization.GetByLabel('UI/Industry/BlueprintMaterialEfficiency') 765 if isinstance(self, industry.ProbabilityModifier): 766 return localization.GetByLabel('UI/Industry/BlueprintBaseProbability') 767 if isinstance(self, industry.CostModifier): 768 return localization.GetByLabel('UI/Industry/BlueprintCostModifier') 769 else: 770 if self.reference == industry.Reference.DECRYPTOR: 771 return localization.GetByLabel('UI/Industry/OptionalDecryptor') 772 if self.reference == industry.Reference.SYSTEM: 773 return localization.GetByLabel('UI/Industry/SystemCostIndex') 774 if self.reference == industry.Reference.FACILITY: 775 return localization.GetByLabel('UI/Industry/Facility') 776 if self.reference == industry.Reference.SKILLS: 777 return localization.GetByLabel('UI/Industry/SkillsAndImplants') 778 if self.reference == industry.Reference.DISTRICT: 779 return localization.GetByLabel('UI/Industry/DistrictModifier') 780 if self.reference == industry.Reference.FACTION: 781 return localization.GetByLabel('UI/Industry/FactionModifier') 782 if self.reference == industry.Reference.CLONE_STATE: 783 return localization.GetByLabel('UI/Industry/ClonestateModifier') 784 if self.reference == industry.Reference.RIG: 785 return localization.GetByLabel('UI/Industry/RigModifier') 786 if self.reference == industry.Reference.HULL: 787 return localization.GetByLabel('UI/Industry/HullModifier') 788 789 def GetAsPercentage(self): 790 return self.GetAsBonus() * 100.0 791 792 def GetAsBonus(self): 793 return self.amount - 1.0 794 795 def GetAsSystemCostIndex(self, activityID): 796 return self.amount 797 798 def GetPercentageLabel(self, decimals = 1): 799 percent = self.GetAsPercentage() 800 if isinstance(self, industry.ProbabilityModifier) and self.reference == Reference.BLUEPRINT: 801 perentageText = self._GetPercentageText(100.0 + percent, decimals) 802 return perentageText 803 else: 804 color = self.GetModifierColor() 805 if percent > 0: 806 perentageText = self._GetPercentageText(percent, decimals) 807 return '<color=%s>+%s</color>' % (Color.RGBtoHex(*color), perentageText) 808 perentageText = self._GetPercentageText(percent, decimals) 809 return '<color=%s>%s</color>' % (Color.RGBtoHex(*color), perentageText) 810 811 def _GetPercentageText(self, percent, decimals = 1): 812 perentageText = '%.*f%%' % (decimals, percent) 813 return perentageText 814 815 def GetModifierColor(self): 816 amount = self.GetAsBonus() 817 if isinstance(self, industry.ProbabilityModifier): 818 amount = -amount 819 if amount < 0.0: 820 return eveColor.SUCCESS_GREEN 821 elif amount > 0.0: 822 return eveColor.DANGER_RED 823 else: 824 return Color.GRAY 825 826 827 industry.Blueprint.extend(BlueprintMixin) 828 industry.Activity.extend(ActivityMixin) 829 industry.Facility.extend(FacilityMixin) 830 industry.Skill.extend(SkillMixin) 831 industry.Material.extend(MaterialMixin) 832 industry.Job.extend(JobMixin) 833 industry.JobData.extend(JobMixin) 834 industry.Location.extend(LocationMixin) 835 industry.modifiers.Modifier.extend(ModifierMixin)