from direct.gui.DirectGui import * from panda3d.core import * from toontown.toonbase import ToontownGlobals from toontown.toontowngui import TTDialog from toontown.toonbase import TTLocalizer import CatalogItemTypes import CatalogItem from CatalogWallpaperItem import getAllWallpapers from CatalogFlooringItem import getAllFloorings from CatalogMouldingItem import getAllMouldings from CatalogWainscotingItem import getAllWainscotings from CatalogFurnitureItem import getAllFurnitures from otp.otpbase import OTPGlobals CATALOG_PANEL_WORDWRAP = 10 CATALOG_PANEL_CHAT_WORDWRAP = 9 CATALOG_PANEL_ACCESSORY_WORDWRAP = 11 class CatalogItemPanel(DirectFrame): notify = directNotify.newCategory('CatalogItemPanel') def __init__(self, parent = aspect2d, parentCatalogScreen = None, **kw): optiondefs = (('item', None, DGG.INITOPT), ('type', CatalogItem.CatalogTypeUnspecified, DGG.INITOPT), ('relief', None, None)) self.parentCatalogScreen = parentCatalogScreen self.defineoptions(kw, optiondefs) DirectFrame.__init__(self, parent) self.loaded = 0 self.initialiseoptions(CatalogItemPanel) return def load(self): if self.loaded: return self.loaded = 1 self.verify = None self.pictureFrame = self.attachNewNode('pictureFrame') self.pictureFrame.setScale(0.15) self.itemIndex = 0 self.ival = None typeCode = self['item'].getTypeCode() if self['item'].needsCustomize() and (typeCode == CatalogItemTypes.WALLPAPER_ITEM or typeCode == CatalogItemTypes.FLOORING_ITEM or typeCode == CatalogItemTypes.MOULDING_ITEM or typeCode == CatalogItemTypes.FURNITURE_ITEM or typeCode == CatalogItemTypes.WAINSCOTING_ITEM or typeCode == CatalogItemTypes.TOON_STATUE_ITEM): if typeCode == CatalogItemTypes.WALLPAPER_ITEM: self.items = getAllWallpapers(self['item'].patternIndex) elif typeCode == CatalogItemTypes.FLOORING_ITEM: self.items = getAllFloorings(self['item'].patternIndex) elif typeCode == CatalogItemTypes.MOULDING_ITEM: self.items = getAllMouldings(self['item'].patternIndex) elif typeCode == CatalogItemTypes.FURNITURE_ITEM: self.items = getAllFurnitures(self['item'].furnitureType) elif typeCode == CatalogItemTypes.TOON_STATUE_ITEM: self.items = self['item'].getAllToonStatues() elif typeCode == CatalogItemTypes.WAINSCOTING_ITEM: self.items = getAllWainscotings(self['item'].patternIndex) self.numItems = len(self.items) if self.numItems > 1: guiItems = loader.loadModel('phase_5.5/models/gui/catalog_gui') nextUp = guiItems.find('**/arrow_up') nextRollover = guiItems.find('**/arrow_Rollover') nextDown = guiItems.find('**/arrow_Down') prevUp = guiItems.find('**/arrowUp') prevDown = guiItems.find('**/arrowDown1') prevRollover = guiItems.find('**/arrowRollover') self.nextVariant = DirectButton(parent=self, relief=None, image=(nextUp, nextDown, nextRollover, nextUp), image3_color=(1, 1, 1, 0.4), pos=(0.13, 0, 0), command=self.showNextVariant) self.prevVariant = DirectButton(parent=self, relief=None, image=(prevUp, prevDown, prevRollover, prevUp), image3_color=(1, 1, 1, 0.4), pos=(-0.13, 0, 0), command=self.showPrevVariant, state=DGG.DISABLED) self.variantPictures = [(None, None)] * self.numItems else: self.variantPictures = [(None, None)] self.showCurrentVariant() else: picture, self.ival = self['item'].getPicture(base.localAvatar) if picture: picture.reparentTo(self) picture.setScale(0.15) self.items = [self['item']] self.variantPictures = [(picture, self.ival)] if self.ival: self.ival.loop() self.typeLabel = DirectLabel(parent=self, relief=None, pos=(0, 0, 0.24), scale=TTLocalizer.CIPtypeLabel, text=self['item'].getTypeName(), text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont(), text_wordwrap=CATALOG_PANEL_WORDWRAP) self.auxText = DirectLabel(parent=self, relief=None, scale=0.05, pos=(-0.2, 0, 0.16)) self.auxText.setHpr(0, 0, -30) self.nameLabel = DirectLabel(parent=self, relief=None, text=self['item'].getDisplayName(), text_fg=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont(), text_scale=TTLocalizer.CIPnameLabel, text_wordwrap=CATALOG_PANEL_WORDWRAP + TTLocalizer.CIPwordwrapOffset) if self['item'].getTypeCode() == CatalogItemTypes.CHAT_ITEM: self.nameLabel['text_wordwrap'] = CATALOG_PANEL_CHAT_WORDWRAP numRows = self.nameLabel.component('text0').textNode.getNumRows() if numRows == 1: namePos = (0, 0, -0.06) elif numRows == 2: namePos = (0, 0, -0.03) else: namePos = (0, 0, 0) nameScale = 0.063 elif self['item'].getTypeCode() == CatalogItemTypes.ACCESSORY_ITEM: self.nameLabel['text_wordwrap'] = CATALOG_PANEL_ACCESSORY_WORDWRAP namePos = (0, 0, -.22) nameScale = 0.06 else: namePos = (0, 0, -.22) nameScale = 0.06 self.nameLabel.setPos(*namePos) self.nameLabel.setScale(nameScale) numericBeanPrice = self['item'].getPrice(self['type']) priceStr = str(numericBeanPrice) + ' ' + TTLocalizer.CatalogCurrency priceScale = 0.07 if self['item'].isSaleItem(): priceStr = TTLocalizer.CatalogSaleItem + priceStr priceScale = 0.06 self.priceLabel = DirectLabel(parent=self, relief=None, pos=(0, 0, -0.3), scale=priceScale, text=priceStr, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ACenter) self.createEmblemPrices(numericBeanPrice) buttonModels = loader.loadModel('phase_3.5/models/gui/inventory_gui') upButton = buttonModels.find('**/InventoryButtonUp') downButton = buttonModels.find('**/InventoryButtonDown') rolloverButton = buttonModels.find('**/InventoryButtonRollover') buyText = TTLocalizer.CatalogBuyText buyTextScale = TTLocalizer.CIPbuyButton if self['item'].isRental(): buyText = TTLocalizer.CatalogRentText self.buyButton = DirectButton(parent=self, relief=None, pos=(0.2, 0, 0.15), scale=(0.7, 1, 0.8), text=buyText, text_scale=buyTextScale, text_pos=(-0.005, -0.01), image=(upButton, downButton, rolloverButton, upButton), image_color=(1.0, 0.2, 0.2, 1), image0_color=Vec4(1.0, 0.4, 0.4, 1), image3_color=Vec4(1.0, 0.4, 0.4, 0.4), command=self.__handlePurchaseRequest) soundIcons = loader.loadModel('phase_5.5/models/gui/catalogSoundIcons') soundOn = soundIcons.find('**/sound07') soundOff = soundIcons.find('**/sound08') self.soundOnButton = DirectButton(parent=self, relief=None, pos=(0.2, 0, -0.15), scale=(0.7, 1, 0.8), text_scale=buyTextScale, text_pos=(-0.005, -0.01), image=(upButton, downButton, rolloverButton, upButton), image_color=(0.2, 0.5, 0.2, 1), image0_color=Vec4(0.4, 0.5, 0.4, 1), image3_color=Vec4(0.4, 0.5, 0.4, 0.4), command=self.handleSoundOnButton) self.soundOnButton.hide() soundOn.setScale(0.1) soundOn.reparentTo(self.soundOnButton) self.soundOffButton = DirectButton(parent=self, relief=None, pos=(0.2, 0, -0.15), scale=(0.7, 1, 0.8), text_scale=buyTextScale, text_pos=(-0.005, -0.01), image=(upButton, downButton, rolloverButton, upButton), image_color=(0.2, 1.0, 0.2, 1), image0_color=Vec4(0.4, 1.0, 0.4, 1), image3_color=Vec4(0.4, 1.0, 0.4, 0.4), command=self.handleSoundOffButton) self.soundOffButton.hide() soundOff = self.soundOffButton.attachNewNode('soundOff') soundOn.copyTo(soundOff) soundOff.reparentTo(self.soundOffButton) upGButton = buttonModels.find('**/InventoryButtonUp') downGButton = buttonModels.find('**/InventoryButtonDown') rolloverGButton = buttonModels.find('**/InventoryButtonRollover') self.giftButton = DirectButton(parent=self, relief=None, pos=(0.2, 0, 0.15), scale=(0.7, 1, 0.8), text=TTLocalizer.CatalogGiftText, text_scale=buyTextScale, text_pos=(-0.005, -0.01), image=(upButton, downButton, rolloverButton, upButton), image_color=(1.0, 0.2, 0.2, 1), image0_color=Vec4(1.0, 0.4, 0.4, 1), image3_color=Vec4(1.0, 0.4, 0.4, 0.4), command=self.__handleGiftRequest) self.updateButtons() return def createEmblemPrices(self, numericBeanPrice): priceScale = 0.07 emblemPrices = self['item'].getEmblemPrices() if emblemPrices: if numericBeanPrice: self.priceLabel.hide() beanModel = loader.loadModel('phase_5.5/models/estate/jellyBean') beanModel.setColorScale(1, 0, 0, 1) self.beanPriceLabel = DirectLabel(parent=self, relief=None, pos=(0, 0, -0.3), scale=priceScale, image=beanModel, image_pos=(-0.4, 0, 0.4), text=str(numericBeanPrice), text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ALeft) else: self.priceLabel.hide() goldPrice = 0 silverPrice = 0 emblemIcon = loader.loadModel('phase_3.5/models/gui/tt_m_gui_gen_emblemIcons') silverModel = emblemIcon.find('**/tt_t_gui_gen_emblemSilver') goldModel = emblemIcon.find('**/tt_t_gui_gen_emblemGold') if ToontownGlobals.EmblemTypes.Silver < len(emblemPrices): silverPrice = emblemPrices[ToontownGlobals.EmblemTypes.Silver] if silverPrice: self.silverPriceLabel = DirectLabel(parent=self, relief=None, pos=(0, 0, -0.3), scale=priceScale, image=silverModel, image_pos=(-0.4, 0, 0.4), text=str(silverPrice), text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ALeft) if ToontownGlobals.EmblemTypes.Gold < len(emblemPrices): goldPrice = emblemPrices[ToontownGlobals.EmblemTypes.Gold] if goldPrice: self.goldPriceLabel = DirectLabel(parent=self, relief=None, pos=(0, 0, -0.3), scale=priceScale, image=goldModel, image_pos=(-0.4, 0, 0.4), text=str(goldPrice), text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ALeft) numPrices = 0 if numericBeanPrice: numPrices += 1 if silverPrice: numPrices += 1 if goldPrice: numPrices += 1 if numPrices == 2: if not numericBeanPrice: self.silverPriceLabel.setX(-0.15) self.goldPriceLabel.setX(0.15) if not silverPrice: self.goldPriceLabel.setX(-0.15) self.beanPriceLabel.setX(0.15) if not goldPrice: self.silverPriceLabel.setX(-0.15) self.beanPriceLabel.setX(0.15) elif numPrices == 3: self.silverPriceLabel.setX(-0.2) self.goldPriceLabel.setX(0) self.beanPriceLabel.setX(0.15) return def showNextVariant(self): messenger.send('wakeup') self.hideCurrentVariant() self.itemIndex += 1 if self.itemIndex >= self.numItems - 1: self.itemIndex = self.numItems - 1 self.nextVariant['state'] = DGG.DISABLED else: self.nextVariant['state'] = DGG.NORMAL self.prevVariant['state'] = DGG.NORMAL self.showCurrentVariant() def showPrevVariant(self): messenger.send('wakeup') self.hideCurrentVariant() self.itemIndex -= 1 if self.itemIndex < 0: self.itemIndex = 0 self.prevVariant['state'] = DGG.DISABLED else: self.prevVariant['state'] = DGG.NORMAL self.nextVariant['state'] = DGG.NORMAL self.showCurrentVariant() def showCurrentVariant(self): newPic, self.ival = self.variantPictures[self.itemIndex] if self.ival: self.ival.finish() if not newPic: variant = self.items[self.itemIndex] newPic, self.ival = variant.getPicture(base.localAvatar) self.variantPictures[self.itemIndex] = (newPic, self.ival) newPic.reparentTo(self.pictureFrame) if self.ival: self.ival.loop() if self['item'].getTypeCode() == CatalogItemTypes.TOON_STATUE_ITEM: if hasattr(self, 'nameLabel'): self.nameLabel['text'] = self.items[self.itemIndex].getDisplayName() self['item'].gardenIndex = self.items[self.itemIndex].gardenIndex def hideCurrentVariant(self): currentPic = self.variantPictures[self.itemIndex][0] if currentPic: currentPic.detachNode() def unload(self): if not self.loaded: DirectFrame.destroy(self) return self.loaded = 0 if self['item'].getTypeCode() == CatalogItemTypes.TOON_STATUE_ITEM: self['item'].deleteAllToonStatues() self['item'].gardenIndex = self['item'].startPoseIndex self.nameLabel['text'] = self['item'].getDisplayName() self['item'].requestPurchaseCleanup() for picture, ival in self.variantPictures: if picture: picture.destroy() if ival: ival.finish() self.variantPictures = None if self.ival: self.ival.finish() self.ival = None if len(self.items): self.items[0].cleanupPicture() self.pictureFrame.removeNode() self.pictureFrame = None self.items = [] if self.verify: self.verify.cleanup() DirectFrame.destroy(self) return def destroy(self): self.parentCatalogScreen = None self.unload() return def updateBuyButton(self): if not self.loaded: return self.buyButton.show() typeCode = self['item'].getTypeCode() orderCount = base.localAvatar.onOrder.count(self['item']) if orderCount > 0: if orderCount > 1: auxText = '%d %s' % (orderCount, TTLocalizer.CatalogOnOrderText) else: auxText = TTLocalizer.CatalogOnOrderText else: auxText = '' isNameTag = typeCode == CatalogItemTypes.NAMETAG_ITEM if isNameTag and self['item'].nametagStyle == base.localAvatar.getNametagStyle(): auxText = TTLocalizer.CatalogCurrent self.buyButton['state'] = DGG.DISABLED elif self['item'].reachedPurchaseLimit(base.localAvatar): max = self['item'].getPurchaseLimit() if max <= 1: auxText = TTLocalizer.CatalogPurchasedText if self['item'].hasBeenGifted(base.localAvatar): auxText = TTLocalizer.CatalogGiftedText else: auxText = TTLocalizer.CatalogPurchasedMaxText self.buyButton['state'] = DGG.DISABLED elif hasattr(self['item'], 'noGarden') and self['item'].noGarden(base.localAvatar): auxText = TTLocalizer.NoGarden self.buyButton['state'] = DGG.DISABLED elif hasattr(self['item'], 'isSkillTooLow') and self['item'].isSkillTooLow(base.localAvatar): auxText = TTLocalizer.SkillTooLow self.buyButton['state'] = DGG.DISABLED elif self['item'].getEmblemPrices() and not base.localAvatar.isEnoughMoneyAndEmblemsToBuy(self['item'].getPrice(self['type']), self['item'].getEmblemPrices()): self.buyButton['state'] = DGG.DISABLED elif hasattr(self['item'], 'houseId') and self['item'].houseId == localAvatar.houseType: auxText = TTLocalizer.CatalogPurchasedMaxText elif self['item'].getPrice(self['type']) <= base.localAvatar.getMoney() + base.localAvatar.getBankMoney(): self.buyButton['state'] = DGG.NORMAL self.buyButton.show() else: self.buyButton['state'] = DGG.DISABLED self.buyButton.show() self.auxText['text'] = auxText def __handlePurchaseRequest(self): if self['item'].replacesExisting() and self['item'].hasExisting(): message = TTLocalizer.CatalogOnlyOnePurchase % {'old': self['item'].getYourOldDesc(), 'item': self['item'].getName(), 'price': self['item'].getPrice(self['type'])} elif self['item'].isRental(): message = TTLocalizer.CatalogVerifyRent % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type'])} else: emblemPrices = self['item'].getEmblemPrices() if emblemPrices: silver = emblemPrices[ToontownGlobals.EmblemTypes.Silver] gold = emblemPrices[ToontownGlobals.EmblemTypes.Gold] price = self['item'].getPrice(self['type']) if price and silver and gold: message = TTLocalizer.CatalogVerifyPurchaseBeanSilverGold % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type']), 'silver': silver, 'gold': gold} elif price and silver: message = TTLocalizer.CatalogVerifyPurchaseBeanSilver % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type']), 'silver': silver, 'gold': gold} elif price and gold: message = TTLocalizer.CatalogVerifyPurchaseBeanGold % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type']), 'silver': silver, 'gold': gold} elif silver and gold: message = TTLocalizer.CatalogVerifyPurchaseSilverGold % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type']), 'silver': silver, 'gold': gold} elif silver: message = TTLocalizer.CatalogVerifyPurchaseSilver % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type']), 'silver': silver, 'gold': gold} elif gold: message = TTLocalizer.CatalogVerifyPurchaseGold % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type']), 'silver': silver, 'gold': gold} else: self.notify.warning('is this a completely free item %s?' % self['item'].getName()) message = TTLocalizer.CatalogVerifyPurchase % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type'])} else: message = TTLocalizer.CatalogVerifyPurchase % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type'])} self.verify = TTDialog.TTGlobalDialog(doneEvent='verifyDone', message=message, style=TTDialog.TwoChoice) self.verify.show() self.accept('verifyDone', self.__handleVerifyPurchase) def __handleVerifyPurchase(self): if base.config.GetBool('want-qa-regression', 0): self.notify.info('QA-REGRESSION: CATALOG: Order item') status = self.verify.doneStatus self.ignore('verifyDone') self.verify.cleanup() del self.verify self.verify = None if status == 'ok': item = self.items[self.itemIndex] messenger.send('CatalogItemPurchaseRequest', [item]) self.buyButton['state'] = DGG.DISABLED return def __handleGiftRequest(self): if self['item'].replacesExisting() and self['item'].hasExisting(): message = TTLocalizer.CatalogOnlyOnePurchase % {'old': self['item'].getYourOldDesc(), 'item': self['item'].getName(), 'price': self['item'].getPrice(self['type'])} else: message = TTLocalizer.CatalogVerifyGift % {'item': self['item'].getName(), 'price': self['item'].getPrice(self['type']), 'friend': self.parentCatalogScreen.friendName if self.parentCatalogScreen.friendName else TTLocalizer.CatalogGiftError} self.verify = TTDialog.TTGlobalDialog(doneEvent='verifyGiftDone', message=message, style=TTDialog.TwoChoice) self.verify.show() self.accept('verifyGiftDone', self.__handleVerifyGift) def __handleVerifyGift(self): if base.config.GetBool('want-qa-regression', 0): self.notify.info('QA-REGRESSION: CATALOG: Gift item') status = self.verify.doneStatus self.ignore('verifyGiftDone') self.verify.cleanup() del self.verify self.verify = None if status == 'ok': self.giftButton['state'] = DGG.DISABLED item = self.items[self.itemIndex] messenger.send('CatalogItemGiftPurchaseRequest', [item]) return def updateButtons(self, giftActivate = 0): if self.parentCatalogScreen.gifting == -1: self.updateBuyButton() if self.loaded: self.giftButton.hide() else: self.updateGiftButton(giftActivate) if self.loaded: self.buyButton.hide() def updateGiftButton(self, giftUpdate = 0): if not self.loaded: return self.giftButton.show() if giftUpdate == 0: return self.auxText['text'] = '' self.giftButton['state'] = DGG.DISABLED self.giftButton.show() if self['item'].isGift() <= 0: self.auxText['text'] = TTLocalizer.CatalogNotAGift return if not self.parentCatalogScreen.friend: return avatar = self.parentCatalogScreen.friend if self['item'].forBoysOnly() and avatar.getStyle().getGender() == 'f' or self['item'].forGirlsOnly() and avatar.getStyle().getGender() == 'm': self.auxText['text'] = TTLocalizer.CatalogNoFit elif self['item'].reachedPurchaseLimit(avatar): self.auxText['text'] = TTLocalizer.CatalogPurchasedGiftText elif len(avatar.mailboxContents) + len(avatar.onOrder) + len(avatar.onGiftOrder) + 1 >= ToontownGlobals.MaxMailboxContents: self.auxText['text'] = TTLocalizer.CatalogMailboxFull else: orderCount = avatar.onGiftOrder.count(self['item']) if orderCount: self.auxText['text'] = TTLocalizer.CatalogOnOrderText if orderCount == 1 else '%d %s' % (orderCount, TTLocalizer.CatalogOnOrderText) if self['item'].getPrice(self['type']) <= base.localAvatar.getMoney() + base.localAvatar.getBankMoney(): self.giftButton['state'] = DGG.NORMAL def handleSoundOnButton(self): item = self.items[self.itemIndex] self.soundOnButton.hide() self.soundOffButton.show() if hasattr(item, 'changeIval'): if self.ival: self.ival.finish() self.ival = None self.ival = item.changeIval(volume=1) self.ival.loop() return def handleSoundOffButton(self): item = self.items[self.itemIndex] self.soundOffButton.hide() self.soundOnButton.show() if hasattr(item, 'changeIval'): if self.ival: self.ival.finish() self.ival = None self.ival = item.changeIval(volume=0) self.ival.loop() return def lockItem(self): self.buyButton['state'] = DGG.DISABLED