mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-23 11:42:39 -06:00
Remove TTI nametag/chat/margin files
This commit is contained in:
parent
5d8aa6e86e
commit
5044724410
16 changed files with 0 additions and 2225 deletions
|
@ -1,120 +0,0 @@
|
|||
from panda3d.core import *
|
||||
|
||||
|
||||
class ChatBalloon(NodePath):
|
||||
TEXT_X_OFFSET = -0.04
|
||||
TEXT_Y_OFFSET = -0.05
|
||||
|
||||
# Proportion of the Z offset based on the default line height, and the new
|
||||
# line height:
|
||||
TEXT_Z_OFFSET = -(4.0/33.0)
|
||||
|
||||
TEXT_MIN_WIDTH = 1.55
|
||||
TEXT_MIN_HEIGHT = 1.1
|
||||
TEXT_GLYPH_SCALE = 0.95
|
||||
TEXT_GLYPH_SHIFT = -0.05
|
||||
|
||||
BALLOON_X_PADDING = 0.525
|
||||
BALLOON_Z_PADDING = 0.5
|
||||
|
||||
BUTTON_SCALE = 6
|
||||
BUTTON_SHIFT = (0, 0, 0.6)
|
||||
|
||||
def __init__(self, model, modelWidth, modelHeight, textNode,
|
||||
foreground=VBase4(0, 0, 0, 1), background=VBase4(1, 1, 1, 1),
|
||||
reversed=False, button=None):
|
||||
NodePath.__init__(self, 'chatBalloon')
|
||||
|
||||
self.model = model
|
||||
self.modelWidth = modelWidth
|
||||
self.modelHeight = modelHeight
|
||||
self.textNode = textNode
|
||||
self.foreground = foreground
|
||||
self.background = background
|
||||
self.button = button
|
||||
|
||||
# Set the TextNode color:
|
||||
self.textNode.setTextColor(self.foreground)
|
||||
|
||||
# Create a balloon:
|
||||
self.balloon = self.model.copyTo(self)
|
||||
self.balloon.setColor(self.background)
|
||||
self.balloon.setTransparency(self.background[3] < 1)
|
||||
|
||||
# Attach the TextNode:
|
||||
self.textNodePath = self.attachNewNode(self.textNode)
|
||||
self.textNodePath.setTransparency(self.foreground[3] < 1)
|
||||
self.textNodePath.setAttrib(DepthWriteAttrib.make(0))
|
||||
|
||||
# Resize the balloon as necessary:
|
||||
middle = self.balloon.find('**/middle')
|
||||
top = self.balloon.find('**/top')
|
||||
self.textWidth = self.textNode.getWidth()
|
||||
if self.textWidth < self.TEXT_MIN_WIDTH:
|
||||
self.textWidth = self.TEXT_MIN_WIDTH
|
||||
paddedWidth = self.textWidth + (self.BALLOON_X_PADDING*2)
|
||||
self.balloon.setSx(paddedWidth / modelWidth)
|
||||
self.textHeight = textNode.getHeight()
|
||||
if self.textHeight < self.TEXT_MIN_HEIGHT:
|
||||
self.textHeight = self.TEXT_MIN_HEIGHT
|
||||
paddedHeight = self.textHeight + (self.BALLOON_Z_PADDING*2)
|
||||
middle.setSz(paddedHeight - 1.5) # Compensate for the top, as well.
|
||||
top.setZ(middle, 1)
|
||||
|
||||
if reversed:
|
||||
self.balloon.setSx(-self.balloon.getSx())
|
||||
self.balloon.setTwoSided(True) # Render the backface of the balloon.
|
||||
|
||||
self.width = paddedWidth
|
||||
self.height = paddedHeight
|
||||
|
||||
# Position the TextNode:
|
||||
self.center = self.balloon.getBounds().getCenter()
|
||||
self.textNodePath.setPos(self.center)
|
||||
self.textNodePath.setY(self.TEXT_Y_OFFSET)
|
||||
self.textNodePath.setX(self.textNodePath, -(self.textWidth/2))
|
||||
if self.textWidth == self.TEXT_MIN_WIDTH:
|
||||
centerX = (self.TEXT_MIN_WIDTH-self.textNode.getWidth()) / 2.0
|
||||
self.textNodePath.setX(self.textNodePath, centerX)
|
||||
self.textNodePath.setZ(top, -self.BALLOON_Z_PADDING + self.TEXT_Z_OFFSET)
|
||||
if self.textHeight == self.TEXT_MIN_HEIGHT:
|
||||
centerZ = (ChatBalloon.TEXT_MIN_HEIGHT-self.textNode.getHeight()) / 2.0
|
||||
self.textNodePath.setZ(self.textNodePath, -centerZ)
|
||||
self.textNodePath.setX(self.textNodePath, self.TEXT_X_OFFSET)
|
||||
|
||||
# Add a button if one is given:
|
||||
if self.button is not None:
|
||||
self.buttonNodePath = button.copyTo(self)
|
||||
self.buttonNodePath.setPos(self.textNodePath, self.textWidth, 0, -self.textHeight)
|
||||
self.buttonNodePath.setPos(self.buttonNodePath, ChatBalloon.BUTTON_SHIFT)
|
||||
self.buttonNodePath.setScale(ChatBalloon.BUTTON_SCALE)
|
||||
else:
|
||||
self.buttonNodePath = None
|
||||
|
||||
# Finally, enable anti-aliasing:
|
||||
self.setAntialias(AntialiasAttrib.MMultisample)
|
||||
|
||||
def setForeground(self, foreground):
|
||||
self.foreground = foreground
|
||||
self.textNode.setTextColor(self.foreground)
|
||||
|
||||
def getForeground(self):
|
||||
return self.foreground
|
||||
|
||||
def setBackground(self, background):
|
||||
self.background = background
|
||||
self.balloon.setColor(self.background)
|
||||
|
||||
def getBackground(self):
|
||||
return self.background
|
||||
|
||||
def setButton(self, button):
|
||||
if self.buttonNodePath is not None:
|
||||
self.buttonNodePath.removeNode()
|
||||
self.buttonNodePath = None
|
||||
|
||||
if button is not None:
|
||||
self.buttonNodePath = button.copyTo(self)
|
||||
self.buttonNodePath.setPos(self.textNodePath, self.textWidth, 0, -self.textHeight)
|
||||
self.buttonNodePath.setPos(self.buttonNodePath, ChatBalloon.BUTTON_SHIFT)
|
||||
self.buttonNodePath.setScale(ChatBalloon.BUTTON_SCALE)
|
|
@ -1,48 +0,0 @@
|
|||
CFSpeech = 1 << 0
|
||||
CFThought = 1 << 1
|
||||
CFQuicktalker = 1 << 2
|
||||
CFTimeout = 1 << 3
|
||||
CFPageButton = 1 << 4
|
||||
CFQuitButton = 1 << 5
|
||||
CFNoQuitButton = 1 << 6
|
||||
CFReversed = 1 << 7
|
||||
|
||||
WTNormal = 0
|
||||
WTSystem = 1
|
||||
WTBattleSOS = 2
|
||||
WTEmote = 3
|
||||
WTToontownBoardingGroup = 4
|
||||
|
||||
# Foreground, background:
|
||||
WhisperColors = {
|
||||
WTNormal: (
|
||||
((0.0, 0.0, 0.0, 1.0), (0.2, 0.6, 0.8, 0.6)), # Normal
|
||||
((1.0, 0.5, 0.5, 1.0), (1.0, 1.0, 1.0, 0.8)), # Click
|
||||
((0.0, 0.0, 0.0, 1.0), (0.2, 0.7, 0.9, 0.6)), # Rollover
|
||||
((0.0, 0.0, 0.0, 1.0), (0.2, 0.7, 0.8, 0.6)) # Disabled
|
||||
),
|
||||
WTSystem: (
|
||||
((0.0, 0.0, 0.0, 1.0), (0.8, 0.3, 0.6, 0.6)), # Normal
|
||||
((1.0, 0.5, 0.5, 1.0), (1.0, 1.0, 1.0, 0.8)), # Click
|
||||
((0.0, 0.0, 0.0, 1.0), (0.8, 0.4, 1.0, 0.6)), # Rollover
|
||||
((0.0, 0.0, 0.0, 1.0), (0.8, 0.3, 0.6, 0.6)) # Disabled
|
||||
),
|
||||
WTEmote: (
|
||||
((0.0, 0.0, 0.0, 1.0), (0.9, 0.5, 0.1, 0.6)), # Normal
|
||||
((1.0, 0.5, 0.5, 1.0), (1.0, 1.0, 1.0, 0.8)), # Click
|
||||
((0.0, 0.0, 0.0, 1.0), (0.9, 0.6, 0.2, 0.6)), # Rollover
|
||||
((0.0, 0.0, 0.0, 1.0), (0.9, 0.6, 0.1, 0.6)), # Disabled
|
||||
),
|
||||
WTBattleSOS: (
|
||||
((0.0, 0.0, 0.0, 1.0), (0.2, 0.6, 0.8, 0.6)), # Normal
|
||||
((1.0, 0.5, 0.5, 1.0), (1.0, 1.0, 1.0, 0.8)), # Click
|
||||
((0.0, 0.0, 0.0, 1.0), (0.2, 0.7, 0.9, 0.6)), # Rollover
|
||||
((0.0, 0.0, 0.0, 1.0), (0.2, 0.7, 0.8, 0.6)) # Disabled
|
||||
),
|
||||
WTToontownBoardingGroup: (
|
||||
((0.0, 0.0, 0.0, 1.0), (0.9, 0.5, 0.1, 0.6)), # Normal
|
||||
((1.0, 0.5, 0.5, 1.0), (1.0, 1.0, 1.0, 0.8)), # Click
|
||||
((0.0, 0.0, 0.0, 1.0), (0.9, 0.6, 0.2, 0.6)), # Rollover
|
||||
((0.0, 0.0, 0.0, 1.0), (0.9, 0.6, 0.1, 0.6)) # Disabled
|
||||
)
|
||||
}
|
|
@ -1,341 +0,0 @@
|
|||
from panda3d.core import TextNode, PGButton, Point3
|
||||
|
||||
from toontown.chat import ChatGlobals
|
||||
from toontown.chat.ChatBalloon import ChatBalloon
|
||||
from toontown.margins import MarginGlobals
|
||||
from toontown.margins.MarginVisible import MarginVisible
|
||||
from toontown.nametag import NametagGlobals
|
||||
from toontown.toontowngui.Clickable2d import Clickable2d
|
||||
|
||||
|
||||
class WhisperQuitButton(Clickable2d):
|
||||
CONTENTS_SCALE = 12
|
||||
|
||||
def __init__(self, whisperPopup):
|
||||
Clickable2d.__init__(self, 'WhisperQuitButton')
|
||||
|
||||
self.whisperPopup = whisperPopup
|
||||
|
||||
self.contents.setScale(self.CONTENTS_SCALE)
|
||||
self.contents.hide()
|
||||
|
||||
self.nodePath = None
|
||||
|
||||
self.update()
|
||||
|
||||
def destroy(self):
|
||||
self.ignoreAll()
|
||||
|
||||
if self.nodePath is not None:
|
||||
self.nodePath.removeNode()
|
||||
self.nodePath = None
|
||||
|
||||
Clickable2d.destroy(self)
|
||||
|
||||
def getUniqueName(self):
|
||||
return 'WhisperQuitButton-' + str(id(self))
|
||||
|
||||
def update(self):
|
||||
if self.nodePath is not None:
|
||||
self.nodePath.removeNode()
|
||||
self.nodePath = None
|
||||
|
||||
self.contents.node().removeAllChildren()
|
||||
|
||||
quitButtonNode = NametagGlobals.quitButton[self.clickState]
|
||||
self.nodePath = quitButtonNode.copyTo(self.contents)
|
||||
|
||||
def applyClickState(self, clickState):
|
||||
if self.nodePath is not None:
|
||||
self.nodePath.removeNode()
|
||||
self.nodePath = None
|
||||
|
||||
quitButtonNode = NametagGlobals.quitButton[clickState]
|
||||
self.nodePath = quitButtonNode.copyTo(self.contents)
|
||||
|
||||
def setClickState(self, clickState):
|
||||
self.applyClickState(clickState)
|
||||
|
||||
if self.isHovering() or self.whisperPopup.isHovering():
|
||||
self.contents.show()
|
||||
elif self.clickState == PGButton.SDepressed:
|
||||
self.contents.show()
|
||||
else:
|
||||
self.contents.hide()
|
||||
|
||||
Clickable2d.setClickState(self, clickState)
|
||||
|
||||
def enterDepressed(self):
|
||||
base.playSfx(NametagGlobals.clickSound)
|
||||
|
||||
def enterRollover(self):
|
||||
if self.lastClickState != PGButton.SDepressed:
|
||||
base.playSfx(NametagGlobals.rolloverSound)
|
||||
|
||||
def updateClickRegion(self):
|
||||
if self.nodePath is not None:
|
||||
right = NametagGlobals.quitButtonWidth / 2.0
|
||||
left = -right
|
||||
top = NametagGlobals.quitButtonHeight / 2.0
|
||||
bottom = -top
|
||||
|
||||
self.setClickRegionFrame(left, right, bottom, top)
|
||||
|
||||
|
||||
class WhisperPopup(Clickable2d, MarginVisible):
|
||||
CONTENTS_SCALE = 0.25
|
||||
|
||||
TEXT_MAX_ROWS = 6
|
||||
TEXT_WORD_WRAP = 8
|
||||
|
||||
QUIT_BUTTON_SHIFT = (0.42, 0, 0.42)
|
||||
|
||||
WHISPER_TIMEOUT_MIN = 10
|
||||
WHISPER_TIMEOUT_MAX = 20
|
||||
|
||||
def __init__(self, text, font, whisperType, timeout=None):
|
||||
Clickable2d.__init__(self, 'WhisperPopup')
|
||||
MarginVisible.__init__(self)
|
||||
|
||||
self.text = text
|
||||
self.font = font
|
||||
self.whisperType = whisperType
|
||||
if timeout is None:
|
||||
self.timeout = len(text) * 0.33
|
||||
if self.timeout < self.WHISPER_TIMEOUT_MIN:
|
||||
self.timeout = self.WHISPER_TIMEOUT_MIN
|
||||
elif self.timeout > self.WHISPER_TIMEOUT_MAX:
|
||||
self.timeout = self.WHISPER_TIMEOUT_MAX
|
||||
else:
|
||||
self.timeout = timeout
|
||||
|
||||
self.active = False
|
||||
|
||||
self.senderName = ''
|
||||
self.fromId = 0
|
||||
|
||||
self.contents.setScale(self.CONTENTS_SCALE)
|
||||
|
||||
self.whisperColor = ChatGlobals.WhisperColors[self.whisperType]
|
||||
|
||||
self.textNode = TextNode('text')
|
||||
self.textNode.setWordwrap(self.TEXT_WORD_WRAP)
|
||||
self.textNode.setTextColor(self.whisperColor[PGButton.SInactive][0])
|
||||
self.textNode.setFont(self.font)
|
||||
self.textNode.setText(self.text)
|
||||
|
||||
self.chatBalloon = None
|
||||
self.quitButton = None
|
||||
|
||||
self.timeoutTaskName = self.getUniqueName() + '-timeout'
|
||||
self.timeoutTask = None
|
||||
|
||||
self.quitEvent = self.getUniqueName() + '-quit'
|
||||
self.accept(self.quitEvent, self.destroy)
|
||||
|
||||
self.setPriority(MarginGlobals.MP_high)
|
||||
self.setVisible(True)
|
||||
|
||||
self.update()
|
||||
|
||||
self.accept('MarginVisible-update', self.update)
|
||||
|
||||
def destroy(self):
|
||||
self.ignoreAll()
|
||||
|
||||
if self.timeoutTask is not None:
|
||||
taskMgr.remove(self.timeoutTask)
|
||||
self.timeoutTask = None
|
||||
|
||||
if self.chatBalloon is not None:
|
||||
self.chatBalloon.removeNode()
|
||||
self.chatBalloon = None
|
||||
|
||||
if self.quitButton is not None:
|
||||
self.quitButton.destroy()
|
||||
self.quitButton = None
|
||||
|
||||
self.textNode = None
|
||||
|
||||
Clickable2d.destroy(self)
|
||||
|
||||
def getUniqueName(self):
|
||||
return 'WhisperPopup-' + str(id(self))
|
||||
|
||||
def update(self):
|
||||
if self.chatBalloon is not None:
|
||||
self.chatBalloon.removeNode()
|
||||
self.chatBalloon = None
|
||||
|
||||
if self.quitButton is not None:
|
||||
self.quitButton.destroy()
|
||||
self.quitButton = None
|
||||
|
||||
self.contents.node().removeAllChildren()
|
||||
|
||||
self.draw()
|
||||
|
||||
if self.cell is not None:
|
||||
# We're in the margin display. Reposition our content, and update
|
||||
# the click region:
|
||||
self.reposition()
|
||||
self.updateClickRegion()
|
||||
else:
|
||||
# We aren't in the margin display. Disable the click region if one
|
||||
# is present:
|
||||
if self.region is not None:
|
||||
self.region.setActive(False)
|
||||
|
||||
def draw(self):
|
||||
if self.isClickable():
|
||||
foreground, background = self.whisperColor[self.clickState]
|
||||
else:
|
||||
foreground, background = self.whisperColor[PGButton.SInactive]
|
||||
self.chatBalloon = ChatBalloon(
|
||||
NametagGlobals.chatBalloon2dModel,
|
||||
NametagGlobals.chatBalloon2dWidth,
|
||||
NametagGlobals.chatBalloon2dHeight, self.textNode,
|
||||
foreground=foreground, background=background
|
||||
)
|
||||
self.chatBalloon.reparentTo(self.contents)
|
||||
|
||||
# Calculate the center of the TextNode:
|
||||
left, right, bottom, top = self.textNode.getFrameActual()
|
||||
center = self.contents.getRelativePoint(
|
||||
self.chatBalloon.textNodePath,
|
||||
((left+right) / 2.0, 0, (bottom+top) / 2.0))
|
||||
|
||||
# Translate the chat balloon along the inverse:
|
||||
self.chatBalloon.setPos(self.chatBalloon, -center)
|
||||
|
||||
# Draw the quit button:
|
||||
self.quitButton = WhisperQuitButton(self)
|
||||
quitButtonNodePath = self.contents.attachNewNode(self.quitButton)
|
||||
|
||||
# Move the quit button to the top right of the TextNode:
|
||||
quitButtonNodePath.setPos(self.contents.getRelativePoint(
|
||||
self.chatBalloon.textNodePath, (right, 0, top)))
|
||||
|
||||
# Apply the quit button shift:
|
||||
quitButtonNodePath.setPos(quitButtonNodePath, self.QUIT_BUTTON_SHIFT)
|
||||
|
||||
# Allow the quit button to close this whisper:
|
||||
self.quitButton.setClickEvent(self.quitEvent)
|
||||
|
||||
def manage(self, marginManager):
|
||||
MarginVisible.manage(self, marginManager)
|
||||
|
||||
self.timeoutTask = taskMgr.doMethodLater(
|
||||
self.timeout, self.unmanage, self.timeoutTaskName, [marginManager])
|
||||
|
||||
def unmanage(self, marginManager):
|
||||
MarginVisible.unmanage(self, marginManager)
|
||||
|
||||
self.destroy()
|
||||
|
||||
def setClickable(self, senderName, fromId):
|
||||
self.senderName = senderName
|
||||
self.fromId = fromId
|
||||
self.setClickEvent('clickedWhisper', extraArgs=[fromId])
|
||||
self.setActive(True)
|
||||
|
||||
def applyClickState(self, clickState):
|
||||
if self.chatBalloon is not None:
|
||||
foreground, background = self.whisperColor[clickState]
|
||||
self.chatBalloon.setForeground(foreground)
|
||||
self.chatBalloon.setBackground(background)
|
||||
|
||||
def setClickState(self, clickState):
|
||||
if self.isClickable():
|
||||
self.applyClickState(clickState)
|
||||
else:
|
||||
self.applyClickState(PGButton.SInactive)
|
||||
|
||||
if self.isHovering() or self.quitButton.isHovering():
|
||||
self.quitButton.contents.show()
|
||||
elif self.quitButton.getClickState() == PGButton.SDepressed:
|
||||
self.quitButton.contents.show()
|
||||
else:
|
||||
self.quitButton.contents.hide()
|
||||
|
||||
Clickable2d.setClickState(self, clickState)
|
||||
|
||||
def enterDepressed(self):
|
||||
if self.isClickable():
|
||||
base.playSfx(NametagGlobals.clickSound)
|
||||
|
||||
def enterRollover(self):
|
||||
if self.isClickable() and (self.lastClickState != PGButton.SDepressed):
|
||||
base.playSfx(NametagGlobals.rolloverSound)
|
||||
|
||||
def updateClickRegion(self):
|
||||
if self.chatBalloon is not None:
|
||||
right = self.chatBalloon.width / 2.0
|
||||
left = -right
|
||||
top = self.chatBalloon.height / 2.0
|
||||
bottom = -top
|
||||
|
||||
self.setClickRegionFrame(left, right, bottom, top)
|
||||
self.region.setActive(True)
|
||||
else:
|
||||
if self.region is not None:
|
||||
self.region.setActive(False)
|
||||
|
||||
if self.quitButton is not None:
|
||||
self.quitButton.updateClickRegion()
|
||||
|
||||
def marginVisibilityChanged(self):
|
||||
if self.cell is not None:
|
||||
# We're in the margin display. Reposition our content, and update
|
||||
# the click region:
|
||||
self.reposition()
|
||||
self.updateClickRegion()
|
||||
else:
|
||||
# We aren't in the margin display. Disable the click region if one
|
||||
# is present:
|
||||
if self.region is not None:
|
||||
self.region.setActive(False)
|
||||
|
||||
def reposition(self):
|
||||
if self.contents is None:
|
||||
return
|
||||
|
||||
origin = Point3()
|
||||
|
||||
self.contents.setPos(origin)
|
||||
|
||||
if self.chatBalloon is not None:
|
||||
self.chatBalloon.removeNode()
|
||||
self.chatBalloon = None
|
||||
|
||||
if self.quitButton is not None:
|
||||
self.quitButton.destroy()
|
||||
self.quitButton = None
|
||||
|
||||
self.contents.node().removeAllChildren()
|
||||
|
||||
if (self.cell in base.leftCells) or (self.cell in base.rightCells):
|
||||
text = self.text.replace('\x01WLDisplay\x01', '').replace('\x02', '')
|
||||
textWidth = self.textNode.calcWidth(text)
|
||||
if (textWidth / self.TEXT_WORD_WRAP) > self.TEXT_MAX_ROWS:
|
||||
self.textNode.setWordwrap(textWidth / (self.TEXT_MAX_ROWS-0.5))
|
||||
else:
|
||||
self.textNode.setWordwrap(self.TEXT_WORD_WRAP)
|
||||
|
||||
self.draw()
|
||||
|
||||
left, right, bottom, top = self.textNode.getFrameActual()
|
||||
if self.cell in base.bottomCells:
|
||||
# Move the origin to the bottom center of the chat balloon:
|
||||
origin = self.contents.getRelativePoint(
|
||||
self.chatBalloon.textNodePath, ((left+right) / 2.0, 0, bottom))
|
||||
elif self.cell in base.leftCells:
|
||||
# Move the origin to the left center of the chat balloon:
|
||||
origin = self.contents.getRelativePoint(
|
||||
self.chatBalloon.textNodePath, (left, 0, (bottom+top) / 2.0))
|
||||
elif self.cell in base.rightCells:
|
||||
# Move the origin to the right center of the chat balloon:
|
||||
origin = self.contents.getRelativePoint(
|
||||
self.chatBalloon.textNodePath, (right, 0, (bottom+top) / 2.0))
|
||||
|
||||
self.contents.setPos(self.contents, -origin)
|
|
@ -1,40 +0,0 @@
|
|||
from pandac.PandaModules import NodePath
|
||||
|
||||
|
||||
class MarginCell(NodePath):
|
||||
def __init__(self):
|
||||
NodePath.__init__(self, 'cell')
|
||||
|
||||
self.active = False
|
||||
self.content = None
|
||||
self.contentNodePath = None
|
||||
|
||||
def setActive(self, active):
|
||||
if not active:
|
||||
self.setContent(None)
|
||||
|
||||
self.active = active
|
||||
|
||||
def getActive(self):
|
||||
return self.active
|
||||
|
||||
def setContent(self, content):
|
||||
if self.content is not None:
|
||||
self.content.setCell(None)
|
||||
self.content.marginVisibilityChanged()
|
||||
self.content = None
|
||||
|
||||
if self.contentNodePath is not None:
|
||||
self.contentNodePath.removeNode()
|
||||
self.contentNodePath = None
|
||||
|
||||
if content is not None:
|
||||
content.setLastCell(self)
|
||||
content.setCell(self)
|
||||
self.contentNodePath = self.attachNewNode(content)
|
||||
content.marginVisibilityChanged()
|
||||
|
||||
self.content = content
|
||||
|
||||
def getContent(self):
|
||||
return self.content
|
|
@ -1,9 +0,0 @@
|
|||
# Priorities:
|
||||
MP_low = 0
|
||||
MP_normal = 1
|
||||
MP_high = 2
|
||||
MP_urgent = 3
|
||||
|
||||
|
||||
def updateMarginVisibles():
|
||||
messenger.send('MarginVisible-update')
|
|
@ -1,76 +0,0 @@
|
|||
from pandac.PandaModules import PandaNode
|
||||
import random
|
||||
|
||||
from toontown.margins.MarginCell import MarginCell
|
||||
|
||||
|
||||
class MarginManager(PandaNode):
|
||||
def __init__(self):
|
||||
PandaNode.__init__(self, 'margins')
|
||||
|
||||
self.cells = set()
|
||||
self.visibles = set()
|
||||
|
||||
def addCell(self, x, y, a2dMarker):
|
||||
cell = MarginCell()
|
||||
cell.reparentTo(a2dMarker)
|
||||
cell.setPos(x, 0, y)
|
||||
cell.setScale(0.2)
|
||||
cell.setActive(True)
|
||||
|
||||
self.cells.add(cell)
|
||||
self.reorganize()
|
||||
|
||||
return cell
|
||||
|
||||
def removeCell(self, cell):
|
||||
if cell in self.cells:
|
||||
self.cells.remove(cell)
|
||||
self.reorganize()
|
||||
|
||||
def addVisible(self, visible):
|
||||
self.visibles.add(visible)
|
||||
self.reorganize()
|
||||
|
||||
def removeVisible(self, visible):
|
||||
if visible in self.visibles:
|
||||
self.visibles.remove(visible)
|
||||
self.reorganize()
|
||||
|
||||
def getActiveCells(self):
|
||||
return [cell for cell in self.cells if cell.getActive()]
|
||||
|
||||
def reorganize(self):
|
||||
# First, get all of the active cells:
|
||||
activeCells = self.getActiveCells()
|
||||
|
||||
# Next, get all of the visibles sorted by priority:
|
||||
visibles = list(self.visibles)
|
||||
visibles.sort(key=lambda visible: visible.getPriority(), reverse=True)
|
||||
|
||||
# We can only display so many visibles, so truncate them based on the
|
||||
# number of active cells:
|
||||
visibles = visibles[:len(activeCells)]
|
||||
|
||||
# Now, let's build a list of empty cells:
|
||||
emptyCells = []
|
||||
for cell in activeCells:
|
||||
content = cell.getContent()
|
||||
if content in visibles:
|
||||
# This cell is already displaying something we want to see.
|
||||
# Ignore it:
|
||||
visibles.remove(content)
|
||||
continue
|
||||
elif content is not None:
|
||||
# This cell isn't displaying anything interesting, so let's
|
||||
# empty it:
|
||||
cell.setContent(None)
|
||||
emptyCells.append(cell)
|
||||
|
||||
# Assign the visibles to their cells:
|
||||
for visible in visibles:
|
||||
cell = visible.getLastCell()
|
||||
if cell not in emptyCells:
|
||||
cell = random.choice(emptyCells)
|
||||
cell.setContent(visible)
|
||||
emptyCells.remove(cell)
|
|
@ -1,59 +0,0 @@
|
|||
class MarginVisible:
|
||||
def __init__(self):
|
||||
self.marginManager = None
|
||||
self.visible = False
|
||||
self.priority = 0
|
||||
self.lastCell = None
|
||||
self.cell = None
|
||||
|
||||
def manage(self, marginManager):
|
||||
if self.marginManager is not None:
|
||||
self.unmanage(self.marginManager)
|
||||
self.marginManager = marginManager
|
||||
if self.visible:
|
||||
self.marginManager.addVisible(self)
|
||||
|
||||
def unmanage(self, marginManager):
|
||||
if marginManager != self.marginManager:
|
||||
return
|
||||
if self.marginManager is None:
|
||||
return
|
||||
if self.visible:
|
||||
self.marginManager.removeVisible(self)
|
||||
self.marginManager = None
|
||||
|
||||
def setVisible(self, visible):
|
||||
if visible == self.visible:
|
||||
return
|
||||
self.visible = visible
|
||||
if self.marginManager is not None:
|
||||
if self.visible:
|
||||
self.marginManager.addVisible(self)
|
||||
else:
|
||||
self.marginManager.removeVisible(self)
|
||||
|
||||
def getVisible(self):
|
||||
return self.visible
|
||||
|
||||
def setPriority(self, priority):
|
||||
self.priority = priority
|
||||
if (self.marginManager is not None) and self.visible:
|
||||
self.marginManager.reorganize()
|
||||
|
||||
def getPriority(self):
|
||||
return self.priority
|
||||
|
||||
def setLastCell(self, cell):
|
||||
self.lastCell = cell
|
||||
|
||||
def getLastCell(self):
|
||||
return self.lastCell
|
||||
|
||||
def setCell(self, cell):
|
||||
self.cell = cell
|
||||
|
||||
def getCell(self):
|
||||
return self.cell
|
||||
|
||||
def marginVisibilityChanged(self):
|
||||
pass # Inheritors should override this method.
|
|
@ -1,308 +0,0 @@
|
|||
from direct.task.Task import Task
|
||||
from pandac.PandaModules import TextNode, VBase4
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from toontown.chat.ChatBalloon import ChatBalloon
|
||||
from toontown.nametag import NametagGlobals
|
||||
|
||||
|
||||
class Nametag:
|
||||
TEXT_WORD_WRAP = 8
|
||||
TEXT_Y_OFFSET = -0.05
|
||||
|
||||
CHAT_TEXT_WORD_WRAP = 12
|
||||
|
||||
PANEL_X_PADDING = 0.2
|
||||
PANEL_Z_PADDING = 0.2
|
||||
|
||||
CHAT_BALLOON_ALPHA = 1
|
||||
|
||||
def __init__(self):
|
||||
self.avatar = None
|
||||
|
||||
self.panel = None
|
||||
self.icon = None
|
||||
self.chatBalloon = None
|
||||
|
||||
self.chatButton = NametagGlobals.noButton
|
||||
self.chatReversed = False
|
||||
|
||||
self.font = None
|
||||
self.chatFont = None
|
||||
|
||||
self.chatType = NametagGlobals.CHAT
|
||||
self.chatBalloonType = NametagGlobals.CHAT_BALLOON
|
||||
|
||||
self.nametagColor = NametagGlobals.NametagColors[NametagGlobals.CCNormal]
|
||||
self.chatColor = NametagGlobals.ChatColors[NametagGlobals.CCNormal]
|
||||
self.speedChatColor = self.chatColor[0][1]
|
||||
|
||||
self.nametagHidden = False
|
||||
self.chatHidden = False
|
||||
self.thoughtHidden = False
|
||||
|
||||
# Create our TextNodes:
|
||||
self.textNode = TextNode('text')
|
||||
self.textNode.setWordwrap(self.TEXT_WORD_WRAP)
|
||||
self.textNode.setAlign(TextNode.ACenter)
|
||||
|
||||
self.chatTextNode = TextNode('chatText')
|
||||
self.chatTextNode.setWordwrap(self.CHAT_TEXT_WORD_WRAP)
|
||||
self.chatTextNode.setGlyphScale(ChatBalloon.TEXT_GLYPH_SCALE)
|
||||
self.chatTextNode.setGlyphShift(ChatBalloon.TEXT_GLYPH_SHIFT)
|
||||
|
||||
# Add the tick task:
|
||||
self.tickTaskName = self.getUniqueName() + '-tick'
|
||||
self.tickTask = taskMgr.add(self.tick, self.tickTaskName, sort=45)
|
||||
|
||||
def destroy(self):
|
||||
if self.tickTask is not None:
|
||||
taskMgr.remove(self.tickTask)
|
||||
self.tickTask = None
|
||||
|
||||
self.chatTextNode = None
|
||||
self.textNode = None
|
||||
|
||||
self.chatFont = None
|
||||
self.font = None
|
||||
|
||||
self.chatButton = NametagGlobals.noButton
|
||||
|
||||
self.removeBalloon()
|
||||
self.removeIcon()
|
||||
self.removePanel()
|
||||
|
||||
self.avatar = None
|
||||
|
||||
def getUniqueName(self):
|
||||
return 'Nametag-' + str(id(self))
|
||||
|
||||
def getChatBalloonModel(self):
|
||||
pass # Inheritors should override this method.
|
||||
|
||||
def getChatBalloonWidth(self):
|
||||
pass # Inheritors should override this method.
|
||||
|
||||
def getChatBalloonHeight(self):
|
||||
pass # Inheritors should override this method.
|
||||
|
||||
def tick(self, task):
|
||||
return Task.done # Inheritors should override this method.
|
||||
|
||||
def updateClickRegion(self):
|
||||
pass # Inheritors should override this method.
|
||||
|
||||
def drawChatBalloon(self, model, modelWidth, modelHeight):
|
||||
pass # Inheritors should override this method.
|
||||
|
||||
def drawNametag(self):
|
||||
pass # Inheritors should override this method.
|
||||
|
||||
def setAvatar(self, avatar):
|
||||
self.avatar = avatar
|
||||
|
||||
def getAvatar(self):
|
||||
return self.avatar
|
||||
|
||||
def setIcon(self, icon):
|
||||
self.icon = icon
|
||||
|
||||
def getIcon(self):
|
||||
return self.icon
|
||||
|
||||
def setChatButton(self, chatButton):
|
||||
self.chatButton = chatButton
|
||||
|
||||
def getChatButton(self):
|
||||
return self.chatButton
|
||||
|
||||
def hasChatButton(self):
|
||||
if (self.chatBalloonType == NametagGlobals.CHAT_BALLOON) and self.chatHidden:
|
||||
return False
|
||||
if (self.chatBalloonType == NametagGlobals.THOUGHT_BALLOON) and self.thoughtHidden:
|
||||
return False
|
||||
return self.chatButton != NametagGlobals.noButton
|
||||
|
||||
def setChatReversed(self, chatReversed):
|
||||
self.chatReversed = chatReversed
|
||||
|
||||
def getChatReversed(self):
|
||||
return self.chatReversed
|
||||
|
||||
def setFont(self, font):
|
||||
self.font = font
|
||||
if self.font is not None:
|
||||
self.textNode.setFont(self.font)
|
||||
self.update()
|
||||
|
||||
def getFont(self):
|
||||
return self.font
|
||||
|
||||
def setChatFont(self, chatFont):
|
||||
self.chatFont = chatFont
|
||||
if self.chatFont is not None:
|
||||
self.chatTextNode.setFont(self.chatFont)
|
||||
self.update()
|
||||
|
||||
def getChatFont(self):
|
||||
return self.chatFont
|
||||
|
||||
def setChatType(self, chatType):
|
||||
self.chatType = chatType
|
||||
|
||||
def getChatType(self):
|
||||
return self.chatType
|
||||
|
||||
def setChatBalloonType(self, chatBalloonType):
|
||||
self.chatBalloonType = chatBalloonType
|
||||
|
||||
def getChatBalloonType(self):
|
||||
return self.chatBalloonType
|
||||
|
||||
def setNametagColor(self, nametagColor):
|
||||
self.nametagColor = nametagColor
|
||||
|
||||
def getNametagColor(self):
|
||||
return self.nametagColor
|
||||
|
||||
def setChatColor(self, chatColor):
|
||||
self.chatColor = chatColor
|
||||
|
||||
def getChatColor(self):
|
||||
return self.chatColor
|
||||
|
||||
def setSpeedChatColor(self, speedChatColor):
|
||||
self.speedChatColor = speedChatColor
|
||||
|
||||
def getSpeedChatColor(self):
|
||||
return self.speedChatColor
|
||||
|
||||
def hideNametag(self):
|
||||
self.nametagHidden = True
|
||||
|
||||
def showNametag(self):
|
||||
self.nametagHidden = False
|
||||
|
||||
def hideChat(self):
|
||||
self.chatHidden = True
|
||||
|
||||
def showChat(self):
|
||||
self.chatHidden = False
|
||||
|
||||
def hideThought(self):
|
||||
self.thoughtHidden = True
|
||||
|
||||
def showThought(self):
|
||||
self.thoughtHidden = False
|
||||
|
||||
def applyClickState(self, clickState):
|
||||
if self.chatBalloon is not None:
|
||||
foreground, background = self.chatColor[clickState]
|
||||
if self.chatType == NametagGlobals.SPEEDCHAT:
|
||||
background = self.speedChatColor
|
||||
if background[3] > self.CHAT_BALLOON_ALPHA:
|
||||
background = VBase4(
|
||||
background[0], background[1], background[2],
|
||||
self.CHAT_BALLOON_ALPHA)
|
||||
self.chatBalloon.setForeground(foreground)
|
||||
self.chatBalloon.setBackground(background)
|
||||
self.chatBalloon.setButton(self.chatButton[clickState])
|
||||
elif self.panel is not None:
|
||||
foreground, background = self.nametagColor[clickState]
|
||||
self.setForeground(foreground)
|
||||
self.setBackground(background)
|
||||
|
||||
def setText(self, text):
|
||||
self.textNode.setText(text)
|
||||
|
||||
def getText(self):
|
||||
try:
|
||||
text = self.textNode.getText()
|
||||
return text
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
def setChatText(self, chatText):
|
||||
self.chatTextNode.setText(chatText)
|
||||
|
||||
def getChatText(self):
|
||||
try:
|
||||
text = self.chatTextNode.getText()
|
||||
return text
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
def setWordWrap(self, wordWrap):
|
||||
if wordWrap is None:
|
||||
wordWrap = self.TEXT_WORD_WRAP
|
||||
self.textNode.setWordwrap(wordWrap)
|
||||
self.update()
|
||||
|
||||
def getWordWrap(self):
|
||||
return self.textNode.getWordwrap()
|
||||
|
||||
def setChatWordWrap(self, chatWordWrap):
|
||||
if (chatWordWrap is None) or (chatWordWrap > self.CHAT_TEXT_WORD_WRAP):
|
||||
chatWordWrap = self.CHAT_TEXT_WORD_WRAP
|
||||
self.chatTextNode.setWordwrap(chatWordWrap)
|
||||
self.update()
|
||||
|
||||
def getChatWordWrap(self):
|
||||
return self.chatTextNode.getWordwrap()
|
||||
|
||||
def setForeground(self, foreground):
|
||||
self.textNode.setTextColor(foreground)
|
||||
|
||||
def setBackground(self, background):
|
||||
if self.panel is not None:
|
||||
self.panel.setColor(background)
|
||||
|
||||
def setShadow(self, shadow):
|
||||
self.textNode.setShadow(shadow)
|
||||
|
||||
def getShadow(self):
|
||||
return self.textNode.getShadow()
|
||||
|
||||
def clearShadow(self):
|
||||
self.textNode.clearShadow()
|
||||
|
||||
def removeBalloon(self):
|
||||
if self.chatBalloon:
|
||||
self.chatBalloon.removeNode()
|
||||
self.chatBalloon = None
|
||||
|
||||
def removePanel(self):
|
||||
if self.panel:
|
||||
self.panel.removeNode()
|
||||
self.panel = None
|
||||
|
||||
def removeIcon(self):
|
||||
if self.icon:
|
||||
self.icon.removeAllChildren()
|
||||
self.icon = None
|
||||
|
||||
def update(self):
|
||||
self.removeBalloon()
|
||||
self.removePanel()
|
||||
|
||||
if self.getChatText():
|
||||
if self.chatBalloonType == NametagGlobals.CHAT_BALLOON:
|
||||
if not self.chatHidden:
|
||||
model = self.getChatBalloonModel()
|
||||
modelWidth = self.getChatBalloonWidth()
|
||||
modelHeight = self.getChatBalloonHeight()
|
||||
self.drawChatBalloon(model, modelWidth, modelHeight)
|
||||
return
|
||||
elif self.chatBalloonType == NametagGlobals.THOUGHT_BALLOON:
|
||||
if not self.thoughtHidden:
|
||||
model = NametagGlobals.thoughtBalloonModel
|
||||
modelWidth = NametagGlobals.thoughtBalloonWidth
|
||||
modelHeight = NametagGlobals.thoughtBalloonHeight
|
||||
self.drawChatBalloon(model, modelWidth, modelHeight)
|
||||
return
|
||||
|
||||
if hasattr(self.avatar, 'ghostMode'):
|
||||
if self.avatar.ghostMode == 2:
|
||||
return
|
||||
|
||||
if self.getText() and (not self.nametagHidden):
|
||||
self.drawNametag()
|
|
@ -1,322 +0,0 @@
|
|||
from direct.task.Task import Task
|
||||
import math
|
||||
from panda3d.core import PGButton, VBase4, DepthWriteAttrib, Point3
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from toontown.chat.ChatBalloon import ChatBalloon
|
||||
from toontown.margins import MarginGlobals
|
||||
from toontown.margins.MarginVisible import MarginVisible
|
||||
from toontown.nametag import NametagGlobals
|
||||
from toontown.nametag.Nametag import Nametag
|
||||
from toontown.toontowngui.Clickable2d import Clickable2d
|
||||
|
||||
|
||||
class Nametag2d(Nametag, Clickable2d, MarginVisible):
|
||||
CONTENTS_SCALE = 0.25
|
||||
|
||||
CHAT_TEXT_MAX_ROWS = 6
|
||||
CHAT_TEXT_WORD_WRAP = 8
|
||||
|
||||
CHAT_BALLOON_ALPHA = 0.4
|
||||
|
||||
ARROW_OFFSET = -1.0
|
||||
ARROW_SCALE = 1.5
|
||||
|
||||
def __init__(self):
|
||||
Nametag.__init__(self)
|
||||
Clickable2d.__init__(self, 'Nametag2d')
|
||||
MarginVisible.__init__(self)
|
||||
|
||||
self.actualChatText = ''
|
||||
|
||||
self.arrow = None
|
||||
self.textNodePath = None
|
||||
|
||||
self.contents.setScale(self.CONTENTS_SCALE)
|
||||
self.hideThought()
|
||||
|
||||
self.accept('MarginVisible-update', self.update)
|
||||
|
||||
def destroy(self):
|
||||
self.ignoreAll()
|
||||
|
||||
Nametag.destroy(self)
|
||||
|
||||
if self.textNodePath is not None:
|
||||
self.textNodePath.removeNode()
|
||||
self.textNodePath = None
|
||||
|
||||
if self.arrow is not None:
|
||||
self.arrow.removeNode()
|
||||
self.arrow = None
|
||||
|
||||
Clickable2d.destroy(self)
|
||||
|
||||
def getUniqueName(self):
|
||||
return 'Nametag2d-' + str(id(self))
|
||||
|
||||
def getChatBalloonModel(self):
|
||||
return NametagGlobals.chatBalloon2dModel
|
||||
|
||||
def getChatBalloonWidth(self):
|
||||
return NametagGlobals.chatBalloon2dWidth
|
||||
|
||||
def getChatBalloonHeight(self):
|
||||
return NametagGlobals.chatBalloon2dHeight
|
||||
|
||||
def setChatText(self, chatText):
|
||||
self.actualChatText = chatText
|
||||
|
||||
Nametag.setChatText(self, chatText)
|
||||
|
||||
def updateClickRegion(self):
|
||||
if self.chatBalloon is not None:
|
||||
right = self.chatBalloon.width / 2.0
|
||||
left = -right
|
||||
top = self.chatBalloon.height / 2.0
|
||||
bottom = -top
|
||||
|
||||
self.setClickRegionFrame(left, right, bottom, top)
|
||||
self.region.setActive(True)
|
||||
elif self.panel is not None:
|
||||
centerX = (self.textNode.getLeft()+self.textNode.getRight()) / 2.0
|
||||
centerY = (self.textNode.getBottom()+self.textNode.getTop()) / 2.0
|
||||
|
||||
left = centerX - (self.panelWidth/2.0)
|
||||
right = centerX + (self.panelWidth/2.0)
|
||||
bottom = centerY - (self.panelHeight/2.0)
|
||||
top = centerY + (self.panelHeight/2.0)
|
||||
|
||||
self.setClickRegionFrame(left, right, bottom, top)
|
||||
self.region.setActive(True)
|
||||
else:
|
||||
if self.region is not None:
|
||||
self.region.setActive(False)
|
||||
|
||||
def isClickable(self):
|
||||
if self.getChatText() and self.hasChatButton():
|
||||
return True
|
||||
return NametagGlobals.wantActiveNametags and Clickable2d.isClickable(self)
|
||||
|
||||
def setClickState(self, clickState):
|
||||
if self.isClickable():
|
||||
self.applyClickState(clickState)
|
||||
else:
|
||||
self.applyClickState(PGButton.SInactive)
|
||||
|
||||
Clickable2d.setClickState(self, clickState)
|
||||
|
||||
def enterDepressed(self):
|
||||
if self.isClickable():
|
||||
base.playSfx(NametagGlobals.clickSound)
|
||||
|
||||
def enterRollover(self):
|
||||
if self.isClickable() and (self.lastClickState != PGButton.SDepressed):
|
||||
base.playSfx(NametagGlobals.rolloverSound)
|
||||
|
||||
def update(self):
|
||||
self.contents.node().removeAllChildren()
|
||||
|
||||
Nametag.update(self)
|
||||
|
||||
if self.cell is not None:
|
||||
# We're in the margin display. Reposition our content, and update
|
||||
# the click region:
|
||||
self.reposition()
|
||||
self.updateClickRegion()
|
||||
else:
|
||||
# We aren't in the margin display. Disable the click region if one
|
||||
# is present:
|
||||
if self.region is not None:
|
||||
self.region.setActive(False)
|
||||
|
||||
def tick(self, task):
|
||||
if (self.avatar is None) or self.avatar.isEmpty():
|
||||
return Task.cont
|
||||
|
||||
if (self.cell is None) or (self.arrow is None):
|
||||
return Task.cont
|
||||
|
||||
location = self.avatar.getPos(NametagGlobals.me)
|
||||
rotation = NametagGlobals.me.getQuat(base.cam)
|
||||
camSpacePos = rotation.xform(location)
|
||||
|
||||
arrowRadians = math.atan2(camSpacePos[0], camSpacePos[1])
|
||||
arrowDegrees = (arrowRadians/math.pi) * 180
|
||||
self.arrow.setR(arrowDegrees - 90)
|
||||
|
||||
return Task.cont
|
||||
|
||||
def drawChatBalloon(self, model, modelWidth, modelHeight):
|
||||
if self.chatFont is None:
|
||||
# We can't draw this without a font.
|
||||
return
|
||||
|
||||
# Prefix the nametag text:
|
||||
self.chatTextNode.setText(self.getText() + ': ' + self.actualChatText)
|
||||
|
||||
# Set our priority in the margin system:
|
||||
self.setPriority(MarginGlobals.MP_normal)
|
||||
|
||||
if self.textNodePath is not None:
|
||||
self.textNodePath.removeNode()
|
||||
self.textNodePath = None
|
||||
|
||||
if self.arrow is not None:
|
||||
self.arrow.removeNode()
|
||||
self.arrow = None
|
||||
|
||||
if self.isClickable():
|
||||
foreground, background = self.chatColor[self.clickState]
|
||||
else:
|
||||
foreground, background = self.chatColor[PGButton.SInactive]
|
||||
if self.chatType == NametagGlobals.SPEEDCHAT:
|
||||
background = self.speedChatColor
|
||||
if background[3] > self.CHAT_BALLOON_ALPHA:
|
||||
background = VBase4(
|
||||
background[0], background[1], background[2],
|
||||
self.CHAT_BALLOON_ALPHA)
|
||||
self.chatBalloon = ChatBalloon(
|
||||
model, modelWidth, modelHeight, self.chatTextNode,
|
||||
foreground=foreground, background=background,
|
||||
reversed=self.chatReversed,
|
||||
button=self.chatButton[self.clickState])
|
||||
self.chatBalloon.reparentTo(self.contents)
|
||||
|
||||
# Calculate the center of the TextNode:
|
||||
left, right, bottom, top = self.chatTextNode.getFrameActual()
|
||||
center = self.contents.getRelativePoint(
|
||||
self.chatBalloon.textNodePath,
|
||||
((left+right) / 2.0, 0, (bottom+top) / 2.0))
|
||||
|
||||
# Translate the chat balloon along the inverse:
|
||||
self.chatBalloon.setPos(self.chatBalloon, -center)
|
||||
|
||||
def drawNametag(self):
|
||||
# Set our priority in the margin system:
|
||||
self.setPriority(MarginGlobals.MP_low)
|
||||
|
||||
if self.textNodePath is not None:
|
||||
self.textNodePath.removeNode()
|
||||
self.textNodePath = None
|
||||
|
||||
if self.arrow is not None:
|
||||
self.arrow.removeNode()
|
||||
self.arrow = None
|
||||
|
||||
if self.font is None:
|
||||
# We can't draw this without a font.
|
||||
return
|
||||
|
||||
# Attach the icon:
|
||||
if self.icon is not None:
|
||||
self.contents.attachNewNode(self.icon)
|
||||
|
||||
if self.isClickable():
|
||||
foreground, background = self.nametagColor[self.clickState]
|
||||
else:
|
||||
foreground, background = self.nametagColor[PGButton.SInactive]
|
||||
|
||||
# Set the color of the TextNode:
|
||||
self.textNode.setTextColor(foreground)
|
||||
|
||||
# Attach the TextNode:
|
||||
self.textNodePath = self.contents.attachNewNode(self.textNode, 1)
|
||||
self.textNodePath.setTransparency(foreground[3] < 1)
|
||||
self.textNodePath.setAttrib(DepthWriteAttrib.make(0))
|
||||
self.textNodePath.setY(self.TEXT_Y_OFFSET)
|
||||
|
||||
# Attach a panel behind the TextNode:
|
||||
self.panel = NametagGlobals.cardModel.copyTo(self.contents, 0)
|
||||
self.panel.setColor(background)
|
||||
self.panel.setTransparency(background[3] < 1)
|
||||
|
||||
# Reposition the panel:
|
||||
x = (self.textNode.getLeft()+self.textNode.getRight()) / 2.0
|
||||
z = (self.textNode.getBottom()+self.textNode.getTop()) / 2.0
|
||||
self.panel.setPos(x, 0, z)
|
||||
|
||||
# Resize the panel:
|
||||
self.panelWidth = self.textNode.getWidth() + self.PANEL_X_PADDING
|
||||
self.panelHeight = self.textNode.getHeight() + self.PANEL_Z_PADDING
|
||||
self.panel.setScale(self.panelWidth, 1, self.panelHeight)
|
||||
|
||||
# Add an arrow:
|
||||
self.arrow = NametagGlobals.arrowModel.copyTo(self.contents)
|
||||
self.arrow.setZ(self.ARROW_OFFSET + self.textNode.getBottom())
|
||||
self.arrow.setScale(self.ARROW_SCALE)
|
||||
self.arrow.setColor(self.nametagColor[4] if len(self.nametagColor) >= 5 else self.nametagColor[0][0])
|
||||
|
||||
def marginVisibilityChanged(self):
|
||||
if self.cell is not None:
|
||||
# We're in the margin display. Reposition our content, and update
|
||||
# the click region:
|
||||
self.reposition()
|
||||
self.updateClickRegion()
|
||||
else:
|
||||
# We aren't in the margin display. Disable the click region if one
|
||||
# is present:
|
||||
if self.region is not None:
|
||||
self.region.setActive(False)
|
||||
|
||||
def reposition(self):
|
||||
if self.contents is None:
|
||||
return
|
||||
|
||||
origin = Point3()
|
||||
|
||||
self.contents.setPos(origin)
|
||||
|
||||
if self.chatBalloon is not None:
|
||||
self.chatBalloon.removeNode()
|
||||
self.chatBalloon = None
|
||||
|
||||
self.contents.node().removeAllChildren()
|
||||
|
||||
if (self.cell in base.leftCells) or (self.cell in base.rightCells):
|
||||
text = self.getChatText().replace('\x01WLDisplay\x01', '').replace('\x02', '')
|
||||
textWidth = self.chatTextNode.calcWidth(text)
|
||||
if (textWidth / self.CHAT_TEXT_WORD_WRAP) > self.CHAT_TEXT_MAX_ROWS:
|
||||
self.chatTextNode.setWordwrap(textWidth / (self.CHAT_TEXT_MAX_ROWS-0.5))
|
||||
else:
|
||||
self.chatTextNode.setWordwrap(self.CHAT_TEXT_WORD_WRAP)
|
||||
|
||||
model = self.getChatBalloonModel()
|
||||
modelWidth = self.getChatBalloonWidth()
|
||||
modelHeight = self.getChatBalloonHeight()
|
||||
self.drawChatBalloon(model, modelWidth, modelHeight)
|
||||
|
||||
nodePath = self.chatBalloon.textNodePath
|
||||
|
||||
left, right, bottom, top = self.chatTextNode.getFrameActual()
|
||||
left -= self.chatBalloon.BALLOON_X_PADDING
|
||||
right += self.chatBalloon.BALLOON_X_PADDING
|
||||
bottom -= self.chatBalloon.BALLOON_Z_PADDING
|
||||
top += self.chatBalloon.BALLOON_Z_PADDING
|
||||
elif self.panel is not None:
|
||||
nodePath = self.textNodePath
|
||||
|
||||
left, right, bottom, top = self.textNode.getFrameActual()
|
||||
left -= self.PANEL_X_PADDING
|
||||
right += self.PANEL_X_PADDING
|
||||
bottom -= self.PANEL_Z_PADDING
|
||||
top += self.PANEL_Z_PADDING
|
||||
|
||||
# Compensate for the arrow:
|
||||
bottom -= self.ARROW_SCALE
|
||||
else:
|
||||
return
|
||||
|
||||
if self.cell in base.bottomCells:
|
||||
# Move the origin to the bottom center of the node path:
|
||||
origin = self.contents.getRelativePoint(
|
||||
nodePath, ((left+right) / 2.0, 0, bottom))
|
||||
elif self.cell in base.leftCells:
|
||||
# Move the origin to the left center of the node path:
|
||||
origin = self.contents.getRelativePoint(
|
||||
nodePath, (left, 0, (bottom+top) / 2.0))
|
||||
elif self.cell in base.rightCells:
|
||||
# Move the origin to the right center of the node path:
|
||||
origin = self.contents.getRelativePoint(
|
||||
nodePath, (right, 0, (bottom+top) / 2.0))
|
||||
|
||||
self.contents.setPos(self.contents, -origin)
|
|
@ -1,185 +0,0 @@
|
|||
from direct.task.Task import Task
|
||||
import math
|
||||
from panda3d.core import BillboardEffect, Vec3, Point3, PGButton, VBase4
|
||||
from panda3d.core import DepthWriteAttrib
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from toontown.chat.ChatBalloon import ChatBalloon
|
||||
from toontown.nametag import NametagGlobals
|
||||
from toontown.nametag.Nametag import Nametag
|
||||
from toontown.toontowngui.Clickable3d import Clickable3d
|
||||
|
||||
|
||||
class Nametag3d(Nametag, Clickable3d):
|
||||
MAX_SCALE = 2.5
|
||||
SCALING_FACTOR = 0.065
|
||||
SCALING_MIN_DISTANCE = 1
|
||||
SCALING_MAX_DISTANCE = math.pow(MAX_SCALE / SCALING_FACTOR, 2)
|
||||
|
||||
def __init__(self):
|
||||
Nametag.__init__(self)
|
||||
Clickable3d.__init__(self, 'Nametag3d')
|
||||
|
||||
self.distance = 0
|
||||
|
||||
self.billboardOffset = 3
|
||||
self.doBillboardEffect()
|
||||
|
||||
def destroy(self):
|
||||
self.ignoreAll()
|
||||
|
||||
Nametag.destroy(self)
|
||||
Clickable3d.destroy(self)
|
||||
|
||||
def getUniqueName(self):
|
||||
return 'Nametag3d-' + str(id(self))
|
||||
|
||||
def getChatBalloonModel(self):
|
||||
return NametagGlobals.chatBalloon3dModel
|
||||
|
||||
def getChatBalloonWidth(self):
|
||||
return NametagGlobals.chatBalloon3dWidth
|
||||
|
||||
def getChatBalloonHeight(self):
|
||||
return NametagGlobals.chatBalloon3dHeight
|
||||
|
||||
def setBillboardOffset(self, billboardOffset):
|
||||
self.billboardOffset = billboardOffset
|
||||
self.doBillboardEffect()
|
||||
|
||||
def getBillboardOffset(self):
|
||||
return self.billboardOffset
|
||||
|
||||
def doBillboardEffect(self):
|
||||
billboardEffect = BillboardEffect.make(
|
||||
Vec3(0, 0, 1), True, False, self.billboardOffset, base.cam,
|
||||
Point3(0, 0, 0))
|
||||
self.contents.setEffect(billboardEffect)
|
||||
|
||||
def updateClickRegion(self):
|
||||
if self.chatBalloon is not None:
|
||||
left = self.chatBalloon.center[0] - (self.chatBalloon.width/2)
|
||||
right = left + self.chatBalloon.width
|
||||
|
||||
# Calculate the bottom of the region based on constants.
|
||||
# 2.4 is the padded height of a single-line message:
|
||||
bottom = NametagGlobals.chatBalloon3dHeight - 2.4
|
||||
top = bottom + self.chatBalloon.height
|
||||
|
||||
self.setClickRegionFrame(left, right, bottom, top)
|
||||
elif self.panel is not None:
|
||||
centerX = (self.textNode.getLeft()+self.textNode.getRight()) / 2.0
|
||||
centerY = (self.textNode.getBottom()+self.textNode.getTop()) / 2.0
|
||||
|
||||
left = centerX - (self.panelWidth/2.0)
|
||||
right = centerX + (self.panelWidth/2.0)
|
||||
bottom = centerY - (self.panelHeight/2.0)
|
||||
top = centerY + (self.panelHeight/2.0)
|
||||
|
||||
self.setClickRegionFrame(left, right, bottom, top)
|
||||
|
||||
def isClickable(self):
|
||||
if self.getChatText() and self.hasChatButton():
|
||||
return True
|
||||
return NametagGlobals.wantActiveNametags and Clickable3d.isClickable(self)
|
||||
|
||||
def setClickState(self, clickState):
|
||||
if self.isClickable():
|
||||
self.applyClickState(clickState)
|
||||
else:
|
||||
self.applyClickState(PGButton.SInactive)
|
||||
|
||||
Clickable3d.setClickState(self, clickState)
|
||||
|
||||
def enterDepressed(self):
|
||||
if self.isClickable():
|
||||
base.playSfx(NametagGlobals.clickSound)
|
||||
|
||||
def enterRollover(self):
|
||||
if self.isClickable() and (self.lastClickState != PGButton.SDepressed):
|
||||
base.playSfx(NametagGlobals.rolloverSound)
|
||||
|
||||
def removeContents(self):
|
||||
if self.contents:
|
||||
self.contents.node().removeAllChildren()
|
||||
|
||||
def update(self):
|
||||
self.removeContents()
|
||||
Nametag.update(self)
|
||||
|
||||
def tick(self, task):
|
||||
distance = self.contents.getPos(base.cam).length()
|
||||
|
||||
if distance < self.SCALING_MIN_DISTANCE:
|
||||
distance = self.SCALING_MIN_DISTANCE
|
||||
elif distance > self.SCALING_MAX_DISTANCE:
|
||||
distance = self.SCALING_MAX_DISTANCE
|
||||
|
||||
if distance != self.distance:
|
||||
self.contents.setScale(math.sqrt(distance) * self.SCALING_FACTOR)
|
||||
self.distance = distance
|
||||
|
||||
self.updateClickRegion()
|
||||
|
||||
return Task.cont
|
||||
|
||||
def drawChatBalloon(self, model, modelWidth, modelHeight):
|
||||
if self.chatFont is None:
|
||||
# We can't draw this without a font.
|
||||
return
|
||||
|
||||
if self.isClickable():
|
||||
foreground, background = self.chatColor[self.clickState]
|
||||
else:
|
||||
foreground, background = self.chatColor[PGButton.SInactive]
|
||||
if self.chatType == NametagGlobals.SPEEDCHAT:
|
||||
background = self.speedChatColor
|
||||
if background[3] > self.CHAT_BALLOON_ALPHA:
|
||||
background = VBase4(
|
||||
background[0], background[1], background[2],
|
||||
self.CHAT_BALLOON_ALPHA)
|
||||
self.chatBalloon = ChatBalloon(
|
||||
model, modelWidth, modelHeight, self.chatTextNode,
|
||||
foreground=foreground, background=background,
|
||||
reversed=self.chatReversed,
|
||||
button=self.chatButton[self.clickState])
|
||||
self.chatBalloon.reparentTo(self.contents)
|
||||
scaleLerp = Sequence(LerpScaleInterval(self.chatBalloon, 0.2, VBase3(1, 1, 1), VBase3(0, 0, 0), blendType='easeInOut'))
|
||||
scaleLerp.start()
|
||||
|
||||
def drawNametag(self):
|
||||
if self.font is None:
|
||||
# We can't draw this without a font.
|
||||
return
|
||||
|
||||
# Attach the icon:
|
||||
if self.icon is not None:
|
||||
self.contents.attachNewNode(self.icon)
|
||||
|
||||
if self.isClickable():
|
||||
foreground, background = self.nametagColor[self.clickState]
|
||||
else:
|
||||
foreground, background = self.nametagColor[PGButton.SInactive]
|
||||
|
||||
# Set the color of the TextNode:
|
||||
self.textNode.setTextColor(foreground)
|
||||
|
||||
# Attach the TextNode:
|
||||
textNodePath = self.contents.attachNewNode(self.textNode, 1)
|
||||
textNodePath.setTransparency(foreground[3] < 1)
|
||||
textNodePath.setAttrib(DepthWriteAttrib.make(0))
|
||||
textNodePath.setY(self.TEXT_Y_OFFSET)
|
||||
|
||||
# Attach a panel behind the TextNode:
|
||||
self.panel = NametagGlobals.cardModel.copyTo(self.contents, 0)
|
||||
self.panel.setColor(background)
|
||||
self.panel.setTransparency(background[3] < 1)
|
||||
|
||||
# Reposition the panel:
|
||||
x = (self.textNode.getLeft()+self.textNode.getRight()) / 2.0
|
||||
z = (self.textNode.getBottom()+self.textNode.getTop()) / 2.0
|
||||
self.panel.setPos(x, 0, z)
|
||||
|
||||
# Resize the panel:
|
||||
self.panelWidth = self.textNode.getWidth() + self.PANEL_X_PADDING
|
||||
self.panelHeight = self.textNode.getHeight() + self.PANEL_Z_PADDING
|
||||
self.panel.setScale(self.panelWidth, 1, self.panelHeight)
|
|
@ -1,21 +0,0 @@
|
|||
from pandac.PandaModules import Point3
|
||||
|
||||
from toontown.nametag.NametagFloat3d import NametagFloat3d
|
||||
|
||||
|
||||
class NametagFloat2d(NametagFloat3d):
|
||||
def doBillboardEffect(self):
|
||||
pass
|
||||
|
||||
def update(self):
|
||||
NametagFloat3d.update(self)
|
||||
|
||||
self.updateClickRegion()
|
||||
|
||||
def setClickRegionFrame(self, left, right, bottom, top):
|
||||
mat = self.contents.getNetTransform().getMat()
|
||||
|
||||
left, _, top = mat.xformPoint(Point3(left, 0, top))
|
||||
right, _, bottom = mat.xformPoint(Point3(right, 0, bottom))
|
||||
|
||||
self.region.setFrame(left, right, bottom, top)
|
|
@ -1,8 +0,0 @@
|
|||
from direct.task.Task import Task
|
||||
|
||||
from toontown.nametag.Nametag3d import Nametag3d
|
||||
|
||||
|
||||
class NametagFloat3d(Nametag3d):
|
||||
def tick(self, task):
|
||||
return Task.done
|
|
@ -1,247 +0,0 @@
|
|||
from pandac.PandaModules import VBase4
|
||||
from otp.otpbase import OTPGlobals
|
||||
|
||||
CCNormal = 0
|
||||
CCNonPlayer = 1
|
||||
CCSuit = 2
|
||||
CCToonBuilding = 3
|
||||
CCSuitBuilding = 4
|
||||
CCHouseBuilding = 5
|
||||
CCSpeedChat = 6
|
||||
CCAdmin = 7
|
||||
|
||||
CHAT = 0
|
||||
SPEEDCHAT = 1
|
||||
|
||||
CHAT_BALLOON = 0
|
||||
THOUGHT_BALLOON = 1
|
||||
|
||||
cardModel = None
|
||||
arrowModel = None
|
||||
chatBalloon3dModel = None
|
||||
chatBalloon3dWidth = 0
|
||||
chatBalloon3dHeight = 0
|
||||
chatBalloon2dModel = None
|
||||
chatBalloon2dWidth = 0
|
||||
chatBalloon2dHeight = 0
|
||||
thoughtBalloonModel = None
|
||||
thoughtBalloonWidth = 0
|
||||
thoughtBalloonHeight = 0
|
||||
noButton = (None, None, None, None)
|
||||
pageButton = (None, None, None, None)
|
||||
quitButton = (None, None, None, None)
|
||||
quitButtonWidth = 0
|
||||
quitButtonHeight = 0
|
||||
|
||||
rolloverSound = None
|
||||
clickSound = None
|
||||
|
||||
me = None
|
||||
want2dNametags = True
|
||||
forceOnscreenChat = False
|
||||
force2dNametags = False
|
||||
wantActiveNametags = True
|
||||
|
||||
|
||||
def setCardModel(model):
|
||||
global cardModel
|
||||
cardModel = loader.loadModel(model)
|
||||
|
||||
|
||||
def setArrowModel(model):
|
||||
global arrowModel
|
||||
arrowModel = loader.loadModel(model)
|
||||
|
||||
|
||||
def setChatBalloon3dModel(model):
|
||||
global chatBalloon3dModel
|
||||
global chatBalloon3dWidth
|
||||
global chatBalloon3dHeight
|
||||
chatBalloon3dModel = loader.loadModel(model)
|
||||
chatBalloon3dWidth, chatBalloon3dHeight = getModelWidthHeight(chatBalloon3dModel)
|
||||
|
||||
|
||||
def setChatBalloon2dModel(model):
|
||||
global chatBalloon2dModel
|
||||
global chatBalloon2dWidth
|
||||
global chatBalloon2dHeight
|
||||
chatBalloon2dModel = loader.loadModel(model)
|
||||
chatBalloon2dWidth, chatBalloon2dHeight = getModelWidthHeight(chatBalloon2dModel)
|
||||
|
||||
|
||||
def setThoughtBalloonModel(model):
|
||||
global thoughtBalloonModel
|
||||
global thoughtBalloonWidth
|
||||
global thoughtBalloonHeight
|
||||
thoughtBalloonModel = loader.loadModel(model)
|
||||
thoughtBalloonWidth, thoughtBalloonHeight = getModelWidthHeight(thoughtBalloonModel)
|
||||
|
||||
|
||||
def setPageButton(normal, down, rollover, disabled):
|
||||
global pageButton
|
||||
pageButton = (normal, down, rollover, disabled)
|
||||
|
||||
|
||||
def setQuitButton(normal, down, rollover, disabled):
|
||||
global quitButton
|
||||
global quitButtonWidth
|
||||
global quitButtonHeight
|
||||
quitButton = (normal, down, rollover, disabled)
|
||||
quitButtonWidth, quitButtonHeight = getModelWidthHeight(normal)
|
||||
|
||||
|
||||
def setRolloverSound(sound):
|
||||
global rolloverSound
|
||||
rolloverSound = sound
|
||||
|
||||
|
||||
def setClickSound(sound):
|
||||
global clickSound
|
||||
clickSound = sound
|
||||
|
||||
|
||||
def setMe(nodePath):
|
||||
global me
|
||||
me = nodePath
|
||||
|
||||
|
||||
def setWant2dNametags(value):
|
||||
global want2dNametags
|
||||
want2dNametags = value
|
||||
|
||||
|
||||
def setForceOnscreenChat(value):
|
||||
global forceOnscreenChat
|
||||
forceOnscreenChat = value
|
||||
|
||||
|
||||
def setForce2dNametags(value):
|
||||
global force2dNametags
|
||||
force2dNametags = value
|
||||
|
||||
|
||||
def setWantActiveNametags(value):
|
||||
global wantActiveNametags
|
||||
wantActiveNametags = value
|
||||
|
||||
|
||||
def getModelWidthHeight(model):
|
||||
tightBounds = model.getTightBounds()
|
||||
if tightBounds is None:
|
||||
return (0, 0)
|
||||
minPoint, maxPoint = tightBounds
|
||||
width = maxPoint.getX() - minPoint.getX()
|
||||
height = maxPoint.getZ() - minPoint.getZ()
|
||||
return (width, height)
|
||||
|
||||
def getFriendColor(handle):
|
||||
if handle.isAdmin():
|
||||
return CCAdmin
|
||||
elif settings['trueFriends'] and base.localAvatar.isTrueFriends(handle.doId):
|
||||
return CCNormal
|
||||
return CCSpeedChat
|
||||
|
||||
# Foreground, background:
|
||||
NametagColors = {
|
||||
CCNormal: ( # Blue
|
||||
(VBase4(0.3, 0.3, 0.7, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Normal
|
||||
(VBase4(0.3, 0.3, 0.7, 1.0), VBase4(0.2, 0.2, 0.2, 0.6)), # Down
|
||||
(VBase4(0.5, 0.5, 1.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.3, 0.3, 0.7, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)) # Disabled
|
||||
),
|
||||
CCNonPlayer: ( # Orange
|
||||
(VBase4(0.8, 0.4, 0.0, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Normal
|
||||
(VBase4(0.8, 0.4, 0.0, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Down
|
||||
(VBase4(0.8, 0.4, 0.0, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Rollover
|
||||
(VBase4(0.8, 0.4, 0.0, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)) # Disabled
|
||||
),
|
||||
CCSuit: (
|
||||
(VBase4(0.2, 0.2, 0.2, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Normal
|
||||
(VBase4(0.2, 0.2, 0.2, 1.0), VBase4(0.2, 0.2, 0.2, 0.6)), # Down
|
||||
(VBase4(0.4, 0.4, 0.4, 1.0), VBase4(1.0, 1.0, 1.0, 0.7)), # Rollover
|
||||
(VBase4(0.2, 0.2, 0.2, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Disabled
|
||||
VBase4(0.8, 0.4, 0.0, 1.0) # Custom arrow color
|
||||
),
|
||||
CCSuitBuilding: (
|
||||
(VBase4(0.5, 0.5, 0.5, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Normal
|
||||
(VBase4(0.5, 0.5, 0.5, 1.0), VBase4(0.2, 0.2, 0.2, 0.6)), # Down
|
||||
(VBase4(0.7, 0.7, 0.7, 1.0), VBase4(1.0, 1.0, 1.0, 0.7)), # Rollover
|
||||
(VBase4(0.5, 0.5, 0.5, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)) # Disabled
|
||||
),
|
||||
CCToonBuilding: (
|
||||
(VBase4(0.2, 0.6, 0.9, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Normal
|
||||
(VBase4(0.2, 0.6, 0.9, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Down
|
||||
(VBase4(0.2, 0.6, 0.9, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Rollover
|
||||
(VBase4(0.2, 0.6, 0.9, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)) # Disabled
|
||||
),
|
||||
CCHouseBuilding: (
|
||||
(VBase4(0.2, 0.6, 0.9, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Normal
|
||||
(VBase4(0.2, 0.2, 0.5, 1.0), VBase4(0.2, 0.2, 0.2, 0.6)), # Down
|
||||
(VBase4(0.5, 0.5, 1.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.0, 0.6, 0.2, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)) # Disabled
|
||||
),
|
||||
CCSpeedChat: ( # Green
|
||||
(VBase4(0.0, 0.6, 0.2, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Normal
|
||||
(VBase4(0.0, 0.5, 0.0, 1.0), VBase4(0.5, 0.5, 0.5, 0.6)), # Down
|
||||
(VBase4(0.0, 0.7, 0.2, 1.0), VBase4(1.0, 1.0, 1.0, 0.7)), # Rollover
|
||||
(VBase4(0.0, 0.6, 0.2, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)) # Disabled
|
||||
),
|
||||
CCAdmin: ( # Red
|
||||
(VBase4(1.0, 0.35, 0.25, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)), # Normal
|
||||
(VBase4(1.0, 0.35, 0.25, 1.0), VBase4(0.5, 0.5, 0.5, 0.6)), # Down
|
||||
(VBase4(1.0, 0.5, 0.56, 1.0), VBase4(1.0, 1.0, 1.0, 0.7)), # Rollover
|
||||
(VBase4(1.0, 0.35, 0.25, 1.0), VBase4(0.8, 0.8, 0.8, 0.5)) # Disabled
|
||||
)
|
||||
}
|
||||
|
||||
# Foreground, background:
|
||||
ChatColors = {
|
||||
CCNormal: (
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Normal
|
||||
(VBase4(1.0, 0.5, 0.5, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Down
|
||||
(VBase4(0.0, 0.6, 0.6, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled
|
||||
),
|
||||
CCNonPlayer: (
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Normal
|
||||
(VBase4(1.0, 0.5, 0.5, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Click
|
||||
(VBase4(0.0, 0.6, 0.6, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled
|
||||
),
|
||||
CCSuit: (
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Normal
|
||||
(VBase4(1.0, 0.5, 0.5, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Down
|
||||
(VBase4(0.0, 0.6, 0.6, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled
|
||||
),
|
||||
CCSuitBuilding: (
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Normal
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Down
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled
|
||||
),
|
||||
CCToonBuilding: (
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Normal
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Down
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled
|
||||
),
|
||||
CCHouseBuilding: (
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Normal
|
||||
(VBase4(1.0, 0.5, 0.5, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Down
|
||||
(VBase4(0.0, 0.6, 0.6, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled
|
||||
),
|
||||
CCSpeedChat: (
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Normal
|
||||
(VBase4(1.0, 0.5, 0.5, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Down
|
||||
(VBase4(0.0, 0.6, 0.6, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled
|
||||
),
|
||||
CCAdmin: (
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Normal
|
||||
(VBase4(1.0, 0.5, 0.5, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Down
|
||||
(VBase4(0.0, 0.6, 0.6, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)), # Rollover
|
||||
(VBase4(0.0, 0.0, 0.0, 1.0), VBase4(1.0, 1.0, 1.0, 1.0)) # Disabled
|
||||
)
|
||||
}
|
|
@ -1,441 +0,0 @@
|
|||
from direct.task.Task import Task
|
||||
from pandac.PandaModules import VBase4, PandaNode
|
||||
|
||||
from toontown.margins.MarginVisible import MarginVisible
|
||||
from toontown.nametag import NametagGlobals
|
||||
from toontown.nametag.Nametag2d import Nametag2d
|
||||
from toontown.nametag.Nametag3d import Nametag3d
|
||||
|
||||
|
||||
class NametagGroup:
|
||||
CHAT_TIMEOUT_MIN = 4.0
|
||||
CHAT_TIMEOUT_MAX = 12.0
|
||||
CHAT_STOMP_DELAY = 0.2
|
||||
|
||||
def __init__(self):
|
||||
self.avatar = None
|
||||
self.active = True
|
||||
self.objectCode = None
|
||||
|
||||
self.chatButton = NametagGlobals.noButton
|
||||
self.chatReversed = False
|
||||
|
||||
self.font = None
|
||||
self.chatFont = None
|
||||
|
||||
self.shadow = None
|
||||
|
||||
self.marginManager = None
|
||||
self.visible3d = True
|
||||
|
||||
self.chatType = NametagGlobals.CHAT
|
||||
self.chatBalloonType = NametagGlobals.CHAT_BALLOON
|
||||
|
||||
self.nametagColor = NametagGlobals.NametagColors[NametagGlobals.CCNormal]
|
||||
self.chatColor = NametagGlobals.ChatColors[NametagGlobals.CCNormal]
|
||||
self.speedChatColor = VBase4(1, 1, 1, 1)
|
||||
|
||||
self.wordWrap = 8
|
||||
self.chatWordWrap = 12
|
||||
|
||||
self.text = ''
|
||||
|
||||
self.chatPages = []
|
||||
self.chatPageIndex = 0
|
||||
self.chatTimeoutTask = None
|
||||
self.chatTimeoutTaskName = self.getUniqueName() + '-timeout'
|
||||
|
||||
self.stompChatText = ''
|
||||
self.stompTask = None
|
||||
self.stompTaskName = self.getUniqueName() + '-stomp'
|
||||
|
||||
self.icon = PandaNode('icon')
|
||||
|
||||
self.nametag2d = Nametag2d()
|
||||
self.nametag3d = Nametag3d()
|
||||
|
||||
self.nametags = set()
|
||||
self.add(self.nametag2d)
|
||||
self.add(self.nametag3d)
|
||||
|
||||
# Add the tick task:
|
||||
self.tickTaskName = self.getUniqueName() + '-tick'
|
||||
self.tickTask = taskMgr.add(self.tick, self.tickTaskName, sort=45)
|
||||
|
||||
def destroy(self):
|
||||
if self.marginManager is not None:
|
||||
self.unmanage(self.marginManager)
|
||||
|
||||
if self.tickTask is not None:
|
||||
taskMgr.remove(self.tickTask)
|
||||
self.tickTask = None
|
||||
|
||||
self.clearChatText()
|
||||
|
||||
for nametag in list(self.nametags):
|
||||
self.remove(nametag)
|
||||
|
||||
self.nametag2d = None
|
||||
self.nametag3d = None
|
||||
|
||||
if self.icon is not None:
|
||||
self.icon.removeAllChildren()
|
||||
self.icon = None
|
||||
|
||||
self.chatFont = None
|
||||
self.font = None
|
||||
|
||||
self.chatButton = NametagGlobals.noButton
|
||||
|
||||
self.avatar = None
|
||||
|
||||
def getUniqueName(self):
|
||||
return 'NametagGroup-' + str(id(self))
|
||||
|
||||
def tick(self, task):
|
||||
if (self.avatar is None) or (self.avatar.isEmpty()):
|
||||
return Task.cont
|
||||
|
||||
chatText = self.getChatText()
|
||||
if (NametagGlobals.forceOnscreenChat and
|
||||
chatText and
|
||||
self.chatBalloonType == NametagGlobals.CHAT_BALLOON):
|
||||
visible3d = False
|
||||
elif self.avatar == NametagGlobals.me:
|
||||
if (chatText and
|
||||
self.chatBalloonType == NametagGlobals.CHAT_BALLOON and
|
||||
not base.cam.node().isInView(self.avatar.getPos(base.cam))):
|
||||
visible3d = False
|
||||
else:
|
||||
visible3d = True
|
||||
elif NametagGlobals.force2dNametags:
|
||||
visible3d = False
|
||||
elif (not NametagGlobals.want2dNametags and
|
||||
((not chatText) or (self.chatBalloonType != NametagGlobals.CHAT_BALLOON))):
|
||||
visible3d = True
|
||||
elif self.avatar.isHidden():
|
||||
visible3d = False
|
||||
else:
|
||||
visible3d = base.cam.node().isInView(self.avatar.getPos(base.cam))
|
||||
|
||||
if visible3d != self.visible3d:
|
||||
self.visible3d = visible3d
|
||||
if self.nametag2d is not None:
|
||||
self.nametag2d.setVisible(not visible3d)
|
||||
|
||||
return Task.cont
|
||||
|
||||
def setAvatar(self, avatar):
|
||||
self.avatar = avatar
|
||||
for nametag in self.nametags:
|
||||
nametag.setAvatar(self.avatar)
|
||||
|
||||
def getAvatar(self):
|
||||
return self.avatar
|
||||
|
||||
def setActive(self, active):
|
||||
self.active = active
|
||||
for nametag in self.nametags:
|
||||
nametag.setActive(self.active)
|
||||
|
||||
def getActive(self):
|
||||
return self.active
|
||||
|
||||
def setObjectCode(self, objectCode):
|
||||
self.objectCode = objectCode
|
||||
|
||||
def getObjectCode(self):
|
||||
return self.objectCode
|
||||
|
||||
def setChatButton(self, chatButton):
|
||||
self.chatButton = chatButton
|
||||
for nametag in self.nametags:
|
||||
nametag.setChatButton(self.chatButton)
|
||||
|
||||
def getChatButton(self):
|
||||
return self.chatButton
|
||||
|
||||
def hasChatButton(self):
|
||||
return self.chatButton != NametagGlobals.noButton
|
||||
|
||||
def setChatReversed(self, reversed):
|
||||
self.chatReversed = reversed
|
||||
for nametag in self.nametags:
|
||||
nametag.setChatReversed(reversed)
|
||||
|
||||
def getChatReversed(self):
|
||||
return self.chatReversed
|
||||
|
||||
def setFont(self, font):
|
||||
self.font = font
|
||||
for nametag in self.nametags:
|
||||
nametag.setFont(self.font)
|
||||
|
||||
def getFont(self):
|
||||
return self.font
|
||||
|
||||
def setChatFont(self, chatFont):
|
||||
self.chatFont = chatFont
|
||||
for nametag in self.nametags:
|
||||
nametag.setChatFont(self.chatFont)
|
||||
|
||||
def getChatFont(self):
|
||||
return self.chatFont
|
||||
|
||||
def setShadow(self, shadow):
|
||||
self.shadow = shadow
|
||||
for nametag in self.nametags:
|
||||
nametag.setShadow(self.shadow)
|
||||
|
||||
def getShadow(self):
|
||||
return self.shadow
|
||||
|
||||
def clearShadow(self):
|
||||
self.shadow = None
|
||||
for nametag in self.nametags:
|
||||
nametag.clearShadow()
|
||||
|
||||
def setChatType(self, chatType):
|
||||
self.chatType = chatType
|
||||
for nametag in self.nametags:
|
||||
nametag.setChatType(self.chatType)
|
||||
|
||||
def getChatType(self):
|
||||
return self.chatType
|
||||
|
||||
def setChatBalloonType(self, chatBalloonType):
|
||||
self.chatBalloonType = chatBalloonType
|
||||
for nametag in self.nametags:
|
||||
nametag.setChatBalloonType(self.chatBalloonType)
|
||||
|
||||
def getChatBalloonType(self):
|
||||
return self.chatBalloonType
|
||||
|
||||
def setNametagColor(self, nametagColor):
|
||||
self.nametagColor = nametagColor
|
||||
for nametag in self.nametags:
|
||||
nametag.setNametagColor(self.nametagColor)
|
||||
|
||||
def getNametagColor(self):
|
||||
return self.nametagColor
|
||||
|
||||
def setChatColor(self, chatColor):
|
||||
self.chatColor = chatColor
|
||||
for nametag in self.nametags:
|
||||
nametag.setChatColor(self.chatColor)
|
||||
|
||||
def getChatColor(self):
|
||||
return self.chatColor
|
||||
|
||||
def setSpeedChatColor(self, speedChatColor):
|
||||
self.speedChatColor = speedChatColor
|
||||
for nametag in self.nametags:
|
||||
nametag.setSpeedChatColor(self.speedChatColor)
|
||||
|
||||
def getSpeedChatColor(self):
|
||||
return self.speedChatColor
|
||||
|
||||
def setWordWrap(self, wordWrap):
|
||||
self.wordWrap = wordWrap
|
||||
for nametag in self.nametags:
|
||||
nametag.setWordWrap(self.wordWrap)
|
||||
|
||||
def getWordWrap(self):
|
||||
return self.wordWrap
|
||||
|
||||
def setChatWordWrap(self, chatWordWrap):
|
||||
self.chatWordWrap = chatWordWrap
|
||||
for nametag in self.nametags:
|
||||
nametag.setChatWordWrap(self.chatWordWrap)
|
||||
|
||||
def getChatWordWrap(self):
|
||||
return self.chatWordWrap
|
||||
|
||||
def setText(self, text):
|
||||
self.text = text
|
||||
for nametag in self.nametags:
|
||||
nametag.setText(self.text)
|
||||
nametag.update()
|
||||
|
||||
def getText(self):
|
||||
return self.text
|
||||
|
||||
def getNumChatPages(self):
|
||||
return len(self.chatPages)
|
||||
|
||||
def setChatPageIndex(self, chatPageIndex):
|
||||
if chatPageIndex >= self.getNumChatPages():
|
||||
return
|
||||
|
||||
self.chatPageIndex = chatPageIndex
|
||||
for nametag in self.nametags:
|
||||
nametag.setChatText(self.chatPages[self.chatPageIndex])
|
||||
nametag.update()
|
||||
|
||||
def getChatPageIndex(self):
|
||||
return self.chatPageIndex
|
||||
|
||||
def setChatText(self, chatText, timeout=False):
|
||||
# If we are currently displaying chat text, we need to "stomp" it. In
|
||||
# other words, we need to clear the current chat text, pause for a
|
||||
# brief moment, and then display the new chat text:
|
||||
if self.getChatText():
|
||||
self.clearChatText()
|
||||
self.stompChatText = chatText
|
||||
self.stompTask = taskMgr.doMethodLater(
|
||||
self.CHAT_STOMP_DELAY, self.__chatStomp, self.stompTaskName,
|
||||
extraArgs=[timeout])
|
||||
return
|
||||
|
||||
self.clearChatText()
|
||||
|
||||
self.chatPages = chatText.split('\x07')
|
||||
self.setChatPageIndex(0)
|
||||
|
||||
if timeout:
|
||||
delay = len(self.getChatText()) * 0.5
|
||||
if delay < self.CHAT_TIMEOUT_MIN:
|
||||
delay = self.CHAT_TIMEOUT_MIN
|
||||
elif delay > self.CHAT_TIMEOUT_MAX:
|
||||
delay = self.CHAT_TIMEOUT_MAX
|
||||
self.chatTimeoutTask = taskMgr.doMethodLater(
|
||||
delay, self.clearChatText, self.chatTimeoutTaskName)
|
||||
|
||||
def getChatText(self):
|
||||
if self.chatPageIndex >= self.getNumChatPages():
|
||||
return ''
|
||||
return self.chatPages[self.chatPageIndex]
|
||||
|
||||
def clearChatText(self, task=None):
|
||||
if self.stompTask is not None:
|
||||
taskMgr.remove(self.stompTask)
|
||||
self.stompTask = None
|
||||
|
||||
self.stompChatText = ''
|
||||
|
||||
if self.chatTimeoutTask is not None:
|
||||
taskMgr.remove(self.chatTimeoutTask)
|
||||
self.chatTimeoutTask = None
|
||||
|
||||
self.chatPages = []
|
||||
self.chatPageIndex = 0
|
||||
|
||||
for nametag in self.nametags:
|
||||
nametag.setChatText('')
|
||||
nametag.update()
|
||||
|
||||
if task is not None:
|
||||
return Task.done
|
||||
|
||||
def getStompChatText(self):
|
||||
return self.stompChatText
|
||||
|
||||
def setIcon(self, icon):
|
||||
self.icon = icon
|
||||
for nametag in self.nametags:
|
||||
nametag.setIcon(self.icon)
|
||||
|
||||
def getIcon(self):
|
||||
return self.icon
|
||||
|
||||
def setNametag2d(self, nametag2d):
|
||||
if self.nametag2d is not None:
|
||||
self.remove(self.nametag2d)
|
||||
self.nametag2d = None
|
||||
|
||||
if nametag2d is None:
|
||||
return
|
||||
|
||||
self.nametag2d = nametag2d
|
||||
self.add(self.nametag2d)
|
||||
|
||||
def getNametag2d(self):
|
||||
return self.nametag2d
|
||||
|
||||
def setNametag3d(self, nametag3d):
|
||||
if self.nametag3d is not None:
|
||||
self.remove(self.nametag3d)
|
||||
self.nametag3d = None
|
||||
|
||||
if nametag3d is None:
|
||||
return
|
||||
|
||||
self.nametag3d = nametag3d
|
||||
self.add(self.nametag3d)
|
||||
|
||||
def getNametag3d(self):
|
||||
return self.nametag3d
|
||||
|
||||
def add(self, nametag):
|
||||
self.nametags.add(nametag)
|
||||
nametag.setAvatar(self.avatar)
|
||||
nametag.setActive(self.active)
|
||||
nametag.setClickEvent(self.getUniqueName())
|
||||
nametag.setChatButton(self.chatButton)
|
||||
nametag.setFont(self.font)
|
||||
nametag.setChatFont(self.chatFont)
|
||||
nametag.setChatType(self.chatType)
|
||||
nametag.setChatBalloonType(self.chatBalloonType)
|
||||
nametag.setNametagColor(self.nametagColor)
|
||||
nametag.setChatColor(self.chatColor)
|
||||
nametag.setSpeedChatColor(self.speedChatColor)
|
||||
nametag.setWordWrap(self.wordWrap)
|
||||
nametag.setChatWordWrap(self.chatWordWrap)
|
||||
nametag.setText(self.text)
|
||||
nametag.setChatText(self.getChatText())
|
||||
nametag.setIcon(self.icon)
|
||||
nametag.update()
|
||||
|
||||
def remove(self, nametag):
|
||||
nametag.destroy()
|
||||
self.nametags.remove(nametag)
|
||||
|
||||
def updateAll(self):
|
||||
for nametag in self.nametags:
|
||||
nametag.update()
|
||||
|
||||
def manage(self, marginManager):
|
||||
if self.marginManager is not None:
|
||||
self.unmanage(self.marginManager)
|
||||
self.marginManager = marginManager
|
||||
for nametag in self.nametags:
|
||||
if isinstance(nametag, MarginVisible):
|
||||
nametag.manage(self.marginManager)
|
||||
|
||||
def unmanage(self, marginManager):
|
||||
if marginManager != self.marginManager:
|
||||
return
|
||||
if self.marginManager is None:
|
||||
return
|
||||
self.marginManager = marginManager
|
||||
for nametag in self.nametags:
|
||||
if isinstance(nametag, MarginVisible):
|
||||
nametag.unmanage(self.marginManager)
|
||||
|
||||
def hideNametag(self):
|
||||
for nametag in self.nametags:
|
||||
nametag.hideNametag()
|
||||
|
||||
def showNametag(self):
|
||||
for nametag in self.nametags:
|
||||
nametag.showNametag()
|
||||
|
||||
def hideChat(self):
|
||||
for nametag in self.nametags:
|
||||
nametag.hideChat()
|
||||
|
||||
def showChat(self):
|
||||
for nametag in self.nametags:
|
||||
nametag.showChat()
|
||||
|
||||
def hideThought(self):
|
||||
for nametag in self.nametags:
|
||||
nametag.hideThought()
|
||||
|
||||
def showThought(self):
|
||||
for nametag in self.nametags:
|
||||
nametag.showThought()
|
||||
|
||||
def __chatStomp(self, timeout=False):
|
||||
self.setChatText(self.stompChatText, timeout=timeout)
|
||||
self.stompChatText = ''
|
Loading…
Reference in a new issue