From 4e8fb45531b753a5b4e5def54a4e0f050546083a Mon Sep 17 00:00:00 2001 From: Loudrob Date: Sun, 12 Jul 2015 15:42:55 -0400 Subject: [PATCH] Current progress on gifting. --- dependencies/config/release/dev.prc | 1 + toontown/catalog/CatalogItem.py | 4 +- toontown/catalog/CatalogManagerUD.py | 43 +++ toontown/catalog/CatalogScreen.py | 2 + toontown/estate/DistributedPhoneAI.py | 305 +++++++++++++-------- toontown/toon/DistributedToonAI.py | 11 +- toontown/uberdog/ToontownUberRepository.py | 4 + toontown/uberdog/TopToonsGlobals.py | 15 + 8 files changed, 266 insertions(+), 119 deletions(-) create mode 100644 toontown/catalog/CatalogManagerUD.py create mode 100644 toontown/uberdog/TopToonsGlobals.py diff --git a/dependencies/config/release/dev.prc b/dependencies/config/release/dev.prc index 03c7bf6e..4bf0134a 100644 --- a/dependencies/config/release/dev.prc +++ b/dependencies/config/release/dev.prc @@ -29,6 +29,7 @@ want-find-four #t want-chinese-checkers #t want-checkers #t want-house-types #t +want-gifting #t # Chat: want-whitelist #t diff --git a/toontown/catalog/CatalogItem.py b/toontown/catalog/CatalogItem.py index 58c91f4d..a54abc36 100755 --- a/toontown/catalog/CatalogItem.py +++ b/toontown/catalog/CatalogItem.py @@ -287,7 +287,7 @@ class CatalogItem: p, r) if store & GiftTag: - self.giftTag = di.getString() + self.giftTag = di.getUint32() self.specialEventId = di.getUint8() def encodeDatagram(self, dg, store): @@ -301,7 +301,7 @@ class CatalogItem: dg.putArg(self.posHpr[4], STInt8, 256.0 / 360.0) dg.putArg(self.posHpr[5], STInt8, 256.0 / 360.0) if store & GiftTag: - dg.addString(self.giftTag) + dg.addUint32(self.giftTag) dg.addUint8(self.specialEventId) def getTypeCode(self): diff --git a/toontown/catalog/CatalogManagerUD.py b/toontown/catalog/CatalogManagerUD.py new file mode 100644 index 00000000..aec62c1b --- /dev/null +++ b/toontown/catalog/CatalogManagerUD.py @@ -0,0 +1,43 @@ +from direct.directnotify import DirectNotifyGlobal +from direct.showbase.DirectObject import DirectObject + +from toontown.catalog import CatalogItem, CatalogItemList + +class CatalogManagerUD(DirectObject): + notify = DirectNotifyGlobal.directNotify.newCategory('CatalogManagerUD') + TIMEOUT = 15 + + def __init__(self, air): + self.air = air + + self.accept('CATALOG_addGift_AI2UD', self.__handleCatalogAddGift) + self.accept('CATALOG_addGift_UD2Toon_resp', self.__handleToonResp) + + self.__context = 0 + + def __handleCatalogAddGift(self, avId, blob): + ctx = self.__context + self.__context += 1 + self.air.sendNetEvent('CATALOG_addGift_UD2Toon_%d' % avId, [blob, ctx]) + taskMgr.doMethodLater(self.TIMEOUT, self.__doTimeout, 'catalogMgr-timeout-%d' % ctx, [blob, avId]) + + def __handleToonResp(self, avId, ctx): + self.notify.info('%d is online, gift deliver order handled by AI' % avId) + taskMgr.remove('catalogMgr-timeout-%d' % ctx) + + def __doTimeout(self, blob, avId): + self.notify.info('%d is offline, adding order to database' % avId) + self.air.dbInterface.queryObject(self.air.dbId, avId, lambda a, b: self.__handleRetrieve(a, b, avId, blob)) + + def __handleRetrieve(self, dclass, fields, avId, blob): + if dclass != self.air.dclassesByName['DistributedToonUD']: + self.notify.warning('Unable to deliver gift: avId is not a DistributedToon!') + return + + store = CatalogItem.Customization | CatalogItem.DeliveryDate | CatalogItem.GiftTag + giftOnOrder = CatalogItemList.CatalogItemList(fields.get('setGiftSchedule', [''])[0], store=store) + giftOnOrder.append(CatalogItem.getItem(blob, store=store)) + fields['setGiftSchedule'] = (giftOnOrder.getBlob(store=store),) + + self.air.dbInterface.updateObject(self.air.dbId, avId, self.air.dclassesByName['DistributedToonUD'], fields) + self.notify.info('Successfully delivered gift to %d' % avId) \ No newline at end of file diff --git a/toontown/catalog/CatalogScreen.py b/toontown/catalog/CatalogScreen.py index 03a6a1a2..1fa5d661 100755 --- a/toontown/catalog/CatalogScreen.py +++ b/toontown/catalog/CatalogScreen.py @@ -94,6 +94,7 @@ class CatalogScreen(DirectFrame): if hasattr(self, 'giftToggle'): self.giftToggle['state'] = DGG.NORMAL self.giftToggle['text'] = TTLocalizer.CatalogGiftToggleOn + #self.__handleUDack() def hide(self): self.ignore('CatalogItemPurchaseRequest') @@ -544,6 +545,7 @@ class CatalogScreen(DirectFrame): -1.45), image_scale=(1.0, 1.0, smash), image_pos=(0.0, 0.0, -1.9 + lift), image=backDown, pressEffect=0, command=self.showEmblemItems, text=TTLocalizer.CatalogEmblem, text_font=ToontownGlobals.getSignFont(), text_pos=(1.75, 0.132), text_scale=0.065, text_fg=(0.353, 0.627, 0.627, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0)) self.emblemCatalogButton2.hide() self.__makeFFlist() + print self.ffList if len(self.ffList) > 0: if config.GetBool('want-gifting', True): self.giftToggle = DirectButton(self.base, relief=None, pressEffect=0, image=(giftToggleUp, giftToggleDown, giftToggleUp), image_scale=(1.0, 1, 0.7), command=self.__giftToggle, text=TTLocalizer.CatalogGiftToggleOff, text_font=ToontownGlobals.getSignFont(), text_pos=TTLocalizer.CSgiftTogglePos, text_scale=TTLocalizer.CSgiftToggle, text_fg=(0.353, 0.627, 0.627, 1.0), text3_fg=(0.15, 0.3, 0.3, 1.0), text2_fg=(0.353, 0.427, 0.427, 1.0), image_color=Vec4(1.0, 1.0, 0.2, 1.0), image1_color=Vec4(0.9, 0.85, 0.2, 1.0), image2_color=Vec4(0.9, 0.85, 0.2, 1.0), image3_color=Vec4(0.5, 0.45, 0.2, 1.0)) diff --git a/toontown/estate/DistributedPhoneAI.py b/toontown/estate/DistributedPhoneAI.py index 34f72eb1..badc0ad2 100755 --- a/toontown/estate/DistributedPhoneAI.py +++ b/toontown/estate/DistributedPhoneAI.py @@ -1,138 +1,211 @@ -from toontown.estate.DistributedFurnitureItemAI import DistributedFurnitureItemAI -from toontown.toonbase import ToontownGlobals -from toontown.catalog import CatalogItem -from toontown.catalog.CatalogInvalidItem import CatalogInvalidItem -from toontown.catalog.CatalogItemList import CatalogItemList +from direct.directnotify import DirectNotifyGlobal from direct.distributed.ClockDelta import * -import time -import PhoneGlobals +from toontown.estate.DistributedFurnitureItemAI import DistributedFurnitureItemAI +from PhoneGlobals import * +from toontown.toonbase import ToontownGlobals +from toontown.catalog import CatalogItem, CatalogInvalidItem +from toontown.catalog.CatalogItemList import CatalogItemList +from toontown.uberdog import TopToonsGlobals + +import time + +MAX_MAILBOX = 10 +MAX_ON_ORDER = 10 class DistributedPhoneAI(DistributedFurnitureItemAI): - notify = directNotify.newCategory('DistributedPhoneAI') - - def __init__(self, air, furnitureMgr, item): - DistributedFurnitureItemAI.__init__(self, air, furnitureMgr, item) - - self.avId = None - + notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPhoneAI") + + def __init__(self, air, furnitureMgr, catalogItem): + DistributedFurnitureItemAI.__init__(self, air, furnitureMgr, catalogItem) + self.initialScale = (1, 1, 1) + self.inUse = False + self.currAvId = 0 + + def calcHouseItems(self, avatar): + houseId = avatar.houseId + + if not houseId: + self.notify.warning('Avatar %s has no houseId associated.' % avatar.doId) + return 0 + + house = simbase.air.doId2do.get(houseId) + if not house: + self.notify.warning('House %s (for avatar %s) not instantiated.' % (houseId, avatar.doId)) + return 0 + + mgr = house.interior.furnitureManager + attic = (mgr.atticItems, mgr.atticWallpaper, mgr.atticWindows) + numHouseItems = len(CatalogItemList(house.getInteriorItems(), store=CatalogItem.Customization | CatalogItem.Location)) + numAtticItems = sum(len(x) for x in attic) + + return numHouseItems + numAtticItems + + def setInitialScale(self, scale): + self.initialScale = scale + def getInitialScale(self): - return (0.8, 0.8, 0.8) - - def setNewScale(self, sx, sy, sz): - if sx + sy + sz < 5: - return - self.sendUpdate('setInitialScale', [sx, sy, sz]) + return self.initialScale def avatarEnter(self): avId = self.air.getAvatarIdFromSender() - if self.avId: - if self.avId == avId: - self.air.writeServerEvent('suspicious', avId, 'Tried to use a phone twice!') - return - self.sendUpdateToAvatarId(avId, 'freeAvatar', []) + if self.inUse: + self.ejectAvatar(avId) return - + av = self.air.doId2do.get(avId) - if not av: - return - - if not av.houseId: - self.d_setMovie(PhoneGlobals.PHONE_MOVIE_NO_HOUSE, avId, globalClockDelta.getRealNetworkTime(bits=32)) - taskMgr.doMethodLater(1, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[]) - return - - if len(av.monthlyCatalog) == 0 and len(av.weeklyCatalog) == 0 and len(av.backCatalog) == 0: - self.d_setMovie(PhoneGlobals.PHONE_MOVIE_EMPTY, avId, globalClockDelta.getRealNetworkTime(bits=32)) - taskMgr.doMethodLater(1, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[]) - return - - self.air.questManager.toonUsedPhone(avId) - self.avId = avId - self.d_setMovie(PhoneGlobals.PHONE_MOVIE_PICKUP, avId, globalClockDelta.getRealNetworkTime(bits=32)) - - house = self.air.doId2do.get(av.houseId) - if house: - numItems = len(house.interiorItems) + len(house.atticItems) + len(house.atticWallpaper) + len(house.atticWindows) + len (house.interiorWallpaper) + len(house.interiorWindows) - self.sendUpdateToAvatarId(avId, 'setLimits', [numItems]) - else: - self.air.dbInterface.queryObject(self.air.dbId, av.houseId, self.__gotHouse) - - av.b_setCatalogNotify(ToontownGlobals.NoItems, av.mailboxNotify) - - def __gotHouse(self, dclass, fields): - if dclass != self.air.dclassesByName['DistributedHouseAI']: - return - - numItems = len(CatalogItemList(fields['setInteriorItems'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setAtticItems'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setAtticWallpaper'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setAtticWindows'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setInteriorWallpaper'][0], store=CatalogItem.Customization)) + len(CatalogItemList(fields['setInteriorWindows'][0], store=CatalogItem.Customization)) - self.sendUpdateToAvatarId(fields['setAvatarId'][0], 'setLimits', [numItems]) - + if av: + self.setInUse(avId) + self.sendUpdateToAvatarId(avId, 'setLimits', [self.calcHouseItems(av)]) + self.d_setMovie(PHONE_MOVIE_PICKUP, avId) + av.b_setCatalogNotify(0, av.mailboxNotify) + def avatarExit(self): - avId = self.air.getAvatarIdFromSender() - if avId != self.avId: - self.air.writeServerEvent('suspicious', avId, 'Tried to exit a phone they weren\'t using!') + if not self.inUse: + self.notify.warning('Requested avatarExit but phone isn\'t in use!') return - - self.avId = None - self.d_setMovie(PhoneGlobals.PHONE_MOVIE_HANGUP, avId, globalClockDelta.getRealNetworkTime(bits=32)) - taskMgr.doMethodLater(1, self.__resetMovie, 'resetMovie-%d' % self.getDoId(), extraArgs=[]) - - def d_setMovie(self, mode, avId, time): - self.sendUpdate('setMovie', [mode, avId, time]) - - def __resetMovie(self): - self.d_setMovie(PhoneGlobals.PHONE_MOVIE_CLEAR, 0, globalClockDelta.getRealNetworkTime(bits=32)) - - def requestPurchaseMessage(self, context, item, optional): avId = self.air.getAvatarIdFromSender() - if avId != self.avId: - self.air.writeServerEvent('suspicious', avId, 'Tried to purchase while not using the phone!') + if avId != self.currAvId: + self.notify.warning('Requested avatarExit from unknown avatar %s' %avId) return - + self.d_setMovie(PHONE_MOVIE_HANGUP, avId) + taskMgr.doMethodLater(1, self.resetMovie, self.taskName('resetMovie')) + self.setFree() + + def setFree(self): + self.inUse = False + self.currAvId = 0 + + def setInUse(self, avId): + self.inUse = True + self.currAvId = avId + + def d_setMovie(self, movie, avId): + self.sendUpdate('setMovie', args=[movie, avId, globalClockDelta.getRealNetworkTime(bits=32)]) + + def ejectAvatar(self, avId): + self.sendUpdateToAvatarId(avId, 'freeAvatar', []) + + def __getCaller(self): + avId = self.air.getAvatarIdFromSender() + if avId != self.currAvId: + self.air.writeServerEvent('suspicious', avId, 'tried purchasing item, but not using phone') + self.notify.warning('%d tried purchasing item, but not using phone' % avId) + return + av = self.air.doId2do.get(avId) if not av: - self.air.writeServerEvent('suspicious', avId, 'Used phone from other shard!') + self.air.writeServerEvent('suspicious', avId, 'tried purchasing item, but not on shard') + self.notify.warning('%d tried purchasing item, but not on shard' % avId) return - - item = CatalogItem.getItem(item) - if isinstance(item, CatalogInvalidItem): - self.air.writeServerEvent('suspicious', avId, 'Tried to purchase invalid catalog item.') - return - if item in av.backCatalog: - price = item.getPrice(CatalogItem.CatalogTypeBackorder) - elif item in av.weeklyCatalog or item in av.monthlyCatalog: - price = item.getPrice(0) - elif item.hasEmblemPrices(): - price = 0 + + return av + + def attemptPurchase(self, avBuying, recepient, blob, optional, payMethod, gifting=False): + avId = avBuying.doId + + item = CatalogItem.getItem(blob, CatalogItem.Customization) + if isinstance(item, CatalogInvalidItem.CatalogInvalidItem): + self.air.writeServerEvent('suspicious', avId, 'tried purchasing invalid item') + self.notify.warning('%d tried purchasing invalid item' % avId) + return ToontownGlobals.P_NotInCatalog + + if item in avBuying.backCatalog: + priceType = CatalogItem.CatalogTypeBackorder + + elif item in avBuying.weeklyCatalog or item in avBuying.monthlyCatalog: + priceType = 0 + + elif item.__class__.__name__ == "CatalogHouseItem": + priceType = 0 + else: - return - - if item.getDeliveryTime(): - if len(av.onOrder) > 25: - self.sendUpdateToAvatarId(avId, 'requestPurchaseResponse', [context, ToontownGlobals.P_OnOrderListFull]) - return - - if len(av.mailboxContents) + len(av.onOrder) >= ToontownGlobals.MaxMailboxContents: - self.sendUpdateToAvatarId(avId, 'requestPurchaseResponse', [context, ToontownGlobals.P_MailboxFull]) - - if not (av.takeMoney(price) and av.subtractEmblems(item.getEmblemPrices())): - return - - item.deliveryDate = int(time.time()/60) + item.getDeliveryTime() - av.onOrder.append(item) - av.b_setDeliverySchedule(av.onOrder) - self.sendUpdateToAvatarId(avId, 'requestPurchaseResponse', [context, ToontownGlobals.P_ItemOnOrder]) - taskMgr.doMethodLater(0.2, self.sendUpdateToAvatarId, 'purchaseItemComplete-%d' % self.getDoId(), extraArgs=[avId, 'purchaseItemComplete', []]) + self.air.writeServerEvent('suspicious', avId, 'tried purchasing non-existing item') + self.notify.warning('%d tried purchasing non-existing item' % avId) + return ToontownGlobals.P_NotInCatalog + + def _getEmblemPrices(): + if config.GetBool('catalog-emblems-OR', False): + ep = list(item.getEmblemPrices()) + if len(ep) != 2: + return [] + + if all(ep): + ep[payMethod] = 0 + + else: + ep = item.getEmblemPrices() + + return ep + + def charge(): + ep = _getEmblemPrices() + if ep: + avBuying.subtractEmblems(ep) + + avBuying.takeMoney(item.getPrice(priceType)) + + if not gifting and item.reachedPurchaseLimit(recepient): + retcode = ToontownGlobals.P_ReachedPurchaseLimit + + elif not gifting and len(recepient.onOrder) >= MAX_ON_ORDER: + retcode = ToontownGlobals.P_ReachedPurchaseLimit + + elif not gifting and len(recepient.mailboxContents) >= MAX_MAILBOX: + retcode = ToontownGlobals.P_MailboxFull + + elif item.getPrice(priceType) >= avBuying.getTotalMoney(): + retcode = ToontownGlobals.P_NotEnoughMoney + + elif not avBuying.isEnoughEmblemsToBuy(_getEmblemPrices()): + retcode = ToontownGlobals.P_NotEnoughMoney + + elif gifting and not item.isGift(): + retcode = ToontownGlobals.P_NotAGift + + elif not item.getDeliveryTime() and not gifting: + retcode = item.recordPurchase(recepient, optional) + if retcode == ToontownGlobals.P_ItemAvailable: + + charge() + else: - if not (av.takeMoney(price) and av.subtractEmblems(item.getEmblemPrices())): - return + retcode = ToontownGlobals.P_ItemOnOrder + charge() + + deliveryTime = item.getDeliveryTime() + if config.GetBool('want-instant-delivery', False): + deliveryTime = 0 + + item.deliveryDate = int(time.time() / 60. + deliveryTime + .5) - resp = item.recordPurchase(av, optional) - if resp < 0: - av.addMoney(price) + if not gifting: + recepient.onOrder.append(item) + recepient.b_setDeliverySchedule(recepient.onOrder) + + else: + item.giftTag = avBuying.doId + store = CatalogItem.Customization | CatalogItem.DeliveryDate | CatalogItem.GiftTag + self.air.sendNetEvent('CATALOG_addGift_AI2UD', [recepient, item.getBlob(store=store)]) + + return retcode - self.sendUpdateToAvatarId(avId, 'requestPurchaseResponse', [context, resp]) - taskMgr.doMethodLater(0.2, self.sendUpdateToAvatarId, 'purchaseItemComplete-%d' % self.getDoId(), extraArgs=[avId, 'purchaseItemComplete', []]) + def requestPurchaseMessage(self, context, blob, optional, payMethod=0): + av = self.__getCaller() + if av: + retcode = self.attemptPurchase(av, av, blob, optional, payMethod) + if retcode in (ToontownGlobals.P_ItemOnOrder, ToontownGlobals.P_ItemAvailable): + messenger.send('topToonsManager-event', [av.doId, TopToonsGlobals.CAT_CATALOG, 1]) + self.sendUpdateToAvatarId(av.doId, 'requestPurchaseResponse', [context, retcode]) + + def requestGiftPurchaseMessage(self, context, targetDoID, blob, optional, payMethod=0): + av = self.__getCaller() + if av: + retcode = self.attemptPurchase(av, targetDoID, blob, optional, payMethod, gifting=True) + if retcode in (ToontownGlobals.P_ItemOnOrder, ToontownGlobals.P_ItemAvailable): + messenger.send('topToonsManager-event', [av.doId, TopToonsGlobals.CAT_CATALOG | TopToonsGlobals.CAT_GIFTS, 1]) + self.sendUpdateToAvatarId(av.doId, 'requestGiftPurchaseResponse', [context, retcode]) - def requestGiftPurchaseMessage(self, context, avId, item, optional): - pass # TODO + def resetMovie(self, task): + self.d_setMovie(PHONE_MOVIE_CLEAR, 0) + return task.done \ No newline at end of file diff --git a/toontown/toon/DistributedToonAI.py b/toontown/toon/DistributedToonAI.py index e4da0b2f..1519e49c 100755 --- a/toontown/toon/DistributedToonAI.py +++ b/toontown/toon/DistributedToonAI.py @@ -175,6 +175,7 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo from toontown.toon.DistributedNPCToonBaseAI import DistributedNPCToonBaseAI if not isinstance(self, DistributedNPCToonBaseAI): self.sendUpdate('setDefaultShard', [self.air.districtId]) + self.accept('CATALOG_addGift_UD2Toon_%d' % self.doId, self.__handleAddGift) def setLocation(self, parentId, zoneId): DistributedPlayerAI.DistributedPlayerAI.setLocation(self, parentId, zoneId) @@ -239,6 +240,8 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo DistributedSmoothNodeAI.DistributedSmoothNodeAI.delete(self) DistributedPlayerAI.DistributedPlayerAI.delete(self) + + self.ignore('CATALOG_addGift_UD2Toon_%d' % self.doId) def deleteDummy(self): if self.inventory: @@ -2178,7 +2181,13 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo self.b_setMailboxContents(self.mailboxContents + delivered) self.b_setCatalogNotify(self.catalogNotify, ToontownGlobals.NewItems) return Task.done - + + def __handleAddGift(self, blob): + store = CatalogItem.Customization | CatalogItem.DeliveryDate | CatalogItem.GiftTag + self.onGiftOrder.append(CatalogItem.getItem(blob, store=store)) + self.b_setBothSchedules(self.onOrder, self.onGiftOrder) + self.air.sendNetEvent('CATALOG_addGift_UD2Toon_resp', [self.doId, ctx]) + def __deliverPurchase(self, task): now = int(time.time() / 60 + 0.5) delivered, remaining = self.onOrder.extractDeliveryItems(now) diff --git a/toontown/uberdog/ToontownUberRepository.py b/toontown/uberdog/ToontownUberRepository.py index 8d3464b0..d4821459 100755 --- a/toontown/uberdog/ToontownUberRepository.py +++ b/toontown/uberdog/ToontownUberRepository.py @@ -3,6 +3,7 @@ import urlparse from otp.distributed.OtpDoGlobals import * from otp.distributed.DistributedDirectoryAI import DistributedDirectoryAI from toontown.distributed.ToontownInternalRepository import ToontownInternalRepository +from toontown.catalog.CatalogManagerUD import CatalogManagerUD import toontown.minigame.MinigameCreatorAI if config.GetBool('want-rpc-server', False): @@ -25,6 +26,8 @@ class ToontownUberRepository(ToontownInternalRepository): self.mongo = pymongo.MongoClient(url) db = (urlparse.urlparse(url).path or '/test')[1:] self.mongodb = self.mongo[db] + + self.catalogManager = CatalogManagerUD(self) self.notify.setInfo(True) @@ -51,3 +54,4 @@ class ToontownUberRepository(ToontownInternalRepository): self.friendsManager = simbase.air.generateGlobalObject(OTP_DO_ID_TTS_FRIENDS_MANAGER, 'TTSFriendsManager') self.globalPartyMgr = simbase.air.generateGlobalObject(OTP_DO_ID_GLOBAL_PARTY_MANAGER, 'GlobalPartyManager') self.groupManager = simbase.air.generateGlobalObject(OPT_DO_ID_GROUP_MANAGER, 'GroupManager') + diff --git a/toontown/uberdog/TopToonsGlobals.py b/toontown/uberdog/TopToonsGlobals.py new file mode 100644 index 00000000..51daf629 --- /dev/null +++ b/toontown/uberdog/TopToonsGlobals.py @@ -0,0 +1,15 @@ +CAT_COGS = 1 +CAT_BLDG = 2 +CAT_CATALOG = 4 +CAT_GIFTS = 8 +CAT_TASKS = 16 +CAT_TROLLEY = 32 +CAT_RACE_WON = 64 +CAT_FISH = 128 +CAT_JELLYBEAN = 256 +CAT_HOLE_IN_ONE = 512 +CAT_COURSE_UNDER_PAR = 1024 +CAT_VP = 2048 +CAT_CFO = 4096 +CAT_CJ = 8192 +CAT_CEO = 16384