toontown-just-works/toontown/pets/PetAvatarPanel.py
2024-07-07 18:08:39 -05:00

302 lines
15 KiB
Python

from panda3d.core import *
from direct.directnotify.DirectNotifyGlobal import *
from direct.gui.DirectGui import *
from direct.showbase import DirectObject
from direct.showbase.PythonUtil import Functor
from direct.task.Task import Task
from direct.distributed import DistributedObject
from otp.avatar import Avatar, AvatarPanel
from toontown.toon import ToonHead
from toontown.toon import LaffMeter
from toontown.toon import ToonAvatarDetailPanel
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from toontown.pets import Pet, PetConstants, PetDetailPanel
class PetAvatarPanel(AvatarPanel.AvatarPanel):
notify = directNotify.newCategory('PetAvatarPanel')
def __init__(self, avatar):
self.notify.debug('Init(): doId=%s' % avatar.doId)
distPet = base.cr.doId2do.get(avatar.doId)
if distPet and not distPet.isProxy():
self.avatar = distPet
self.petIsLocal = True
else:
self.avatar = avatar
self.petIsLocal = False
from toontown.friends import FriendsListPanel
AvatarPanel.AvatarPanel.__init__(self, self.avatar, FriendsListPanel=FriendsListPanel)
base.localAvatar.obscureFriendsListButton(1)
base.panel = self
gui = loader.loadModel('phase_3.5/models/gui/PetControlPannel')
guiScale = 0.116
guiPos = (-0.213, 0, -0.70)
self.frame = DirectFrame(parent=base.a2dTopRight, image=gui, scale=guiScale, pos=guiPos, relief=None)
disabledImageColor = Vec4(0.6, 0.6, 0.6, 1)
text0Color = Vec4(1, 1, 1, 1)
text1Color = Vec4(0.5, 1, 0.5, 1)
text2Color = Vec4(1, 1, 0.5, 1)
text3Color = Vec4(0.6, 0.6, 0.6, 1)
self.closeButton = DirectButton(parent=self.frame, image=(gui.find('**/CancelButtonUp'), gui.find('**/CancelButtonDown'), gui.find('**/CancelButtonRollover')), relief=None, command=self.__handleClose)
self.feedButton = DirectButton(parent=self.frame, image=(gui.find('**/ButtonFeedUp'),
gui.find('**/ButtonFeedDown'),
gui.find('**/ButtonFeedRollover'),
gui.find('**/ButtonFeedUp')), geom=gui.find('**/PetControlFeedIcon'), geom3_color=disabledImageColor, image3_color=disabledImageColor, relief=None, text=TTLocalizer.PetPanelFeed, text_scale=TTLocalizer.PAPfeedButton, text0_fg=text0Color, text1_fg=text1Color, text2_fg=text2Color, text3_fg=text3Color, text_pos=(-0.5, 2.8), text_align=TextNode.ALeft, command=self.__handleFeed)
if not self.petIsLocal:
self.feedButton['state'] = DGG.DISABLED
else:
self.feedButton['state'] = self.feedButtonState()
self.callButton = DirectButton(parent=self.frame, image=(gui.find('**/ButtonGoToUp'),
gui.find('**/ButtonGoToDown'),
gui.find('**/ButtonGoToRollover'),
gui.find('**/ButtonGoToUp')), geom=gui.find('**/PetControlGoToIcon'), geom3_color=disabledImageColor, image3_color=disabledImageColor, relief=None, text=TTLocalizer.PetPanelCall, text0_fg=text0Color, text1_fg=text1Color, text2_fg=text2Color, text3_fg=text3Color, text_scale=TTLocalizer.PAPcallButton, text_pos=(-0.5, 1.3), text_align=TextNode.ALeft, command=self.__handleCall)
if not self.petIsLocal:
self.callButton['state'] = DGG.DISABLED
self.scratchButton = DirectButton(parent=self.frame, image=(gui.find('**/ButtonScratchUp'),
gui.find('**/ButtonScratchDown'),
gui.find('**/ButtonScratchRollover'),
gui.find('**/ButtonScratchUp')), geom=gui.find('**/PetControlScratchIcon'), geom3_color=disabledImageColor, image3_color=disabledImageColor, relief=None, text=TTLocalizer.PetPanelScratch, text0_fg=text0Color, text1_fg=text1Color, text2_fg=text2Color, text3_fg=text3Color, text_scale=TTLocalizer.PAPscratchButton, text_pos=(-0.5, 2.05), text_align=TextNode.ALeft, command=self.__handleScratch)
if not self.petIsLocal:
self.scratchButton['state'] = DGG.DISABLED
self.ownerButton = DirectButton(parent=self.frame, image=(gui.find('**/PetControlToonButtonUp'), gui.find('**/PetControlToonButtonDown'), gui.find('**/PetControlToonButtonRollover')), geom=gui.find('**/PetControlToonIcon'), geom3_color=disabledImageColor, relief=None, image3_color=disabledImageColor, text=('',
TTLocalizer.PetPanelOwner,
TTLocalizer.PetPanelOwner,
''), text_fg=text2Color, text_shadow=(0, 0, 0, 1), text_scale=TTLocalizer.PAPownerButton, text_pos=(0.3, 1.05), text_align=TextNode.ACenter, command=self.__handleToOwner)
if self.avatar.getOwnerId() == base.localAvatar.doId:
self.ownerButton['state'] = DGG.DISABLED
toonGui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui')
self.detailButton = DirectButton(parent=self.frame, image=(toonGui.find('**/ChtBx_BackBtn_UP'),
toonGui.find('**/ChtBx_BackBtn_DN'),
toonGui.find('**/ChtBx_BackBtn_Rllvr'),
toonGui.find('**/ChtBx_BackBtn_UP')), relief=None, pos=(-1.3, 0, 0.67), image3_color=disabledImageColor, text=('',
TTLocalizer.PetPanelDetail,
TTLocalizer.PetPanelDetail,
''), text_fg=text2Color, text_shadow=(0, 0, 0, 1), text_scale=0.05, text_pos=(0.05, 0.05), text_align=TextNode.ACenter, command=self.__handleDetail)
self.detailButton.setScale(7.5)
if not self.petIsLocal:
self.detailButton['state'] = DGG.DISABLED
gui.removeNode()
toonGui.removeNode()
self.petDetailPanel = None
self.__fillPetInfo(self.avatar)
self.accept('petNameChanged', self.__refreshPetInfo)
self.accept('petStateUpdated', self.__refreshPetInfo)
self.frame.show()
if self.petIsLocal:
proxTask = Task.loop(Task(self.__checkPetProximity), Task.pause(0.5))
taskMgr.add(proxTask, 'petpanel-proximity-check', priority=ToontownGlobals.PetPanelProximityPriority)
if base.localAvatar.isLockedDown():
self.disableInteractionButtons()
if self.petIsLocal:
self.listenForInteractionDone()
messenger.send('petPanelDone')
if not self.petIsLocal and hasattr(self.avatar, 'updateMoodFromServer'):
if self.avatar.doId != localAvatar.getPetId() or bboard.get(PetConstants.OurPetsMoodChangedKey, False):
self.stateLabel['text'] = ''
def refresh(self = self, av = self.avatar):
bboard.remove(PetConstants.OurPetsMoodChangedKey)
self.__refreshPetInfo(av)
self.avatar.updateMoodFromServer(refresh)
return
def __checkPetProximity(self, task = None):
if self.petIsLocal:
if base.localAvatar.isInWater():
self.scratchButton['state'] = DGG.DISABLED
self.feedButton['state'] = DGG.DISABLED
self.callButton['state'] = DGG.DISABLED
self.notify.debug('local avatar is in water')
else:
petPos = self.avatar.getPos()
toonPos = base.localAvatar.getPos()
diff = Vec3(petPos - toonPos)
distance = diff.length()
self.notify.debug('pet distance is %s' % distance)
if distance > 20.0:
self.scratchButton['state'] = DGG.DISABLED
self.feedButton['state'] = DGG.DISABLED
else:
tooVert = abs(diff[2]) > 5.0
if tooVert:
self.scratchButton['state'] = DGG.DISABLED
else:
self.scratchButton['state'] = DGG.NORMAL
self.feedButton['state'] = self.feedButtonState()
self.callButton['state'] = DGG.NORMAL
return Task.done
def enableInteractionButtons(self):
self.notify.debug('enable buttons')
proxTask = Task.loop(Task(self.__checkPetProximity), Task.pause(0.5))
taskMgr.add(proxTask, 'petpanel-proximity-check', priority=ToontownGlobals.PetPanelProximityPriority)
self.__checkPetProximity()
def disableInteractionButtons(self):
self.notify.debug('disable buttons')
taskMgr.remove('petpanel-proximity-check')
self.scratchButton['state'] = DGG.DISABLED
self.feedButton['state'] = DGG.DISABLED
self.callButton['state'] = DGG.DISABLED
def listenForInteractionDone(self):
self.accept('pet-interaction-done', self.enableInteractionButtons)
def cancelListenForInteractionDone(self):
self.ignore('pet-interaction-done')
def feedButtonState(self):
if base.localAvatar.getMoney() >= PetConstants.FEED_AMOUNT:
return DGG.NORMAL
else:
return DGG.DISABLED
def cleanup(self):
self.notify.debug('cleanup(): doId=%s' % self.avatar.doId)
if self.frame == None:
return
self.cancelListenForInteractionDone()
taskMgr.remove('petpanel-proximity-check')
if hasattr(self, 'toonDetail'):
del self.toonDetail
self.frame.destroy()
del self.frame
self.frame = None
self.petView.removeNode()
del self.petView
self.petModel.delete()
del self.petModel
base.localAvatar.obscureFriendsListButton(-1)
self.ignore('petStateUpdated')
self.ignore('petNameChanged')
if self.avatar.bFake:
self.avatar.disable()
self.avatar.delete()
AvatarPanel.AvatarPanel.cleanup(self)
base.panel = None
return
def disableAll(self):
self.disableInteractionButtons()
self.ownerButton['state'] = DGG.DISABLED
self.closeButton['state'] = DGG.DISABLED
self.detailButton['state'] = DGG.DISABLED
def __handleDetailDone(self):
if self.petDetailPanel != None:
self.petDetailPanel.cleanup()
self.petDetailPanel = None
self.detailButton['state'] = DGG.NORMAL
return
def __handleDetail(self):
self.petDetailPanel = PetDetailPanel.PetDetailPanel(pet=self.avatar, closeCallback=self.__handleDetailDone, parent=self.frame)
self.detailButton['state'] = DGG.DISABLED
def __handleToOwner(self):
self.notify.debug('__handleToOwner(): doId=%s' % self.avatar.doId)
handle = base.cr.identifyFriend(self.avatar.ownerId)
if handle != None:
self.cleanup()
messenger.send('clickedNametag', [handle])
else:
self.disableAll()
from toontown.toon import ToonDetail
self.toonDetail = ToonDetail.ToonDetail(self.avatar.ownerId, self.__ownerDetailsLoaded)
return
def __ownerDetailsLoaded(self, avatar):
self.notify.debug('__ownerDetailsLoaded(): doId=%s' % self.avatar.doId)
self.cleanup()
if avatar is not None:
messenger.send('clickedNametag', [avatar])
return
def __handleCall(self):
if base.config.GetBool('want-qa-regression', 0):
self.notify.info('QA-REGRESSION: PET: Call')
self.notify.debug('__handleCall(): doId=%s' % self.avatar.doId)
base.localAvatar.b_setPetMovie(self.avId, PetConstants.PET_MOVIE_CALL)
base.panel.disableInteractionButtons()
if self.avatar.trickIval is not None and self.avatar.trickIval.isPlaying():
self.avatar.trickIval.finish()
base.cr.playGame.getPlace().setState('pet')
base.localAvatar.lock()
return
def __handleFeed(self):
if base.config.GetBool('want-qa-regression', 0):
self.notify.info('QA-REGRESSION: PET: Feed')
self.notify.debug('__handleFeed(): doId=%s' % self.avatar.doId)
base.localAvatar.b_setPetMovie(self.avId, PetConstants.PET_MOVIE_FEED)
base.panel.disableInteractionButtons()
if self.avatar.trickIval is not None and self.avatar.trickIval.isPlaying():
self.avatar.trickIval.finish()
base.cr.playGame.getPlace().setState('pet')
base.localAvatar.lock()
return
def __handleScratch(self):
if base.config.GetBool('want-qa-regression', 1):
self.notify.info('QA-REGRESSION: PET: Scratch')
self.notify.debug('__handleScratch(): doId=%s' % self.avatar.doId)
base.localAvatar.b_setPetMovie(self.avId, PetConstants.PET_MOVIE_SCRATCH)
base.panel.disableInteractionButtons()
if self.avatar.trickIval is not None and self.avatar.trickIval.isPlaying():
self.avatar.trickIval.finish()
base.cr.playGame.getPlace().setState('pet')
base.localAvatar.lock()
return
def __handleDisableAvatar(self):
self.notify.debug('__handleDisableAvatar(): doId=%s' % self.avatar.doId)
self.cleanup()
AvatarPanel.currentAvatarPanel = None
return
def __handleGenerateAvatar(self, avatar):
pass
def __handleClose(self):
self.notify.debug('__handleClose(): doId=%s' % self.avatar.doId)
self.cleanup()
AvatarPanel.currentAvatarPanel = None
if self.friendsListShown:
self.FriendsListPanel.showFriendsList()
return
def __fillPetInfo(self, avatar):
self.notify.debug('__fillPetInfo(): doId=%s' % avatar.doId)
self.petView = self.frame.attachNewNode('petView')
self.petView.setPos(0, 0, 5)
if hasattr(avatar, 'announceGenerate'):
avatar.announceGenerate()
self.petModel = Pet.Pet(forGui=1)
self.petModel.setDNA(avatar.getDNA())
self.petModel.fitAndCenterHead(3.575, forGui=1)
self.petModel.reparentTo(self.petView)
self.petModel.enterNeutralHappy()
self.petModel.startBlink()
self.petModel.setScale(0.75)
self.nameLabel = DirectLabel(parent=self.frame, pos=(0, 0, 5.2), relief=None, text=avatar.getName(), text_font=avatar.getFont(), text_fg=Vec4(0, 0, 0, 1), text_pos=(0, 0), text_scale=0.4, text_wordwrap=7.5, text_shadow=(1, 1, 1, 1))
self.stateLabel = DirectLabel(parent=self.frame, pos=TTLocalizer.PAPstateLabelPos, relief=None, text='', text_font=avatar.getFont(), text_fg=Vec4(0, 0, 0, 1), text_scale=TTLocalizer.PAPstateLabel, text_wordwrap=TTLocalizer.PAPstateLabelWordwrap, text_shadow=(1, 1, 1, 1))
self.__refreshPetInfo(avatar)
return
def __refreshPetInfo(self, avatar):
self.notify.debug('__refreshPetInfo(): doId=%s' % avatar.doId)
if avatar.doId != self.avatar.doId:
self.notify.warning('avatar not self!')
return
if self.frame == None:
return
if not self.petIsLocal:
self.avatar.updateOfflineMood()
mood = self.avatar.getDominantMood()
self.stateLabel['text'] = TTLocalizer.PetMoodAdjectives[mood]
self.nameLabel['text'] = avatar.getName()
if self.petDetailPanel != None:
self.petDetailPanel.update(avatar)
return