Merge branch 'nametags'
This commit is contained in:
commit
4e1da2bfd7
13 changed files with 226 additions and 30 deletions
|
@ -1,6 +1,7 @@
|
|||
import time
|
||||
import string
|
||||
from pandac.PandaModules import *
|
||||
from otp.nametag.Nametag import Nametag
|
||||
from direct.distributed import DistributedNode
|
||||
from direct.actor.DistributedActor import DistributedActor
|
||||
from direct.task import Task
|
||||
|
@ -88,11 +89,11 @@ class DistributedAvatar(DistributedActor, Avatar):
|
|||
|
||||
def do_setParent(self, parentToken):
|
||||
if not self.isDisabled():
|
||||
#if parentToken == OTPGlobals.SPHidden:
|
||||
# self.nametag2dDist &= ~Nametag.CName
|
||||
#else:
|
||||
# self.nametag2dDist |= Nametag.CName
|
||||
#self.nametag.getNametag2d().setContents(self.nametag2dContents & self.nametag2dDist)
|
||||
if parentToken == OTPGlobals.SPHidden:
|
||||
self.nametag2dDist &= ~Nametag.CName
|
||||
else:
|
||||
self.nametag2dDist |= Nametag.CName
|
||||
self.nametag.getNametag2d().setContents(self.nametag2dContents & self.nametag2dDist)
|
||||
DistributedActor.do_setParent(self, parentToken)
|
||||
self.__setTags()
|
||||
|
||||
|
|
|
@ -894,7 +894,6 @@ class LocalAvatar(DistributedAvatar.DistributedAvatar, DistributedSmoothNode.Dis
|
|||
messenger.send('customMessagesChanged')
|
||||
|
||||
def displayWhisper(self, fromId, chatString, whisperType):
|
||||
return # TODO: We really need a replacement for libotp before we can display these...
|
||||
sender = None
|
||||
sfx = self.soundWhisper
|
||||
if whisperType == WhisperPopup.WTNormal or whisperType == WhisperPopup.WTQuickTalker:
|
||||
|
|
5
otp/margins/ClickablePopup.py
Normal file
5
otp/margins/ClickablePopup.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from pandac.PandaModules import *
|
||||
|
||||
class ClickablePopup(PandaNode):
|
||||
def __init__(self):
|
||||
PandaNode.__init__(self, 'popup')
|
5
otp/margins/MarginPopup.py
Normal file
5
otp/margins/MarginPopup.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from pandac.PandaModules import *
|
||||
|
||||
class MarginPopup(PandaNode):
|
||||
def __init__(self):
|
||||
PandaNode.__init__(self, '')
|
|
@ -1,4 +1,7 @@
|
|||
class WhisperPopup:
|
||||
from MarginPopup import *
|
||||
from ClickablePopup import *
|
||||
|
||||
class WhisperPopup(MarginPopup, ClickablePopup):
|
||||
WTNormal=0
|
||||
WTQuickTalker=1
|
||||
WTSystem=2
|
||||
|
|
|
@ -1,3 +1,49 @@
|
|||
from pandac.PandaModules import *
|
||||
|
||||
class ChatBalloon:
|
||||
TEXT_SHIFT = (0.1, 0, 1.1)
|
||||
TEXT_SHIFT_PROP = 0.08
|
||||
NATIVE_WIDTH = 10.0
|
||||
BUBBLE_PADDING = 0.3
|
||||
BUBBLE_PADDING_PROP = 0.05
|
||||
|
||||
def __init__(self, model):
|
||||
self.model = model
|
||||
self.wordWrap = 15.0
|
||||
|
||||
def generate(self, text, font, textColor=(0,0,0,1), balloonColor=(1,1,1,1)):
|
||||
root = NodePath('balloon')
|
||||
|
||||
# Add balloon geometry:
|
||||
balloon = self.model.copyTo(root)
|
||||
top = balloon.find('**/top')
|
||||
middle = balloon.find('**/middle')
|
||||
bottom = balloon.find('**/bottom')
|
||||
|
||||
balloon.setColor(balloonColor)
|
||||
if balloonColor[3] < 1.0:
|
||||
balloon.setTransparency(1)
|
||||
|
||||
# Render the text into a TextNode, using the font:
|
||||
t = root.attachNewNode(TextNode('text'))
|
||||
t.node().setFont(font)
|
||||
t.node().setWordwrap(self.wordWrap)
|
||||
t.node().setText(text)
|
||||
t.node().setTextColor(textColor)
|
||||
|
||||
width, height = t.node().getWidth(), t.node().getHeight()
|
||||
|
||||
t.setDepthOffset(1)
|
||||
t.setPos(self.TEXT_SHIFT)
|
||||
t.setX(t, self.TEXT_SHIFT_PROP*width)
|
||||
t.setZ(t, height)
|
||||
|
||||
# Set the balloon's size:
|
||||
width *= 1+self.BUBBLE_PADDING_PROP
|
||||
width += self.BUBBLE_PADDING
|
||||
balloon.setSx(width/self.NATIVE_WIDTH)
|
||||
middle.setSz(height)
|
||||
top.setZ(top, height-1)
|
||||
|
||||
root.flattenStrong()
|
||||
return root
|
||||
|
|
|
@ -1,7 +1,67 @@
|
|||
class Nametag:
|
||||
from NametagConstants import *
|
||||
import NametagGlobals
|
||||
from otp.margins.ClickablePopup import ClickablePopup
|
||||
from pandac.PandaModules import *
|
||||
|
||||
class Nametag(ClickablePopup):
|
||||
CName = 1
|
||||
CSpeech = 2
|
||||
CThought = 4
|
||||
|
||||
def __init__(self):
|
||||
ClickablePopup.__init__(self)
|
||||
self.contents = 0 # To be set by subclass.
|
||||
|
||||
self.innerNP = NodePath.anyPath(self).attachNewNode('nametag_contents')
|
||||
|
||||
self.wordWrap = 10
|
||||
|
||||
self.font = None
|
||||
self.name = ''
|
||||
self.displayName = ''
|
||||
self.qtColor = VBase4(1,1,1,1)
|
||||
|
||||
self.chatString = ''
|
||||
self.chatFlags = 0
|
||||
|
||||
def setContents(self, contents):
|
||||
self.contents = contents
|
||||
self.update()
|
||||
|
||||
def update(self):
|
||||
self.innerNP.node().removeAllChildren()
|
||||
if self.contents&self.CThought and self.chatFlags&CFThought:
|
||||
self.showThought()
|
||||
elif self.contents&self.CSpeech and self.chatFlags&CFSpeech:
|
||||
self.showSpeech()
|
||||
elif self.contents&self.CName and self.displayName:
|
||||
self.showName()
|
||||
|
||||
def showThought(self):
|
||||
pass
|
||||
|
||||
def showSpeech(self):
|
||||
pass
|
||||
|
||||
def showName(self):
|
||||
if not self.font:
|
||||
# If no font is set, we can't actually display a name yet...
|
||||
return
|
||||
|
||||
# Create text node:
|
||||
t = self.innerNP.attachNewNode(TextNode('name'), 1)
|
||||
t.node().setFont(self.font)
|
||||
t.node().setAlign(TextNode.ACenter)
|
||||
t.node().setWordwrap(self.wordWrap)
|
||||
t.node().setText(self.displayName)
|
||||
t.node().setTextColor(VBase4(0,0,0,1))
|
||||
|
||||
width, height = t.node().getWidth(), t.node().getHeight()
|
||||
|
||||
t.setDepthOffset(100)
|
||||
|
||||
# Apply panel behind the text:
|
||||
panel = NametagGlobals.nametagCardModel.copyTo(self.innerNP, 0)
|
||||
panel.setPos((t.node().getLeft()+t.node().getRight())/2.0, 0,
|
||||
(t.node().getTop()+t.node().getBottom())/2.0)
|
||||
panel.setScale(width, 1, height)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from Nametag import *
|
||||
from otp.margins.MarginPopup import *
|
||||
from pandac.PandaModules import *
|
||||
|
||||
class Nametag2d(Nametag, PandaNode):
|
||||
class Nametag2d(Nametag, MarginPopup):
|
||||
def __init__(self):
|
||||
Nametag.__init__(self)
|
||||
PandaNode.__init__(self, '')
|
||||
MarginPopup.__init__(self)
|
||||
|
||||
def setContents(self, contents):
|
||||
pass
|
||||
self.contents = self.CName|self.CSpeech
|
||||
|
|
|
@ -1,10 +1,36 @@
|
|||
from Nametag import *
|
||||
import NametagGlobals
|
||||
from NametagConstants import *
|
||||
from pandac.PandaModules import *
|
||||
|
||||
class Nametag3d(Nametag, PandaNode):
|
||||
class Nametag3d(Nametag):
|
||||
CONTENTS_SCALE = 0.17
|
||||
BILLBOARD_OFFSET = 3.0
|
||||
SHOULD_BILLBOARD = True
|
||||
|
||||
def __init__(self):
|
||||
Nametag.__init__(self)
|
||||
PandaNode.__init__(self, '')
|
||||
|
||||
def setContents(self, contents):
|
||||
pass
|
||||
self.contents = self.CName|self.CSpeech|self.CThought
|
||||
|
||||
if self.SHOULD_BILLBOARD:
|
||||
self.innerNP.setEffect(BillboardEffect.make(
|
||||
Vec3(0,0,1),
|
||||
True,
|
||||
False,
|
||||
self.BILLBOARD_OFFSET,
|
||||
NametagGlobals.camera,
|
||||
Point3(0,0,0)))
|
||||
self.innerNP.setScale(self.CONTENTS_SCALE)
|
||||
|
||||
def showSpeech(self):
|
||||
color = self.qtColor if (self.chatFlags&CFQuicktalker) else VBase4(1,1,1,1)
|
||||
bubble = NametagGlobals.speechBalloon3d.generate(self.chatString, self.font,
|
||||
balloonColor=color)
|
||||
bubble.reparentTo(self.innerNP)
|
||||
|
||||
def showThought(self):
|
||||
color = self.qtColor if (self.chatFlags&CFQuicktalker) else VBase4(1,1,1,1)
|
||||
bubble = NametagGlobals.thoughtBalloon3d.generate(self.chatString, self.font,
|
||||
balloonColor=color)
|
||||
bubble.reparentTo(self.innerNP)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from Nametag2d import *
|
||||
from Nametag3d import *
|
||||
|
||||
class NametagFloat2d(Nametag2d):
|
||||
pass
|
||||
class NametagFloat2d(Nametag3d):
|
||||
CONTENTS_SCALE = 1.0
|
||||
SHOULD_BILLBOARD = False
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from pandac.PandaModules import *
|
||||
from NametagConstants import *
|
||||
from Nametag3d import *
|
||||
from Nametag2d import *
|
||||
|
||||
|
@ -18,6 +19,16 @@ class NametagGroup:
|
|||
self.nametag3d = Nametag3d()
|
||||
self.icon = PandaNode('icon')
|
||||
|
||||
self.chatTimeoutTask = None
|
||||
|
||||
self.font = None
|
||||
self.name = ''
|
||||
self.displayName = ''
|
||||
self.qtColor = VBase4(1,1,1,1)
|
||||
|
||||
self.chatString = ''
|
||||
self.chatFlags = 0
|
||||
|
||||
self.nametags = []
|
||||
self.addNametag(self.nametag2d)
|
||||
self.addNametag(self.nametag3d)
|
||||
|
@ -38,13 +49,13 @@ class NametagGroup:
|
|||
return 0
|
||||
|
||||
def getChat(self):
|
||||
return ''
|
||||
return self.chatString
|
||||
|
||||
def getStompText(self):
|
||||
return ''
|
||||
|
||||
def getUniqueId(self):
|
||||
return 'foo'
|
||||
return 'Nametag-%d' % id(self)
|
||||
|
||||
def setActive(self, active):
|
||||
pass
|
||||
|
@ -53,28 +64,67 @@ class NametagGroup:
|
|||
pass
|
||||
|
||||
def setFont(self, font):
|
||||
pass
|
||||
self.font = font
|
||||
self.updateTags()
|
||||
|
||||
def setColorCode(self, cc):
|
||||
pass
|
||||
|
||||
def setName(self, name):
|
||||
pass
|
||||
self.name = name
|
||||
self.updateTags()
|
||||
|
||||
def setDisplayName(self, name):
|
||||
pass
|
||||
self.displayName = name
|
||||
self.updateTags()
|
||||
|
||||
def setQtColor(self, color):
|
||||
pass
|
||||
self.qtColor = color
|
||||
|
||||
def setChat(self, chatString, chatFlags):
|
||||
pass
|
||||
self.chatString = chatString
|
||||
self.chatFlags = chatFlags
|
||||
self.updateTags()
|
||||
|
||||
self._stopChatTimeout()
|
||||
if chatFlags&CFTimeout:
|
||||
self._startChatTimeout()
|
||||
|
||||
def _startChatTimeout(self):
|
||||
self.chatTimeoutTask = taskMgr.doMethodLater(5, self.__doChatTimeout,
|
||||
'ChatTimeout-' + self.getUniqueId())
|
||||
|
||||
def __doChatTimeout(self, task):
|
||||
self.setChat('', 0)
|
||||
return task.done
|
||||
|
||||
def _stopChatTimeout(self):
|
||||
if self.chatTimeoutTask:
|
||||
taskMgr.remove(self.chatTimeoutTask)
|
||||
|
||||
def clearShadow(self):
|
||||
pass
|
||||
|
||||
def clearChat(self):
|
||||
self.setChat('', 0)
|
||||
|
||||
def updateNametag(self, tag):
|
||||
tag.font = self.font
|
||||
tag.name = self.name
|
||||
tag.displayName = self.displayName
|
||||
tag.qtColor = self.qtColor
|
||||
tag.chatString = self.chatString
|
||||
tag.chatFlags = self.chatFlags
|
||||
|
||||
tag.update()
|
||||
|
||||
def updateTags(self):
|
||||
for nametag in self.nametags:
|
||||
self.updateNametag(nametag)
|
||||
|
||||
def addNametag(self, nametag):
|
||||
self.nametags.append(nametag)
|
||||
self.updateNametag(nametag)
|
||||
|
||||
def removeNametag(self, nametag):
|
||||
self.nametags.remove(nametag)
|
||||
|
|
|
@ -2,7 +2,7 @@ import math
|
|||
import random
|
||||
from pandac.PandaModules import VBase3, CollisionPlane, CollisionNode, CollisionSphere, CollisionTube, NodePath, Plane, Vec3, Vec2, Point3, BitMask32, CollisionHandlerEvent, TextureStage, VBase4, BoundingSphere
|
||||
from otp.nametag.NametagConstants import CFSpeech
|
||||
#from otp.nametag.NametagGroup import NametagGroup # TODO -- NAMETAGTODO
|
||||
from otp.nametag.NametagGroup import NametagGroup
|
||||
from direct.interval.IntervalGlobal import Sequence, Wait, Func, LerpHprInterval, Parallel, LerpPosInterval, Track, ActorInterval, ParallelEndTogether, LerpFunctionInterval, LerpScaleInterval, LerpPosHprInterval, SoundInterval
|
||||
from direct.task import Task
|
||||
from direct.fsm import FSM
|
||||
|
|
|
@ -220,9 +220,9 @@ class ToonBase(OTPBase.OTPBase):
|
|||
def initNametagGlobals(self):
|
||||
arrow = loader.loadModel('phase_3/models/props/arrow')
|
||||
card = loader.loadModel('phase_3/models/props/panel')
|
||||
speech3d = ChatBalloon(loader.loadModelNode('phase_3/models/props/chatbox'))
|
||||
thought3d = ChatBalloon(loader.loadModelNode('phase_3/models/props/chatbox_thought_cutout'))
|
||||
speech2d = ChatBalloon(loader.loadModelNode('phase_3/models/props/chatbox_noarrow'))
|
||||
speech3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox'))
|
||||
thought3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_thought_cutout'))
|
||||
speech2d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_noarrow'))
|
||||
chatButtonGui = loader.loadModel('phase_3/models/gui/chat_button_gui')
|
||||
NametagGlobals.setCamera(self.cam)
|
||||
NametagGlobals.setArrowModel(arrow)
|
||||
|
|
Loading…
Reference in a new issue