shipTreeShipGroup.py (12680B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\shipTree\shipTreeShipGroup.py 2 from __future__ import absolute_import 3 import uthread2 4 from carbon.client.script.environment.AudioUtil import PlaySound 5 from carbonui.primitives.containerAutoSize import ContainerAutoSize 6 import carbonui.const as uiconst 7 from eve.client.script.ui.control.eveLabel import EveHeaderMedium 8 from . import shipTreeConst 9 from eve.client.script.ui.shared.shipTree.skillLevelsCont import SkillLevelsCont 10 from expertSystems.client import ExpertSystemService 11 from .shipTreeShipIcon import ShipTreeShipIcon 12 from carbonui.primitives.sprite import Sprite 13 from carbonui.primitives.container import Container 14 from carbonui.primitives.fill import Fill 15 from carbonui.primitives.stretchspritehorizontal import StretchSpriteHorizontal 16 from carbonui.primitives.frame import Frame 17 from eve.client.script.ui.shared.shipTree.shipTreeConst import ZOOMED_OUT, COLOR_SHIPGROUP_UNLOCKED, COLOR_FRAME, COLOR_BG, COLOR_HOVER_LOCKED, COLOR_HOVER_UNLOCKED 18 import blue 19 from carbon.common.script.sys.service import ROLE_PROGRAMMER 20 from carbonui.const import ANIM_REPEAT, ANIM_WAVE 21 from localization import GetByMessageID 22 from carbonui.uicore import uicore 23 import expertSystems.client 24 OPACITY_LOCKED = 0.6 25 26 class ShipTreeShipGroup(ContainerAutoSize): 27 default_name = 'ShipTreeShipGroup' 28 default_iconsPerRow = 3 29 default_align = uiconst.TOPLEFT 30 default_state = uiconst.UI_PICKCHILDREN 31 default_alignMode = uiconst.TOPLEFT 32 __notifyevents__ = ('OnShipTreeZoomChanged', 'OnShipTreeSkillTrained') 33 34 def ApplyAttributes(self, attributes): 35 ContainerAutoSize.ApplyAttributes(self, attributes) 36 sm.RegisterNotify(self) 37 self.node = attributes.node 38 self.factionID = self.node.factionID 39 self.shipGroupID = self.node.shipGroupID 40 self.name = self.GetNameForShipGroup(self.shipGroupID) 41 self.iconsPerRow = self.node.GetIconsPerRow() 42 self.typeIDs = sm.GetService('shipTree').GetShipTypeIDs(self.factionID, self.shipGroupID) 43 self.zoomLevel = sm.GetService('shipTreeUI').GetZoomLevel() 44 self.iconSize = self.node.GetIconSize() 45 nodeNum = attributes.nodeNum 46 self.groupNameLabel = EveHeaderMedium(name='groupNameLabel', parent=self, align=uiconst.TOPLEFT, text=GetByMessageID(cfg.infoBubbleGroups[self.shipGroupID]['nameID']), left=43, top=0) 47 self.iconAndBar = ShipGroupIconAndSkillBar(parent=self, top=20, node=self.node) 48 self.shipContainer = ContainerAutoSize(name='shipContainer', parent=self, align=uiconst.TOPLEFT, height=self.iconSize, left=46, top=24) 49 self.LoadShips() 50 self.lineTop = StretchSpriteHorizontal(name='lineTop', parent=self, align=uiconst.TOTOP, texturePath='res:/UI/Texture/Classes/ShipTree/Groups/frameUpper.png', leftEdgeSize=4, rightEdgeSize=4, height=3, padTop=16) 51 width = len(self.typeIDs) % self.iconsPerRow or self.iconsPerRow 52 width = self.iconSize * width + 4 53 self.lineBottom = StretchSpriteHorizontal(name='lineBottom', parent=self, align=uiconst.BOTTOMLEFT, texturePath='res:/UI/Texture/Classes/ShipTree/Groups/frameLower.png', leftEdgeSize=4, rightEdgeSize=4, height=1, width=width, left=43, top=-7) 54 self.UpdateState(nodeNum, animate=False) 55 zoomLevel = sm.GetService('shipTreeUI').GetZoomLevel() 56 if zoomLevel == ZOOMED_OUT: 57 self.groupNameLabel.opacity = 0.0 58 self.lineTop.opacity = 0.0 59 self.lineBottom.opacity = 0.0 60 61 def UpdateState(self, i = 0, animate = True): 62 if self.zoomLevel == ZOOMED_OUT: 63 opacity = 0.0 64 elif self.node.IsLocked(): 65 opacity = OPACITY_LOCKED 66 else: 67 opacity = 1.0 68 for uiObj in (self.groupNameLabel, self.lineTop, self.lineBottom): 69 if animate: 70 uicore.animations.FadeTo(uiObj, uiObj.opacity, opacity, timeOffset=0.05 * i, duration=0.6) 71 else: 72 uiObj.opacity = opacity 73 74 self.iconAndBar.UpdateState(i, animate) 75 for shipIcon in self.shipContainer.children: 76 shipIcon.UpdateState(animate) 77 78 def LoadShips(self): 79 for i, typeID in enumerate(self.typeIDs): 80 beneficialExpertSystems = [] 81 activeRelatedExpertSystem = False 82 if not sm.GetService('skills').IsSkillRequirementMet(typeID) and expertSystems.is_expert_systems_enabled(): 83 associatedExpertSystems = expertSystems.get_associated_expert_systems(typeID) 84 beneficialExpertSystems = [ expertSystem.type_id for expertSystem in associatedExpertSystems if expertSystems.expert_system_benefits_player(expertSystem.type_id) ] 85 activeExpertSystems = ExpertSystemService.instance().GetMyExpertSystems() 86 associatedExpertSystemsIds = [ expertSystem.type_id for expertSystem in associatedExpertSystems ] 87 for es in activeExpertSystems: 88 if es in associatedExpertSystemsIds: 89 activeRelatedExpertSystem = True 90 91 x = i % self.iconsPerRow 92 y = (i - x) / self.iconsPerRow 93 ShipTreeShipIcon(name=str(typeID), parent=self.shipContainer, typeID=typeID, factionID=self.factionID, groupNode=self.node, pos=(x * (self.iconSize + 1), 94 y * (self.iconSize + 1), 95 self.iconSize, 96 self.iconSize), expertSystemTypeIDs=beneficialExpertSystems, activeRelatedExpertSystem=activeRelatedExpertSystem) 97 98 def OnShipTreeZoomChanged(self, zoomLevel): 99 self.zoomLevel = zoomLevel 100 self.UpdateState(0, True) 101 102 def OnShipTreeSkillTrained(self): 103 self.UpdateState(0, animate=True) 104 self.iconAndBar.UpdateState(0, animate=True) 105 106 def FlashGroupIcon(self, duration = 0.8, delay = 0): 107 self.iconAndBar.shipGroupIcon.Flash(duration, delay) 108 109 def PlayFanfare(self): 110 thump_duration = 0.45 111 thump_delay = 0.4 112 for i, child in enumerate(self.shipContainer.children): 113 child.Thump(thump_duration, thump_delay * i) 114 115 return len(self.shipContainer.children) * thump_delay 116 117 @classmethod 118 def GetNameForShipGroup(cls, shipGroupID): 119 return 'ship_tree_group_{shipGroupID}'.format(shipGroupID=shipGroupID) 120 121 122 class ShipGroupIconAndSkillBar(ContainerAutoSize): 123 default_name = 'ShipGroupIconAndSkillBar' 124 default_state = uiconst.UI_NORMAL 125 default_align = uiconst.TOPLEFT 126 __notifyevents__ = ('OnSkillQueueRefreshed', 'OnSkillsChanged', 'OnHighlightExpertSystemShipTreeShips', 'OnUnHighlightExpertSystemShipTreeShips') 127 default_bgColor = COLOR_BG 128 129 def ApplyAttributes(self, attributes): 130 ContainerAutoSize.ApplyAttributes(self, attributes) 131 sm.RegisterNotify(self) 132 self.node = attributes.node 133 self.shipGroupIcon = ShipGroupIcon(parent=self, node=self.node) 134 self.skillBarCont = ContainerAutoSize(parent=self, align=uiconst.TOPLEFT, width=42, top=43, state=uiconst.UI_DISABLED) 135 for typeID, _ in self.node.GetBonusSkillsSorted(): 136 SkillLevelsCont(parent=self.skillBarCont, typeID=typeID, align=uiconst.TOTOP, padTop=1, padBottom=1, frameColor=COLOR_FRAME, barColor=shipTreeConst.COLOR_HILIGHT) 137 138 def OnMouseEnter(self, *args): 139 PlaySound(uiconst.SOUND_BUTTON_HOVER) 140 sm.GetService('shipTreeUI').ShowInfoBubble(self, node=self.node) 141 self.shipGroupIcon.OnMouseEnter() 142 143 def OnMouseExit(self, *args): 144 self.shipGroupIcon.OnMouseExit() 145 146 def GetMenu(self): 147 m = [] 148 if session.role & ROLE_PROGRAMMER: 149 text = 'shipGroupID: %s' % self.node.shipGroupID 150 m.append((text, blue.pyos.SetClipboardData, (str(self.node.shipGroupID),))) 151 return m 152 153 def UpdateState(self, i, animate = True): 154 self.shipGroupIcon.UpdateState(i, animate) 155 self.UpdateBars(i, animate) 156 157 def OnSkillQueueRefreshed(self): 158 self.UpdateBars() 159 160 def OnSkillsChanged(self, *args): 161 self.UpdateBars() 162 163 def UpdateBars(self, i = 0, animate = True): 164 if self.node.IsLocked(): 165 self.skillBarCont.Hide() 166 else: 167 self.skillBarCont.Show() 168 isZoomedOut = sm.GetService('shipTreeUI').GetZoomLevel() == ZOOMED_OUT 169 barPadding = 2 if isZoomedOut else 1 170 for bar in self.skillBarCont.children: 171 bar.SetBarPadding(barPadding) 172 bar.Update() 173 174 def OnHighlightExpertSystemShipTreeShips(self, *args): 175 uicore.animations.FadeTo(self, startVal=self.opacity, endVal=0.2) 176 177 def OnUnHighlightExpertSystemShipTreeShips(self): 178 uicore.animations.FadeTo(self, startVal=self.opacity, endVal=1.0) 179 180 181 class ShipGroupIcon(Container): 182 default_name = 'ShipGroupIcon' 183 default_align = uiconst.TOPLEFT 184 default_state = uiconst.UI_DISABLED 185 default_width = 42 186 default_height = 42 187 __notifyevents__ = ('OnShipTreeZoomChanged', 'OnShipTreeShipGroupFocused') 188 189 def ApplyAttributes(self, attributes): 190 Container.ApplyAttributes(self, attributes) 191 sm.RegisterNotify(self) 192 self.node = attributes.node 193 self.bgFrame = Frame(name='bgFrame', bgParent=self, texturePath='res:/UI/Texture/Classes/ShipTree/Groups/groupIconFrame.png') 194 self.bgFill = Fill(name='bgFill', bgParent=self, color=shipTreeConst.COLOR_BG) 195 self.bgBlinkFill = None 196 self.icon = Sprite(parent=self, align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath=cfg.infoBubbleGroups[self.node.shipGroupID]['icon'], color=shipTreeConst.COLOR_HILIGHT, width=32, height=32) 197 self.bgFlash = Sprite(name='bgFillBlink', bgParent=self, texturePath='res:/UI/Texture/Classes/ShipTree/groups/groupIconFlash.png', idx=0, color=(1, 1, 1, 1), opacity=0.0) 198 199 def OnShipTreeZoomChanged(self, zoom): 200 self.UpdateState(0, True) 201 202 def OnShipTreeShipGroupFocused(self, factionID, shipGroupID): 203 if (factionID, shipGroupID) == (self.node.factionID, self.node.shipGroupID): 204 self.Blink() 205 elif self.bgBlinkFill and not self.node.IsBeingTrained(): 206 uicore.animations.FadeOut(self.bgBlinkFill) 207 208 def Blink(self): 209 self.ConstructBgBlinkFill() 210 uicore.animations.FadeTo(self.bgBlinkFill, 0.0, 0.5, loops=ANIM_REPEAT, duration=1.2, curveType=ANIM_WAVE) 211 212 def Flash(self, duration = 0.3, delay = 0.0): 213 PlaySound('ship_goals_reveal_ship_group_play') 214 uicore.animations.FadeTo(self.bgFlash, 0.0, 3, duration=duration, curveType=ANIM_WAVE, timeOffset=delay) 215 uicore.animations.SpColorMorphTo(self.icon, endColor=(0, 0, 0, 1), duration=duration, curveType=uiconst.ANIM_WAVE, timeOffset=delay) 216 217 def ConstructBgBlinkFill(self): 218 if self.node.IsLocked(): 219 color = COLOR_HOVER_LOCKED 220 else: 221 color = COLOR_HOVER_UNLOCKED 222 if not self.bgBlinkFill: 223 self.bgBlinkFill = Sprite(name='bgFillBlink', bgParent=self, texturePath='res:/UI/Texture/Classes/ShipTree/groups/bgVignette.png', idx=0, color=color, opacity=0.0) 224 else: 225 self.bgBlinkFill.SetRGBA(color[0], color[1], color[2], self.bgBlinkFill.opacity) 226 227 def OnMouseEnter(self, *args): 228 self.ConstructBgBlinkFill() 229 uicore.animations.FadeTo(self.bgBlinkFill, self.bgBlinkFill.opacity, 0.4, duration=0.3) 230 231 def OnMouseExit(self, *args): 232 if self.bgBlinkFill: 233 uicore.animations.FadeTo(self.bgBlinkFill, self.bgBlinkFill.opacity, 0.0, duration=0.3) 234 235 def UpdateState(self, i, animate = True): 236 zoomLevel = sm.GetService('shipTreeUI').GetZoomLevel() 237 isLocked = self.node.IsLocked() 238 opacity = OPACITY_LOCKED if isLocked else 1.0 239 if animate: 240 uicore.animations.FadeTo(self.icon, self.icon.opacity, opacity, timeOffset=0.05 * i, duration=0.3) 241 else: 242 self.icon.opacity = opacity 243 if zoomLevel == ZOOMED_OUT: 244 opacity = 0.0 245 elif isLocked: 246 opacity = OPACITY_LOCKED 247 else: 248 opacity = 1.0 249 if animate: 250 uicore.animations.FadeTo(self.bgFrame, self.bgFrame.opacity, opacity, timeOffset=0.05 * i, duration=0.3) 251 else: 252 self.bgFrame.opacity = opacity 253 color = COLOR_BG if isLocked else COLOR_SHIPGROUP_UNLOCKED 254 if animate: 255 uicore.animations.SpColorMorphTo(self.bgFill, self.bgFill.GetRGBA(), color) 256 else: 257 self.bgFill.SetRGBA(*color) 258 if self.node.IsBeingTrained(): 259 self.Blink() 260 elif self.bgBlinkFill: 261 uicore.animations.FadeOut(self.bgBlinkFill)