Some pet stuff.

This commit is contained in:
Loudrob 2015-03-29 18:16:26 -04:00
parent 4e50e8a485
commit 47361ccb04
14 changed files with 105 additions and 62 deletions

View file

@ -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")]

View file

@ -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:

View file

@ -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:

View file

@ -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

View file

@ -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)

View file

@ -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)}

View file

@ -1,3 +1,2 @@
if hasattr(simbase, 'wantPets') and simbase.wantPets:
import DistributedPetAI
import DistributedPetUD

View file

@ -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,

View file

@ -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)

View file

@ -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)
av.b_setPetId(0)
# XXX to do: check for current pet and destroy it if generated

View file

@ -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:

View file

@ -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),

View file

@ -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)

View file

@ -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: