2015-06-23 18:11:48 -05:00
|
|
|
from panda3d.core import *
|
2015-03-03 16:10:12 -06:00
|
|
|
from toontown.toonbase.ToontownGlobals import *
|
|
|
|
from direct.gui.DirectGui import *
|
2015-08-17 07:55:43 -05:00
|
|
|
from direct.interval.IntervalGlobal import *
|
2015-03-03 16:10:12 -06:00
|
|
|
from direct.showbase import DirectObject
|
|
|
|
from direct.fsm import ClassicFSM, State
|
|
|
|
from direct.fsm import State
|
|
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
|
|
import DistributedToon
|
|
|
|
from toontown.friends import FriendInviter
|
|
|
|
import ToonTeleportPanel
|
2015-08-17 07:55:43 -05:00
|
|
|
from toontown.toonbase import TTLocalizer, ToontownGlobals
|
2015-03-03 16:10:12 -06:00
|
|
|
from toontown.hood import ZoneUtil
|
2015-08-03 19:18:12 -05:00
|
|
|
from toontown.toonbase.ToontownBattleGlobals import Tracks, Levels, getAvPropDamage
|
2015-08-17 07:55:43 -05:00
|
|
|
import Toon, NPCFriendPanel
|
2015-03-03 16:10:12 -06:00
|
|
|
globalAvatarDetail = None
|
|
|
|
|
2015-04-23 12:55:47 -05:00
|
|
|
def showAvatarDetail(avId, avName):
|
2015-03-03 16:10:12 -06:00
|
|
|
global globalAvatarDetail
|
|
|
|
if globalAvatarDetail != None:
|
|
|
|
globalAvatarDetail.cleanup()
|
|
|
|
globalAvatarDetail = None
|
2015-04-23 12:55:47 -05:00
|
|
|
globalAvatarDetail = ToonAvatarDetailPanel(avId, avName)
|
2015-03-03 16:10:12 -06:00
|
|
|
|
|
|
|
|
|
|
|
def hideAvatarDetail():
|
|
|
|
global globalAvatarDetail
|
|
|
|
if globalAvatarDetail != None:
|
|
|
|
globalAvatarDetail.cleanup()
|
|
|
|
globalAvatarDetail = None
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def unloadAvatarDetail():
|
|
|
|
global globalAvatarDetail
|
|
|
|
if globalAvatarDetail != None:
|
|
|
|
globalAvatarDetail.cleanup()
|
|
|
|
globalAvatarDetail = None
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
class ToonAvatarDetailPanel(DirectFrame):
|
|
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('ToonAvatarDetailPanel')
|
|
|
|
|
2015-04-23 12:55:47 -05:00
|
|
|
def __init__(self, avId, avName, parent = base.a2dTopRight, **kw):
|
2015-03-03 16:10:12 -06:00
|
|
|
buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
|
|
|
|
gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui')
|
2015-08-17 07:55:43 -05:00
|
|
|
sosGui = loader.loadModel('phase_3.5/models/gui/playingCard')
|
2015-03-03 16:10:12 -06:00
|
|
|
detailPanel = gui.find('**/avatarInfoPanel')
|
|
|
|
textScale = 0.095
|
|
|
|
textWrap = 16.4
|
|
|
|
optiondefs = (('pos', (-0.79, 0.0, -0.47), None),
|
|
|
|
('scale', 0.5, None),
|
|
|
|
('relief', None, None),
|
|
|
|
('image', detailPanel, None),
|
|
|
|
('image_color', GlobalDialogColor, None),
|
|
|
|
('text', '', None),
|
|
|
|
('text_wordwrap', textWrap, None),
|
|
|
|
('text_scale', textScale, None),
|
|
|
|
('text_pos', (-0.125, 0.775), None))
|
|
|
|
self.defineoptions(kw, optiondefs)
|
|
|
|
DirectFrame.__init__(self, parent)
|
|
|
|
self.dataText = DirectLabel(self, text='', text_scale=0.09, text_align=TextNode.ALeft, text_wordwrap=15, relief=None, pos=(-0.85, 0.0, 0.645))
|
|
|
|
self.avId = avId
|
|
|
|
self.avName = avName
|
|
|
|
self.avatar = None
|
|
|
|
self.createdAvatar = None
|
|
|
|
self.fsm = ClassicFSM.ClassicFSM('ToonAvatarDetailPanel', [State.State('off', self.enterOff, self.exitOff, ['begin']),
|
|
|
|
State.State('begin', self.enterBegin, self.exitBegin, ['query', 'data', 'off']),
|
|
|
|
State.State('query', self.enterQuery, self.exitQuery, ['data', 'invalid', 'off']),
|
|
|
|
State.State('data', self.enterData, self.exitData, ['off']),
|
|
|
|
State.State('invalid', self.enterInvalid, self.exitInvalid, ['off'])], 'off', 'off')
|
|
|
|
ToonTeleportPanel.hideTeleportPanel()
|
|
|
|
FriendInviter.hideFriendInviter()
|
|
|
|
self.bCancel = DirectButton(self, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), image_scale=1.1, relief=None, text=TTLocalizer.AvatarDetailPanelCancel, text_scale=TTLocalizer.TADPbCancel, text_pos=(0.12, -0.01), pos=TTLocalizer.TADPbCancelPos, scale=2.0, command=self.__handleCancel)
|
|
|
|
self.bCancel.hide()
|
2015-08-17 07:55:43 -05:00
|
|
|
self.sosButton = DirectButton(self, relief=None, image=sosGui.find('**/card_back'), scale=0.05, pos=(0.3, 0, -0.76), text=('', TTLocalizer.DetailPanelSOS, TTLocalizer.DetailPanelSOS, ''), text_fg=(1, 1, 0.5, 1), text_shadow=(0, 0, 0, 1), text_scale=2, text_pos=(0, -3.4), text_align=TextNode.ACenter, state=DGG.NORMAL, command=self.__toggleSOSGui)
|
|
|
|
self.sosButton.hide()
|
|
|
|
self.sosFrame = DirectFrame(self, relief=None, image=DGG.getDefaultDialogGeom(), image_scale=(2.6, 1, 1.87), image_color=ToontownGlobals.GlobalDialogColor, pos=(0.2, 0, 0.8))
|
|
|
|
self.sosFrame.setBin('background', 10)
|
|
|
|
self.sosFrame.setScale(0.5)
|
|
|
|
self.sosPage = NPCFriendPanel.NPCFriendPanel(parent=self.sosFrame, callable=False)
|
|
|
|
self.sosPage.setScale(0.18)
|
|
|
|
self.sosPage.setPos(0, 0, 0.05)
|
2015-03-03 16:10:12 -06:00
|
|
|
self.initialiseoptions(ToonAvatarDetailPanel)
|
|
|
|
self.fsm.enterInitialState()
|
|
|
|
self.fsm.request('begin')
|
|
|
|
buttons.removeNode()
|
|
|
|
gui.removeNode()
|
2015-08-17 07:55:43 -05:00
|
|
|
sosGui.removeNode()
|
2015-03-03 16:10:12 -06:00
|
|
|
|
|
|
|
def cleanup(self):
|
|
|
|
if self.fsm:
|
|
|
|
self.fsm.request('off')
|
|
|
|
self.fsm = None
|
|
|
|
base.cr.cancelAvatarDetailsRequest(self.avatar)
|
|
|
|
if self.createdAvatar:
|
|
|
|
self.avatar.delete()
|
|
|
|
self.createdAvatar = None
|
|
|
|
self.destroy()
|
|
|
|
|
|
|
|
def enterOff(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def exitOff(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def enterBegin(self):
|
|
|
|
myId = base.localAvatar.doId
|
|
|
|
self['text'] = self.avName
|
|
|
|
if self.avId == myId:
|
|
|
|
self.avatar = base.localAvatar
|
|
|
|
self.createdAvatar = 0
|
|
|
|
self.fsm.request('data')
|
|
|
|
else:
|
|
|
|
self.fsm.request('query')
|
|
|
|
|
|
|
|
def exitBegin(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def enterQuery(self):
|
|
|
|
self.dataText['text'] = TTLocalizer.AvatarDetailPanelLookup % self.avName
|
2015-08-17 07:55:43 -05:00
|
|
|
self.sosButton.hide()
|
2015-03-03 16:10:12 -06:00
|
|
|
self.bCancel.show()
|
|
|
|
self.avatar = base.cr.doId2do.get(self.avId)
|
|
|
|
if self.avatar != None and not self.avatar.ghostMode:
|
|
|
|
self.createdAvatar = 0
|
|
|
|
else:
|
|
|
|
self.avatar = DistributedToon.DistributedToon(base.cr)
|
|
|
|
self.createdAvatar = 1
|
|
|
|
self.avatar.doId = self.avId
|
|
|
|
self.avatar.forceAllowDelayDelete()
|
|
|
|
base.cr.getAvatarDetails(self.avatar, self.__handleAvatarDetails, 'DistributedToon')
|
|
|
|
return
|
|
|
|
|
|
|
|
def exitQuery(self):
|
|
|
|
self.bCancel.hide()
|
|
|
|
|
|
|
|
def enterData(self):
|
|
|
|
self.bCancel['text'] = TTLocalizer.AvatarDetailPanelClose
|
|
|
|
self.bCancel.show()
|
|
|
|
self.__showData()
|
|
|
|
|
|
|
|
def exitData(self):
|
|
|
|
self.bCancel.hide()
|
|
|
|
|
|
|
|
def enterInvalid(self):
|
|
|
|
self.dataText['text'] = TTLocalizer.AvatarDetailPanelFailedLookup % self.avName
|
|
|
|
|
|
|
|
def exitInvalid(self):
|
|
|
|
self.bCancel.hide()
|
|
|
|
|
|
|
|
def __handleCancel(self):
|
|
|
|
unloadAvatarDetail()
|
|
|
|
|
|
|
|
def __handleAvatarDetails(self, gotData, avatar, dclass):
|
|
|
|
if not self.fsm or avatar != self.avatar:
|
|
|
|
self.notify.warning('Ignoring unexpected request for avatar %s' % avatar.doId)
|
|
|
|
return
|
|
|
|
if gotData:
|
|
|
|
self.fsm.request('data')
|
|
|
|
else:
|
|
|
|
self.fsm.request('invalid')
|
|
|
|
|
|
|
|
def __showData(self):
|
|
|
|
av = self.avatar
|
|
|
|
online = 1
|
|
|
|
if base.cr.isFriend(self.avId):
|
|
|
|
online = base.cr.isFriendOnline(self.avId)
|
2015-06-02 09:06:55 -05:00
|
|
|
identifier = int(str(self.avId)[1:])
|
|
|
|
|
2015-03-03 16:10:12 -06:00
|
|
|
if online:
|
|
|
|
shardName = base.cr.getShardName(av.defaultShard)
|
|
|
|
hoodName = base.cr.hoodMgr.getFullnameFromId(av.lastHood)
|
2015-06-02 09:06:55 -05:00
|
|
|
text = TTLocalizer.AvatarDetailPanelOnline % {'district': shardName, 'location': hoodName, 'identifier': identifier}
|
2015-03-03 16:10:12 -06:00
|
|
|
else:
|
2015-06-02 09:06:55 -05:00
|
|
|
text = TTLocalizer.AvatarDetailPanelOffline % {'identifier': identifier}
|
2015-03-03 16:10:12 -06:00
|
|
|
self.dataText['text'] = text
|
2015-08-17 07:55:43 -05:00
|
|
|
self.sosButton.show()
|
2015-07-10 14:25:09 -05:00
|
|
|
self.__addToonModel()
|
2015-03-03 16:10:12 -06:00
|
|
|
self.__updateTrackInfo()
|
|
|
|
self.__updateTrophyInfo()
|
|
|
|
self.__updateLaffInfo()
|
2015-08-17 07:55:43 -05:00
|
|
|
self.__updateSOSPage()
|
2015-03-03 16:10:12 -06:00
|
|
|
|
2015-07-10 14:25:09 -05:00
|
|
|
def __addToonModel(self):
|
|
|
|
toon = Toon.Toon()
|
|
|
|
toon.setDNA(self.avatar.style)
|
|
|
|
toon.reparentTo(self)
|
|
|
|
toon.setPos(0.45, 0, 0.3)
|
|
|
|
toon.setH(180)
|
|
|
|
toon.setScale(0.11)
|
|
|
|
toon.loop('neutral')
|
|
|
|
toon.setDepthWrite(True)
|
|
|
|
toon.setDepthTest(True)
|
|
|
|
|
2015-03-03 16:10:12 -06:00
|
|
|
def __updateLaffInfo(self):
|
|
|
|
avatar = self.avatar
|
|
|
|
messenger.send('updateLaffMeter', [avatar, avatar.hp, avatar.maxHp])
|
|
|
|
|
|
|
|
def __updateTrackInfo(self):
|
|
|
|
xOffset = -0.501814
|
|
|
|
xSpacing = 0.1835
|
|
|
|
yOffset = 0.1
|
|
|
|
ySpacing = -0.115
|
|
|
|
inventory = self.avatar.inventory
|
2015-08-17 07:55:43 -05:00
|
|
|
self.inventoryFrame = DirectFrame(parent=self, relief=None)
|
2015-03-03 16:10:12 -06:00
|
|
|
inventoryModels = loader.loadModel('phase_3.5/models/gui/inventory_gui')
|
2015-08-17 07:55:43 -05:00
|
|
|
rolloverFrame = DirectFrame(parent=self.inventoryFrame, relief=None, geom=DGG.getDefaultDialogGeom(), geom_color=(0, 0.5, 1, 1), geom_scale=(0.5, 0.3, 0.2), text_scale=0.05, text_pos=(0, 0.0125), text='', text_fg=(1, 1, 1, 1))
|
2015-08-03 19:18:12 -05:00
|
|
|
rolloverFrame.setBin('gui-popup', 0)
|
|
|
|
rolloverFrame.hide()
|
2015-03-03 16:10:12 -06:00
|
|
|
buttonModel = inventoryModels.find('**/InventoryButtonUp')
|
|
|
|
for track in xrange(0, len(Tracks)):
|
2015-08-17 07:55:43 -05:00
|
|
|
DirectLabel(parent=self.inventoryFrame, relief=None, text=TextEncoder.upper(TTLocalizer.BattleGlobalTracks[track]), text_scale=TTLocalizer.TADPtrackLabel, text_align=TextNode.ALeft, pos=(-0.9, 0, TTLocalizer.TADtrackLabelPosZ + track * ySpacing))
|
2015-03-03 16:10:12 -06:00
|
|
|
if self.avatar.hasTrackAccess(track):
|
|
|
|
curExp, nextExp = inventory.getCurAndNextExpValues(track)
|
|
|
|
for item in xrange(0, len(Levels[track])):
|
|
|
|
level = Levels[track][item]
|
|
|
|
if curExp >= level:
|
|
|
|
numItems = inventory.numItem(track, item)
|
2015-08-03 19:18:12 -05:00
|
|
|
organic = self.avatar.checkGagBonus(track, item)
|
2015-03-03 16:10:12 -06:00
|
|
|
if numItems == 0:
|
|
|
|
image_color = Vec4(0.5, 0.5, 0.5, 1)
|
|
|
|
geom_color = Vec4(0.2, 0.2, 0.2, 0.5)
|
2015-08-03 19:18:12 -05:00
|
|
|
elif organic:
|
2015-06-09 11:40:31 -05:00
|
|
|
image_color = Vec4(0, 0.8, 0.4, 1)
|
|
|
|
geom_color = None
|
2015-03-03 16:10:12 -06:00
|
|
|
else:
|
|
|
|
image_color = Vec4(0, 0.6, 1, 1)
|
|
|
|
geom_color = None
|
2015-08-03 19:18:12 -05:00
|
|
|
pos = (xOffset + item * xSpacing, 0, yOffset + track * ySpacing)
|
2015-08-17 07:55:43 -05:00
|
|
|
label = DirectLabel(parent=self.inventoryFrame, image=buttonModel, image_scale=(0.92, 1, 1), image_color=image_color, geom=inventory.invModels[track][item], geom_color=geom_color, geom_scale=0.6, relief=None, pos=pos, state=DGG.NORMAL)
|
2015-08-03 19:18:12 -05:00
|
|
|
label.bind(DGG.ENTER, self.showInfo, extraArgs=[rolloverFrame, track, int(getAvPropDamage(track, item, curExp, organic)), numItems, (pos[0] + 0.37, pos[1], pos[2])])
|
|
|
|
label.bind(DGG.EXIT, self.hideInfo, extraArgs=[rolloverFrame])
|
2015-03-03 16:10:12 -06:00
|
|
|
else:
|
|
|
|
break
|
2015-08-03 19:18:12 -05:00
|
|
|
|
|
|
|
def showInfo(self, frame, track, damage, numItems, pos, extra):
|
|
|
|
frame.setPos(*pos)
|
|
|
|
frame.show()
|
|
|
|
frame['text'] = TTLocalizer.GagPopup % (self.avatar.inventory.getToonupDmgStr(track, 0), damage, numItems)
|
2015-03-03 16:10:12 -06:00
|
|
|
|
2015-08-03 19:18:12 -05:00
|
|
|
def hideInfo(self, frame, extra):
|
|
|
|
frame.hide()
|
2015-03-03 16:10:12 -06:00
|
|
|
|
|
|
|
def __updateTrophyInfo(self):
|
|
|
|
if self.createdAvatar:
|
|
|
|
return
|
|
|
|
if self.avatar.trophyScore >= TrophyStarLevels[2]:
|
|
|
|
color = TrophyStarColors[2]
|
|
|
|
elif self.avatar.trophyScore >= TrophyStarLevels[1]:
|
|
|
|
color = TrophyStarColors[1]
|
|
|
|
elif self.avatar.trophyScore >= TrophyStarLevels[0]:
|
|
|
|
color = TrophyStarColors[0]
|
|
|
|
else:
|
|
|
|
color = None
|
|
|
|
if color:
|
|
|
|
gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui')
|
|
|
|
star = gui.find('**/avatarStar')
|
|
|
|
self.star = DirectLabel(parent=self, image=star, image_color=color, pos=(0.610165, 0, -0.760678), scale=0.9, relief=None)
|
|
|
|
gui.removeNode()
|
2015-08-17 07:55:43 -05:00
|
|
|
|
|
|
|
def __updateSOSPage(self):
|
|
|
|
self.sosPage.setFriends(self.avatar.NPCFriendsDict)
|
|
|
|
self.sosPage.update()
|
|
|
|
|
|
|
|
def __toggleSOSGui(self):
|
|
|
|
self.sosButton['state'] = DGG.DISABLED
|
|
|
|
|
|
|
|
if self.sosFrame.getScale() == 0.5:
|
|
|
|
pos = (-0.4, 0, -1.88)
|
|
|
|
scale = 1.0
|
|
|
|
else:
|
|
|
|
pos = (0, 0, 0.05)
|
|
|
|
scale = 0.5
|
2015-08-17 08:54:59 -05:00
|
|
|
self.sosFrame.setBin('background', 10)
|
2015-08-17 07:55:43 -05:00
|
|
|
|
|
|
|
Sequence(
|
|
|
|
Parallel(
|
|
|
|
self.sosFrame.posInterval(1.0, pos, blendType='easeOut'),
|
|
|
|
self.sosFrame.scaleInterval(1.0, scale, blendType='easeOut')
|
|
|
|
),
|
|
|
|
Func(self.__enableSOSButton)
|
|
|
|
).start()
|
|
|
|
|
|
|
|
def __enableSOSButton(self):
|
|
|
|
try:
|
|
|
|
self.sosButton['state'] = DGG.NORMAL
|
2015-08-17 08:54:59 -05:00
|
|
|
|
|
|
|
if self.sosFrame.getScale() == 1.0:
|
|
|
|
self.sosFrame.clearBin()
|
2015-08-17 07:55:43 -05:00
|
|
|
except:
|
|
|
|
pass
|