from direct.gui.DirectGui import * from panda3d.core import * from toontown.toonbase.ToontownGlobals import * from toontown.toonbase.ToonBaseGlobal import * from direct.interval.IntervalGlobal import * from direct.distributed.ClockDelta import * from toontown.toonbase import ToontownGlobals from direct.showbase import DirectObject from toontown.toon import ToonDNA from direct.fsm import ClassicFSM, State, StateData import ClosetGUI from direct.task.Task import Task import ClosetGlobals import DistributedFurnitureItem from toontown.toonbase import TTLocalizer from toontown.catalog import CatalogFurnitureItem class DistributedCloset(DistributedFurnitureItem.DistributedFurnitureItem): notify = directNotify.newCategory('DistributedCloset') def __init__(self, cr): DistributedFurnitureItem.DistributedFurnitureItem.__init__(self, cr) self.notify.debug('__init__') self.lastAvId = 0 self.hasLocalAvatar = 0 self.lastTime = 0 self.av = None self.closetGUI = None self.closetModel = None self.closetSphere = None self.closetSphereNode = None self.closetSphereNodePath = None self.topList = [] self.botList = [] self.oldTopList = [] self.oldBotList = [] self.oldStyle = None self.button = None self.topTrashButton = None self.bottomTrashButton = None self.isLocalToon = None self.popupInfo = None self.isOwner = 0 self.ownerId = 0 self.customerId = 0 self.purchaseDoneEvent = '' self.swapEvent = '' self.locked = 0 self.gender = None self.topDeleted = 0 self.bottomDeleted = 0 self.closetTrack = None self.avMoveTrack = None self.scale = 1.0 self.fsm = ClassicFSM.ClassicFSM('Closet', [State.State('off', self.enterOff, self.exitOff, ['ready', 'open', 'closed']), State.State('ready', self.enterReady, self.exitReady, ['open', 'closed']), State.State('closed', self.enterClosed, self.exitClosed, ['open', 'off']), State.State('open', self.enterOpen, self.exitOpen, ['closed', 'off'])], 'off', 'off') self.fsm.enterInitialState() return def generate(self): DistributedFurnitureItem.DistributedFurnitureItem.generate(self) def announceGenerate(self): self.notify.debug('announceGenerate') DistributedFurnitureItem.DistributedFurnitureItem.announceGenerate(self) self.load() self.setupCollisionSphere() self.fsm.request('ready') def load(self): self.setTwoSided(1) lNode = self.find('**/door_rotate_L') lDoor = self.find('**/closetdoor_L') if lNode.isEmpty() or lDoor.isEmpty(): self.leftDoor = None else: lDoor.wrtReparentTo(lNode) self.leftDoor = lNode rNode = self.find('**/door_rotate_R') rDoor = self.find('**/closetdoor_R') if rNode.isEmpty() or rDoor.isEmpty(): self.rightDoor = None else: rDoor.wrtReparentTo(rNode) self.rightDoor = rNode if not lNode.isEmpty(): self.scale = lNode.getScale()[0] return def setupCollisionSphere(self): if self.ownerId: self.closetSphereEvent = self.uniqueName('closetSphere') self.closetSphereEnterEvent = 'enter' + self.closetSphereEvent self.closetSphere = CollisionSphere(0, 0, 0, self.scale * 2.125) self.closetSphere.setTangible(0) self.closetSphereNode = CollisionNode(self.closetSphereEvent) self.closetSphereNode.setIntoCollideMask(WallBitmask) self.closetSphereNode.addSolid(self.closetSphere) self.closetSphereNodePath = self.attachNewNode(self.closetSphereNode) def disable(self): self.notify.debug('disable') self.ignore(self.closetSphereEnterEvent) self.ignoreAll() taskMgr.remove(self.uniqueName('popupChangeClothesGUI')) taskMgr.remove(self.uniqueName('lerpCamera')) taskMgr.remove(self.uniqueName('lerpToon')) if self.closetTrack: self.closetTrack.finish() self.closetTrack = None if self.closetGUI: self.closetGUI.resetClothes(self.oldStyle) self.resetCloset() if self.hasLocalAvatar: self.freeAvatar() self.ignoreAll() DistributedFurnitureItem.DistributedFurnitureItem.disable(self) return def delete(self): self.notify.debug('delete') DistributedFurnitureItem.DistributedFurnitureItem.delete(self) if self.popupInfo: self.popupInfo.destroy() self.popupInfo = None if self.av: del self.av del self.gender del self.closetSphere del self.closetSphereNode del self.closetSphereNodePath del self.closetGUI del self.fsm return def enterOff(self): pass def exitOff(self): pass def enterReady(self): if self.ownerId: self.accept(self.closetSphereEnterEvent, self.handleEnterSphere) def exitReady(self): pass def enterOpen(self): if self.ownerId: self.ignore(self.closetSphereEnterEvent) self._openDoors() if self.customerId == base.localAvatar.doId: camera.wrtReparentTo(self) camera.posQuatInterval(1, (-7.58, -6.02, 6.9), (286.3, 336.8, 0), other=self, blendType='easeOut').start() camera.setPosHpr(self, -7.58, -6.02, 6.9, 286.3, 336.8, 0) if self.av: if self.avMoveTrack: self.avMoveTrack.finish() self.av.stopSmooth() self.avMoveTrack = Sequence(Parallel(Func(self.av.play, 'walk'), LerpPosHprInterval(nodePath=self.av, other=self, duration=1.0, pos=Vec3(1.67, -3.29, 0.025), hpr=Vec3(112, 0, 0), blendType='easeOut')), Func(self.av.loop, 'neutral'), Func(self.av.startSmooth)) self.avMoveTrack.start() def exitOpen(self): if self.ownerId: self._closeDoors() def enterClosed(self): if self.ownerId: self.accept(self.closetSphereEnterEvent, self.handleEnterSphere) def exitClosed(self): pass def handleEnterSphere(self, collEntry): if self.smoothStarted: return if base.localAvatar.doId == self.lastAvId and globalClock.getFrameTime() <= self.lastTime + 0.5: self.notify.info('Ignoring duplicate entry for avatar.') return if self.hasLocalAvatar: self.freeAvatar() self.notify.debug('Entering Closet Sphere....%s' % self.closetSphereEnterEvent) if self.cr.playGame.getPlace() == None: self.notify.info('Not opening closet before place is defined.') return self.ignore(self.closetSphereEnterEvent) if not self.locked: self.cr.playGame.getPlace().fsm.request('closet') self.accept('closetAsleep', self._handleCancel) self.sendUpdate('enterAvatar', []) self.hasLocalAvatar = 1 return def setState(self, mode, avId, ownerId, gender, topList, botList): self.notify.debug('setState, mode=%s, avId=%s, ownerId=%d' % (mode, avId, ownerId)) self.isOwner = avId == ownerId self.ownerGender = gender if mode == ClosetGlobals.CLOSED: self.fsm.request('closed') return elif mode == ClosetGlobals.OPEN: self.customerId = avId self.av = self.cr.doId2do.get(self.customerId, None) if self.av: if base.localAvatar.getDoId() == self.customerId: self.gender = self.av.style.gender self.topList = topList self.botList = botList self.oldTopList = self.topList[0:] self.oldBotList = self.botList[0:] self.printInfo() if not self.isOwner: self.__popupNotOwnerPanel() else: taskMgr.doMethodLater(0.5, self.popupChangeClothesGUI, self.uniqueName('popupChangeClothesGUI')) self.fsm.request('open') return def _revertGender(self): if self.gender: self.av.style.gender = self.gender self.av.loop('neutral') def popupChangeClothesGUI(self, task): self.notify.debug('popupChangeClothesGUI') self.purchaseDoneEvent = self.uniqueName('purchaseDone') self.swapEvent = self.uniqueName('swap') self.cancelEvent = self.uniqueName('cancel') self.accept(self.purchaseDoneEvent, self.__proceedToCheckout) self.accept(self.swapEvent, self.__handleSwap) self.accept(self.cancelEvent, self._handleCancel) self.deleteEvent = self.uniqueName('delete') if self.isOwner: self.accept(self.deleteEvent, self.__handleDelete) if not self.closetGUI: maxClothes = CatalogFurnitureItem.ClosetToClothes.get(self.item.furnitureType) self.closetGUI = ClosetGUI.ClosetGUI(self.isOwner, self.purchaseDoneEvent, self.cancelEvent, self.swapEvent, self.deleteEvent, self.topList, self.botList, maxClothes) self.closetGUI.load() if self.gender != self.ownerGender: self.closetGUI.setGender(self.ownerGender) self.closetGUI.enter(base.localAvatar) self.closetGUI.showButtons() style = self.av.getStyle() self.oldStyle = ToonDNA.ToonDNA() self.oldStyle.makeFromNetString(style.makeNetString()) return Task.done def resetCloset(self): self.ignoreAll() taskMgr.remove(self.uniqueName('popupChangeClothesGUI')) taskMgr.remove(self.uniqueName('lerpCamera')) taskMgr.remove(self.uniqueName('lerpToon')) if self.closetGUI: self.closetGUI.hideButtons() self.closetGUI.exit() self.closetGUI.unload() self.closetGUI = None del self.av self.av = base.localAvatar style = self.av.getStyle() self.oldStyle = ToonDNA.ToonDNA() self.oldStyle.makeFromNetString(style.makeNetString()) self.topDeleted = 0 self.bottomDeleted = 0 return Task.done def __handleButton(self): messenger.send('next') def _handleCancel(self): if self.oldStyle: self.d_setDNA(self.oldStyle.makeNetString(), 1) else: self.notify.info('avoided crash in handleCancel') self._handlePurchaseDone() if self.closetGUI: self.closetGUI.resetClothes(self.oldStyle) if self.popupInfo != None: self.popupInfo.destroy() self.popupInfo = None return def __handleSwap(self): self.d_setDNA(self.av.getStyle().makeNetString(), 0) def __handleDelete(self, t_or_b): if t_or_b == ClosetGlobals.SHIRT: itemList = self.closetGUI.tops trashIndex = self.closetGUI.topChoice swapFunc = self.closetGUI.swapTop removeFunc = self.closetGUI.removeTop self.topDeleted = self.topDeleted | 1 def setItemChoice(i): self.closetGUI.topChoice = i else: itemList = self.closetGUI.bottoms trashIndex = self.closetGUI.bottomChoice swapFunc = self.closetGUI.swapBottom removeFunc = self.closetGUI.removeBottom self.bottomDeleted = self.bottomDeleted | 1 def setItemChoice(i): self.closetGUI.bottomChoice = i if len(itemList) > 1: trashDNA = ToonDNA.ToonDNA() trashItem = self.av.getStyle().makeNetString() trashDNA.makeFromNetString(trashItem) if trashIndex == 0: swapFunc(1) else: swapFunc(-1) removeFunc(trashIndex) self.sendUpdate('removeItem', [trashItem, t_or_b]) swapFunc(0) self.closetGUI.updateTrashButtons() else: self.notify.warning("cant delete this item(type = %s), since we don't have a replacement" % t_or_b) def __proceedToCheckout(self): if self.topDeleted or self.bottomDeleted: self.__popupAreYouSurePanel() else: self._handlePurchaseDone() def _handlePurchaseDone(self, timeout = 0): if timeout == 1: self.d_setDNA(self.oldStyle.makeNetString(), 1) else: which = 0 if hasattr(self.closetGUI, 'topChoice') and hasattr(self.closetGUI, 'bottomChoice'): if self.closetGUI.topChoice != 0 or self.topDeleted: which = which | 1 if self.closetGUI.bottomChoice != 0 or self.bottomDeleted: which = which | 2 self.d_setDNA(self.av.getStyle().makeNetString(), 2, which) def d_setDNA(self, dnaString, finished, whichItems = 3): self.sendUpdate('setDNA', [dnaString, finished, whichItems]) def setCustomerDNA(self, avId, dnaString): if avId and avId != base.localAvatar.doId: av = base.cr.doId2do.get(avId, None) if av: if self.av == base.cr.doId2do[avId]: oldTorso = self.av.style.torso self.av.style.makeFromNetString(dnaString) if len(oldTorso) == 2 and len(self.av.style.torso) == 2 and self.av.style.torso[1] != oldTorso[1]: self.av.swapToonTorso(self.av.style.torso, genClothes=0) self.av.loop('neutral', 0) self.av.generateToonClothes() def printInfo(self): print 'avid: %s, gender: %s' % (self.av.doId, self.av.style.gender) print 'current top = %s,%s,%s,%s and bot = %s,%s,' % (self.av.style.topTex, self.av.style.topTexColor, self.av.style.sleeveTex, self.av.style.sleeveTexColor, self.av.style.botTex, self.av.style.botTexColor) print 'topsList = %s' % self.av.getClothesTopsList() print 'bottomsList = %s' % self.av.getClothesBottomsList() def setMovie(self, mode, avId, timestamp): self.isLocalToon = avId == base.localAvatar.doId if avId != 0: self.lastAvId = avId self.lastTime = globalClock.getFrameTime() if mode == ClosetGlobals.CLOSET_MOVIE_CLEAR: return elif mode == ClosetGlobals.CLOSET_MOVIE_COMPLETE: if self.isLocalToon: self._revertGender() self.printInfo() self.resetCloset() self.freeAvatar() return elif mode == ClosetGlobals.CLOSET_MOVIE_TIMEOUT: taskMgr.remove(self.uniqueName('lerpCamera')) taskMgr.remove(self.uniqueName('lerpToon')) if self.isLocalToon: self.ignore(self.purchaseDoneEvent) self.ignore(self.swapEvent) if self.closetGUI: self.closetGUI.resetClothes(self.oldStyle) self._handlePurchaseDone(timeout=1) self.resetCloset() self._popupTimeoutPanel() self.freeAvatar() def freeAvatar(self): self.notify.debug('freeAvatar()') if self.hasLocalAvatar: base.localAvatar.posCamera(0, 0) place = base.cr.playGame.getPlace() if place: place.setState('walk') self.ignore('closetAsleep') base.localAvatar.startLookAround() self.hasLocalAvatar = 0 self.lastTime = globalClock.getFrameTime() def setOwnerId(self, avId): self.ownerId = avId def _popupTimeoutPanel(self): if self.popupInfo != None: self.popupInfo.destroy() self.popupInfo = None buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui') okButtonImage = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')) self.popupInfo = DirectFrame(parent=hidden, relief=None, state='normal', text=TTLocalizer.ClosetTimeoutMessage, frameSize=(-1, 1, -1, 1), geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(0.88, 1, 0.45), geom_pos=(0, 0, -.08), text_scale=0.08) DirectButton(self.popupInfo, image=okButtonImage, relief=None, text=TTLocalizer.ClosetPopupOK, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(0.0, 0.0, -0.16), command=self.__handleTimeoutMessageOK) buttons.removeNode() self.popupInfo.reparentTo(aspect2d) def __handleTimeoutMessageOK(self): self.popupInfo.reparentTo(hidden) def __popupNotOwnerPanel(self): if self.popupInfo != None: self.popupInfo.destroy() self.popupInfo = None self.purchaseDoneEvent = self.uniqueName('purchaseDone') self.swapEvent = self.uniqueName('swap') self.cancelEvent = self.uniqueName('cancel') self.accept(self.purchaseDoneEvent, self.__proceedToCheckout) self.accept(self.swapEvent, self.__handleSwap) self.accept(self.cancelEvent, self._handleCancel) self.deleteEvent = self.uniqueName('delete') if self.isOwner: self.accept(self.deleteEvent, self.__handleDelete) buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui') okButtonImage = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')) self.popupInfo = DirectFrame(parent=hidden, relief=None, state='normal', text=TTLocalizer.ClosetNotOwnerMessage, frameSize=(-1, 1, -1, 1), text_wordwrap=10, geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(0.88, 1, 0.55), geom_pos=(0, 0, -.08), text_scale=0.08, text_pos=(0, 0.06)) DirectButton(self.popupInfo, image=okButtonImage, relief=None, text=TTLocalizer.ClosetPopupOK, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(0.0, 0.0, -0.21), command=self._handleNotOwnerMessageOK) buttons.removeNode() self.popupInfo.reparentTo(aspect2d) return def _handleNotOwnerMessageOK(self): self.popupInfo.reparentTo(hidden) taskMgr.doMethodLater(0.1, self.popupChangeClothesGUI, self.uniqueName('popupChangeClothesGUI')) def __popupAreYouSurePanel(self): if self.popupInfo != None: self.popupInfo.destroy() self.popupInfo = None buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui') okButtonImage = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')) cancelButtonImage = (buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')) self.popupInfo = DirectFrame(parent=hidden, relief=None, state='normal', text=TTLocalizer.ClosetAreYouSureMessage, frameSize=(-1, 1, -1, 1), text_wordwrap=10, geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(0.88, 1, 0.55), geom_pos=(0, 0, -.08), text_scale=0.08, text_pos=(0, 0.08)) DirectButton(self.popupInfo, image=okButtonImage, relief=None, text=TTLocalizer.ClosetPopupOK, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(-0.1, 0.0, -0.21), command=self._handleYesImSure) DirectButton(self.popupInfo, image=cancelButtonImage, relief=None, text=TTLocalizer.ClosetPopupCancel, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(0.1, 0.0, -0.21), command=self._handleNotSure) buttons.removeNode() self.popupInfo.reparentTo(aspect2d) return def _handleYesImSure(self): self.popupInfo.reparentTo(hidden) self._handlePurchaseDone() def _handleNotSure(self): self.popupInfo.reparentTo(hidden) def _openDoors(self): if self.closetTrack: self.closetTrack.finish() leftHpr = Vec3(-110, 0, 0) rightHpr = Vec3(110, 0, 0) self.closetTrack = Parallel() if self.rightDoor: self.closetTrack.append(self.rightDoor.hprInterval(0.5, rightHpr)) if self.leftDoor: self.closetTrack.append(self.leftDoor.hprInterval(0.5, leftHpr)) self.closetTrack.start() def _closeDoors(self): if self.closetTrack: self.closetTrack.finish() leftHpr = Vec3(0, 0, 0) rightHpr = Vec3(0, 0, 0) self.closetTrack = Parallel() if self.rightDoor: self.closetTrack.append(self.rightDoor.hprInterval(0.5, rightHpr)) if self.leftDoor: self.closetTrack.append(self.leftDoor.hprInterval(0.5, leftHpr)) self.closetTrack.start()