NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

message.py (12453B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\message.py
      2 import collections
      3 import blue
      4 import localization
      5 import logging
      6 import uthread
      7 from carbonui import uiconst
      8 from carbonui.control.message import MessageData, MessageParentClass
      9 from carbonui.primitives.container import Container
     10 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     11 from carbonui.primitives.frame import Frame
     12 from carbonui.primitives.sprite import Sprite
     13 from carbonui.uicore import uicore
     14 from eve.client.script.ui.control.eveLabel import Label
     15 from eve.client.script.util.settings import IsShipHudTopAligned
     16 from eve.common.lib import appConst as const
     17 log = logging.getLogger(__name__)
     18 
     19 class CombatMessage(MessageParentClass):
     20 
     21     def ApplyAttributes(self, attributes):
     22         self.noDamageMsgTimer = 10 * const.SEC
     23         self.expiryTime = 5 * const.SEC
     24         numMessagePerSec = 6
     25         self.messageSleepTime = 1000 / numMessagePerSec
     26         self.messageSleepTimeInMs = self.messageSleepTime / 1000.0
     27         self.fadeOutTime = 5.0
     28         self.moveUpTime = 0.8
     29         self.messageList = []
     30         self.showingMessage = False
     31         self.configName = 'damageMessages_config'
     32         self.settingNameAlign = 'dmgnotifictions_alignment'
     33         self.defaultConfig = self.GetDefaultAlignmentValues()
     34         MessageParentClass.ApplyAttributes(self, attributes)
     35         self.myLayer = uicore.layer.target
     36         self.minTop = -40
     37         self.scope = uiconst.SCOPE_INGAME
     38         self.state = uiconst.UI_DISABLED
     39         self.allContainers = []
     40         self.allLabels = []
     41         self.noDamageDict = {}
     42         self.messageCounter = collections.deque([], maxlen=8 * numMessagePerSec)
     43         uthread.new(self.ShowMsg)
     44 
     45     def GetLayerOffset(self):
     46         return uicore.layer.target.absoluteLeft
     47 
     48     def GetDefaultAlignmentValues(self, *args):
     49         offset = sm.GetService('window').GetCameraLeftOffset(300, align=uiconst.CENTERTOP, left=0)
     50         if IsShipHudTopAligned():
     51             top = uicore.desktop.height * 0.7
     52         else:
     53             top = max(uicore.desktop.height * 0.32, 225)
     54         defaultConfig = (uiconst.CENTERTOP,
     55          uiconst.CENTERBOTTOM,
     56          offset,
     57          top)
     58         return defaultConfig
     59 
     60     def Prepare_Text_(self):
     61         uiAlignment = self.GetUIAlignment(self.currentTextAlignment)
     62         notificationFontSize = settings.user.ui.Get('dmgnotifictions_fontsize', 12)
     63         for i in xrange(6):
     64             container = ContainerAutoSize(parent=self, name='C%s' % i, left=6, top=5, align=uiAlignment, state=uiconst.UI_DISABLED)
     65             numberContainer = ContainerAutoSize(parent=container, width=0, height=0, align=uiconst.TOLEFT)
     66             container.numberLabel = Label(text='', name='N%s' % i, parent=numberContainer, align=uiAlignment, state=uiconst.UI_DISABLED, fontsize=notificationFontSize)
     67             iconContainer = Container(parent=container, width=0, height=0, align=uiconst.TOLEFT)
     68             container.iconContainer = iconContainer
     69             name = 'L%s' % i
     70             labelContainer = ContainerAutoSize(parent=container, width=0, height=0, align=uiconst.TOLEFT)
     71             message = Label(text='', name=name, parent=labelContainer, align=uiAlignment, state=uiconst.UI_DISABLED, fontsize=notificationFontSize)
     72             container.msgIndex = i
     73             container.label = message
     74             container.display = False
     75             setattr(self, 'message%s' % i, message)
     76             self.allLabels.append(message)
     77             self.allContainers.append(container)
     78 
     79     def ShowMsg(self, *args):
     80         if self.showingMessage:
     81             return
     82         while 1:
     83             if not self or self.destroyed:
     84                 return
     85             try:
     86                 if len(self.messageList) == 0:
     87                     self.messageCounter.append(0)
     88                     continue
     89                 self.messageCounter.append(1)
     90                 now = blue.os.GetWallclockTime()
     91                 validTime = now - self.expiryTime
     92                 message = None
     93                 numMessagesDiscarded = 0
     94                 while len(self.messageList) > 0:
     95                     message = self.messageList.pop(0)
     96                     if message.time_stamp < validTime:
     97                         numMessagesDiscarded += 1
     98                         continue
     99                     break
    100 
    101                 if numMessagesDiscarded:
    102                     sm.GetService('logger').LogWarn('CombatMessage::ShowMsg - Discarded %s combat UI messages' % numMessagesDiscarded)
    103                 if not message or not message.text:
    104                     continue
    105                 if len(self.allContainers) < 1:
    106                     self.Prepare_Text_()
    107                 fakeText = self.GetFakeText()
    108                 if fakeText:
    109                     fakeText.Close()
    110                 container, otherVisibleContainers = self.FindFreeContainer()
    111                 self.apply_message_to_container(container, message)
    112                 self.SetSizeAndPosition()
    113                 otherVisibleContainers.sort(lambda x, y: cmp(x.top, y.top))
    114                 if sum(self.messageCounter) > 8:
    115                     duration = 0.166
    116                     secondPoint = 0.05
    117                 else:
    118                     secondPoint = 0.2
    119                     duration = 0.4
    120                 for i, ovc in enumerate(otherVisibleContainers):
    121                     uicore.animations.MorphScalar(ovc, 'top', startVal=ovc.top, endVal=(i + 1) * 20, duration=duration)
    122                     ovc.msgIndex = i
    123                     if i == 4:
    124                         uicore.animations.FadeOut(ovc, duration=self.messageSleepTimeInMs)
    125 
    126                 curvePoints = ([0, 0], [secondPoint, 1.0], [1, 0])
    127                 uicore.animations.MorphScalar(container, 'opacity', duration=self.fadeOutTime, curveType=curvePoints)
    128                 self.SetOrder(0)
    129             except Exception as e:
    130                 log.exception(e)
    131             finally:
    132                 blue.pyos.synchro.SleepWallclock(self.messageSleepTime)
    133 
    134     def apply_message_to_container(self, container, message):
    135         if message.icons:
    136             container.label.text = ' ' + message.text
    137         else:
    138             container.label.text = message.text
    139         container.iconContainer.Flush()
    140         container.iconContainer.width = container.label.height * len(message.icons)
    141         container.width = container.label.width + container.iconContainer.width
    142         container.height = container.label.height
    143         container.top = 0
    144         container.msgIndex = -1
    145         if message.damage_html is not None:
    146             container.numberLabel.text = message.damage_html + ' '
    147             container.numberLabel.Show()
    148         else:
    149             container.numberLabel.Hide()
    150         container.display = True
    151         for iconResPath in message.icons:
    152             Sprite(parent=container.iconContainer, width=container.label.height, height=container.label.height, texturePath=iconResPath, align=uiconst.TORIGHT, color=message.icon_color)
    153 
    154     def AddActionMessage(self, text, icons = None, icon_color = None):
    155         now = blue.os.GetWallclockTime()
    156         if icons is None:
    157             icons = []
    158         self.messageList.append(MessageData(now, text, icons, icon_color=icon_color))
    159 
    160     def AddMessage(self, text, hitQuality, attackerID, images, damage_html, icon_color = None, *args):
    161         now = blue.os.GetWallclockTime()
    162         if hitQuality == 0 and attackerID:
    163             if attackerID in self.noDamageDict:
    164                 lastNoDmgMsgTime = self.noDamageDict[attackerID]
    165                 if lastNoDmgMsgTime > now - self.noDamageMsgTimer:
    166                     return
    167             self.noDamageDict[attackerID] = now
    168             damage_html = None
    169         else:
    170             self.noDamageDict.pop(attackerID, None)
    171         self.messageList.append(MessageData(now, text, icons=images, damage_html=damage_html, icon_color=icon_color))
    172 
    173     def FindFreeContainer(self, *args):
    174         myContainer = None
    175         self.allContainers.sort(lambda x, y: cmp(x.msgIndex, y.msgIndex), reverse=True)
    176         myContainer = self.allContainers[0]
    177         myContainer.StopAnimations()
    178         otherVisibleContainers = []
    179         for container in self.allContainers:
    180             if container == myContainer:
    181                 continue
    182             if container.display and self.IsStillFadingOut(container):
    183                 otherVisibleContainers.append(container)
    184             else:
    185                 container.display = False
    186                 container.msgIndex = len(self.allContainers)
    187 
    188         return (myContainer, otherVisibleContainers)
    189 
    190     def IsStillFadingOut(self, label):
    191         curveSet = uicore.animations.GetAnimationCurveSet(label, 'opacity')
    192         return bool(curveSet)
    193 
    194     def SetSizeAndPosition(self, *args):
    195         boxHeight = 0
    196         widths = []
    197         for container in self.allContainers:
    198             if container.display:
    199                 boxHeight += container.label.textheight
    200                 widths.append(container.label.textwidth)
    201 
    202         fakeText = self.GetFakeText()
    203         if not widths and fakeText:
    204             widths = [fakeText.textwidth]
    205         else:
    206             widths.append(100)
    207         self.width = max(widths) + 30
    208         if boxHeight == 0 and fakeText:
    209             self.height = fakeText.textheight
    210         else:
    211             self.height = boxHeight
    212         self.height += 10
    213         self.top = max(self.minTop, min(uicore.desktop.height - self.height, self.topOffset - self.height))
    214 
    215     def SaveSettings(self, *args):
    216         settings.char.ui.Set('damageMessages_config', (self.align,
    217          self.currentTextAlignment,
    218          self.left,
    219          self.topOffset))
    220 
    221     def SetTextAlignmentIfNeeded(self, alignment, *args):
    222         alignmentMode = settings.user.ui.Get(self.settingNameAlign, 'auto')
    223         if alignmentMode != 'auto' and alignmentMode in ('center', 'right', 'left'):
    224             alignment = alignmentMode
    225         if self.currentTextAlignment != alignment:
    226             uiAlignment = self.GetUIAlignment(alignment)
    227             for container in self.allContainers:
    228                 container.SetAlign(uiAlignment)
    229 
    230             fakeText = self.GetFakeText()
    231             if fakeText:
    232                 fakeText.text = '<%s>%s' % (alignment, self.fakeText.cleanText)
    233             self.currentTextAlignment = alignment
    234 
    235     def GetUIAlignment(self, alignment):
    236         if alignment == 'left':
    237             uiAlignment = uiconst.BOTTOMLEFT
    238         elif alignment == 'right':
    239             uiAlignment = uiconst.BOTTOMRIGHT
    240         else:
    241             uiAlignment = uiconst.CENTERBOTTOM
    242         return uiAlignment
    243 
    244     def ExitDragMode(self, *args):
    245         if getattr(self, 'border', None) is not None:
    246             self.border.Close()
    247         MessageParentClass.ExitDragMode(self, *args)
    248         self.state = uiconst.UI_DISABLED
    249         self.SetParent(uicore.layer.target)
    250 
    251     def EnterDragMode(self, *args):
    252         for container in self.allContainers:
    253             if container.display and container.opacity > 0.05:
    254                 break
    255         else:
    256             uiAlignment = self.GetUIAlignment(self.currentTextAlignment)
    257             self.fakeText = Label(text='', name='faketext', parent=self, left=6, top=5, align=uiAlignment, state=uiconst.UI_DISABLED, fontsize=12, width=380)
    258             text = localization.GetByLabel('UI/Accessories/Log/ExampleText')
    259             self.fakeText.text = '<%s>%s' % (self.currentTextAlignment, text)
    260             self.fakeText.cleanText = text
    261             self.height = self.fakeText.textheight + 20
    262             self.width = 400
    263 
    264         self.border = Frame(parent=self, frameConst=uiconst.FRAME_BORDER1_CORNER5, state=uiconst.UI_DISABLED, color=(1.0, 1.0, 1.0, 0.25), top=-5)
    265         MessageParentClass.EnterDragMode(self, *args)
    266         self.dragFill.top = -5
    267         self.exitMoveModeBtn.top = -5
    268         self.SetParent(uicore.layer.abovemain)
    269 
    270     def ResetAlignment(self, *args):
    271         MessageParentClass.ResetAlignment(self, *args)
    272         self.ChangeAlignment()
    273 
    274     def ChangeFontSize(self, *args):
    275         fontsize = settings.user.ui.Get('dmgnotifictions_fontsize', 12)
    276         if len(self.allLabels) < 1:
    277             return
    278         for label in self.allLabels:
    279             label.fontsize = fontsize
    280 
    281     def ChangeAlignment(self, *args):
    282         self.DoAlignment()
    283 
    284     def OnSessionChanged(self, isRemote, sess, change):
    285         self.noDamageDict = {}