mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-23 11:42:39 -06:00
114 lines
3.6 KiB
Python
114 lines
3.6 KiB
Python
|
from Nametag import *
|
||
|
from otp.margins.MarginPopup import *
|
||
|
from pandac.PandaModules import *
|
||
|
import math
|
||
|
|
||
|
class Nametag2d(Nametag, MarginPopup):
|
||
|
SCALE_2D = 0.25
|
||
|
CHAT_ALPHA = 0.5
|
||
|
ARROW_OFFSET = -1.0
|
||
|
ARROW_SCALE = 1.5
|
||
|
|
||
|
DEFAULT_CHAT_WORDWRAP = 8.0
|
||
|
|
||
|
def __init__(self):
|
||
|
Nametag.__init__(self)
|
||
|
MarginPopup.__init__(self)
|
||
|
|
||
|
self.contents = self.CName|self.CSpeech
|
||
|
self.chatWordWrap = 7.5
|
||
|
|
||
|
self.arrow = None
|
||
|
|
||
|
self.innerNP.setScale(self.SCALE_2D)
|
||
|
|
||
|
def showBalloon(self, balloon, text):
|
||
|
text = '%s: %s' % (self.name, text)
|
||
|
Nametag.showBalloon(self, balloon, text)
|
||
|
|
||
|
# Next, center the balloon in the cell:
|
||
|
balloon = NodePath.anyPath(self).find('*/balloon')
|
||
|
|
||
|
# Calculate the center of the TextNode.
|
||
|
text = balloon.find('**/+TextNode')
|
||
|
t = text.node()
|
||
|
left, right, bottom, top = t.getFrameActual()
|
||
|
center = self.innerNP.getRelativePoint(text,
|
||
|
((left+right)/2., 0, (bottom+top)/2.))
|
||
|
|
||
|
# Next translate the balloon along the inverse.
|
||
|
balloon.setPos(balloon, -center)
|
||
|
# Also translate the frame:
|
||
|
left, right, bottom, top = self.frame
|
||
|
self.frame = (left-center.getX(), right-center.getX(),
|
||
|
bottom-center.getZ(), top-center.getZ())
|
||
|
|
||
|
# When a balloon is active, we need to be somewhat higher-priority in the
|
||
|
# popup system:
|
||
|
self.setPriority(1)
|
||
|
|
||
|
# Remove our pointer arrow:
|
||
|
if self.arrow is not None:
|
||
|
self.arrow.removeNode()
|
||
|
self.arrow = None
|
||
|
|
||
|
def showName(self):
|
||
|
Nametag.showName(self)
|
||
|
|
||
|
# Revert our priority back to basic:
|
||
|
self.setPriority(0)
|
||
|
|
||
|
# Tack on an arrow:
|
||
|
t = self.innerNP.find('**/+TextNode')
|
||
|
arrowZ = self.ARROW_OFFSET + t.node().getBottom()
|
||
|
|
||
|
self.arrow = NametagGlobals.arrowModel.copyTo(self.innerNP)
|
||
|
self.arrow.setZ(arrowZ)
|
||
|
self.arrow.setScale(self.ARROW_SCALE)
|
||
|
self.arrow.setColor(ARROW_COLORS.get(self.colorCode, self.nameFg))
|
||
|
|
||
|
def update(self, scale=True):
|
||
|
Nametag.update(self, scale)
|
||
|
self.considerUpdateClickRegion()
|
||
|
|
||
|
def marginVisibilityChanged(self):
|
||
|
self.considerUpdateClickRegion()
|
||
|
|
||
|
def considerUpdateClickRegion(self):
|
||
|
# If we are onscreen, we update our click region:
|
||
|
if self.isDisplayed():
|
||
|
left, right, bottom, top = self.frame
|
||
|
self.updateClickRegion(left*self.SCALE_2D, right*self.SCALE_2D,
|
||
|
bottom*self.SCALE_2D, top*self.SCALE_2D)
|
||
|
else:
|
||
|
self.stashClickRegion()
|
||
|
|
||
|
def tick(self):
|
||
|
# Update the arrow's pointing.
|
||
|
if not self.isDisplayed() or self.arrow is None:
|
||
|
return # No arrow or not onscreen.
|
||
|
|
||
|
if self.avatar is None or self.avatar.isEmpty():
|
||
|
return # No avatar, can't be done.
|
||
|
|
||
|
# Get points needed in calculation:
|
||
|
cam = NametagGlobals.camera or base.cam
|
||
|
toon = NametagGlobals.toon or cam
|
||
|
|
||
|
# libotp calculates this using the offset from localToon->avatar, but
|
||
|
# the orientation from cam. Therefore, we duplicate it like so:
|
||
|
location = self.avatar.getPos(toon)
|
||
|
rotation = toon.getQuat(cam)
|
||
|
|
||
|
camSpacePos = rotation.xform(location)
|
||
|
arrowRadians = math.atan2(camSpacePos[0], camSpacePos[1])
|
||
|
arrowDegrees = arrowRadians/math.pi*180
|
||
|
|
||
|
self.arrow.setR(arrowDegrees - 90)
|
||
|
|
||
|
def getSpeechBalloon(self):
|
||
|
return NametagGlobals.speechBalloon2d
|
||
|
|
||
|
def getThoughtBalloon(self):
|
||
|
return NametagGlobals.thoughtBalloon2d
|