Poodletooth-iLand/otp/nametag/NametagGroup.py

323 lines
9.6 KiB
Python
Raw Normal View History

2015-11-14 13:28:53 -06:00
from pandac.PandaModules import *
from NametagConstants import *
from Nametag3d import *
from Nametag2d import *
import subprocess
class NametagGroup:
CCNormal = CCNormal
CCNonPlayer = CCNonPlayer
CCSuit = CCSuit
CCToonBuilding = CCToonBuilding
CCSuitBuilding = CCSuitBuilding
CCHouseBuilding = CCHouseBuilding
CCSpeedChat = CCSpeedChat
CHAT_TIMEOUT_MAX = 12.0
CHAT_TIMEOUT_MIN = 4.0
CHAT_TIMEOUT_PROP = 0.5
def __init__(self):
self.nametag2d = Nametag2d()
self.nametag3d = Nametag3d()
self.icon = PandaNode('icon')
self.chatTimeoutTask = None
self.font = None
self.speechFont = None
self.name = ''
self.displayName = ''
self.wordWrap = None
self.qtColor = VBase4(1,1,1,1)
self.colorCode = CCNormal
self.avatar = None
self.active = True
self.chatPages = []
self.chatPage = 0
self.chatFlags = 0
self.objectCode = None
self.manager = None
self.nametags = []
self.addNametag(self.nametag2d)
self.addNametag(self.nametag3d)
self.visible3d = True # Is a 3D nametag visible, or do we need a 2D popup?
self.tickTask = taskMgr.add(self.__tickTask, self.getUniqueId(), sort=45)
self.stompTask = None
self.stompText = None
self.stompFlags = 0
def destroy(self):
taskMgr.remove(self.tickTask)
if self.manager is not None:
self.unmanage(self.manager)
for nametag in list(self.nametags):
self.removeNametag(nametag)
if self.stompTask:
self.stompTask.remove()
def getNametag2d(self):
return self.nametag2d
def getNametag3d(self):
return self.nametag3d
def getNameIcon(self):
return self.icon
def getNumChatPages(self):
if not self.chatFlags & (CFSpeech|CFThought):
return 0
return len(self.chatPages)
def setPageNumber(self, page):
self.chatPage = page
self.updateTags()
def getChatStomp(self):
return bool(self.stompTask)
def getChat(self):
if self.chatPage >= len(self.chatPages):
return ''
else:
return self.chatPages[self.chatPage]
def getStompText(self):
return self.stompText
def getStompDelay(self):
return 0.2
def getUniqueId(self):
return 'Nametag-%d' % id(self)
def hasButton(self):
return bool(self.getButtons())
def getButtons(self):
if self.getNumChatPages() < 2:
# Either only one page or no pages displayed. This means no button,
# unless the game code specifically requests one.
if self.chatFlags & CFQuitButton:
return NametagGlobals.quitButtons
elif self.chatFlags & CFPageButton:
return NametagGlobals.pageButtons
else:
return None
elif self.chatPage == self.getNumChatPages()-1:
# Last page of a multiple-page chat. This calls for a quit button,
# unless the game says otherwise.
if not self.chatFlags & CFNoQuitButton:
return NametagGlobals.quitButtons
else:
return None
else:
# Non-last page of a multiple-page chat. This calls for a page
# button, but only if the game requests it:
if self.chatFlags & CFPageButton:
return NametagGlobals.pageButtons
else:
return None
def setActive(self, active):
self.active = active
def isActive(self):
return self.active
def setAvatar(self, avatar):
self.avatar = avatar
def setFont(self, font):
self.font = font
self.updateTags()
def setSpeechFont(self, font):
self.speechFont = font
self.updateTags()
def setWordwrap(self, wrap):
self.wordWrap = wrap
self.updateTags()
def setColorCode(self, cc):
self.colorCode = cc
self.updateTags()
def setName(self, name):
self.name = name
self.updateTags()
def setDisplayName(self, name):
self.displayName = name
self.updateTags()
def setQtColor(self, color):
self.qtColor = color
self.updateTags()
def setChat(self, chatString, chatFlags):
if not self.chatFlags&CFSpeech:
# We aren't already displaying some chat. Therefore, we don't have
# to stomp.
self._setChat(chatString, chatFlags)
else:
# Stomp!
self.clearChat()
self.stompText = chatString
self.stompFlags = chatFlags
self.stompTask = taskMgr.doMethodLater(self.getStompDelay(), self.__updateStomp,
'ChatStomp-' + self.getUniqueId())
def _setChat(self, chatString, chatFlags):
if chatString:
self.chatPages = chatString.split('\x07')
self.chatFlags = chatFlags
else:
self.chatPages = []
self.chatFlags = 0
self.setPageNumber(0) # Calls updateTags() for us.
self._stopChatTimeout()
if chatFlags&CFTimeout:
self._startChatTimeout()
def __updateStomp(self, task):
self._setChat(self.stompText, self.stompFlags)
self.stompTask = None
def setContents(self, contents):
# This function is a little unique, it's meant to override contents on
# EXISTING nametags only:
for tag in self.nametags:
tag.setContents(contents)
def setObjectCode(self, objectCode):
self.objectCode = objectCode
def getObjectCode(self):
return self.objectCode
def _startChatTimeout(self):
length = len(self.getChat())
timeout = min(max(length*self.CHAT_TIMEOUT_PROP, self.CHAT_TIMEOUT_MIN), self.CHAT_TIMEOUT_MAX)
self.chatTimeoutTask = taskMgr.doMethodLater(timeout, self.__doChatTimeout,
'ChatTimeout-' + self.getUniqueId())
def __doChatTimeout(self, task):
self._setChat('', 0)
return task.done
def _stopChatTimeout(self):
if self.chatTimeoutTask:
taskMgr.remove(self.chatTimeoutTask)
def clearShadow(self):
pass
def clearChat(self):
self._setChat('', 0)
if self.stompTask:
self.stompTask.remove()
def updateNametag(self, tag):
tag.font = self.font
tag.speechFont = self.speechFont
tag.name = self.name
tag.wordWrap = self.wordWrap or DEFAULT_WORDWRAPS[self.colorCode]
tag.displayName = self.displayName or self.name
tag.qtColor = self.qtColor
tag.colorCode = self.colorCode
tag.chatString = self.getChat()
tag.buttons = self.getButtons()
tag.chatFlags = self.chatFlags
tag.avatar = self.avatar
tag.icon = self.icon
if settings['talk2speech']:
subprocess.Popen('espeak "%s"' % tag.chatString)
tag.update()
def __testVisible3D(self):
# We must determine if a 3D nametag is visible or not, since this
# affects the visibility state of 2D nametags.
# Next, we iterate over all of our nametags until we find a visible
# one:
for nametag in self.nametags:
if not isinstance(nametag, Nametag3d):
continue # It's not in the 3D system, disqualified.
if nametag.isOnScreen():
return True
# If we got here, none of the tags were a match...
return False
def __tickTask(self, task):
for nametag in self.nametags:
nametag.tick()
if (NametagGlobals.masterNametagsActive and self.active) or self.hasButton():
nametag.setClickRegionEvent(self.getUniqueId())
else:
nametag.setClickRegionEvent(None)
if NametagGlobals.onscreenChatForced and self.chatFlags & CFSpeech:
# Because we're *forcing* chat onscreen, we skip the visible3d test
# and go ahead and display it anyway.
visible3d = False
elif not NametagGlobals.masterArrowsOn and not self.chatFlags:
# We're forcing margins offscreen; therefore, we should pretend
# that the 3D nametag is always visible.
visible3d = True
else:
visible3d = self.__testVisible3D()
if visible3d ^ self.visible3d:
self.visible3d = visible3d
for nametag in self.nametags:
if isinstance(nametag, MarginPopup):
nametag.setVisible(not visible3d)
return task.cont
def updateTags(self):
for nametag in self.nametags:
self.updateNametag(nametag)
def addNametag(self, nametag):
self.nametags.append(nametag)
self.updateNametag(nametag)
if self.manager is not None and isinstance(nametag, MarginPopup):
nametag.manage(manager)
def removeNametag(self, nametag):
self.nametags.remove(nametag)
if self.manager is not None and isinstance(nametag, MarginPopup):
nametag.unmanage(manager)
nametag.destroy()
def manage(self, manager):
self.manager = manager
for tag in self.nametags:
if isinstance(tag, MarginPopup):
tag.manage(manager)
def unmanage(self, manager):
self.manager = None
for tag in self.nametags:
if isinstance(tag, MarginPopup):
tag.unmanage(manager)
tag.destroy()