diff --git a/toontown/friends/TTUFriendsManagerUD.py b/toontown/friends/TTUFriendsManagerUD.py index 4bc68240..168458ab 100644 --- a/toontown/friends/TTUFriendsManagerUD.py +++ b/toontown/friends/TTUFriendsManagerUD.py @@ -261,7 +261,7 @@ class TTUFriendsManagerUD(DistributedObjectGlobalUD): def getPetDetails(self, avId): senderId = self.air.getAvatarIdFromSender() def handlePet(dclass, fields): - if dclass != self.air.dclassesByName['DistributedPetUD']: + if dclass != self.air.dclassesByName['DistributedPetAI']: return dna = [fields.get(x, [0])[0] for x in ("setHead", "setEars", "setNose", "setTail", "setBodyTexture", "setColor", "setColorScale", "setEyeColor", "setGender")] diff --git a/toontown/pets/DistributedPetAI.py b/toontown/pets/DistributedPetAI.py index 8a848a70..06301364 100644 --- a/toontown/pets/DistributedPetAI.py +++ b/toontown/pets/DistributedPetAI.py @@ -956,6 +956,9 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke self.__petMovieStart(avId) def enableLockMover(self): + if not hasattr(self, 'brain'): + return + if self.lockMoverEnabled == 0: self.brain._startMovie() self.lockMoverEnabled += 1 @@ -964,6 +967,9 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke return self.lockMoverEnabled > 0 def disableLockMover(self): + if not hasattr(self, 'brain'): + return + if self.lockMoverEnabled > 0: self.lockMoverEnabled -= 1 if self.lockMoverEnabled == 0: diff --git a/toontown/pets/DistributedPetProxyAI.py b/toontown/pets/DistributedPetProxyAI.py index ae83e489..1b9f91b9 100644 --- a/toontown/pets/DistributedPetProxyAI.py +++ b/toontown/pets/DistributedPetProxyAI.py @@ -356,6 +356,7 @@ class DistributedPetProxyAI(DistributedObjectAI.DistributedObjectAI): def generate(self): DistributedObjectAI.DistributedObjectAI.generate(self) self.traits = PetTraits.PetTraits(self.traitSeed, self.safeZone) + print self.traits.traits for i in xrange(len(self.traitList)): value = self.traitList[i] if value == 0.0: diff --git a/toontown/pets/Pet.py b/toontown/pets/Pet.py index d37d14f2..7f5c9498 100644 --- a/toontown/pets/Pet.py +++ b/toontown/pets/Pet.py @@ -9,7 +9,6 @@ from direct.actor import Actor from direct.task import Task from toontown.pets import PetDNA from PetDNA import HeadParts, EarParts, NoseParts, TailParts, BodyTypes, BodyTextures, AllPetColors, getColors, ColorScales, PetEyeColors, EarTextures, TailTextures, getFootTexture, getEarTexture, GiraffeTail, LeopardTail, PetGenders -from toontown.toonbase.BitmaskGlobals import PieBitmask from toontown.toonbase import TTLocalizer from toontown.toonbase import ToontownGlobals from direct.showbase import PythonUtil @@ -30,7 +29,6 @@ Component2IconDict = {'boredom': 'Bored', from toontown.nametag import * from toontown.nametag.NametagGlobals import * -from toontown.nametag.NametagGroup import * class Pet(Avatar.Avatar): notify = DirectNotifyGlobal.directNotify.newCategory('Pet') @@ -268,7 +266,7 @@ class Pet(Avatar.Avatar): def initializeBodyCollisions(self, collIdStr): Avatar.Avatar.initializeBodyCollisions(self, collIdStr) if not self.ghostMode: - self.collNode.setCollideMask(self.collNode.getIntoCollideMask() | PieBitmask) + self.collNode.setCollideMask(self.collNode.getIntoCollideMask() | ToontownGlobals.PieBitmask) def amplifyColor(self, color, scale): color = color * scale diff --git a/toontown/pets/PetAvatarPanel.py b/toontown/pets/PetAvatarPanel.py index 0792e893..19e985a3 100644 --- a/toontown/pets/PetAvatarPanel.py +++ b/toontown/pets/PetAvatarPanel.py @@ -273,6 +273,8 @@ class PetAvatarPanel(AvatarPanel.AvatarPanel): self.notify.debug('__fillPetInfo(): doId=%s' % avatar.doId) self.petView = self.frame.attachNewNode('petView') self.petView.setPos(0, 0, 5.4) + if hasattr(avatar, 'announceGenerate'): + avatar.announceGenerate() self.petModel = Pet.Pet(forGui=1) self.petModel.setDNA(avatar.getDNA()) self.petModel.fitAndCenterHead(3.575, forGui=1) diff --git a/toontown/pets/PetConstants.py b/toontown/pets/PetConstants.py index 72c4c9e2..02480b7c 100644 --- a/toontown/pets/PetConstants.py +++ b/toontown/pets/PetConstants.py @@ -58,4 +58,5 @@ ZoneToCostRange = {ToontownGlobals.ToontownCentral: (100, 500), ToontownGlobals.DaisyGardens: (1000, 2500), ToontownGlobals.MinniesMelodyland: (1500, 3000), ToontownGlobals.TheBrrrgh: (2500, 4000), - ToontownGlobals.DonaldsDreamland: (3000, 5000)} + ToontownGlobals.DonaldsDreamland: (3000, 5000), + ToontownGlobals.FunnyFarm: (3700, 5800)} diff --git a/toontown/pets/PetDCImportsAI.py b/toontown/pets/PetDCImportsAI.py index 1c92bbeb..fb2b5c86 100644 --- a/toontown/pets/PetDCImportsAI.py +++ b/toontown/pets/PetDCImportsAI.py @@ -1,3 +1,2 @@ if hasattr(simbase, 'wantPets') and simbase.wantPets: import DistributedPetAI - import DistributedPetUD diff --git a/toontown/pets/PetDNA.py b/toontown/pets/PetDNA.py index 46be0712..0983e579 100644 --- a/toontown/pets/PetDNA.py +++ b/toontown/pets/PetDNA.py @@ -2,7 +2,6 @@ from toontown.toon import ToonDNA from pandac.PandaModules import VBase4 from toontown.toonbase import TTLocalizer, ToontownGlobals from direct.showbase import PythonUtil -import random NumFields = 9 Fields = {'head': 0, 'ears': 1, @@ -85,7 +84,14 @@ PetRarities = {'body': {ToontownGlobals.ToontownCentral: {'threeStripe': 50, 'tigerStripe': 20, 'turtle': 25, 'giraffe': 20, - 'leopard': 10}}} + 'leopard': 10}, + ToontownGlobals.FunnyFarm: {'leopard': 20, + 'giraffe': 20, + 'dots': 10, + 'tigerStripe': 25, + 'turtle': 25} + + }} BodyTextures = {'dots': 'phase_4/maps/BeanbodyDots6.jpg', 'threeStripe': 'phase_4/maps/Beanbody3stripes6.jpg', 'tigerStripe': 'phase_4/maps/BeanbodyZebraStripes6.jpg', @@ -180,17 +186,17 @@ PetEyeColors = (VBase4(0.29, 0.29, 0.69, 1.0), VBase4(0.49, 0.99, 0.49, 1.0)) PetGenders = [0, 1] -def getRandomPetDNA(seed = 0, zoneId = ToontownGlobals.DonaldsDreamland): - random.seed(seed + zoneId) - head = random.choice(range(-1, len(HeadParts))) - ears = random.choice(range(-1, len(EarParts))) - nose = random.choice(range(-1, len(NoseParts))) - tail = random.choice(range(-1, len(TailParts))) +def getRandomPetDNA(zoneId = ToontownGlobals.DonaldsDreamland): + from random import choice + head = choice(range(-1, len(HeadParts))) + ears = choice(range(-1, len(EarParts))) + nose = choice(range(-1, len(NoseParts))) + tail = choice(range(-1, len(TailParts))) body = getSpecies(zoneId) - color = random.choice(range(0, len(getColors(body)))) - colorScale = random.choice(range(0, len(ColorScales))) - eyes = random.choice(range(0, len(PetEyeColors))) - gender = random.choice(range(0, len(PetGenders))) + color = choice(range(0, len(getColors(body)))) + colorScale = choice(range(0, len(ColorScales))) + eyes = choice(range(0, len(PetEyeColors))) + gender = choice(range(0, len(PetGenders))) return [head, ears, nose, diff --git a/toontown/pets/PetLookerAI.py b/toontown/pets/PetLookerAI.py index b9bede67..6cbdd42d 100644 --- a/toontown/pets/PetLookerAI.py +++ b/toontown/pets/PetLookerAI.py @@ -2,7 +2,7 @@ from pandac.PandaModules import * from direct.directnotify import DirectNotifyGlobal from direct.showbase import DirectObject from otp.ai.AIZoneData import AIZoneData -from toontown.toonbase.BitmaskGlobals import PetLookatPetBitmask, PetLookatNonPetBitmask +from toontown.toonbase import ToontownGlobals from toontown.pets import PetConstants def getStartLookingAtOtherEvent(lookingAvId): @@ -83,11 +83,11 @@ class PetLookerAI: lookSphereNode.addSolid(lookSphere) lookSphereNode.setFromCollideMask(BitMask32.allOff()) if isPet: - intoCollideMask = PetLookatPetBitmask - fromCollideMask = PetLookatPetBitmask | PetLookatNonPetBitmask + intoCollideMask = ToontownGlobals.PetLookatPetBitmask + fromCollideMask = ToontownGlobals.PetLookatPetBitmask | ToontownGlobals.PetLookatNonPetBitmask else: - intoCollideMask = PetLookatNonPetBitmask - fromCollideMask = PetLookatPetBitmask + intoCollideMask = ToontownGlobals.PetLookatNonPetBitmask + fromCollideMask = ToontownGlobals.PetLookatPetBitmask lookSphereNode.setIntoCollideMask(intoCollideMask) lookSphereNode.setFromCollideMask(fromCollideMask) self.lookSphereNodePath = self.__collNode.attachNewNode(lookSphereNode) diff --git a/toontown/pets/PetManagerAI.py b/toontown/pets/PetManagerAI.py index da991ce3..96b30aad 100644 --- a/toontown/pets/PetManagerAI.py +++ b/toontown/pets/PetManagerAI.py @@ -1,10 +1,7 @@ -from direct.directnotify import DirectNotifyGlobal from direct.fsm.FSM import FSM import PetUtil, PetDNA -from toontown.hood import ZoneUtil -from toontown.building import PetshopBuildingAI -from toontown.toonbase import ToontownGlobals, TTLocalizer -import random +from toontown.toonbase import ToontownGlobals +from toontown.toonbase import TTLocalizer import cPickle, time, random, os MINUTE = 60 @@ -15,8 +12,9 @@ def getDayId(): return int(time.time() // DAY) class PetManagerAI: - NUM_DAILY_PETS = 5 + NUM_DAILY_PETS = 5 # per hood cachePath = config.GetString('air-pet-cache', 'astron/databases/air_cache/') + def __init__(self, air): self.air = air self.cacheFile = '%spets_%d.pets' % (self.cachePath, self.air.districtId) @@ -29,28 +27,28 @@ class PetManagerAI: self.generateSeeds() else: - self.generateSeeds() - + self.generateSeeds() + def generateSeeds(self): seeds = range(0, 255) random.shuffle(seeds) self.seeds = {} for hood in (ToontownGlobals.ToontownCentral, ToontownGlobals.DonaldsDock, ToontownGlobals.DaisyGardens, - ToontownGlobals.MinniesMelodyland, ToontownGlobals.TheBrrrgh, ToontownGlobals.DonaldsDreamland): + ToontownGlobals.MinniesMelodyland, ToontownGlobals.TheBrrrgh, ToontownGlobals.DonaldsDreamland, + ToontownGlobals.FunnyFarm): self.seeds[hood] = [seeds.pop() for _ in xrange(self.NUM_DAILY_PETS)] self.seeds['day'] = getDayId() with open(self.cacheFile, 'wb') as f: - f.write(cPickle.dumps(self.seeds)) + f.write(cPickle.dumps(self.seeds)) - def getAvailablePets(self, seed, safezoneId): if self.seeds.get('day', -1) != getDayId(): self.generateSeeds() - return self.seeds.get(safezoneId, [seed]) + return list(set(self.seeds.get(safezoneId, [seed]))) def createNewPetFromSeed(self, avId, seed, nameIndex, gender, safeZoneId): av = self.air.doId2do[avId] @@ -83,4 +81,6 @@ class PetManagerAI: if pet in self.air.doId2do: self.air.doId2do[pet].requestDelete() - av.b_setPetId(0) \ No newline at end of file + av.b_setPetId(0) + # XXX to do: check for current pet and destroy it if generated + diff --git a/toontown/pets/PetMoverAI.py b/toontown/pets/PetMoverAI.py index f0502e51..b5a2066f 100644 --- a/toontown/pets/PetMoverAI.py +++ b/toontown/pets/PetMoverAI.py @@ -9,6 +9,8 @@ estateCenter = (0, -40) houseRadius = 15 houses = ((60, 10), (42, 75), (-37, 35), (80, -80), (-70, -120), (-55, -40)) +dist = 2 + def inCircle(x, y, c=estateCenter, r=estateRadius): center_x, center_y = c square_dist = (center_x - x) ** 2 + (center_y - y) ** 2 @@ -77,6 +79,15 @@ def generatePath(start, end): if not houseCollision(next, end): points.append(end) return points + +def angle(A, B): + ax = A.getX() + ay = A.getY() + + bx = B.getX() + by = B.getY() + + return math.atan2(by-ay, bx-ax) class PetMoverAI(FSM): def __init__(self, pet): @@ -96,10 +107,7 @@ class PetMoverAI(FSM): taskMgr.remove(self.pet.uniqueName('next-state')) def __moveFromStill(self, task=None): - choices = ["Wander"] - # if self.pet._getNearbyAvatarDict(): - # choices.append("Chase") - + choices = ["Wander"] nextState = random.choice(choices) self.request(nextState) @@ -113,9 +121,9 @@ class PetMoverAI(FSM): def walkToPoint(self, target): here = self.pet.getPos() - dist = Vec3((here - target)).length() - dist = dist * 0.9 - self.__seq = Sequence(Func(self.pet.lookAt, target), self.pet.posInterval(dist / self.fwdSpeed, target, here), + dist = Vec3(here - target).length() + + self.__seq = Sequence(Func(self.pet.lookAt, target), Func(self.pet.setP, 0), self.pet.posInterval(dist / self.fwdSpeed, target, here), Func(self.__stateComplete)) self.__seq.start() @@ -156,8 +164,12 @@ class PetMoverAI(FSM): target = hidden.attachNewNode('target') target.setPos(self.getPoint()) - self.walkToPoint(target.getPos()) + pos = target.getPos() + theta = angle(self.pet.getPos(), pos) * (math.pi / 180) + dx = dist * math.cos(theta) + dy = dist * math.sin(theta) + self.walkToPoint(Point3(pos.getX() - dx, pos.getY() - dy, pos.getZ())) def exitChase(self): if self.__chaseCallback: diff --git a/toontown/pets/PetTraits.py b/toontown/pets/PetTraits.py index 538b1ecf..1ce07ef4 100644 --- a/toontown/pets/PetTraits.py +++ b/toontown/pets/PetTraits.py @@ -120,7 +120,8 @@ class PetTraits: ToontownGlobals.DaisyGardens: (0.4, 0.75), ToontownGlobals.MinniesMelodyland: (0.5, 0.8), ToontownGlobals.TheBrrrgh: (0.6, 0.85), - ToontownGlobals.DonaldsDreamland: (0.7, 0.9)} + ToontownGlobals.DonaldsDreamland: (0.7, 0.9), + ToontownGlobals.FunnyFarm: (0.8, 0.9)} class StdDecDistrib(TraitDistribution): TraitType = TraitDistribution.TraitTypes.DECREASING @@ -129,7 +130,8 @@ class PetTraits: ToontownGlobals.DaisyGardens: (0.25, 0.6), ToontownGlobals.MinniesMelodyland: (0.2, 0.5), ToontownGlobals.TheBrrrgh: (0.15, 0.4), - ToontownGlobals.DonaldsDreamland: (0.1, 0.3)} + ToontownGlobals.DonaldsDreamland: (0.1, 0.3), + ToontownGlobals.FunnyFarm: (0.05, 0.2)} class ForgetfulnessDistrib(TraitDistribution): TraitType = TraitDistribution.TraitTypes.DECREASING @@ -138,7 +140,8 @@ class PetTraits: ToontownGlobals.DaisyGardens: (0.0, 0.8), ToontownGlobals.MinniesMelodyland: (0.0, 0.7), ToontownGlobals.TheBrrrgh: (0.0, 0.6), - ToontownGlobals.DonaldsDreamland: (0.0, 0.5)} + ToontownGlobals.DonaldsDreamland: (0.0, 0.5), + ToontownGlobals.FunnyFarm: (0.0, 0.4)} TraitDescs = (('forgetfulness', ForgetfulnessDistrib(), True), ('boredomThreshold', StdIncDistrib(), True), diff --git a/toontown/pets/PetUtil.py b/toontown/pets/PetUtil.py index 454482c9..254387a0 100644 --- a/toontown/pets/PetUtil.py +++ b/toontown/pets/PetUtil.py @@ -1,12 +1,16 @@ from toontown.pets import PetDNA, PetTraits, PetConstants -from toontown.toonbase import TTLocalizer from direct.showbase import PythonUtil +from toontown.toonbase import TTLocalizer +import random def getPetInfoFromSeed(seed, safezoneId): - dnaArray = PetDNA.getRandomPetDNA(seed, safezoneId) + S = random.getstate() + random.seed(seed) + dnaArray = PetDNA.getRandomPetDNA(safezoneId) gender = PetDNA.getGender(dnaArray) nameString = TTLocalizer.getRandomPetName(gender=gender, seed=seed) traitSeed = PythonUtil.randUint31() + random.setstate(S) return (nameString, dnaArray, traitSeed) diff --git a/toontown/pets/PetshopGUI.py b/toontown/pets/PetshopGUI.py index b9360b4e..d1bd11d9 100644 --- a/toontown/pets/PetshopGUI.py +++ b/toontown/pets/PetshopGUI.py @@ -1,22 +1,23 @@ -from direct.directnotify import DirectNotifyGlobal from direct.gui.DirectGui import * -from direct.showbase.DirectObject import DirectObject from pandac.PandaModules import * -import random -import string - +from direct.directnotify import DirectNotifyGlobal +from direct.showbase.DirectObject import DirectObject +from toontown.toonbase import ToontownGlobals +from toontown.toonbase import TTLocalizer +from toontown.toonbase import ToontownTimer +from direct.task import Task +from otp.namepanel import NameTumbler +from otp.otpbase import OTPGlobals +from otp.otpbase import OTPLocalizer from toontown.fishing import FishSellGUI -from toontown.hood import ZoneUtil from toontown.pets import Pet, PetConstants from toontown.pets import PetDNA +from toontown.pets import PetUtil from toontown.pets import PetDetail from toontown.pets import PetTraits -from toontown.pets import PetUtil -from toontown.toonbase import TTLocalizer -from toontown.toonbase import ToontownGlobals -from toontown.toonbase import ToontownTimer - - +from toontown.hood import ZoneUtil +import string +import random Dialog_MainMenu = 0 Dialog_AdoptPet = 1 Dialog_ChoosePet = 2 @@ -46,6 +47,7 @@ class PetshopGUI(DirectObject): self.bNo = DirectButton(self, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), relief=None, text=TTLocalizer.TutorialNo, text_scale=0.05, text_pos=(0.0, -0.1), pos=(0.15, 0.0, -0.1), command=lambda : messenger.send(doneEvent, [0])) buttons.removeNode() gui.removeNode() + return class NamePicker(DirectFrame): notify = DirectNotifyGlobal.directNotify.newCategory('PetshopGUI.NamePicker') @@ -91,6 +93,7 @@ class PetshopGUI(DirectObject): cancelIcon = model.find('**/CancelIcon') self.cancelButton = DirectButton(parent=self, relief=None, pos=(-0.04, 0, -0.47), image=cancelImageList, geom=cancelIcon, scale=modelScale, pressEffect=False, command=lambda : messenger.send(doneEvent, [-1])) self.randomName() + return def destroy(self): self.petModel.delete() @@ -192,6 +195,7 @@ class PetshopGUI(DirectObject): if not base.localAvatar.hasPet(): self.returnPetButton['state'] = DGG.DISABLED model.removeNode() + return class AdoptPetDlg(DirectFrame): notify = DirectNotifyGlobal.directNotify.newCategory('PetshopGUI.AdoptPetDlg') @@ -224,6 +228,7 @@ class PetshopGUI(DirectObject): self.cancelButton = DirectButton(parent=self, relief=None, image=cancelImageList, geom=cancelIcon, scale=modelScale, text=('', TTLocalizer.PetshopGoBack), text_pos=(-5.8, 4.4), text_scale=0.7, pressEffect=False, command=lambda : messenger.send(doneEvent, [0])) self.okButton = DirectButton(parent=self, relief=None, image=okImageList, geom=checkIcon, scale=modelScale, text=('', TTLocalizer.PetshopAdopt), text_pos=(5.8, 4.4), text_scale=0.7, pressEffect=False, command=lambda : messenger.send(doneEvent, [1])) model.removeNode() + return def destroy(self): self.ignore(localAvatar.uniqueName('moneyChange')) @@ -276,6 +281,7 @@ class PetshopGUI(DirectObject): self.PetPanel = None self.petModel.delete() DirectFrame.destroy(self) + return class ChoosePetDlg(DirectFrame): notify = DirectNotifyGlobal.directNotify.newCategory('PetshopGUI.ChoosePetDlg') @@ -309,6 +315,7 @@ class PetshopGUI(DirectObject): self.petSeeds = petSeeds self.makePetList() self.showPet() + return def makePetList(self): self.numPets = len(self.petSeeds) @@ -317,7 +324,7 @@ class PetshopGUI(DirectObject): self.petName = [] self.petDesc = [] self.petCost = [] - for i in xrange(self.numPets): + for i in range(self.numPets): random.seed(self.petSeeds[i]) zoneId = ZoneUtil.getCanonicalSafeZoneId(base.localAvatar.getZoneId()) name, dna, traitSeed = PetUtil.getPetInfoFromSeed(self.petSeeds[i], zoneId) @@ -372,6 +379,7 @@ class PetshopGUI(DirectObject): self.okButton['state'] = DGG.DISABLED else: self.okButton['state'] = DGG.NORMAL + return def __moneyChange(self, money): self.moneyDisplay['text'] = str(base.localAvatar.getTotalMoney()) @@ -393,6 +401,7 @@ class PetshopGUI(DirectObject): self.timer.posInTopRightCorner() self.timer.countdown(PetConstants.PETCLERK_TIMER, self.__timerExpired) self.doDialog(Dialog_MainMenu) + return def __timerExpired(self): messenger.send(self.eventDict['guiDone'], [True]) @@ -413,6 +422,7 @@ class PetshopGUI(DirectObject): if self.dialog != None: self.dialog.destroy() self.dialog = None + return def popDialog(self): self.dialogStack.pop() @@ -495,6 +505,7 @@ class PetshopGUI(DirectObject): self.notify.warning('Tried to go home, but place is None.') return place.goHomeNow(base.localAvatar.lastHood) + return def __handleReturnPetDlg(self, exitVal): if exitVal == 0: