mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-24 04:02:40 -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