Upstream update

This commit is contained in:
Daniel 2015-03-29 18:41:02 +03:00
parent 8516b04c1e
commit f38f910638
36 changed files with 623 additions and 274 deletions

View file

@ -3740,6 +3740,9 @@ dclass TTUFriendsManager : DistributedObjectGlobal {
getAvatarDetails(uint32) clsend; getAvatarDetails(uint32) clsend;
friendDetails(uint32, blob, uint16[], uint16, int16, int16, uint32, uint32, blob, blob, int8[]); friendDetails(uint32, blob, uint16[], uint16, int16, int16, uint32, uint32, blob, blob, int8[]);
getPetDetails(uint32) clsend;
petDetails(uint32, uint32, string, uint32, uint32, uint16/1000[], PetTrait[], int8[], uint32);
routeTeleportQuery(uint32 toId) clsend; routeTeleportQuery(uint32 toId) clsend;
teleportQuery(uint32 fromId); teleportQuery(uint32 fromId);

View file

@ -769,7 +769,7 @@ class BattleCalculatorAI:
return return
tgts = self.__createToonTargetList(toonId) tgts = self.__createToonTargetList(toonId)
for currTgt in tgts: for currTgt in tgts:
tgtPos = self.battle.suits.index(currTgt) tgtPos = self.battle.activeSuits.index(currTgt)
attackerId = self.toonAtkOrder[attackIndex] attackerId = self.toonAtkOrder[attackIndex]
attack = self.battle.toonAttacks[attackerId] attack = self.battle.toonAttacks[attackerId]
track = self.__getActualTrack(attack) track = self.__getActualTrack(attack)

View file

@ -76,7 +76,6 @@ class DistributedBattleBaseAI(DistributedObjectAI.DistributedObjectAI, BattleBas
self.numNPCAttacks = 0 self.numNPCAttacks = 0
self.npcAttacks = {} self.npcAttacks = {}
self.pets = {} self.pets = {}
self.fireCount = 0
self.fsm = ClassicFSM.ClassicFSM('DistributedBattleAI', [State.State('FaceOff', self.enterFaceOff, self.exitFaceOff, ['WaitForInput', 'Resume']), self.fsm = ClassicFSM.ClassicFSM('DistributedBattleAI', [State.State('FaceOff', self.enterFaceOff, self.exitFaceOff, ['WaitForInput', 'Resume']),
State.State('WaitForJoin', self.enterWaitForJoin, self.exitWaitForJoin, ['WaitForInput', 'Resume']), State.State('WaitForJoin', self.enterWaitForJoin, self.exitWaitForJoin, ['WaitForInput', 'Resume']),
State.State('WaitForInput', self.enterWaitForInput, self.exitWaitForInput, ['MakeMovie', 'Resume']), State.State('WaitForInput', self.enterWaitForInput, self.exitWaitForInput, ['MakeMovie', 'Resume']),
@ -1051,13 +1050,7 @@ class DistributedBattleBaseAI(DistributedObjectAI.DistributedObjectAI, BattleBas
elif track == PASS: elif track == PASS:
self.toonAttacks[toonId] = getToonAttack(toonId, track=PASS) self.toonAttacks[toonId] = getToonAttack(toonId, track=PASS)
elif track == FIRE: elif track == FIRE:
if simbase.air.doId2do[toonId].getPinkSlips() < self.getFireCount() + 1: self.toonAttacks[toonId] = getToonAttack(toonId, track=FIRE, target=av)
#Not allowed to fire, force them to pass >:D
self.toonAttacks[toonId] = getToonAttack(toonId, track=PASS)
else:
#Allowed to fire
self.setFireCount(self.fireCount + 1)
self.toonAttacks[toonId] = getToonAttack(toonId, track=FIRE, target=av)
else: else:
if not self.validate(toonId, track >= 0 and track <= MAX_TRACK_INDEX, 'requestAttack: invalid track %s' % track): if not self.validate(toonId, track >= 0 and track <= MAX_TRACK_INDEX, 'requestAttack: invalid track %s' % track):
return return
@ -1104,25 +1097,65 @@ class DistributedBattleBaseAI(DistributedObjectAI.DistributedObjectAI, BattleBas
petId = toon.getPetId() petId = toon.getPetId()
zoneId = self.zoneId zoneId = self.zoneId
if petId == av: if petId == av:
if toonId not in self.pets: if not toonId in self.pets:
def handleGetPetProxy(success, pet, petId = petId, zoneId = zoneId, toonId = toonId):
def handleGetPetProxy(success, petProxy, petId = petId, zoneId = zoneId, toonId = toonId):
if success: if success:
if petId not in simbase.air.doId2do: petProxy = DistributedPetProxyAI.DistributedPetProxyAI(self.air)
simbase.air.requestDeleteDoId(petId) petProxy.setOwnerId(pet.getOwnerId())
else: petProxy.setPetName(pet.getPetName())
petDO = simbase.air.doId2do[petId] petProxy.setTraitSeed(pet.getTraitSeed())
petDO.requestDelete() petProxy.setSafeZone(pet.getSafeZone())
simbase.air.deleteDistObject(petDO) petProxy.setForgetfulness(pet.getForgetfulness())
petProxy.dbObject = 1 petProxy.setBoredomThreshold(pet.getBoredomThreshold())
petProxy.generateWithRequiredAndId(petId, self.air.districtId, zoneId) petProxy.setRestlessnessThreshold(pet.getRestlessnessThreshold())
petProxy.broadcastDominantMood() petProxy.setPlayfulnessThreshold(pet.getPlayfulnessThreshold())
self.pets[toonId] = petProxy petProxy.setLonelinessThreshold(pet.getLonelinessThreshold())
petProxy.setSadnessThreshold(pet.getSadnessThreshold())
petProxy.setFatigueThreshold(pet.getFatigueThreshold())
petProxy.setHungerThreshold(pet.getHungerThreshold())
petProxy.setConfusionThreshold(pet.getConfusionThreshold())
petProxy.setExcitementThreshold(pet.getExcitementThreshold())
petProxy.setAngerThreshold(pet.getAngerThreshold())
petProxy.setSurpriseThreshold(pet.getSurpriseThreshold())
petProxy.setAffectionThreshold(pet.getAffectionThreshold())
petProxy.setHead(pet.getHead())
petProxy.setEars(pet.getEars())
petProxy.setNose(pet.getNose())
petProxy.setTail(pet.getTail())
petProxy.setBodyTexture(pet.getBodyTexture())
petProxy.setColor(pet.getColor())
petProxy.setColorScale(pet.getColorScale())
petProxy.setEyeColor(pet.getEyeColor())
petProxy.setGender(pet.getGender())
petProxy.setLastSeenTimestamp(pet.getLastSeenTimestamp())
petProxy.setBoredom(pet.getBoredom())
petProxy.setRestlessness(pet.getRestlessness())
petProxy.setPlayfulness(pet.getPlayfulness())
petProxy.setLoneliness(pet.getLoneliness())
petProxy.setSadness(pet.getSadness())
petProxy.setAffection(pet.getAffection())
petProxy.setHunger(pet.getHunger())
petProxy.setConfusion(pet.getConfusion())
petProxy.setExcitement(pet.getExcitement())
petProxy.setFatigue(pet.getFatigue())
petProxy.setAnger(pet.getAnger())
petProxy.setSurprise(pet.getSurprise())
pet.requestDelete()
def deleted(task):
petProxy.dbObject = 1
petProxy.generateWithRequiredAndId(petId, self.air.districtId, self.zoneId)
petProxy.broadcastDominantMood()
self.pets[toonId] = petProxy
return task.done
self.acceptOnce(self.air.getAvatarExitEvent(petId),
lambda: taskMgr.doMethodLater(0,
deleted, self.uniqueName('petdel-%d' % petId)))
else: else:
self.notify.warning('error generating petProxy: %s' % petId) self.notify.warning('error generating petProxy: %s' % petId)
self.getPetProxyObject(petId, handleGetPetProxy) self.getPetProxyObject(petId, handleGetPetProxy)
return
def suitCanJoin(self): def suitCanJoin(self):
return len(self.suits) < self.maxSuits and self.isJoinable() return len(self.suits) < self.maxSuits and self.isJoinable()
@ -1809,18 +1842,12 @@ class DistributedBattleBaseAI(DistributedObjectAI.DistributedObjectAI, BattleBas
return None return None
def getPetProxyObject(self, petId, callback): def getPetProxyObject(self, petId, callback):
doneEvent = 'readPet-%s' % self._getNextSerialNum() doneEvent = 'generate-%d' % petId
dbo = DatabaseObject.DatabaseObject(self.air, petId, doneEvent=doneEvent)
pet = dbo.readPetProxy()
def handlePetProxyRead(dbo, retCode, callback = callback, pet = pet): def handlePetProxyRead(pet):
success = retCode == 0 callback(1, pet)
if not success:
self.notify.warning('pet DB read failed')
pet = None
callback(success, pet)
return
self.air.sendActivate(petId, self.air.districtId, 0)
self.acceptOnce(doneEvent, handlePetProxyRead) self.acceptOnce(doneEvent, handlePetProxyRead)
def _getNextSerialNum(self): def _getNextSerialNum(self):
@ -1828,13 +1855,8 @@ class DistributedBattleBaseAI(DistributedObjectAI.DistributedObjectAI, BattleBas
self.serialNum += 1 self.serialNum += 1
return num return num
def setFireCount(self, amount):
self.fireCount = amount
def getFireCount(self): @magicWord(category=CATEGORY_MODERATOR)
return self.fireCount
@magicWord(category=CATEGORY_PROGRAMMER)
def skipMovie(): def skipMovie():
invoker = spellbook.getInvoker() invoker = spellbook.getInvoker()
battleId = invoker.getBattleId() battleId = invoker.getBattleId()

View file

@ -411,7 +411,7 @@ def __createSuitTrack(drop, delay, level, alreadyDodged, alreadyTeased, target,
suitTrack.append(suitGettingHit) suitTrack.append(suitGettingHit)
bonusTrack = None bonusTrack = None
if hpbonus > 0: if hpbonus > 0:
bonusTrack = Sequence(Wait(delay + tObjectAppears + 0.75), Func(suit.showHpText, -hpbonus, 1, openEnded=0)) bonusTrack = Sequence(Wait(delay + tObjectAppears + 0.75), Func(suit.showHpText, -hpbonus, 1, openEnded=0), Func(suit.updateHealthBar, hpbonus))
if revived != 0: if revived != 0:
suitTrack.append(MovieUtil.createSuitReviveTrack(suit, toon, battle, npcs)) suitTrack.append(MovieUtil.createSuitReviveTrack(suit, toon, battle, npcs))
elif died != 0: elif died != 0:

View file

@ -102,7 +102,7 @@ def __getSuitTrack(sound, lastSoundThatHit, delay, hitCount, targets, totalDamag
suitTrack.append(Func(battle.unlureSuit, suit)) suitTrack.append(Func(battle.unlureSuit, suit))
bonusTrack = None bonusTrack = None
if hpbonus > 0: if hpbonus > 0:
bonusTrack = Sequence(Wait(delay + tSuitReact + delay + 0.75 + uberDelay), Func(suit.showHpText, -hpbonus, 1, openEnded=0)) bonusTrack = Sequence(Wait(delay + tSuitReact + delay + 0.75 + uberDelay), Func(suit.showHpText, -hpbonus, 1, openEnded=0), Func(suit.updateHealthBar, hpbonus))
suitTrack.append(Func(suit.loop, 'neutral')) suitTrack.append(Func(suit.loop, 'neutral'))
if bonusTrack == None: if bonusTrack == None:
tracks.append(suitTrack) tracks.append(suitTrack)

View file

@ -206,9 +206,11 @@ def __getSuitTrack(suit, tContact, tDodge, hp, hpbonus, kbbonus, anim, died, lef
if kbbonus > 0: if kbbonus > 0:
bonusTrack.append(Wait(0.75)) bonusTrack.append(Wait(0.75))
bonusTrack.append(Func(suit.showHpText, -kbbonus, 2, openEnded=0, attackTrack=SQUIRT_TRACK)) bonusTrack.append(Func(suit.showHpText, -kbbonus, 2, openEnded=0, attackTrack=SQUIRT_TRACK))
bonusTrack.append(Func(suit.updateHealthBar, kbbonus))
if hpbonus > 0: if hpbonus > 0:
bonusTrack.append(Wait(0.75)) bonusTrack.append(Wait(0.75))
bonusTrack.append(Func(suit.showHpText, -hpbonus, 1, openEnded=0, attackTrack=SQUIRT_TRACK)) bonusTrack.append(Func(suit.showHpText, -hpbonus, 1, openEnded=0, attackTrack=SQUIRT_TRACK))
bonusTrack.append(Func(suit.updateHealthBar, hpbonus))
if died != 0: if died != 0:
suitTrack.append(MovieUtil.createSuitDeathTrack(suit, toon, battle)) suitTrack.append(MovieUtil.createSuitDeathTrack(suit, toon, battle))
else: else:

View file

@ -367,9 +367,11 @@ def __throwPie(throw, delay, hitCount):
if kbbonus > 0: if kbbonus > 0:
bonusTrack.append(Wait(0.75)) bonusTrack.append(Wait(0.75))
bonusTrack.append(Func(suit.showHpText, -kbbonus, 2, openEnded=0, attackTrack=THROW_TRACK)) bonusTrack.append(Func(suit.showHpText, -kbbonus, 2, openEnded=0, attackTrack=THROW_TRACK))
bonusTrack.append(Func(suit.updateHealthBar, kbbonus))
if hpbonus > 0: if hpbonus > 0:
bonusTrack.append(Wait(0.75)) bonusTrack.append(Wait(0.75))
bonusTrack.append(Func(suit.showHpText, -hpbonus, 1, openEnded=0, attackTrack=THROW_TRACK)) bonusTrack.append(Func(suit.showHpText, -hpbonus, 1, openEnded=0, attackTrack=THROW_TRACK))
bonusTrack.append(Func(suit.updateHealthBar, hpbonus))
if revived != 0: if revived != 0:
suitResponseTrack.append(MovieUtil.createSuitReviveTrack(suit, toon, battle)) suitResponseTrack.append(MovieUtil.createSuitReviveTrack(suit, toon, battle))
elif died != 0: elif died != 0:
@ -563,9 +565,11 @@ def __throwGroupPie(throw, delay, groupHitDict):
if kbbonus > 0: if kbbonus > 0:
bonusTrack.append(Wait(0.75)) bonusTrack.append(Wait(0.75))
bonusTrack.append(Func(suit.showHpText, -kbbonus, 2, openEnded=0, attackTrack=THROW_TRACK)) bonusTrack.append(Func(suit.showHpText, -kbbonus, 2, openEnded=0, attackTrack=THROW_TRACK))
bonusTrack.append(Func(suit.updateHealthBar, kbbonus))
if hpbonus > 0: if hpbonus > 0:
bonusTrack.append(Wait(0.75)) bonusTrack.append(Wait(0.75))
bonusTrack.append(Func(suit.showHpText, -hpbonus, 1, openEnded=0, attackTrack=THROW_TRACK)) bonusTrack.append(Func(suit.showHpText, -hpbonus, 1, openEnded=0, attackTrack=THROW_TRACK))
bonusTrack.append(Func(suit.updateHealthBar, hpbonus))
if revived != 0: if revived != 0:
singleSuitResponseTrack.append(MovieUtil.createSuitReviveTrack(suit, toon, battle)) singleSuitResponseTrack.append(MovieUtil.createSuitReviveTrack(suit, toon, battle))
elif died != 0: elif died != 0:

View file

@ -1,14 +1,17 @@
from pandac.PandaModules import *
from direct.directnotify import DirectNotifyGlobal
import DistributedDoorAI import DistributedDoorAI
import DistributedPetshopInteriorAI import DistributedPetshopInteriorAI
import FADoorCodes
import DoorTypes import DoorTypes
from pandac.PandaModules import *
from toontown.hood import ZoneUtil
# from toontown.pets import DistributedPetAI, PetTraits, PetUtil
from toontown.toon import NPCToons from toontown.toon import NPCToons
from toontown.toonbase import ToontownGlobals from toontown.toonbase import ToontownGlobals
from toontown.quest import Quests
from toontown.hood import ZoneUtil
class PetshopBuildingAI: class PetshopBuildingAI:
notify = DirectNotifyGlobal.directNotify.newCategory('PetshopBuildingAI')
def __init__(self, air, exteriorZone, interiorZone, blockNumber): def __init__(self, air, exteriorZone, interiorZone, blockNumber):
self.air = air self.air = air
self.exteriorZone = exteriorZone self.exteriorZone = exteriorZone
@ -33,6 +36,8 @@ class PetshopBuildingAI:
self.npcs = NPCToons.createNpcsInZone(self.air, self.interiorZone) self.npcs = NPCToons.createNpcsInZone(self.air, self.interiorZone)
seeds = self.air.petMgr.getAvailablePets(1, len(self.npcs))
door = DistributedDoorAI.DistributedDoorAI( door = DistributedDoorAI.DistributedDoorAI(
self.air, blockNumber, DoorTypes.EXT_STANDARD) self.air, blockNumber, DoorTypes.EXT_STANDARD)
insideDoor = DistributedDoorAI.DistributedDoorAI( insideDoor = DistributedDoorAI.DistributedDoorAI(
@ -47,13 +52,4 @@ class PetshopBuildingAI:
self.insideDoor = insideDoor self.insideDoor = insideDoor
def createPet(self, ownerId, seed): def createPet(self, ownerId, seed):
zoneId = self.interiorZone return
safeZoneId = ZoneUtil.getCanonicalSafeZoneId(zoneId)
(name, dna, traitSeed) = PetUtil.getPetInfoFromSeed(seed, safeZoneId)
pet = DistributedPetAI.DistributedPetAI(self.air, dna=dna)
pet.setOwnerId(ownerId)
pet.setPetName(name)
pet.traits = PetTraits.PetTraits(traitSeed=traitSeed, safeZoneId=safeZoneId)
pet.generateWithRequired(zoneId)
pet.setPos(0, 0, 0)
pet.b_setParent(ToontownGlobals.SPRender)

View file

@ -44,7 +44,7 @@ class CatalogPetTrickItem(CatalogItem.CatalogItem):
def getPicture(self, avatar): def getPicture(self, avatar):
from toontown.pets import PetDNA, Pet from toontown.pets import PetDNA, Pet
pet = Pet.Pet(forGui=1) pet = Pet.Pet(forGui=1)
dna = avatar.petDNA dna = avatar.getPetDNA()
if dna == None: if dna == None:
dna = PetDNA.getRandomPetDNA() dna = PetDNA.getRandomPetDNA()
pet.setDNA(dna) pet.setDNA(dna)

View file

@ -349,7 +349,7 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository):
pad.avatar = avatar pad.avatar = avatar
pad.delayDelete = DelayDelete.DelayDelete(avatar, 'getAvatarDetails') pad.delayDelete = DelayDelete.DelayDelete(avatar, 'getAvatarDetails')
self.__queryAvatarMap[avatar.doId] = pad self.__queryAvatarMap[avatar.doId] = pad
self.__sendGetAvatarDetails(avatar.doId) self.__sendGetAvatarDetails(avatar.doId, pet=(args[0].endswith("Pet")))
def cancelAvatarDetailsRequest(self, avatar): def cancelAvatarDetailsRequest(self, avatar):
avId = avatar.doId avId = avatar.doId
@ -357,8 +357,11 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository):
pad = self.__queryAvatarMap.pop(avId) pad = self.__queryAvatarMap.pop(avId)
pad.delayDelete.destroy() pad.delayDelete.destroy()
def __sendGetAvatarDetails(self, avId): def __sendGetAvatarDetails(self, avId, pet=0):
self.ttuFriendsManager.d_getAvatarDetails(avId) if pet:
self.ttuFriendsManager.d_getPetDetails(avId)
else:
self.ttuFriendsManager.d_getAvatarDetails(avId)
def n_handleGetAvatarDetailsResp(self, avId, fields): def n_handleGetAvatarDetailsResp(self, avId, fields):
self.notify.info('Query reponse for avId %d' % avId) self.notify.info('Query reponse for avId %d' % avId)
@ -759,12 +762,13 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository):
def addPetToFriendsMap(self, callback = None): def addPetToFriendsMap(self, callback = None):
doId = base.localAvatar.getPetId() doId = base.localAvatar.getPetId()
if doId not in self.friendsMap: if not doId or doId in self.friendsMap:
if callback: if callback:
callback() callback()
return return
def petDetailsCallback(petAvatar): def petDetailsCallback(petAvatar):
petAvatar.announceGenerate()
handle = PetHandle.PetHandle(petAvatar) handle = PetHandle.PetHandle(petAvatar)
self.friendsMap[doId] = handle self.friendsMap[doId] = handle
petAvatar.disable() petAvatar.disable()

View file

@ -7,6 +7,7 @@ import HouseGlobals
import functools import functools
class LoadHouseFSM(FSM): class LoadHouseFSM(FSM):
notify = DirectNotifyGlobal.directNotify.newCategory('LoadHouseFSM')
def __init__(self, mgr, estate, houseIndex, toon, callback): def __init__(self, mgr, estate, houseIndex, toon, callback):
FSM.__init__(self, 'LoadHouseFSM') FSM.__init__(self, 'LoadHouseFSM')
self.mgr = mgr self.mgr = mgr
@ -100,6 +101,35 @@ class LoadHouseFSM(FSM):
self.done = True self.done = True
self.callback(self.house) self.callback(self.house)
class LoadPetFSM(FSM):
def __init__(self, mgr, estate, toon, callback):
FSM.__init__(self, 'LoadPetFSM')
self.mgr = mgr
self.estate = estate
self.toon = toon
self.callback = callback
self.pet = None
self.done = False
def start(self):
self.petId = self.toon['setPetId'][0]
if not self.petId in self.mgr.air.doId2do:
self.mgr.air.sendActivate(self.petId, self.mgr.air.districtId, self.estate.zoneId)
self.acceptOnce('generate-%d' % self.petId, self.__generated)
else:
self.__generated(self.mgr.air.doId2do[self.petId])
def __generated(self, pet):
self.pet = pet
self.estate.pets.append(pet)
self.demand('Off')
def enterOff(self):
self.done = True
self.callback(self.pet)
class LoadEstateFSM(FSM): class LoadEstateFSM(FSM):
def __init__(self, mgr, callback): def __init__(self, mgr, callback):
FSM.__init__(self, 'LoadEstateFSM') FSM.__init__(self, 'LoadEstateFSM')
@ -201,6 +231,7 @@ class LoadEstateFSM(FSM):
def __gotEstate(self, estate): def __gotEstate(self, estate):
self.estate = estate self.estate = estate
self.estate.pets = []
self.estate.toons = self.toonIds self.estate.toons = self.toonIds
self.estate.updateToons() self.estate.updateToons()
@ -229,6 +260,28 @@ class LoadEstateFSM(FSM):
# A houseFSM just finished! Let's see if all of them are done: # A houseFSM just finished! Let's see if all of them are done:
if all(houseFSM.done for houseFSM in self.houseFSMs): if all(houseFSM.done for houseFSM in self.houseFSMs):
self.demand('LoadPets')
def enterLoadPets(self):
self.petFSMs = []
for houseIndex in range(6):
toon = self.toons[houseIndex]
if toon and toon['setPetId'][0] != 0:
fsm = LoadPetFSM(self.mgr, self.estate, toon, self.__petDone)
self.petFSMs.append(fsm)
fsm.start()
else:
continue
if not self.petFSMs:
self.demand('Finished')
def __petDone(self, pet):
if self.state != 'LoadPets':
pet.requestDelete()
return
if all(petFSM.done for petFSM in self.petFSMs):
self.demand('Finished') self.demand('Finished')
def enterFinished(self): def enterFinished(self):
@ -403,5 +456,7 @@ class EstateManagerAI(DistributedObjectAI):
pass pass
def _lookupEstate(self, toon): def _lookupEstate(self, toon):
print(self.toon2estate)
return self.toon2estate.get(toon) return self.toon2estate.get(toon)
def getOwnerFromZone(self, avId):
return False

View file

@ -41,6 +41,26 @@ class TTUFriendsManager(DistributedObjectGlobal):
] ]
base.cr.n_handleGetAvatarDetailsResp(avId, fields=fields) base.cr.n_handleGetAvatarDetailsResp(avId, fields=fields)
def d_getPetDetails(self, avId):
self.sendUpdate('getPetDetails', [avId])
def petDetails(self, avId, ownerId, petName, traitSeed, sz, traits, moods, dna, lastSeen):
fields = list(zip(("setHead", "setEars", "setNose", "setTail", "setBodyTexture", "setColor", "setColorScale", "setEyeColor", "setGender"), dna))
fields.extend(zip(("setBoredom", "setRestlessness", "setPlayfulness", "setLoneliness",
"setSadness", "setAffection", "setHunger", "setConfusion", "setExcitement",
"setFatigue", "setAnger", "setSurprise"), moods))
fields.extend(zip(("setForgetfulness", "setBoredomThreshold", "setRestlessnessThreshold",
"setPlayfulnessThreshold", "setLonelinessThreshold", "setSadnessThreshold",
"setFatigueThreshold", "setHungerThreshold", "setConfusionThreshold",
"setExcitementThreshold", "setAngerThreshold", "setSurpriseThreshold",
"setAffectionThreshold"), traits))
fields.append(("setOwnerId", ownerId))
fields.append(("setPetName", petName))
fields.append(("setTraitSeed", traitSeed))
fields.append(("setSafeZone", sz))
fields.append(("setLastSeenTimestamp", lastSeen))
base.cr.n_handleGetAvatarDetailsResp(avId, fields=fields)
def d_teleportQuery(self, toId): def d_teleportQuery(self, toId):
self.sendUpdate('routeTeleportQuery', [toId]) self.sendUpdate('routeTeleportQuery', [toId])

View file

@ -258,6 +258,26 @@ class TTUFriendsManagerUD(DistributedObjectGlobalUD):
self.sendUpdateToAvatarId(senderId, 'friendDetails', [avId, inventory, trackAccess, trophies, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel]) self.sendUpdateToAvatarId(senderId, 'friendDetails', [avId, inventory, trackAccess, trophies, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel])
self.air.dbInterface.queryObject(self.air.dbId, avId, handleToon) self.air.dbInterface.queryObject(self.air.dbId, avId, handleToon)
def getPetDetails(self, avId):
senderId = self.air.getAvatarIdFromSender()
def handlePet(dclass, fields):
if dclass != self.air.dclassesByName['DistributedPetUD']:
return
dna = [fields.get(x, [0])[0] for x in ("setHead", "setEars", "setNose", "setTail", "setBodyTexture", "setColor",
"setColorScale", "setEyeColor", "setGender")]
moods = [fields.get(x, [0])[0] for x in ("setBoredom", "setRestlessness", "setPlayfulness", "setLoneliness",
"setSadness", "setAffection", "setHunger", "setConfusion", "setExcitement",
"setFatigue", "setAnger", "setSurprise")]
traits = [fields.get(x, [0])[0] for x in ("setForgetfulness", "setBoredomThreshold", "setRestlessnessThreshold",
"setPlayfulnessThreshold", "setLonelinessThreshold", "setSadnessThreshold",
"setFatigueThreshold", "setHungerThreshold", "setConfusionThreshold",
"setExcitementThreshold", "setAngerThreshold", "setSurpriseThreshold",
"setAffectionThreshold")]
self.sendUpdateToAvatarId(senderId, 'petDetails', [avId, fields.get("setOwnerId", [0])[0], fields.get("setPetName", ["???"])[0],
fields.get("setTraitSeed", [0])[0], fields.get("setSafeZone", [0])[0],
traits, moods, dna, fields.get("setLastSeenTimestamp", [0])[0]])
self.air.dbInterface.queryObject(self.air.dbId, avId, handlePet)
# -- Toon Online/Offline -- # -- Toon Online/Offline --
def toonOnline(self, doId, friendsList): def toonOnline(self, doId, friendsList):
self.onlineToons.append(doId) self.onlineToons.append(doId)

View file

@ -720,10 +720,17 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
base.localAvatar.b_teleportGreeting(avId) base.localAvatar.b_teleportGreeting(avId)
else: else:
friend = base.cr.identifyAvatar(avId) friend = base.cr.identifyAvatar(avId)
if friend != None: if friend == None:
teleportDebug(requestStatus, 'friend not here, giving up') teleportDebug(requestStatus, 'friend not here, giving up')
base.localAvatar.setSystemMessage(avId, OTPLocalizer.WhisperTargetLeftVisit % (friend.getName(),)) base.localAvatar.setSystemMessage(avId, OTPLocalizer.WhisperTargetLeftVisit % (friend.getName(),))
friend.d_teleportGiveup(base.localAvatar.doId) friend.d_teleportGiveup(base.localAvatar.doId)
else:
def doTeleport(task):
avatar = base.cr.doId2do[friend.getDoId()]
base.localAvatar.gotoNode(avatar)
base.localAvatar.b_teleportGreeting(friend.getDoId())
return task.done
self.acceptOnce('generate-%d' % friend.getDoId(), lambda x: taskMgr.doMethodLater(1, doTeleport, uniqueName('doTeleport')))
base.transitions.irisIn() base.transitions.irisIn()
self.nextState = requestStatus.get('nextState', 'walk') self.nextState = requestStatus.get('nextState', 'walk')
base.localAvatar.attachCamera() base.localAvatar.attachCamera()

View file

@ -9,9 +9,7 @@ from direct.fsm import ClassicFSM, State
from direct.interval.IntervalGlobal import * from direct.interval.IntervalGlobal import *
from toontown.toonbase import ToontownGlobals from toontown.toonbase import ToontownGlobals
from direct.task import Task from direct.task import Task
from otp.movement import Mover from toontown.pets import PetLookerAI
from toontown.pets import PetChase, PetFlee, PetWander, PetLeash
from toontown.pets import PetCollider, PetSphere, PetLookerAI
from toontown.pets import PetConstants, PetDNA, PetTraits from toontown.pets import PetConstants, PetDNA, PetTraits
from toontown.pets import PetObserve, PetBrain, PetMood from toontown.pets import PetObserve, PetBrain, PetMood
from toontown.pets import PetActionFSM, PetBase, PetGoal, PetTricks from toontown.pets import PetActionFSM, PetBase, PetGoal, PetTricks
@ -24,6 +22,8 @@ import string
import copy import copy
from direct.showbase.PythonUtil import StackTrace from direct.showbase.PythonUtil import StackTrace
from PetMoverAI import PetMoverAI
class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLookerAI.PetLookerAI, PetBase.PetBase): class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLookerAI.PetLookerAI, PetBase.PetBase):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedPetAI') notify = DirectNotifyGlobal.directNotify.newCategory('DistributedPetAI')
movieTimeSwitch = {PetConstants.PET_MOVIE_FEED: PetConstants.FEED_TIME, movieTimeSwitch = {PetConstants.PET_MOVIE_FEED: PetConstants.FEED_TIME,
@ -126,18 +126,16 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
def handleLogicalZoneChange(self, newZoneId, oldZoneId): def handleLogicalZoneChange(self, newZoneId, oldZoneId):
DistributedSmoothNodeAI.DistributedSmoothNodeAI.handleLogicalZoneChange(self, newZoneId, oldZoneId) DistributedSmoothNodeAI.DistributedSmoothNodeAI.handleLogicalZoneChange(self, newZoneId, oldZoneId)
self.announceZoneChange(newZoneId, oldZoneId) self.announceZoneChange(newZoneId, oldZoneId)
self.destroySphereImpulse()
self.createSphereImpulse()
def announceZoneChange(self, newZoneId, oldZoneId): def announceZoneChange(self, newZoneId, oldZoneId):
DistributedPetAI.notify.debug('%s.announceZoneChange: %s->%s' % (self.doId, oldZoneId, newZoneId)) DistributedPetAI.notify.debug('%s.announceZoneChange: %s->%s' % (self.doId, oldZoneId, newZoneId))
broadcastZones = list2dict([newZoneId, oldZoneId]) broadcastZones = list2dict([newZoneId, oldZoneId])
self.estateOwnerId = simbase.air.estateMgr.getOwnerFromZone(newZoneId) self.estateOwnerId = simbase.air.estateManager.getOwnerFromZone(newZoneId)
if self.estateOwnerId: if self.estateOwnerId:
if __dev__: if __dev__:
pass pass
self.inEstate = 1 self.inEstate = 1
self.estateZones = simbase.air.estateMgr.getEstateZones(self.estateOwnerId) self.estateZones = simbase.air.estateManager.getEstateZones(self.estateOwnerId)
else: else:
self.inEstate = 0 self.inEstate = 0
self.estateZones = [] self.estateZones = []
@ -475,8 +473,8 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
else: else:
self.setTrickAptitudes(aptitudes, local=1) self.setTrickAptitudes(aptitudes, local=1)
def generate(self): def announceGenerate(self):
DistributedSmoothNodeAI.DistributedSmoothNodeAI.generate(self) DistributedSmoothNodeAI.DistributedSmoothNodeAI.announceGenerate(self)
self._hasCleanedUp = False self._hasCleanedUp = False
self.setHasRequestedDelete(False) self.setHasRequestedDelete(False)
self.b_setParent(ToontownGlobals.SPHidden) self.b_setParent(ToontownGlobals.SPHidden)
@ -517,9 +515,7 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
self.requiredMoodComponents = {} self.requiredMoodComponents = {}
self.brain = PetBrain.PetBrain(self) self.brain = PetBrain.PetBrain(self)
self.mover = Mover.Mover(self) self.mover = PetMoverAI(self)
self.lockMover = Mover.Mover(self)
self.createImpulses()
self.enterPetLook() self.enterPetLook()
self.actionFSM = PetActionFSM.PetActionFSM(self) self.actionFSM = PetActionFSM.PetActionFSM(self)
self.teleportIn() self.teleportIn()
@ -591,11 +587,8 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
self.actionFSM.destroy() self.actionFSM.destroy()
del self.actionFSM del self.actionFSM
self.exitPetLook() self.exitPetLook()
self.destroyImpulses()
self.mover.destroy() self.mover.destroy()
del self.mover del self.mover
self.lockMover.destroy()
del self.lockMover
self.stopPosHprBroadcast() self.stopPosHprBroadcast()
if hasattr(self, 'mood'): if hasattr(self, 'mood'):
self.mood.destroy() self.mood.destroy()
@ -645,37 +638,6 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
self.ignoreAll() self.ignoreAll()
return return
def createImpulses(self):
self.createSphereImpulse()
self.chaseImpulse = PetChase()
self.fleeImpulse = PetFlee()
self.wanderImpulse = PetWander.PetWander()
self.lockChaseImpulse = PetChase()
def destroyImpulses(self):
self.wanderImpulse.destroy()
del self.chaseImpulse
del self.fleeImpulse
del self.wanderImpulse
self.destroySphereImpulse()
del self.lockChaseImpulse
def createSphereImpulse(self):
petRadius = 1.0
collTrav = self.getCollTrav()
if collTrav is None:
DistributedPetAI.notify.warning('no collision traverser for zone %s' % self.zoneId)
else:
self.sphereImpulse = PetSphere.PetSphere(petRadius, collTrav)
self.mover.addImpulse('sphere', self.sphereImpulse)
return
def destroySphereImpulse(self):
self.mover.removeImpulse('sphere')
if hasattr(self, 'sphereImpulse'):
self.sphereImpulse.destroy()
del self.sphereImpulse
def getMoveTaskName(self): def getMoveTaskName(self):
return 'petMove-%s' % self.doId return 'petMove-%s' % self.doId
@ -684,15 +646,10 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
def move(self, task = None): def move(self, task = None):
if self.isEmpty(): if self.isEmpty():
try: self.air.writeServerEvent('Late Pet Move Call', self.doId, ' ')
self.air.writeServerEvent('Late Pet Move Call', self.doId, ' ')
except:
pass
taskMgr.remove(task.name) taskMgr.remove(task.name)
return Task.done return Task.done
if not self.isLockMoverEnabled():
self.mover.move()
numNearby = len(self.brain.nearbyAvs) - 1 numNearby = len(self.brain.nearbyAvs) - 1
minNearby = 5 minNearby = 5
if numNearby > minNearby: if numNearby > minNearby:
@ -784,6 +741,7 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
def lockPet(self): def lockPet(self):
DistributedPetAI.notify.debug('%s: lockPet' % self.doId) DistributedPetAI.notify.debug('%s: lockPet' % self.doId)
if not self.lockedDown: if not self.lockedDown:
self.mover.lock()
self.stopPosHprBroadcast() self.stopPosHprBroadcast()
self.lockedDown += 1 self.lockedDown += 1
@ -840,18 +798,6 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
def unstickEnterOn(self): def unstickEnterOn(self):
self._collisionTimestamps = [] self._collisionTimestamps = []
self.accept(self.mover.getCollisionEventName(), self._handleCollided)
def _handleCollided(self, collEntry):
now = globalClock.getFrameTime()
self._collisionTimestamps.append(now)
while now - self._collisionTimestamps[0] > PetConstants.UnstickSampleWindow:
del self._collisionTimestamps[0:1]
if len(self._collisionTimestamps) > PetConstants.UnstickCollisionThreshold:
self._collisionTimestamps = []
DistributedPetAI.notify.debug('unsticking pet %s' % self.doId)
self.brain._unstick()
def unstickExitOn(self): def unstickExitOn(self):
pass pass
@ -987,14 +933,10 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
def startLockPetMove(self, avId): def startLockPetMove(self, avId):
self.enableLockMover() self.enableLockMover()
self.lockChaseImpulse.setTarget(self.air.doId2do.get(avId))
self.lockMover.addImpulse('LockTarget', self.lockChaseImpulse)
self.lockMover.setFwdSpeed(self.mover.getFwdSpeed())
self.lockMover.setRotSpeed(self.mover.getRotSpeed())
dist_Callable = self.movieDistSwitch.get(self.movieMode) dist_Callable = self.movieDistSwitch.get(self.movieMode)
dist = dist_Callable(self.air.doId2do.get(avId).getStyle().getLegSize()) dist = dist_Callable(self.air.doId2do.get(avId).getStyle().getLegSize())
self.lockChaseImpulse.setMinDist(dist)
self.distList = [0, 0, 0] self.distList = [0, 0, 0]
self.mover.walkToAvatar(self.air.doId2do[avId], callback=lambda: self.endLockPetMove(avId))
self.__lockPetMoveTask(avId) self.__lockPetMoveTask(avId)
def getAverageDist(self): def getAverageDist(self):
@ -1005,33 +947,12 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
return sum / 3.0 return sum / 3.0
def __lockPetMoveTask(self, avId): def __lockPetMoveTask(self, avId):
if not hasattr(self, 'air') or avId not in self.air.doId2do:
self.notify.warning('avId: %s gone or self deleted!' % avId)
return Task.done
av = self.air.doId2do.get(avId)
dist = av.getDistance(self)
self.distList.append(dist)
if len(self.distList) > 3:
self.distList.pop(0)
if self.movieMode in self.movieDistSwitch:
dist_Callable = self.movieDistSwitch.get(self.movieMode)
movieDist = dist_Callable(av.getStyle().getLegSize())
else:
self.notify.warning('movieMode: %s not in movieSwitchDist map!' % self.movieMode)
return Task.done
avgDist = self.getAverageDist()
if dist - movieDist > 0.25 and abs(avgDist - dist) > 0.1:
self.lockMover.move()
taskMgr.doMethodLater(simbase.petMovePeriod, self.__lockPetMoveTask, self.getLockMoveTaskName(), [avId])
else:
self.endLockPetMove(avId)
return Task.done return Task.done
def endLockPetMove(self, avId): def endLockPetMove(self, avId):
del self.distList del self.distList
taskMgr.remove(self.getLockMoveTaskName()) taskMgr.remove(self.getLockMoveTaskName())
self.lockPet() self.lockPet()
self.lockMover.removeImpulse('LockTarget')
self.__petMovieStart(avId) self.__petMovieStart(avId)
def enableLockMover(self): def enableLockMover(self):
@ -1060,7 +981,7 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
if self.mood.isComponentActive('fatigue'): if self.mood.isComponentActive('fatigue'):
cutoff *= 0.5 cutoff *= 0.5
cutoff *= PetTricks.TrickAccuracies[trickId] cutoff *= PetTricks.TrickAccuracies[trickId]
DistributedPetAI.notify.debug('_willDoTrick: %s / %s' % (randVal, cutoff)) DistributedPetAI.notify.info('_willDoTrick: %s / %s' % (randVal, cutoff)) # .debug
return randVal < cutoff return randVal < cutoff
def _handleDidTrick(self, trickId): def _handleDidTrick(self, trickId):
@ -1081,13 +1002,9 @@ class DistributedPetAI(DistributedSmoothNodeAI.DistributedSmoothNodeAI, PetLooke
if self.leashMode: if self.leashMode:
self.leashMode = 0 self.leashMode = 0
self.leashAvId = None self.leashAvId = None
self.brain.goalMgr.removeGoal(self.leashGoal)
del self.leashGoal
response = 'leash OFF' response = 'leash OFF'
else: else:
self.leashMode = 1 self.leashMode = 1
self.leashAvId = avId self.leashAvId = avId
self.leashGoal = PetGoal.ChaseAvatarLeash(avId)
self.brain.goalMgr.addGoal(self.leashGoal)
response = 'leash ON' response = 'leash ON'
return response return response

View file

@ -356,7 +356,6 @@ class DistributedPetProxyAI(DistributedObjectAI.DistributedObjectAI):
def generate(self): def generate(self):
DistributedObjectAI.DistributedObjectAI.generate(self) DistributedObjectAI.DistributedObjectAI.generate(self)
self.traits = PetTraits.PetTraits(self.traitSeed, self.safeZone) self.traits = PetTraits.PetTraits(self.traitSeed, self.safeZone)
print self.traits.traits
for i in xrange(len(self.traitList)): for i in xrange(len(self.traitList)):
value = self.traitList[i] value = self.traitList[i]
if value == 0.0: if value == 0.0:

View file

@ -0,0 +1,55 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectUD import DistributedObjectUD
class DistributedPetUD(DistributedObjectUD):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPetUD")
def setDNA(self, dna):
pass
def setOwnerId(self, ownerId):
pass
def setTraitSeed(self, traitSeed):
pass
def setSafeZone(self, safeZone):
pass
def setHead(self, head):
pass
def setEars(self, ears):
pass
def setNose(self, nose):
pass
def setTail(self, tail):
pass
def setBodyTexture(self, bodyTexture):
pass
def setColor(self, color):
pass
def setColorScale(self, colorScale):
pass
def setEyeColor(self, eyeColor):
pass
def setGender(self, gender):
pass
def setLastSeenTimestamp(self, timestamp):
pass
def setTrickAptitudes(self, aptitudes):
pass
def setLastSeenTimestamp(self, timestamp):
pass

View file

@ -1,24 +1,20 @@
from direct.actor import Actor from pandac.PandaModules import *
from direct.directnotify import DirectNotifyGlobal from direct.directnotify import DirectNotifyGlobal
from direct.distributed.ClockDelta import globalClockDelta from direct.interval.IntervalGlobal import *
from direct.fsm.ClassicFSM import * from direct.fsm.ClassicFSM import *
from direct.fsm.State import * from direct.fsm.State import *
from direct.interval.IntervalGlobal import * from direct.distributed.ClockDelta import globalClockDelta
from direct.showbase import PythonUtil
from direct.task import Task
from pandac.PandaModules import *
import random
import types
from PetDNA import HeadParts, EarParts, NoseParts, TailParts, BodyTypes, BodyTextures, AllPetColors, getColors, ColorScales, PetEyeColors, EarTextures, TailTextures, getFootTexture, getEarTexture, GiraffeTail, LeopardTail, PetGenders
from otp.avatar import Avatar from otp.avatar import Avatar
from toontown.chat.ChatGlobals import * from direct.actor import Actor
from toontown.nametag import NametagGlobals from direct.task import Task
from toontown.pets import PetDNA 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 TTLocalizer
from toontown.toonbase import ToontownGlobals from toontown.toonbase import ToontownGlobals
from direct.showbase import PythonUtil
import random
import types
Component2IconDict = {'boredom': 'Bored', Component2IconDict = {'boredom': 'Bored',
'restlessness': None, 'restlessness': None,
'playfulness': 'Play', 'playfulness': 'Play',
@ -32,6 +28,10 @@ Component2IconDict = {'boredom': 'Bored',
'surprise': 'Surprised', 'surprise': 'Surprised',
'affection': 'Love'} 'affection': 'Love'}
from toontown.nametag import *
from toontown.nametag.NametagGlobals import *
from toontown.nametag.NametagGroup import *
class Pet(Avatar.Avatar): class Pet(Avatar.Avatar):
notify = DirectNotifyGlobal.directNotify.newCategory('Pet') notify = DirectNotifyGlobal.directNotify.newCategory('Pet')
SerialNum = 0 SerialNum = 0
@ -268,7 +268,7 @@ class Pet(Avatar.Avatar):
def initializeBodyCollisions(self, collIdStr): def initializeBodyCollisions(self, collIdStr):
Avatar.Avatar.initializeBodyCollisions(self, collIdStr) Avatar.Avatar.initializeBodyCollisions(self, collIdStr)
if not self.ghostMode: if not self.ghostMode:
self.collNode.setCollideMask(self.collNode.getIntoCollideMask() | ToontownGlobals.PieBitmask) self.collNode.setCollideMask(self.collNode.getIntoCollideMask() | PieBitmask)
def amplifyColor(self, color, scale): def amplifyColor(self, color, scale):
color = color * scale color = color * scale
@ -284,7 +284,7 @@ class Pet(Avatar.Avatar):
self.moodIcons.setScale(2.0) self.moodIcons.setScale(2.0)
self.moodIcons.setZ(3.65) self.moodIcons.setZ(3.65)
moods = moodIcons.findAllMatches('**/+GeomNode') moods = moodIcons.findAllMatches('**/+GeomNode')
for moodNum in xrange(0, moods.getNumPaths()): for moodNum in range(0, moods.getNumPaths()):
mood = moods.getPath(moodNum) mood = moods.getPath(moodNum)
mood.reparentTo(self.moodIcons) mood.reparentTo(self.moodIcons)
mood.setBillboardPointEye() mood.setBillboardPointEye()
@ -327,9 +327,9 @@ class Pet(Avatar.Avatar):
if self.moodModel: if self.moodModel:
self.moodModel.hide() self.moodModel.hide()
if base.config.GetBool('want-speech-bubble', 1): if base.config.GetBool('want-speech-bubble', 1):
self.nametag.setChatText(random.choice(TTLocalizer.SpokenMoods[mood])) self.nametag.setChat(random.choice(TTLocalizer.SpokenMoods[mood]), CFSpeech)
else: else:
self.nametag.setChatText(random.choice(TTLocalizer.SpokenMoods[mood])) self.nametag.setChat(random.choice(TTLocalizer.SpokenMoods[mood]), CFThought)
def getGenderString(self): def getGenderString(self):
if self.style: if self.style:
@ -653,7 +653,7 @@ def gridPets():
offsetX = 0 offsetX = 0
offsetY = 0 offsetY = 0
startPos = base.localAvatar.getPos() startPos = base.localAvatar.getPos()
for body in xrange(0, len(BodyTypes)): for body in range(0, len(BodyTypes)):
colors = getColors(body) colors = getColors(body)
for color in colors: for color in colors:
p = Pet() p = Pet()

View file

@ -18,70 +18,30 @@ class PetActionFSM(FSM.FSM):
def destroy(self): def destroy(self):
self.cleanup() self.cleanup()
def enterNeutral(self):
PetActionFSM.notify.debug('enterNeutral')
def exitNeutral(self):
pass
def enterChase(self, target): def enterChase(self, target):
PetActionFSM.notify.debug('enterChase: %s' % target) PetActionFSM.notify.debug('enterChase: %s' % target)
self.pet.chaseImpulse.setTarget(target)
self.pet.mover.addImpulse('chase', self.pet.chaseImpulse)
self.pet.unstickFSM.request('on') self.pet.unstickFSM.request('on')
def exitChase(self): def exitChase(self):
self.pet.unstickFSM.request('off') self.pet.unstickFSM.request('off')
self.pet.mover.removeImpulse('chase')
def enterFlee(self, chaser): def enterFlee(self, chaser):
PetActionFSM.notify.debug('enterFlee: %s' % chaser) PetActionFSM.notify.debug('enterFlee: %s' % chaser)
self.pet.fleeImpulse.setChaser(chaser)
self.pet.mover.addImpulse('flee', self.pet.fleeImpulse)
self.pet.unstickFSM.request('on') self.pet.unstickFSM.request('on')
def exitFlee(self): def exitFlee(self):
self.pet.unstickFSM.request('off') self.pet.unstickFSM.request('off')
self.pet.mover.removeImpulse('flee')
def enterWander(self):
PetActionFSM.notify.debug('enterWander')
self.pet.mover.addImpulse('wander', self.pet.wanderImpulse)
def exitWander(self):
self.pet.mover.removeImpulse('wander')
def enterUnstick(self):
PetActionFSM.notify.debug('enterUnstick')
self.pet.mover.addImpulse('unstick', self.pet.wanderImpulse)
def exitUnstick(self):
self.pet.mover.removeImpulse('unstick')
def enterInspectSpot(self, spot): def enterInspectSpot(self, spot):
PetActionFSM.notify.debug('enterInspectSpot') PetActionFSM.notify.debug('enterInspectSpot')
self.pet.chaseImpulse.setTarget(spot)
self.pet.mover.addImpulse('inspect', self.pet.chaseImpulse)
self.pet.unstickFSM.request('on') self.pet.unstickFSM.request('on')
def exitInspectSpot(self): def exitInspectSpot(self):
self.pet.unstickFSM.request('off') self.pet.unstickFSM.request('off')
self.pet.mover.removeImpulse('inspect')
def enterStay(self, avatar):
PetActionFSM.notify.debug('enterStay')
def exitStay(self):
pass
def enterHeal(self, avatar): def enterHeal(self, avatar):
PetActionFSM.notify.debug('enterHeal') PetActionFSM.notify.debug('enterHeal')
avatar.toonUp(3) avatar.toonUp(3)
self.pet.chaseImpulse.setTarget(avatar)
self.pet.mover.addImpulse('chase', self.pet.chaseImpulse)
def exitHeal(self):
self.pet.mover.removeImpulse('chase')
def enterTrick(self, avatar, trickId): def enterTrick(self, avatar, trickId):
PetActionFSM.notify.debug('enterTrick') PetActionFSM.notify.debug('enterTrick')
@ -95,11 +55,9 @@ class PetActionFSM(FSM.FSM):
aptitude = self.pet.getTrickAptitude(trickId) aptitude = self.pet.getTrickAptitude(trickId)
healAmt = int(lerp(healRange[0], healRange[1], aptitude)) healAmt = int(lerp(healRange[0], healRange[1], aptitude))
if healAmt: if healAmt:
for avId in self.pet.brain.getAvIdsLookingAtUs(): for avId, av in self.pet._getFullNearbyToonDict().items():
av = self.pet.air.doId2do.get(avId) if isinstance(av, DistributedToonAI.DistributedToonAI):
if av: av.toonUp(healAmt)
if isinstance(av, DistributedToonAI.DistributedToonAI):
av.toonUp(healAmt)
self.pet._handleDidTrick(trickId) self.pet._handleDidTrick(trickId)
if not self.pet.isLockedDown(): if not self.pet.isLockedDown():
@ -124,9 +82,3 @@ class PetActionFSM(FSM.FSM):
if self.pet.isLockedDown(): if self.pet.isLockedDown():
self.pet.unlockPet() self.pet.unlockPet()
del self.trickDoneEvent del self.trickDoneEvent
def enterMovie(self):
PetActionFSM.notify.debug('enterMovie')
def exitMovie(self):
pass

View file

@ -2,11 +2,10 @@ from pandac.PandaModules import *
from direct.showbase.PythonUtil import weightedChoice, randFloat, Functor from direct.showbase.PythonUtil import weightedChoice, randFloat, Functor
from direct.showbase.PythonUtil import list2dict from direct.showbase.PythonUtil import list2dict
from direct.showbase import DirectObject from direct.showbase import DirectObject
from direct.distributed import DistributedObjectAI from direct.distributed import DistributedObject, DistributedObjectAI
from direct.directnotify import DirectNotifyGlobal from direct.directnotify import DirectNotifyGlobal
from direct.task import Task from direct.task import Task
from direct.fsm import FSM from direct.fsm import FSM
from toontown.toon import DistributedToonAI
from toontown.pets import PetConstants, PetObserve, PetGoal, PetGoalMgr from toontown.pets import PetConstants, PetObserve, PetGoal, PetGoalMgr
from toontown.pets import PetTricks, PetLookerAI from toontown.pets import PetTricks, PetLookerAI
import random, types import random, types
@ -387,13 +386,13 @@ class PetBrain(DirectObject.DirectObject):
def _handleComeHere(avId, self = self): def _handleComeHere(avId, self = self):
avatar = simbase.air.doId2do.get(avId) avatar = simbase.air.doId2do.get(avId)
if avatar: if avatar:
self._chase(avatar) self.pet.mover.walkToAvatar(avatar)
avatar.setHatePets(0) avatar.setHatePets(0)
def _handleFollowMe(avId, self = self): def _handleFollowMe(avId, self = self):
avatar = simbase.air.doId2do.get(avId) avatar = simbase.air.doId2do.get(avId)
if avatar: if avatar:
self._chase(avatar) self.pet.mover.walkToAvatar(avatar)
avatar.setHatePets(0) avatar.setHatePets(0)
def _handleStay(avId, self = self): def _handleStay(avId, self = self):
@ -421,15 +420,14 @@ class PetBrain(DirectObject.DirectObject):
return return
def _handleDoTrick(trickId, avId, self = self): def _handleDoTrick(trickId, avId, self = self):
looked = self.lookedAtBy(avId) or config.GetBool('pet-brain-ignore-looked-tricks', True)
avatar = simbase.air.doId2do.get(avId) avatar = simbase.air.doId2do.get(avId)
if avatar: if avatar:
if self.lookedAtBy(avatar.doId): if looked:
if not self.goalMgr.hasTrickGoal(): if not self.pet._willDoTrick(trickId):
if not self.pet._willDoTrick(trickId): self.pet.trickFailLogger.addEvent(trickId)
self.pet.trickFailLogger.addEvent(trickId) trickId = PetTricks.Tricks.BALK
trickId = PetTricks.Tricks.BALK self._doTrick(trickId, avatar)
trickGoal = PetGoal.DoTrick(avatar, trickId)
self.goalMgr.addGoal(trickGoal)
phrase = observe.getPetPhrase() phrase = observe.getPetPhrase()
avId = observe.getAvId() avId = observe.getAvId()

View file

@ -69,3 +69,6 @@ class PetChase(Impulse.Impulse):
if vH: if vH:
self.rotVel.setX(vH) self.rotVel.setX(vH)
self.mover.addRotShove(self.rotVel) self.mover.addRotShove(self.rotVel)
def setMinDist(self, minDist):
self.minDist = minDist

View file

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

View file

@ -240,7 +240,7 @@ def getBodyRarity(bodyIndex):
for zoneId in PetRarities['body']: for zoneId in PetRarities['body']:
for body in PetRarities['body'][zoneId]: for body in PetRarities['body'][zoneId]:
totalWeight += PetRarities['body'][zoneId][body] totalWeight += PetRarities['body'][zoneId][body]
if body in weight: if weight.has_key(body):
weight[body] += PetRarities['body'][zoneId][body] weight[body] += PetRarities['body'][zoneId][body]
else: else:
weight[body] = PetRarities['body'][zoneId][body] weight[body] = PetRarities['body'][zoneId][body]

View file

@ -59,6 +59,7 @@ class PetHandle:
def updateMoodFromServer(self, callWhenDone = None): def updateMoodFromServer(self, callWhenDone = None):
def handleGotDetails(avatar, callWhenDone = callWhenDone): def handleGotDetails(avatar, callWhenDone = callWhenDone):
avatar.announceGenerate()
self._grabMood(avatar) self._grabMood(avatar)
if callWhenDone: if callWhenDone:
callWhenDone() callWhenDone()

View file

@ -2,7 +2,7 @@ from pandac.PandaModules import *
from direct.directnotify import DirectNotifyGlobal from direct.directnotify import DirectNotifyGlobal
from direct.showbase import DirectObject from direct.showbase import DirectObject
from otp.ai.AIZoneData import AIZoneData from otp.ai.AIZoneData import AIZoneData
from toontown.toonbase import ToontownGlobals from toontown.toonbase.BitmaskGlobals import PetLookatPetBitmask, PetLookatNonPetBitmask
from toontown.pets import PetConstants from toontown.pets import PetConstants
def getStartLookingAtOtherEvent(lookingAvId): def getStartLookingAtOtherEvent(lookingAvId):
@ -83,11 +83,11 @@ class PetLookerAI:
lookSphereNode.addSolid(lookSphere) lookSphereNode.addSolid(lookSphere)
lookSphereNode.setFromCollideMask(BitMask32.allOff()) lookSphereNode.setFromCollideMask(BitMask32.allOff())
if isPet: if isPet:
intoCollideMask = ToontownGlobals.PetLookatPetBitmask intoCollideMask = PetLookatPetBitmask
fromCollideMask = ToontownGlobals.PetLookatPetBitmask | ToontownGlobals.PetLookatNonPetBitmask fromCollideMask = PetLookatPetBitmask | PetLookatNonPetBitmask
else: else:
intoCollideMask = ToontownGlobals.PetLookatNonPetBitmask intoCollideMask = PetLookatNonPetBitmask
fromCollideMask = ToontownGlobals.PetLookatPetBitmask fromCollideMask = PetLookatPetBitmask
lookSphereNode.setIntoCollideMask(intoCollideMask) lookSphereNode.setIntoCollideMask(intoCollideMask)
lookSphereNode.setFromCollideMask(fromCollideMask) lookSphereNode.setFromCollideMask(fromCollideMask)
self.lookSphereNodePath = self.__collNode.attachNewNode(lookSphereNode) self.lookSphereNodePath = self.__collNode.attachNewNode(lookSphereNode)

View file

@ -1,12 +1,86 @@
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 import random
import cPickle, time, random, os
MINUTE = 60
HOUR = 60 * MINUTE
DAY = 24 * HOUR
def getDayId():
return int(time.time() // DAY)
class PetManagerAI: class PetManagerAI:
NUM_DAILY_PETS = 5
cachePath = config.GetString('air-pet-cache', 'astron/databases/air_cache/')
def __init__(self, air): def __init__(self, air):
self.air = air self.air = air
self.cacheFile = '%spets_%d.pets' % (self.cachePath, self.air.districtId)
if os.path.isfile(self.cacheFile):
with open(self.cacheFile, 'rb') as f:
data = f.read()
def getAvailablePets(self, numPets=5): self.seeds = cPickle.loads(data)
return random.sample(xrange(256), numPets) if self.seeds.get('day', -1) != getDayId() or len(self.seeds.get(ToontownGlobals.ToontownCentral, [])) != self.NUM_DAILY_PETS:
self.generateSeeds()
def createNewPetFromSeed(self, avId, petSeeds, nameIndex, gender, safeZoneId): else:
pass # TODO 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):
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))
def getAvailablePets(self, seed, safezoneId):
if self.seeds.get('day', -1) != getDayId():
self.generateSeeds()
return self.seeds.get(safezoneId, [seed])
def createNewPetFromSeed(self, avId, seed, nameIndex, gender, safeZoneId):
av = self.air.doId2do[avId]
name = TTLocalizer.getPetName(nameIndex)
_, dna, traitSeed = PetUtil.getPetInfoFromSeed(seed, safeZoneId)
head, ears, nose, tail, body, color, cs, eye, _ = dna
numGenders = len(PetDNA.PetGenders)
gender %= numGenders
fields = {'setOwnerId' : avId, 'setPetName' : name, 'setTraitSeed' : traitSeed, 'setSafeZone' : safeZoneId,
'setHead' : head, 'setEars' : ears, 'setNose' : nose, 'setTail' : tail, 'setBodyTexture' : body,
'setColor' : color, 'setColorScale' : cs, 'setEyeColor' : eye, 'setGender' : gender}
def response(doId):
if not doId:
self.air.notify.warning("Cannot create pet for %s!" % avId)
return
self.air.writeServerEvent('bought-pet', avId, doId)
av.b_setPetId(doId)
self.air.dbInterface.createObject(self.air.dbId, self.air.dclassesByName['DistributedPetAI'],
{k: (v,) for k,v in fields.items()}, response)
def deleteToonsPet(self, avId):
av = self.air.doId2do[avId]
pet = av.getPetId()
if pet:
if pet in self.air.doId2do:
self.air.doId2do[pet].requestDelete()
av.b_setPetId(0)

177
toontown/pets/PetMoverAI.py Normal file
View file

@ -0,0 +1,177 @@
from panda3d.core import *
from direct.interval.IntervalGlobal import *
from direct.fsm.FSM import *
import random, math
estateRadius = 130
estateCenter = (0, -40)
houseRadius = 15
houses = ((60, 10), (42, 75), (-37, 35), (80, -80), (-70, -120), (-55, -40))
def inCircle(x, y, c=estateCenter, r=estateRadius):
center_x, center_y = c
square_dist = (center_x - x) ** 2 + (center_y - y) ** 2
return square_dist <= r ** 2
def housePointCollision(x, y):
for i, h in enumerate(houses):
if inCircle(x, y, h, houseRadius):
return 1
return 0
def generatePos():
def get():
r = random.randint(0, estateRadius) - estateRadius / 2
r2 = random.randint(0, estateRadius) - estateRadius / 2
x = r + estateCenter[0]
y = r2 + estateCenter[1]
assert inCircle(x, y)
return x, y
p = get()
while housePointCollision(*p):
p = get()
return p
def lineInCircle(pt1, pt2, circlePoint, circleRadius=houseRadius):
x1, y1 = pt1
x2, y2 = pt2
dist = math.hypot(x2 - x1, y2 - y1)
if dist == 0:
return 0
dx = (x2 - x1) / dist
dy = (y2 - y1) / dist
t = dx * (circlePoint[0] - x1) + dy * (circlePoint[1] - y1)
ex = t * dx + x1
ey = t * dy + y1
d2 = math.hypot(ex - circlePoint[0], ey - circlePoint[1])
return d2 <= circleRadius
def houseCollision(pt1, pt2):
for i, h in enumerate(houses):
if lineInCircle(pt1, pt2, h):
return 1
return 0
def generatePath(start, end):
points = [start]
if not houseCollision(start, end):
points.append(end)
return points
while True:
next = generatePos()
while houseCollision(points[-1], next):
next = generatePos()
points.append(next)
if not houseCollision(next, end):
points.append(end)
return points
class PetMoverAI(FSM):
def __init__(self, pet):
self.pet = pet
FSM.__init__(self, 'PetMoverAI-%d' % self.pet.doId)
self.chaseTarget = None
self.__seq = None
self.fwdSpeed = 10.0
self.rotSpeed = 360.0
self.__moveFromStill()
self.__chaseCallback = None
def enterStill(self):
taskMgr.doMethodLater(random.randint(15, 60), self.__moveFromStill, self.pet.uniqueName('next-state'))
def exitStill(self):
taskMgr.remove(self.pet.uniqueName('next-state'))
def __moveFromStill(self, task=None):
choices = ["Wander"]
# if self.pet._getNearbyAvatarDict():
# choices.append("Chase")
nextState = random.choice(choices)
self.request(nextState)
def enterWander(self):
target = self.getPoint()
self.walkToPoint(target)
def getPoint(self):
x, y = generatePos()
return Point3(x, y, 0)
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),
Func(self.__stateComplete))
self.__seq.start()
def exitWander(self):
if self.__seq:
self.__seq.pause()
self.__seq = None
def __stateComplete(self):
try:
self.request("Still")
except:
pass
def destroy(self):
self.demand("Off")
def setFwdSpeed(self, speed):
self.fwdSpeed = speed
def getFwdSpeed(self):
return self.fwdSpeed
def setRotSpeed(self, speed):
self.rotSpeed = speed
def getRotSpeed(self):
return self.rotSpeed
def lock(self):
if self.state != "Still":
self.demand("Still")
def enterChase(self, target=None):
if not target:
target = hidden.attachNewNode('target')
target.setPos(self.getPoint())
self.walkToPoint(target.getPos())
def exitChase(self):
if self.__chaseCallback:
self.__chaseCallback()
self.__chaseCallback = None
if self.__seq:
self.__seq.pause()
self.__seq = None
def walkToAvatar(self, av, callback=None):
if callback:
self.__chaseCallback = callback
self.demand("Chase", av)

View file

@ -7,7 +7,7 @@ NonHappyMinActualTrickAptitude = 0.1
NonHappyMaxActualTrickAptitude = 0.6 NonHappyMaxActualTrickAptitude = 0.6
MinActualTrickAptitude = 0.5 MinActualTrickAptitude = 0.5
MaxActualTrickAptitude = 0.97 MaxActualTrickAptitude = 0.97
AptitudeIncrementDidTrick = 0.0005 AptitudeIncrementDidTrick = 0.0005 * config.GetFloat('pet-trick-aptitude-mult', 4)
MaxAptitudeIncrementGotPraise = 0.0003 MaxAptitudeIncrementGotPraise = 0.0003
MaxTrickFatigue = 0.65 MaxTrickFatigue = 0.65
MinTrickFatigue = 0.1 MinTrickFatigue = 0.1

View file

@ -24,14 +24,14 @@ class PetWander(PetChase, DirectObject.DirectObject):
return return
def _setMover(self, mover): def _setMover(self, mover):
CPetChase.setMover(self, mover) PetChase._setMover(self, mover)
self.mover = mover self.mover = mover
self.__ignoreCollisions() self.__ignoreCollisions()
self.collEvent = mover.getCollisionEventName() self.collEvent = mover.getCollisionEventName()
self.accept(self.collEvent, self._handleCollision) self.accept(self.collEvent, self._handleCollision)
def _clearMover(self, mover): def _clearMover(self, mover):
CPetChase.clearMover(self, mover) PetChase._clearMover(self, mover)
self.__ignoreCollisions() self.__ignoreCollisions()
def _handleCollision(self, collEntry): def _handleCollision(self, collEntry):
@ -58,4 +58,4 @@ class PetWander(PetChase, DirectObject.DirectObject):
target.setY(target, distance) target.setY(target, distance)
duration = distance / self.mover.getFwdSpeed() duration = distance / self.mover.getFwdSpeed()
self.targetMoveCountdown = duration * randFloat(1.2, 3.0) self.targetMoveCountdown = duration * randFloat(1.2, 3.0)
CPetChase.process(self, dt) PetChase._process(self, dt)

View file

@ -254,6 +254,7 @@ class PetshopGUI(DirectObject):
self.okButton = DirectButton(parent=self, relief=None, image=okImageList, geom=checkIcon, scale=modelScale, text=('', TTLocalizer.PetshopReturn), text_pos=(5.8, 4.4), text_scale=0.7, pressEffect=False, command=lambda : messenger.send(doneEvent, [1])) self.okButton = DirectButton(parent=self, relief=None, image=okImageList, geom=checkIcon, scale=modelScale, text=('', TTLocalizer.PetshopReturn), text_pos=(5.8, 4.4), text_scale=0.7, pressEffect=False, command=lambda : messenger.send(doneEvent, [1]))
self.petView = self.attachNewNode('petView') self.petView = self.attachNewNode('petView')
self.petView.setPos(-0.15, 0, 0.8) self.petView.setPos(-0.15, 0, 0.8)
avatar.announceGenerate()
self.petModel = Pet.Pet(forGui=1) self.petModel = Pet.Pet(forGui=1)
self.petModel.setDNA(avatar.getDNA()) self.petModel.setDNA(avatar.getDNA())
self.petModel.fitAndCenterHead(0.395, forGui=1) self.petModel.fitAndCenterHead(0.395, forGui=1)
@ -342,7 +343,7 @@ class PetshopGUI(DirectObject):
descList.append('\t%s' % trait) descList.append('\t%s' % trait)
descList.append(TTLocalizer.PetshopDescCost % cost) descList.append(TTLocalizer.PetshopDescCost % cost)
self.petDesc.append(string.join(descList, '\n')) self.petDesc.append('\n'.join(descList))
self.petCost.append(cost) self.petCost.append(cost)
def destroy(self): def destroy(self):

View file

@ -5,6 +5,7 @@ from toontown.toonbase import TTLocalizer
from direct.task import Task from direct.task import Task
from toontown.fishing import FishGlobals from toontown.fishing import FishGlobals
from toontown.pets import PetUtil, PetDNA, PetConstants from toontown.pets import PetUtil, PetDNA, PetConstants
from toontown.hood import ZoneUtil
class DistributedNPCPetclerkAI(DistributedNPCToonBaseAI): class DistributedNPCPetclerkAI(DistributedNPCToonBaseAI):
@ -20,13 +21,13 @@ class DistributedNPCPetclerkAI(DistributedNPCToonBaseAI):
def avatarEnter(self): def avatarEnter(self):
avId = self.air.getAvatarIdFromSender() avId = self.air.getAvatarIdFromSender()
if avId not in self.air.doId2do: if not self.air.doId2do.has_key(avId):
self.notify.warning('Avatar: %s not found' % avId) self.notify.warning('Avatar: %s not found' % avId)
return return
if self.isBusy(): if self.isBusy():
self.freeAvatar(avId) self.freeAvatar(avId)
return return
self.petSeeds = simbase.air.petMgr.getAvailablePets(5) self.petSeeds = self.petMgr.getAvailablePets(3, ZoneUtil.getCanonicalSafeZoneId(self.zoneId))
numGenders = len(PetDNA.PetGenders) numGenders = len(PetDNA.PetGenders)
self.petSeeds *= numGenders self.petSeeds *= numGenders
self.petSeeds.sort() self.petSeeds.sort()
@ -125,6 +126,7 @@ class DistributedNPCPetclerkAI(DistributedNPCToonBaseAI):
if av: if av:
simbase.air.petMgr.deleteToonsPet(avId) simbase.air.petMgr.deleteToonsPet(avId)
self.transactionType = 'return' self.transactionType = 'return'
self.transactionDone()
def transactionDone(self): def transactionDone(self):
avId = self.air.getAvatarIdFromSender() avId = self.air.getAvatarIdFromSender()

View file

@ -1758,9 +1758,6 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
def getPetId(self): def getPetId(self):
return self.petId return self.petId
def getPetId(self):
return self.petId
def hasPet(self): def hasPet(self):
return self.petId != 0 return self.petId != 0

View file

@ -140,6 +140,7 @@ class LocalToon(DistributedToon.DistributedToon, LocalAvatar.LocalAvatar):
self.shovelRelatedDoId = 0 self.shovelRelatedDoId = 0
self.shovelAbility = '' self.shovelAbility = ''
self.plantToWater = 0 self.plantToWater = 0
self.petId = 0
self.shovelButtonActiveCount = 0 self.shovelButtonActiveCount = 0
self.wateringCanButtonActiveCount = 0 self.wateringCanButtonActiveCount = 0
self.showingWateringCan = 0 self.showingWateringCan = 0
@ -1877,10 +1878,23 @@ class LocalToon(DistributedToon.DistributedToon, LocalAvatar.LocalAvatar):
self.questMap.stop() self.questMap.stop()
def getPetId(self): def getPetId(self):
return False return self.petId
def hasPet(self): def hasPet(self):
return False return self.petId != 0
def getPetDNA(self):
if self.hasPet():
pet = base.cr.doId2do(self.petId)
return pet.petDNA
return None
def setPetId(self, petId):
self.petId = petId
if petId == 0:
self.petDNA = None
elif self.isLocal():
base.cr.addPetToFriendsMap()
def setAchievements(self, achievements): def setAchievements(self, achievements):
if base.wantAchievements: if base.wantAchievements:

View file

@ -0,0 +1,23 @@
from pandac.PandaModules import BitMask32
WallBitmask = BitMask32(1)
FloorBitmask = BitMask32(2)
CameraBitmask = BitMask32(4)
CameraTransparentBitmask = BitMask32(8)
SafetyNetBitmask = BitMask32(512)
SafetyGateBitmask = BitMask32(1024)
GhostBitmask = BitMask32(2048)
PathFindingBitmask = BitMask32.bit(29)
PickerBitmask = BitMask32(4096)
CeilingBitmask = BitMask32(256)
FloorEventBitmask = BitMask32(16)
PieBitmask = BitMask32(256)
PetBitmask = BitMask32(8)
CatchGameBitmask = BitMask32(16)
CashbotBossObjectBitmask = BitMask32(16)
FurnitureSideBitmask = BitMask32(32)
FurnitureTopBitmask = BitMask32(64)
FurnitureDragBitmask = BitMask32(128)
PetLookatPetBitmask = BitMask32(256)
PetLookatNonPetBitmask = BitMask32(512)
BanquetTableBitmask = BitMask32(1024)

View file

@ -248,17 +248,19 @@ class Street(BattlePlace.BattlePlace):
zoneId = requestStatus['zoneId'] zoneId = requestStatus['zoneId']
if avId != -1: if avId != -1:
if avId not in base.cr.doId2do: if avId not in base.cr.doId2do:
teleportDebug(requestStatus, "couldn't find friend %s" % avId) friend = base.cr.identifyAvatar(avId)
handle = base.cr.identifyFriend(avId) if friend == None:
requestStatus = {'how': 'teleportIn', teleportDebug(requestStatus, "couldn't find friend %s" % avId)
'hoodId': hoodId, handle = base.cr.identifyFriend(avId)
'zoneId': hoodId, requestStatus = {'how': 'teleportIn',
'shardId': None, 'hoodId': hoodId,
'loader': 'safeZoneLoader', 'zoneId': hoodId,
'where': 'playground', 'shardId': None,
'avId': avId} 'loader': 'safeZoneLoader',
self.fsm.request('final') 'where': 'playground',
self.__teleportOutDone(requestStatus) 'avId': avId}
self.fsm.request('final')
self.__teleportOutDone(requestStatus)
return return
def exitTeleportIn(self): def exitTeleportIn(self):