planetCommon.py (14828B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\planet\planetCommon.py 2 import math 3 import blue 4 import evetypes 5 import localization 6 import log 7 import trinity 8 import utillib 9 from carbon.common.script.util.format import FmtTime 10 from carbonui.uicore import uicore 11 from carbonui.util.color import Color 12 from carbonui.util.various_unsorted import SortListOfTuples 13 from eve.client.script.ui.camera import cameraUtil 14 from eve.common.lib import appConst 15 from eve.common.script.planet.surfacePoint import SurfacePoint 16 from eve.common.script.util import planetCommon 17 from eve.common.script.util.eveFormat import FmtISKAndRound 18 from fsdBuiltData.common.planet import get_schematic, get_schematic_ids_for_pin_type_id, get_schematic_info_for_type_id, get_schematic_name, get_schematic_types 19 from inventorycommon import typeHelpers 20 from localization import GetByLabel 21 PLANET_SCALE = 1000.0 22 PLANET_TEXTURE_SIZE = 2048 23 PLANET_RESOURCE_TEX_WIDTH = 2048 24 PLANET_RESOURCE_TEX_HEIGHT = 1024 25 PLANET_HEATMAP_COLORS = ((0, 0, 0.5, 0.5), 26 (0, 0, 1, 1), 27 (0, 0.5, 1, 1), 28 (0, 1, 1, 1), 29 (0, 1, 0.5, 1), 30 (0, 1, 0, 1), 31 (0.5, 1, 0, 1), 32 (1, 1, 0, 1), 33 (1, 0.5, 0, 1), 34 (1, 0, 0, 1)) 35 PANEL_STATS = 1 36 PANEL_LINKS = 2 37 PANEL_DECOMMISSION = 3 38 PANEL_STORAGE = 4 39 PANEL_INCOMING = 5 40 PANEL_OUTGOING = 6 41 PANEL_LAUNCH = 7 42 PANEL_PRODUCTS = 8 43 PANEL_SURVEYFORDEPOSITS = 9 44 PANEL_SCHEMATICS = 10 45 PANEL_UPGRADELINK = 11 46 PANEL_UPGRADE = 12 47 PANEL_ROUTES = 13 48 PANEL_CREATEROUTE = 14 49 PANEL_TRANSFER = 15 50 PANELDATA = {PANEL_STATS: ('res:/UI/Texture/Icons/44_32_24.png', 'UI/PI/Common/Stats'), 51 PANEL_LINKS: ('res:/UI/Texture/Icons/77_32_31.png', 'UI/PI/Common/Links'), 52 PANEL_DECOMMISSION: ('res:/UI/Texture/Icons/77_32_22.png', 'UI/PI/Common/Decommission'), 53 PANEL_STORAGE: ('res:/UI/Texture/Icons/77_32_18.png', 'UI/PI/Common/Storage'), 54 PANEL_INCOMING: ('res:/UI/Texture/Icons/77_32_21.png', 'UI/PI/Common/Incoming'), 55 PANEL_OUTGOING: ('res:/UI/Texture/Icons/77_32_20.png', 'UI/PI/Common/Outgoing'), 56 PANEL_LAUNCH: ('res:/UI/Texture/Icons/77_32_19.png', 'UI/PI/Common/Launch'), 57 PANEL_PRODUCTS: ('res:/UI/Texture/Icons/77_32_24.png', 'UI/PI/Common/Products'), 58 PANEL_SURVEYFORDEPOSITS: ('res:/UI/Texture/Icons/77_32_23.png', 'UI/PI/Common/InstallExtractionProgram'), 59 PANEL_SCHEMATICS: ('res:/UI/Texture/Icons/77_32_17.png', 'UI/PI/Common/Schematics'), 60 PANEL_UPGRADELINK: ('res:/UI/Texture/Icons/77_32_36.png', 'UI/PI/Common/UpgradeLink'), 61 PANEL_UPGRADE: ('res:/UI/Texture/Icons/77_32_37.png', 'UI/PI/Common/Upgrade'), 62 PANEL_ROUTES: ('res:/UI/Texture/Icons/77_32_32.png', 'UI/PI/Common/Routes'), 63 PANEL_CREATEROUTE: ('', 'UI/PI/Common/CreateRoute'), 64 PANEL_TRANSFER: ('', 'UI/PI/Common/SelectTransferDestination')} 65 PANEL_MIN_MAX_HEIGHT = {PANEL_STATS: (100, 200), 66 PANEL_LINKS: (200, None), 67 PANEL_DECOMMISSION: (100, 150), 68 PANEL_STORAGE: (200, None), 69 PANEL_INCOMING: (200, None), 70 PANEL_OUTGOING: (200, None), 71 PANEL_LAUNCH: (300, None), 72 PANEL_PRODUCTS: (200, None), 73 PANEL_SURVEYFORDEPOSITS: (200, None), 74 PANEL_SCHEMATICS: (300, None), 75 PANEL_UPGRADELINK: (250, None), 76 PANEL_UPGRADE: (180, 180), 77 PANEL_ROUTES: (200, None), 78 PANEL_CREATEROUTE: (155, 155), 79 PANEL_TRANSFER: (30, 30)} 80 PLANET_COLOR_POWER = (236 / 255.0, 28 / 255.0, 36 / 255.0) 81 PLANET_COLOR_CPU = (0.0, 255 / 255.0, 212 / 255.0) 82 PLANET_COLOR_CYCLE = (1.0, 1.0, 1.0) 83 PLANET_COLOR_BANDWIDTH = (1.0, 1.0, 1.0) 84 PLANET_COLOR_LINKEDITMODE = (255 / 255.0, 85 205 / 255.0, 86 0.0, 87 1.0) 88 PLANET_COLOR_PINEDITMODE = (255 / 255.0, 205 / 255.0, 0.0) 89 PLANET_COLOR_STORAGE = (10 / 255.0, 90 67 / 255.0, 91 102 / 255.0, 92 1.0) 93 PLANET_COLOR_EXTRACTOR = (0 / 255.0, 94 153 / 255.0, 95 153 / 255.0, 96 1.0) 97 PLANET_COLOR_PROCESSOR = (178 / 255.0, 98 98 / 255.0, 99 45 / 255.0, 100 1.0) 101 PLANET_COLOR_PROCESSOR_ADVANCED = (0.929, 0.859, 0.207, 1.0) 102 PLANET_COLOR_PROCESSOR_HIGHTECH = (0.739, 0.929, 0.207, 1.0) 103 PLANET_COLOR_CURRLEVEL = (0.247, 0.745, 0.165, 1.0) 104 PLANET_COLOR_UPGRADELEVEL = (0.271, 0.494, 0.137, 1.0) 105 PLANET_COLOR_POWERUPGRADE = (0.671, 0.047, 0.071, 1.0) 106 PLANET_COLOR_CPUUPGRADE = (0.278, 0.655, 0.592, 1.0) 107 PLANET_COLOR_EXTRACTIONLINK = (0.4, 1.0, 1.0, 1.0) 108 PLANET_COLOR_USED_STORAGE = (0 / 255.0, 169 / 255.0, 244 / 255.0) 109 PLANET_COLOR_USED_PROCESSOR = (237 / 255.0, 153 / 255.0, 53 / 255.0) 110 PLANET_COLOR_NEEDSATTENTION = (1.0, 0.0, 0.0, 1.0) 111 PLANET_COLOR_ICON_COMMANDCENTER = (171 / 255.0, 243 / 255.0, 255 / 255.0) 112 PLANET_COLOR_ICON_STORAGE = (2 / 255.0, 106 / 255.0, 147 / 255.0) 113 PLANET_COLOR_ICON_SPACEPORT = (3 / 255.0, 178 / 255.0, 239 / 255.0) 114 PLANET_COLOR_ICON_EXTRACTOR = (48 / 255.0, 239 / 255.0, 216 / 255.0) 115 PLANET_COLOR_ICON_PROCESSOR = (237 / 255.0, 153 / 255.0, 53 / 255.0) 116 PLANET_COLOR_ICON_PROCESSOR_ADVANCED = (0.929, 0.859, 0.207, 1.0) 117 PLANET_COLOR_ICON_PROCESSOR_HIGHTECH = (0.739, 0.929, 0.207, 1.0) 118 PINTYPE_NOPICK = 0 119 PINTYPE_NORMAL = 1 120 PINTYPE_NORMALEDIT = 2 121 PINTYPE_EXTRACTIONHEAD = 3 122 PINTYPE_OTHERS = 4 123 PINTYPE_DEPLETION = 5 124 PLANET_2PI = math.pi * 2 125 PLANET_PI_DIV_2 = math.pi / 2 126 PLANET_COMMANDCENTERMAXLEVEL = 5 127 DARKPLANETS = (appConst.typePlanetPlasma, appConst.typePlanetLava, appConst.typePlanetSandstorm) 128 129 def GetContrastColorForCurrPlanet(): 130 if not sm.GetService('viewState').IsViewActive('planet'): 131 return None 132 else: 133 planetTypeID = sm.GetService('planetUI').planet.planetTypeID 134 if planetTypeID in DARKPLANETS: 135 return Color.WHITE 136 return Color.BLACK 137 138 139 def GetPickIntersectionPoint(x = None, y = None, scale = 1.0): 140 if None in (x, y): 141 x, y = int(uicore.uilib.x * uicore.desktop.dpiScaling), int(uicore.uilib.y * uicore.desktop.dpiScaling) 142 device = trinity.device 143 proj, view, vp = cameraUtil.GetFullscreenProjectionViewAndViewport() 144 ray, start = device.GetPickRayFromViewport(x, y, vp, view.transform, proj.transform) 145 lineVec = trinity.TriVector(*ray) 146 lineP0 = trinity.TriVector(*start) 147 sphereP0 = trinity.TriVector(0.0, 0.0, 0.0) 148 sphereRad = 1000.0 * scale 149 pInt = GetSphereLineIntersectionPoint(lineP0, lineVec, sphereP0, sphereRad) 150 if not pInt: 151 return 152 ret = SurfacePoint(pInt.x, pInt.y, pInt.z) 153 ret.SetRadius(1.0) 154 return ret 155 156 157 def GetSphereLineIntersectionPoint(lineP0, lineVec, sphereP0, sphereRad): 158 a = 1 159 b = (lineVec * 2).DotProduct(lineP0 - sphereP0) 160 c = (lineP0 - sphereP0).Length() ** 2 - sphereRad ** 2 161 d = b ** 2.0 - 4.0 * a * c 162 if d < 0: 163 return None 164 elif d == 0: 165 t = -b / (2 * a) 166 return lineP0 + lineVec * t / lineVec.Length() 167 d = math.sqrt(d) 168 t1 = (-b + d) / (2 * a) 169 t2 = (-b - d) / (2 * a) 170 lineLength = lineVec.Length() 171 P1 = lineP0 + lineVec * t1 / lineLength 172 P2 = lineP0 + lineVec * t2 / lineLength 173 l1 = (lineP0 - P1).LengthSq() 174 l2 = (lineP0 - P2).LengthSq() 175 if l1 < l2: 176 return P1 177 else: 178 return P2 179 180 181 def NormalizeLatitude(angle): 182 while angle < -PLANET_PI_DIV_2: 183 angle += math.pi 184 185 while angle > PLANET_PI_DIV_2: 186 angle -= math.pi 187 188 return angle 189 190 191 def NormalizeLongitude(angle): 192 while angle <= -math.pi: 193 angle += PLANET_2PI 194 195 while angle > math.pi: 196 angle -= PLANET_2PI 197 198 return angle 199 200 201 def FmtGeoCoordinates(latitude, longitude): 202 latitude = math.degrees(NormalizeLatitude(latitude)) 203 longitude = math.degrees(NormalizeLongitude(longitude)) 204 d1, m1, s1 = ConvertToDMS(latitude) 205 d2, m2, s2 = ConvertToDMS(longitude) 206 dir1 = 'N' if d1 >= 0 else 'S' 207 dir2 = 'E' if d2 >= 0 else 'W' 208 return "%d %d' %d'' %s, %d %d' %d'' %s" % (d1, 209 m1, 210 s1, 211 dir1, 212 d2, 213 m2, 214 s2, 215 dir2) 216 217 218 def ConvertToDMS(value): 219 degrees = int(value) 220 minPart = abs(value - degrees) 221 secPart = minPart - int(minPart) 222 return (degrees, int(minPart * 60), int(round(secPart * 60))) 223 224 225 def GetPinCycleInfo(pin, cycleTime = None): 226 if cycleTime is None: 227 cycleTime = pin.GetCycleTime() 228 if pin.IsActive() and not pin.IsInEditMode(): 229 currCycle = min(blue.os.GetWallclockTime() - pin.lastRunTime, cycleTime) 230 currCycleProportion = currCycle / float(cycleTime) 231 else: 232 currCycle = currCycleProportion = 0 233 if cycleTime is None: 234 cycleText = localization.GetByLabel('UI/PI/Common/InactivePin') 235 else: 236 cycleText = '%s / %s' % (FmtTime(currCycle), FmtTime(cycleTime)) 237 return (cycleText, currCycleProportion) 238 239 240 def GetSchematicData(processorTypeID): 241 schematicsIDs = get_schematic_ids_for_pin_type_id(processorTypeID) 242 if len(schematicsIDs) == 0: 243 log.LogTraceback('Authoring error: No schematics found for processor pin with typeID %s' % processorTypeID) 244 schematics = [] 245 for schematicID in schematicsIDs: 246 sData = GetSchematicDataForID(schematicID) 247 schematics.append((sData.name, sData)) 248 249 return SortListOfTuples(schematics) 250 251 252 def GetSchematicDataForID(schematicID): 253 schematic = get_schematic(schematicID) 254 if not schematic: 255 log.LogTraceback('Authoring error: No schematic found with id=%s' % schematicID) 256 raise KeyError('RecordNotFound', schematicID) 257 inputs, outputs = GetSchematicInputsAndOutputs(schematicID, schematic) 258 outputsDict = {} 259 for o in outputs: 260 outputsDict[o.typeID] = o.quantity 261 262 volumePerCycle = planetCommon.GetCommodityTotalVolume(outputsDict) 263 volumePerHour = planetCommon.GetBandwidth(volumePerCycle, schematic.cycleTime * appConst.SEC) 264 sData = utillib.KeyVal(name=get_schematic_name(schematicID, schematic), schematicID=schematicID, cycleTime=schematic.cycleTime, outputs=outputs, inputs=inputs, outputVolume=volumePerHour) 265 return sData 266 267 268 def GetSchematicInputsAndOutputs(schematicID, schematic): 269 inputs = [] 270 outputs = [] 271 if not schematic.types: 272 log.LogTraceback('Authoring error: No inputs/outputs defined for schematic with id=%s' % schematicID) 273 for typeID, typeInfo in schematic.types.iteritems(): 274 data = utillib.KeyVal(name=evetypes.GetName(typeID), typeID=typeID, quantity=typeInfo.quantity) 275 if typeInfo.isInput: 276 inputs.append(data) 277 else: 278 outputs.append(data) 279 280 return (inputs, outputs) 281 282 283 def GetSchematicOutput(schematicID): 284 for typeID, typeInfo in get_schematic_types(schematicID).iteritems(): 285 if not typeInfo.isInput: 286 return typeID 287 288 289 def GetSchematicByOutput(typeID): 290 for schematicID, isInput in get_schematic_info_for_type_id(typeID): 291 if not isInput: 292 return schematicID 293 294 295 def GetSchematicDataByGroupID(): 296 schematics = GetSchematicData() 297 ret = {} 298 for schematic in schematics: 299 groupID = evetypes.GetGroupID(schematic.output.typeID) 300 if groupID not in ret: 301 ret[groupID] = [] 302 ret[groupID].append(schematic) 303 304 return ret 305 306 307 def PinHasBeenBuilt(pinID): 308 if isinstance(pinID, tuple): 309 return False 310 return True 311 312 313 def _AddSchematicIconAndLabel(item, tooltipPanel): 314 label = localization.GetByLabel('UI/PI/Common/ItemAmount', amount=int(item.quantity), itemName=GetProductNameAndTier(item.typeID)) 315 icon = typeHelpers.GetIconFile(item.typeID) 316 tooltipPanel.AddIconLabel(icon=icon, label=label, iconSize=28) 317 318 319 def LoadSchematicTooltipPanel(tooltipPanel, schematic): 320 tooltipPanel.LoadGeneric2ColumnTemplate() 321 tooltipPanel.AddLabelMedium(text=localization.GetByLabel('UI/PI/Common/SchematicInput'), bold=True, colSpan=2, cellPadding=(0, 0, 0, 2)) 322 for i, item in enumerate(schematic.inputs): 323 _AddSchematicIconAndLabel(item, tooltipPanel) 324 325 tooltipPanel.AddLabelMedium(text=localization.GetByLabel('UI/PI/Common/OutputProduct'), bold=True, colSpan=2, cellPadding=(0, 10, 0, 2)) 326 _AddSchematicIconAndLabel(schematic.outputs[0], tooltipPanel) 327 text = GetSchematicCycleTimeText(schematic) 328 tooltipPanel.AddLabelMedium(colSpan=2, cellPadding=(0, 10, 0, 0), text=text) 329 text = GetSchematicOutputVolumeText(schematic) 330 tooltipPanel.AddLabelMedium(colSpan=2, cellPadding=(0, 4, 0, 2), text=text) 331 332 333 def GetSchematicCycleTimeText(schematic): 334 return '%s: <b>%s</b>' % (localization.GetByLabel('UI/PI/Common/CycleTime'), localization.GetByLabel('UI/PI/Common/TimeHourMinSec', time=schematic.cycleTime * appConst.SEC)) 335 336 337 def GetSchematicOutputVolumeText(schematic): 338 return '%s: <b>%s</b>' % (localization.GetByLabel('UI/PI/Common/OutputPerHour'), localization.GetByLabel('UI/PI/Common/CapacityAmount', amount=schematic.outputVolume)) 339 340 341 def _AddProductIconAndLabel(typeID, tooltipPanel): 342 label = GetProductNameAndTier(typeID) 343 icon = typeHelpers.GetIconFile(typeID) 344 tooltipPanel.AddIconLabel(icon=icon, label=label, iconSize=28, padBottom=2) 345 346 347 def LoadProductTooltipPanel(tooltipPanel, typeID, amount = None): 348 tooltipPanel.LoadGeneric2ColumnTemplate() 349 text = GetProductNameAndTier(typeID) 350 if amount: 351 text = GetByLabel('UI/PI/Common/ItemAmount', amount=int(amount), itemName=text) 352 tooltipPanel.AddLabelLarge(colSpan=2, text=text) 353 _CheckAddEstPrice(amount, tooltipPanel, typeID) 354 _AddRequiredforItems(tooltipPanel, typeID) 355 356 357 def _AddRequiredforItems(tooltipPanel, typeID): 358 typeIDs = GetRequiredForItems(typeID) 359 if not typeIDs: 360 return 361 tooltipPanel.AddLabelMedium(colSpan=2, cellPadding=(0, 10, 0, 2), text=GetByLabel('UI/InfoWindow/TabNames/RequiredFor')) 362 for typeID in typeIDs: 363 _AddProductIconAndLabel(typeID, tooltipPanel) 364 365 366 def _CheckAddEstPrice(amount, tooltipPanel, typeID): 367 if amount: 368 price = typeHelpers.GetAveragePrice(typeID) or 0.0 369 if price is not None: 370 text = GetByLabel('UI/Inventory/EstIskPrice', iskString=FmtISKAndRound(price * amount, False)) 371 tooltipPanel.AddLabelMedium(text=text, colSpan=2, cellPadding=(0, 10, 0, 2)) 372 373 374 def GetRequiredForItems(typeID): 375 requiredFor = [] 376 for schematicID, isInput in get_schematic_info_for_type_id(typeID): 377 if isInput: 378 requiredFor.append(GetSchematicOutput(schematicID)) 379 380 return requiredFor 381 382 383 def GetTierByTypeID(typeID): 384 categoryID = evetypes.GetCategoryID(typeID) 385 if categoryID == appConst.categoryPlanetaryResources: 386 return 0 387 groupID = evetypes.GetGroupID(typeID) 388 if groupID == appConst.groupBasicCommodities: 389 return 1 390 if groupID == appConst.groupRefinedCommodities: 391 return 2 392 if groupID == appConst.groupSpecializedCommodities: 393 return 3 394 if groupID == appConst.groupAdvancedCommodities: 395 return 4 396 397 398 def GetTierNameByTypeID(typeID): 399 tier = GetTierByTypeID(typeID) 400 if tier == 0: 401 return GetByLabel('UI/PI/Common/TierRawResource') 402 else: 403 return GetByLabel('UI/PI/Common/TierX', tier=tier) 404 405 406 def GetProductNameAndTier(typeID): 407 return GetByLabel('UI/PI/Common/ProductNameAndTier', name=evetypes.GetName(typeID), tier=GetTierNameByTypeID(typeID))