bracketVarious.py (14540B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\bracketsAndTargets\bracketVarious.py 2 import eve.client.script.ui.inflight.overview.overviewConst as overviewConst 3 from behaviors.const.combat import FW_ATTACK_NOT_SAME_FACTION 4 from carbonui.primitives.vectorlinetrace import VectorLineTrace 5 from eve.client.script.ui.control.eveIcon import Icon 6 import evetypes 7 import trinity 8 import carbonui.const as uiconst 9 import telemetry 10 import eve.common.script.mgt.entityConst as entities 11 import localization 12 from eve.common.script.sys.idCheckers import IsPlayerOwner 13 from spacecomponents.client.components.entitystandings import get_icon_color_sort_value_and_hint_for_owner_standing, get_icon_color_sort_value_and_hint_for_fw_attack_method, ICON_COLOR_NEUTRAL, ICON_COLOR_BAD 14 from spacecomponents.common.helper import HasEntityStandingsComponent, HasBehaviorComponent 15 from carbonui.uicore import uicore 16 import logging 17 logger = logging.getLogger(__name__) 18 LEFT = 0 19 TOP = 1 20 RIGHT = 2 21 BOTTOM = 3 22 SHOWLABELS_NEVER = 0 23 SHOWLABELS_ONMOUSEENTER = 1 24 SHOWLABELS_ALWAYS = 2 25 TARGETTING_UI_UPDATE_RATE = 50 26 MAXOVERLAP_TOOLTIP_ENTRIES = 15 27 LABELMARGIN = 6 28 GROUPS_WITH_LOOTRIGHTS = (const.groupWreck, const.groupCargoContainer, const.groupFreightContainer) 29 entityStateStrings = {entities.STATE_ANCHORING: 'UI/Entities/States/Anchoring', 30 entities.STATE_ONLINING: 'UI/Entities/States/Onlining', 31 entities.STATE_ANCHORED: 'UI/Entities/States/Anchored', 32 entities.STATE_UNANCHORING: 'UI/Entities/States/Unanchoring', 33 entities.STATE_UNANCHORED: 'UI/Entities/States/Unanchored', 34 entities.STATE_INCAPACITATED: 'UI/Entities/States/Incapacitated', 35 entities.STATE_IDLE: 'UI/Entities/States/Idle', 36 entities.STATE_COMBAT: 'UI/Entities/States/Fighting', 37 entities.STATE_MINING: 'UI/Entities/States/Mining', 38 entities.STATE_APPROACHING: 'UI/Entities/States/Approaching', 39 entities.STATE_FLEEING: 'UI/Entities/States/Fleeing', 40 entities.STATE_REINFORCED: 'UI/Entities/States/Reinforced', 41 entities.STATE_OPERATING: 'UI/Entities/States/Operating', 42 entities.STATE_VULNERABLE: 'UI/Entities/States/Vulnerable', 43 entities.STATE_INVULNERABLE: 'UI/Entities/States/Invulnerable', 44 entities.STATE_SHIELD_REINFORCE: 'UI/Entities/States/ShieldReinforced', 45 entities.STATE_ARMOR_REINFORCE: 'UI/Entities/States/ArmorReinforced', 46 entities.STATE_SALVAGING: 'UI/Entities/States/Salvaging'} 47 48 def GetEntityStateString(entityState): 49 if entityState in entityStateStrings: 50 return localization.GetByLabel(entityStateStrings[entityState]) 51 else: 52 return localization.GetByLabel('UI/Entities/States/Unknown', entityStateID=entityState) 53 54 55 class BracketSubIconNew(Icon): 56 57 def ApplyAttributes(self, attributes): 58 Icon.ApplyAttributes(self, attributes) 59 bracket = attributes.bracket 60 cs = uicore.uilib.bracketCurveSet 61 xBinding = trinity.CreateBinding(cs, bracket.renderObject, 'displayX', self.renderObject, 'displayX') 62 yBinding = trinity.CreateBinding(cs, bracket.renderObject, 'displayY', self.renderObject, 'displayY') 63 self.bindings = (xBinding, yBinding) 64 self.OnMouseUp = bracket.OnMouseUp 65 self.OnMouseDown = bracket.OnMouseDown 66 self.OnMouseEnter = bracket.OnMouseEnter 67 self.OnMouseExit = bracket.OnMouseExit 68 self.OnMouseHover = bracket.OnMouseHover 69 self.OnClick = bracket.OnClick 70 self.GetMenu = bracket.GetMenu 71 72 def Close(self, *args, **kw): 73 if getattr(self, 'bindings', None): 74 cs = uicore.uilib.bracketCurveSet 75 for each in self.bindings: 76 if cs and each in cs.bindings: 77 cs.bindings.remove(each) 78 79 self.OnMouseUp = None 80 self.OnMouseDown = None 81 self.OnMouseEnter = None 82 self.OnMouseExit = None 83 self.OnMouseHover = None 84 self.OnClick = None 85 self.GetMenu = None 86 Icon.Close(self, *args, **kw) 87 88 89 @telemetry.ZONE_METHOD 90 def GetIconColor(slimItem, getSortValue = False, getColorHint = False): 91 iconColor = overviewConst.OVERVIEW_NORMAL_COLOR 92 colorSortValue = 0 93 colorHint = None 94 if slimItem.categoryID in (const.categoryShip, const.categoryDrone): 95 if slimItem.itemID == session.shipid: 96 iconColor = overviewConst.OVERVIEW_OWN_SHIP_COLOR 97 elif IsNpcObject(slimItem) and slimItem.typeID: 98 iconColor = ICON_COLOR_NEUTRAL 99 fwAttackMethod = getattr(slimItem, 'fwAttackMethod', None) 100 if fwAttackMethod and session.warfactionid: 101 iconColor, colorSortValue, colorHint = get_icon_color_sort_value_and_hint_for_fw_attack_method(slimItem, session.warfactionid, slimItem.fwAttackMethod) 102 if fwAttackMethod == FW_ATTACK_NOT_SAME_FACTION: 103 pass 104 elif iconColor != ICON_COLOR_BAD: 105 if fwAttackMethod is not None and HasBehaviorComponent(slimItem.typeID) and getattr(slimItem, 'group_standings_disabled', None) is True: 106 pass 107 elif HasEntityStandingsComponent(slimItem.typeID): 108 iconColor, colorSortValue, colorHint = get_icon_color_sort_value_and_hint_for_owner_standing(slimItem, session.charid) 109 elif slimItem.groupID == const.groupStation or slimItem.categoryID == const.categoryStructure: 110 waypoints = sm.GetService('starmap').GetWaypoints() 111 destinationPath = sm.GetService('starmap').GetDestinationPath() 112 jumpToLocationID = getattr(slimItem, 'targetSolarsystemID', None) 113 if jumpToLocationID and destinationPath and jumpToLocationID == destinationPath[0]: 114 iconColor = overviewConst.OVERVIEW_AUTO_PILOT_DESTINATION_COLOR 115 colorSortValue = -1 116 colorHint = 'Tooltips/Overview/StargateOnRoute' 117 elif waypoints and slimItem.itemID == waypoints[0]: 118 iconColor = overviewConst.OVERVIEW_AUTO_PILOT_DESTINATION_COLOR 119 colorSortValue = -1 120 colorHint = 'Tooltips/Overview/StargateOnRoute' 121 elif HasEntityStandingsComponent(slimItem.typeID): 122 iconColor, colorSortValue, colorHint = get_icon_color_sort_value_and_hint_for_owner_standing(slimItem, session.charid) 123 elif slimItem.groupID == const.groupStargate and slimItem.jumps: 124 destinationPath = sm.GetService('starmap').GetDestinationPath() 125 jumpToLocationID = slimItem.jumps[0].locationID 126 if destinationPath and jumpToLocationID == destinationPath[0]: 127 iconColor = overviewConst.OVERVIEW_AUTO_PILOT_DESTINATION_COLOR 128 colorSortValue = -1 129 colorHint = 'Tooltips/Overview/StargateOnRoute' 130 elif IsAbandonedContainer(slimItem): 131 iconColor = overviewConst.OVERVIEW_ABANDONED_CONTAINER_COLOR 132 colorHint = 'Tooltips/Overview/AbandonedContainer' 133 elif IsForbiddenContainer(slimItem): 134 iconColor = overviewConst.OVERVIEW_FORBIDDEN_CONTAINER_COLOR 135 colorHint = 'Tooltips/Overview/RestrictedContainer' 136 colorSortValue = -1 137 if getSortValue: 138 if getColorHint: 139 return (iconColor, colorSortValue, localization.GetByLabel(colorHint) if colorHint else None) 140 return (iconColor, colorSortValue) 141 if getColorHint: 142 return (iconColor, localization.GetByLabel(colorHint) if colorHint else None) 143 return iconColor 144 145 146 def IsForbiddenContainer(slimItem): 147 if slimItem.groupID not in GROUPS_WITH_LOOTRIGHTS: 148 return False 149 bp = sm.StartService('michelle').GetBallpark() 150 if bp is None: 151 return False 152 if bp.HaveLootRight(slimItem.itemID): 153 return False 154 return True 155 156 157 def IsAbandonedContainer(slimItem): 158 if slimItem.groupID not in GROUPS_WITH_LOOTRIGHTS: 159 return False 160 bp = sm.StartService('michelle').GetBallpark() 161 if bp is None: 162 return False 163 if bp.IsAbandoned(slimItem.itemID): 164 return True 165 return False 166 167 168 def GetAbsolute(bracket): 169 ro = bracket.renderObject 170 x = ro.displayX 171 y = ro.displayY 172 centerX = x + ro.displayWidth / 2 173 centerY = y + ro.displayHeight / 2 174 return [centerX - 8, 175 centerY - 8, 176 centerX + 8, 177 centerY + 8] 178 179 180 def GetOverlaps(sender, useMousePosition = True, customBracketParent = None): 181 overlaps = [] 182 if customBracketParent is None or customBracketParent is sender.parent: 183 overlaps.append(sender) 184 excludedC = (const.categoryAsteroid,) 185 excludedG = (const.groupHarvestableCloud,) 186 bBox = GetAbsolute(sender) 187 senderParent = customBracketParent or sender.parent 188 parentOffsetX, parentOffsetY = senderParent.GetAbsolutePosition() 189 mouseX = uicore.ReverseScaleDpi(uicore.uilib.x) - parentOffsetX 190 mouseY = uicore.ReverseScaleDpi(uicore.uilib.y) - parentOffsetY 191 for bracket in senderParent.children: 192 if not (isinstance(bracket, sender.__class__) or getattr(bracket, 'IsBracket', 0)) or not bracket.displayName or not bracket.display or bracket.invisible or bracket.categoryID in excludedC or bracket.groupID in excludedG or bracket in overlaps: 193 continue 194 b = GetAbsolute(bracket) 195 if useMousePosition: 196 overlapx = b[LEFT] <= mouseX <= b[RIGHT] 197 overlapy = b[TOP] <= mouseY <= b[BOTTOM] 198 else: 199 overlapx = not (b[RIGHT] <= bBox[LEFT] or b[LEFT] >= bBox[RIGHT]) 200 overlapy = not (b[BOTTOM] <= bBox[TOP] or b[TOP] >= bBox[BOTTOM]) 201 if overlapx and overlapy: 202 overlaps.append(bracket) 203 if len(overlaps) == MAXOVERLAP_TOOLTIP_ENTRIES: 204 break 205 206 overlaps = sorted(overlaps, key=lambda x: x.displayName) 207 return (overlaps, bBox) 208 209 210 class TargetingHairlines: 211 __guid__ = 'bracketUtils.TargetingHairlines' 212 213 def __init__(self): 214 self.trace = None 215 self.line = None 216 217 def CreateHairlines(self, moduleID, bracket, target): 218 self.trace = VectorLineTrace(parent=uicore.layer.shipui, lineWidth=2.5, idx=-1, name='vectorlineTrace') 219 self.trace.SetRGBA(0.5, 0.7, 0.6, 0.5) 220 self.line = VectorLineTrace(parent=uicore.layer.shipui, lineWidth=0.1, idx=-1, name='vectorline') 221 linePoints = self.GetHairlinePoints(moduleID, bracket, target) 222 if linePoints is None: 223 return 224 startPoint, midPoint, endPoint = linePoints 225 self.line.AddPoint(startPoint) 226 self.line.AddPoint(midPoint) 227 self.line.AddPoint(endPoint) 228 self.trace.AddPoint(startPoint) 229 self.trace.AddPoint(midPoint) 230 self.trace.AddPoint(endPoint) 231 return (self.trace, self.line) 232 233 def UpdateHairlinePoints(self, moduleID, bracket, target): 234 linePoints = self.GetHairlinePoints(moduleID, bracket, target) 235 if linePoints is None: 236 return 237 startPoint, midPoint, endPoint = linePoints 238 if self.line.renderObject is None or self.trace.renderObject is None: 239 sm.GetService('bracket').LogWarn('Hairlines were broken, new ones were made') 240 self.line.Close() 241 self.trace.Close() 242 self.CreateHairlines(moduleID, bracket, target) 243 self.line.renderObject.vertices[0].position = startPoint 244 self.line.renderObject.vertices[1].position = midPoint 245 self.line.renderObject.vertices[2].position = endPoint 246 self.line.renderObject.isDirty = True 247 self.trace.renderObject.vertices[0].position = startPoint 248 self.trace.renderObject.vertices[1].position = midPoint 249 self.trace.renderObject.vertices[2].position = endPoint 250 self.trace.renderObject.isDirty = True 251 self.ShowLines() 252 253 def GetHairlinePoints(self, moduleID, bracket, target, *args): 254 moduleButton = uicore.layer.shipui.GetModuleFromID(moduleID) 255 ro = bracket.GetRenderObject() 256 if not ro or moduleButton is None: 257 return 258 x = uicore.ScaleDpi(moduleButton.absoluteLeft + moduleButton.width / 2.0) 259 y = uicore.ScaleDpi(moduleButton.absoluteTop + moduleButton.height / 2.0) 260 startPoint = (x, y) 261 weapon = target.GetWeapon(moduleID) 262 if weapon: 263 endPointObject = weapon 264 else: 265 endPointObject = target 266 x = uicore.ScaleDpi(endPointObject.absoluteLeft + endPointObject.width / 2.0) 267 y = uicore.ScaleDpi(endPointObject.absoluteTop + endPointObject.height / 2.0) 268 endPoint = (x, y) 269 x = ro.displayX 270 y = ro.displayY 271 l, r = uicore.layer.sidePanels.GetSideOffset() 272 x += uicore.ScaleDpi(l) 273 midPoint = (int(x + bracket.width / 2.0), int(y + bracket.height / 2.0)) 274 return (startPoint, midPoint, endPoint) 275 276 def StartAnimation(self, reverse = False, *args): 277 if reverse: 278 start_values = (0.99, 0.0) 279 end_values = (1.0, 0.01) 280 else: 281 start_values = (0.0, 1.0) 282 end_values = (0.01, 1.01) 283 uicore.animations.MorphScalar(self.trace, 'start', startVal=start_values[0], endVal=start_values[1], duration=1.0, loops=1, curveType=uiconst.ANIM_LINEAR) 284 uicore.animations.MorphScalar(self.trace, 'end', startVal=end_values[0], endVal=end_values[1], duration=1.0, loops=1, curveType=uiconst.ANIM_LINEAR) 285 286 def ShowLines(self, *args): 287 self.line.display = True 288 self.trace.display = True 289 290 def HideLines(self, *args): 291 self.line.display = False 292 self.trace.display = False 293 294 def StopAnimations(self, *args): 295 self.trace.StopAnimations() 296 297 298 def FixLines(target): 299 300 def FindLine(name): 301 return getattr(target.lines, name) 302 303 l, r, t, b = map(FindLine, ['lineleft', 304 'lineright', 305 'linetop', 306 'linebottom']) 307 l.left -= uicore.desktop.width - l.width 308 l.width = r.width = uicore.desktop.width 309 t.top -= uicore.desktop.height - t.height 310 t.height = b.height = uicore.desktop.height 311 312 313 def GetMinDispRangeForOwnShip(typeID): 314 radius = evetypes.GetRadius(typeID) 315 if radius >= 5000: 316 return 100000 317 elif radius >= 1500: 318 return 40000 319 elif radius >= 700: 320 return 27000 321 elif radius >= 200: 322 return 18000 323 else: 324 return 5000 325 326 327 def IsTargetingOrSettingSecondPoint(): 328 positionalControl = uicore.layer.inflight.positionalControl 329 if positionalControl.IsTargeting(): 330 return True 331 if positionalControl.IsFirstPointSet(): 332 return True 333 return False 334 335 336 def IsNpcObject(slimItem): 337 if slimItem.categoryID != const.categoryEntity and slimItem.groupID != const.groupLargeCollidableObject: 338 return False 339 return not IsPlayerOwner(slimItem.ownerID)