Exemplo n.º 1
0
 def __init__(self, cr):
     try:
         self.LocalToon_initialized
         return
     except:
         self.LocalToon_initialized = 1
     DistributedToon.__init__(self, cr)
     self.avatarChoice = cr.localAvChoice
     self.smartCamera = SmartCamera()
     self.chatInput = ChatInput()
     self.moneyGui = MoneyGui()
     self.pieGui = PieGui(self.pies)
     self.laffMeter = LaffOMeter()
     self.runSfx = base.loadSfx(
         "phase_3.5/audio/sfx/AV_footstep_runloop.ogg")
     self.runSfx.setLoop(True)
     self.walkSfx = base.loadSfx(
         "phase_3.5/audio/sfx/AV_footstep_walkloop.ogg")
     self.walkSfx.setLoop(True)
     self.controlManager = ControlManager.ControlManager(True, False)
     self.offset = 3.2375
     self.movementKeymap = {
         "forward": 0,
         "backward": 0,
         "left": 0,
         "right": 0,
         "jump": 0
     }
     self.avatarMovementEnabled = False
     self.isMoving_forward = False
     self.isMoving_side = False
     self.isMoving_back = False
     self.isMoving_jump = False
     base.cTrav = CollisionTraverser()
Exemplo n.º 2
0
 def __makeHeadMeter(self):
     self.headMeter = LaffOMeter(forRender=True)
     r, g, b, _ = self.getHeadColor()
     animal = self.getAnimal()
     maxHp = self.getMaxHealth()
     hp = self.getHealth()
     self.headMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp)
     self.headMeter.reparentTo(self)
     self.headMeter.setZ(self.getHeight() + 2)
     self.headMeter.setScale(0.4)
     self.headMeter.setBillboardAxis()
     self.__updateHeadMeter()
Exemplo n.º 3
0
 def enterPanel(self):
     self.nameText = OnscreenText(text=self.avatarInfo[1], parent=self, pos=(0, 0.2), scale=0.035, wordwrap=8)
     self.nameText.setBin('gui-popup', 60)
     dna = ToonDNA.ToonDNA()
     dna.setDNAStrand(self.avatarInfo[2])
     self.head = ToonHead.ToonHead(base.cr)
     self.head.generateHead(dna.gender, dna.animal, dna.head, 1)
     self.head.setHeadColor(dna.headcolor)
     self.head.reparentTo(self)
     self.head.setDepthWrite(1)
     self.head.setDepthTest(1)
     self.head.setH(180)
     self.head.setScale(self.animal2HeadData[dna.animal][0])
     self.head.setZ(self.animal2HeadData[dna.animal][1])
     self.laffMeter = LaffOMeter()
     r, g, b, _ = dna.headcolor
     self.laffMeter.generate(r, g, b, dna.animal, self.avatarInfo[3], self.avatarInfo[4])
     self.laffMeter.reparentTo(self)
     self.laffMeter.setBin('gui-popup', 60)
     self.laffMeter.setScale(0.045)
     self.laffMeter.setPos(0, 0, -0.1)
     self.friendButton = DirectButton(geom=CIGlobals.getDefaultBtnGeom(), text='Add Friend', scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarFriendListResponse'])
     self.friendButton.setPos(0, 0.0, -0.225)
     self.maybeUpdateFriendButton()
     self.teleportButton = DirectButton(geom=CIGlobals.getDefaultBtnGeom(), text='Teleport', scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarTeleportResponse'])
     self.teleportButton.setPos(0, 0, -0.275)
     self.exitButton = DirectButton(geom=CIGlobals.getCancelBtnGeom(), parent=self, relief=None, scale=0.6, pos=(-0.127, 0.0, -0.3425), command=self.exitClicked)
     return
	def __init__(self, cr, head, headtype, headcolor, torsocolor, legcolor,
				gender, torsotype, legtype, name, shirtcolor, shortscolor, shirt, short, sleeve):
		self.cr = cr
		self.head = head
		self.headtype = headtype
		self.hr, self.hg, self.hb, self.ha = headcolor
		self.tr, self.tg, self.tb, self.ta = torsocolor
		self.lr, self.lg, self.lb, self.la = legcolor
		self.shir, self.shig, self.shib, self.shia = shirtcolor
		self.shor, self.shog, self.shob, self.shoa = shortscolor
		self.shirt = shirt
		self.short = short
		self.sleeve = sleeve
		self.gender = gender
		self.torsotype = torsotype
		self.legtype = legtype
		self.name = name
		
		base.avatar = None
		self.sb = ShtickerBook(self)
		
		self.laffMeter = LaffOMeter()
		
		self.run_sfx = loader.loadSfx("phase_3.5/audio/sfx/AV_footstep_runloop.ogg")
		self.run_sfx.setLoop(True)
		self.walk_sfx = loader.loadSfx("phase_3.5/audio/sfx/AV_footstep_walkloop.ogg")
		self.walk_sfx.setLoop(True)
		
		self.hoodUtil = HoodUtil(self.cr)
		
		self.smart_cam = SmartCamera.SmartCamera()
		
		self.isThrowing = False
		
		self.controlManager = ControlManager.ControlManager(True, False)
		
		self.offset = 3.2375
		
		self.keyMap = {"forward":0,"backward":0, "left":0, "right":0, "jump":0}
		
		base.cTrav = CollisionTraverser('general_traverser')
		self.dFov = CIGlobals.DefaultCameraFov
		self.oFov = CIGlobals.OriginalCameraFov
		
		self.createReady()
Exemplo n.º 5
0
 def makeBattleMeter(self):
     if self.getHealth() < self.getMaxHealth():
         if not self.battleMeter:
             self.battleMeter = LaffOMeter()
             r, g, b, _ = self.getHeadColor()
             animal = self.getAnimal()
             maxHp = self.getMaxHealth()
             hp = self.getHealth()
             self.battleMeter.generate(r,
                                       g,
                                       b,
                                       animal,
                                       maxHP=maxHp,
                                       initialHP=hp)
             self.battleMeter.reparentTo(self)
             self.battleMeter.setZ(self.getHeight() + 5)
             self.battleMeter.setScale(0.5)
             self.battleMeter.start()
Exemplo n.º 6
0
 def __makeHeadMeter(self):
     self.headMeter = LaffOMeter(forRender=True)
     r, g, b, _ = self.getHeadColor()
     animal = self.getAnimal()
     maxHp = self.getMaxHealth()
     hp = self.getHealth()
     self.headMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp)
     self.headMeter.reparentTo(self)
     self.headMeter.setZ(self.getHeight() + 2)
     self.headMeter.setScale(0.4)
     self.headMeter.setBillboardAxis()
     self.__updateHeadMeter()
Exemplo n.º 7
0
 def makeBattleMeter(self):
     if self.getHealth() < self.getMaxHealth():
         if not self.battleMeter:
             self.battleMeter = LaffOMeter()
             r, g, b, _ = self.getHeadColor()
             animal = self.getAnimal()
             maxHp = self.getMaxHealth()
             hp = self.getHealth()
             self.battleMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp)
             self.battleMeter.reparentTo(self)
             self.battleMeter.setZ(self.getHeight() + 5)
             self.battleMeter.setScale(0.5)
             self.battleMeter.start()
Exemplo n.º 8
0
    def __init__(self, cr):
        try:
            self.LocalToon_initialized
            return
        except:
            self.LocalToon_initialized = 1

        DistributedToon.__init__(self, cr)
        self.avatarChoice = cr.localAvChoice
        self.smartCamera = SmartCamera()
        self.chatInput = ChatInput()
        self.moneyGui = MoneyGui()
        self.laffMeter = LaffOMeter()
        self.positionExaminer = PositionExaminer()
        self.friendRequestManager = FriendRequestManager()
        self.friendsList = FriendsList()
        self.panel = ToonPanel()
        friendsgui = loader.loadModel('phase_3.5/models/gui/friendslist_gui.bam')
        self.friendButton = DirectButton(geom=(friendsgui.find('**/FriendsBox_Closed'), friendsgui.find('**/FriendsBox_Rollover'), friendsgui.find('**/FriendsBox_Rollover')), text=('', 'Friends', 'Friends', ''), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), text_scale=0.065, text_pos=(0, -0.2), relief=None, parent=base.a2dTopRight, pos=(-0.18, 0.0, -0.17), command=self.friendsButtonClicked, scale=0.75)
        friendsgui.removeNode()
        del friendsgui
        self.hideFriendButton()
        self.runSfx = base.loadSfx('phase_3.5/audio/sfx/AV_footstep_runloop.wav')
        self.runSfx.setLoop(True)
        self.walkSfx = base.loadSfx('phase_3.5/audio/sfx/AV_footstep_walkloop.wav')
        self.walkSfx.setLoop(True)
        self.controlManager = ControlManager.ControlManager(True, False)
        self.offset = 3.2375
        self.movementKeymap = {'forward': 0,
         'backward': 0,
         'left': 0,
         'right': 0,
         'jump': 0}
        self.avatarMovementEnabled = False
        self.isMoving_forward = False
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_jump = False
        self.pieThrowBtn = None
        self.myBattle = None
        self.invGui = None
        self.pickerTrav = None
        self.pickerRay = None
        self.pickerRayNode = None
        self.pickerHandler = None
        self.rolledOverTag = None
        self.inTutorial = False
        self.hasDoneJump = False
        self.lastState = None
        self.lastAction = None
        return
Exemplo n.º 9
0
class DistributedToon(Toon.Toon, DistributedAvatar, DistributedSmoothNode, DelayDeletable):

    def __init__(self, cr):
        try:
            self.DistributedToon_initialized
            return
        except:
            self.DistributedToon_initialized = 1

        Toon.Toon.__init__(self, cr)
        DistributedAvatar.__init__(self, cr)
        DistributedSmoothNode.__init__(self, cr)
        self.questManager = QuestManager.QuestManager()
        self.token = -1
        self.ghost = 0
        self.puInventory = []
        self.equippedPU = -1
        self.backpackId = None
        self.backpack = None
        self.animState2animId = {}
        self.battleMeter = None
        for index in range(len(self.animFSM.getStates())):
            self.animState2animId[self.animFSM.getStates()[index].getName()] = index

        self.animId2animState = {v:k for k, v in self.animState2animId.items()}
        self.initAmmo = []
        self.initGagIds = []
        self.headMeter = None
        self.firstTimeChangingHP = True
        self.gagBPData = []
        self.quests = []
        self.tier = None
        self.questHistory = None
        self.busy = 1
        self.friends = None
        self.tutDone = 0
        self.hoodsDiscovered = []
        self.teleportAccess = []
        self.lastHood = 0
        return

    def doSmoothTask(self, task):
        self.smoother.computeAndApplySmoothPosHpr(self, self)
        if not hasattr(base, 'localAvatar'):
            return task.done
        if self.doId != base.localAvatar.doId:
            self.setSpeed(self.smoother.getSmoothForwardVelocity(), self.smoother.getSmoothRotationalVelocity())
        return task.cont

    def setLastHood(self, zoneId):
        self.lastHood = zoneId

    def b_setLastHood(self, zoneId):
        self.sendUpdate('setLastHood', [zoneId])
        self.setLastHood(zoneId)

    def getLastHood(self):
        return self.lastHood

    def setTeleportAccess(self, array):
        self.teleportAccess = array

    def getTeleportAccess(self):
        return self.teleportAccess

    def setHoodsDiscovered(self, array):
        self.hoodsDiscovered = array

    def b_setHoodsDiscovered(self, array):
        self.sendUpdate('setHoodsDiscovered', [array])
        self.setHoodsDiscovered(array)

    def getHoodsDiscovered(self):
        return self.hoodsDiscovered

    def setTutorialCompleted(self, value):
        self.tutDone = value

    def getTutorialCompleted(self):
        return self.tutDone

    def setFriendsList(self, friends):
        self.friends = friends

    def getFriendsList(self):
        return self.friends

    def setBusy(self, busy):
        self.busy = busy

    def getBusy(self):
        return self.busy

    def setTier(self, tier):
        self.tier = tier

    def getTier(self):
        return self.tier

    def setQuestHistory(self, array):
        self.questHistory = array

    def getQuestHistrory(self):
        return self.questHistory

    def setQuests(self, questIds, currentObjectives, currentObjectivesProgress):
        self.quests = [questIds, currentObjectives, currentObjectivesProgress]
        self.questManager.makeQuestsFromData()

    def getQuests(self):
        return self.quests

    def maybeMakeHeadMeter(self):
        if base.localAvatar.doId != self.doId:
            if self.health < self.getMaxHealth():
                if not self.headMeter:
                    self.__makeHeadMeter()

    def __makeHeadMeter(self):
        self.headMeter = LaffOMeter(forRender=True)
        r, g, b, _ = self.getHeadColor()
        animal = self.getAnimal()
        maxHp = self.getMaxHealth()
        hp = self.getHealth()
        self.headMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp)
        self.headMeter.reparentTo(self)
        self.headMeter.setZ(self.getHeight() + 2)
        self.headMeter.setScale(0.4)
        self.headMeter.setBillboardAxis()
        self.__updateHeadMeter()

    def __removeHeadMeter(self):
        if self.headMeter:
            self.headMeter.disable()
            self.headMeter.delete()
            self.headMeter = None
        return

    def __updateHeadMeter(self):
        if self.headMeter:
            self.headMeter.updateMeter(self.getHealth())

    def setHealth(self, health):
        if self.doId != base.localAvatar.doId:
            if not self.firstTimeChangingHP:
                if health < self.getMaxHealth():
                    if not self.headMeter:
                        self.__makeHeadMeter()
                    else:
                        self.__updateHeadMeter()
                else:
                    self.__removeHeadMeter()
        self.health = health
        self.firstTimeChangingHP = False

    def d_createBattleMeter(self):
        self.sendUpdate('makeBattleMeter', [])

    def b_createBattleMeter(self):
        self.makeBattleMeter()
        self.d_createBattleMeter()

    def d_cleanupBattleMeter(self):
        self.sendUpdate('destroyBattleMeter', [])

    def b_cleanupBattleMeter(self):
        self.destroyBattleMeter()
        self.d_cleanupBattleMeter()

    def makeBattleMeter(self):
        if self.getHealth() < self.getMaxHealth():
            if not self.battleMeter:
                self.battleMeter = LaffOMeter()
                r, g, b, _ = self.getHeadColor()
                animal = self.getAnimal()
                maxHp = self.getMaxHealth()
                hp = self.getHealth()
                self.battleMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp)
                self.battleMeter.reparentTo(self)
                self.battleMeter.setZ(self.getHeight() + 5)
                self.battleMeter.setScale(0.5)
                self.battleMeter.start()

    def destroyBattleMeter(self):
        if self.battleMeter:
            self.battleMeter.stop()
            self.battleMeter.disable()
            self.battleMeter.delete()
            self.battleMeter = None
        return

    def setEquippedPU(self, index):
        self.equippedPU = index

    def getEquippedPU(self):
        return self.equippedPU

    def setPUInventory(self, array):
        self.puInventory = array

    def getPUInventory(self):
        return self.puInventory

    def setGhost(self, value):
        self.ghost = value
        if value:
            self.ghostOn()
        else:
            self.ghostOff()

    def d_setGhost(self, value):
        self.sendUpdate('setGhost', [value])

    def b_setGhost(self, value):
        self.d_setGhost(value)
        self.setGhost(value)

    def getGhost(self):
        return self.ghost

    def setDNAStrand(self, dnaStrand):
        Toon.Toon.setDNAStrand(self, dnaStrand)
        self.maybeMakeHeadMeter()

    def d_setDNAStrand(self, dnaStrand):
        self.sendUpdate('setDNAStrand', [dnaStrand])

    def b_setDNAStrand(self, dnaStrand):
        self.setDNAStrand(dnaStrand)
        self.d_setDNAStrand(dnaStrand)

    def lookAtObject(self, h, p, r, blink = 1):
        if self.getPart('head').getHpr() == (h, p, r):
            return
        Toon.Toon.lerpLookAt(self, self.getPart('head'), tuple((h, p, r)))
        if blink:
            self.stopBlink()
            maxBlinks = random.randint(1, 2)
            numBlinks = 0
            delay = 0
            for blink in range(maxBlinks):
                if numBlinks == 0:
                    taskMgr.add(self.doBlink, self.uniqueName('blinkOnTurn'))
                else:
                    delay += 0.22
                    taskMgr.doMethodLater(delay, self.doBlink, self.doBlinkTaskName)
                numBlinks += 1

            taskMgr.doMethodLater(delay, self.__startBlinkAfterLook, self.uniqueName('sBAL'))

    def __startBlinkAfterLook(self, task):
        self.startBlink()
        return task.done

    def toonUp(self):
        pass

    def b_lookAtObject(self, h, p, r, blink = 1):
        self.d_lookAtObject(h, p, r, blink)
        self.lookAtObject(h, p, r, blink)

    def d_lookAtObject(self, h, p, r, blink = 1):
        self.sendUpdate('lookAtObject', [h,
         p,
         r,
         blink])

    def setChat(self, chat):
        Toon.Toon.setChat(self, chat)

    def setTarget(self, gagId, targetId):
        gag = self.backpack.getGagByID(gagId)
        target = self.cr.doId2do.get(targetId, None)
        gag.setTarget(target)
        return

    def trapActivate(self, gagId, avId, entityId, suitId):
        sender = self.cr.doId2do.get(avId, None)
        suit = self.cr.doId2do.get(suitId, None)
        if sender:
            backpack = sender.getBackpack()
            trapGag = backpack.getGagByID(gagId)
            if backpack and trapGag:
                entity = None
                if hasattr(trapGag, 'getEntities'):
                    entity = trapGag.getEntities()[entityId]
                trapGag.onActivate(entity, suit)
        return

    def b_trapActivate(self, gagId, avId, entityId, suitId):
        self.trapActivate(gagId, avId, entityId, suitId)
        self.d_trapActivate(gagId, avId, entityId, suitId)

    def d_trapActivate(self, gagId, avId, entityId, suitId):
        self.sendUpdate('trapActivate', [gagId,
         avId,
         entityId,
         suitId])

    def gagCollision(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        gag.doCollision()

    def b_gagCollision(self, gagId):
        self.sendUpdate('gagCollision', [gagId])
        self.gagCollision(gagId)

    def gagActivate(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if hasattr(gag, 'activate'):
            gag.activate()

    def b_gagActivate(self, gagId):
        self.sendUpdate('gagActivate', [gagId])
        self.gagActivate(gagId)

    def setDropLoc(self, gagId, x, y, z):
        gag = self.backpack.getGagByID(gagId)
        gag.setEndPos(x, y, z)

    def setGagPos(self, gagId, x, y, z):
        pos = Point3(x, y, z)
        gag = self.backpack.getGagByID(gagId)
        ent = gag.getGag()
        if ent:
            ent.setPos(pos)

    def gagStart(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if gag:
            gag.start()

    def b_gagStart(self, gagId):
        self.sendUpdate('gagStart', [gagId])
        self.gagStart(gagId)

    def gagThrow(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if gag:
            gag.throw()

    def b_gagThrow(self, gagId):
        self.sendUpdate('gagThrow', [gagId])
        self.gagThrow(gagId)

    def gagRelease(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if gag and hasattr(gag, 'name'):
            gag.release()

    def b_gagRelease(self, gagId):
        self.sendUpdate('gagRelease', [gagId])
        self.gagRelease(gagId)

    def setSplatPos(self, gagId, x, y, z):
        splatGag = self.backpack.getGagByID(gagId)
        if splatGag:
            splatGag.setSplatPos(x, y, z)

    def d_setSplatPos(self, gagId, x, y, z):
        self.sendUpdate('setSplatPos', [gagId,
         x,
         y,
         z])

    def gagBuild(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if gag:
            gag.build()

    def b_gagBuild(self, gagId):
        self.gagBuild(gagId)
        self.sendUpdate('gagBuild', [gagId])

    def handleSuitAttack(self, attack_id, suit_id):
        attack = SuitAttacks.SuitAttackLengths.keys()[attack_id]
        if attack == 'canned':
            sfx = base.loadSfx('phase_5/audio/sfx/SA_canned_impact_only.mp3')
            SoundInterval(sfx, node=self).start()
        elif attack == 'playhardball':
            sfx = base.loadSfx('phase_5/audio/sfx/SA_hardball_impact_only_alt.mp3')
            SoundInterval(sfx, node=self).start()
        elif attack == 'clipontie':
            sfx = base.loadSfx('phase_5/audio/sfx/SA_powertie_impact.mp3')
            SoundInterval(sfx, node=self).start()
        if not self.isDead():
            if attack in ('fountainpen',):
                self.getPart('head').setColorScale(0, 0, 0, 1)
                Sequence(Wait(3.0), Func(self.resetHeadColor)).start()

    def resetHeadColor(self):
        head = self.getPart('head')
        if head:
            head.setColorScale(1, 1, 1, 1)

    def b_handleSuitAttack(self, attack_id, suit_id):
        self.handleSuitAttack(attack_id, suit_id)
        self.b_lookAtObject(0, 0, 0, blink=1)
        self.sendUpdate('handleSuitAttack', [attack_id, suit_id])

    def equip(self, gag_id):
        if self.backpack:
            gag = self.backpack.getGagByID(gag_id)
            if gag:
                if not gag.getAvatar():
                    gag.setAvatar(self)
                self.backpack.setCurrentGag(gag.getName())

    def unEquip(self):
        if self.backpack:
            self.backpack.setCurrentGag(None)
        return

    def b_unEquip(self):
        self.unEquip()
        self.sendUpdate('unEquip', [])

    def b_equip(self, gag_id):
        self.equip(gag_id)
        self.sendUpdate('equip', [gag_id])

    def setBackpack(self, backpack):
        if not isinstance(backpack, numbers.Number):
            self.backpack = backpack
        else:
            self.backpackId = backpack
            self.backpack = BackpackManager.getBackpack(backpack)
        if self.initAmmo:
            self.setBackpackAmmo(self.initGagIds, self.initAmmo)
        self.backpack.setup(self)
        Toon.Toon.backpack = self.backpack

    def b_setBackpack(self, backpackId):
        self.d_setBackpack(backpackId)
        self.setBackpack(BackpackManager.getBackpack(backpackId))

    def getBackpack(self):
        return self.backpack

    def buildAmmoList(self, gagIds):
        ammoList = []
        for index in range(len(gagIds)):
            gagId = gagIds[index]
            amt = self.backpack.getSupply(GagGlobals.getGagByID(gagId))
            ammoList.append(amt)

        return ammoList

    def setLoadout(self, gagIds):
        if self.backpack:
            loadout = []
            for i in range(len(gagIds)):
                gagId = gagIds[i]
                gag = self.backpack.getGagByID(gagId)
                if gag:
                    loadout.append(gag)

            self.backpack.setLoadout(loadout)

    def setBackpackAmmo(self, gagIds, ammoList):
        if -1 in ammoList:
            return
        else:
            self.gagBPData = [gagIds, ammoList]
            if not self.initAmmo:
                self.initAmmo = ammoList
                self.initGagIds = gagIds
            else:
                self.initAmmo = None
                self.initGagIds = None
            bpReset = False
            if len(self.backpack.gags.keys()) > 0:
                for index in range(len(gagIds)):
                    gagId = gagIds[index]
                    numOfThisGag = 0
                    for gag in self.backpack.gags.keys():
                        if type(self.backpack.gagMgr.getGagByName(GagGlobals.getGagByID(gagId))) == type(gag):
                            numOfThisGag += 1

                    if numOfThisGag < 1:
                        self.backpack.resetGags()
                        bpReset = True
                        break

            for index in range(len(ammoList)):
                amt = ammoList[index]
                gagId = gagIds[index]
                self.backpack.setSupply(amt, GagGlobals.getGagByID(gagId))

            if self.backpack.gagGUI:
                if bpReset:
                    self.disablePies()
                    self.enablePies(1)
                self.backpack.gagGUI.update()
            return

    def getBackpackAmmo(self):
        return self.gagBPData

    def setGagAmmo(self, gagId, ammo):
        self.backpack.setSupply(ammo, GagGlobals.getGagByID(gagId))
        if self.backpack.gagGUI:
            self.backpack.gagGUI.update()

    def updateBackpackAmmo(self):
        gagIds = []
        ammoList = []
        for gag in self.backpack.getGags():
            gagIds.append(GagGlobals.getIDByName(gag.getName()))
            ammoList.append(self.backpack.getSupply(gag.getName()))

        self.setBackpackAmmo(gagIds, ammoList)

    def setMoney(self, money):
        self.money = money

    def getMoney(self):
        return self.money

    def setAdminToken(self, value):
        self.token = value
        if value > -1:
            Toon.Toon.setAdminToken(self, value)
        else:
            Toon.Toon.removeAdminToken(self)

    def getAdminToken(self):
        return self.token

    def setAnimState(self, anim, timestamp = None, callback = None, extraArgs = []):
        self.anim = anim
        if timestamp == None:
            ts = 0.0
        else:
            ts = globalClockDelta.localElapsedTime(timestamp)
        if type(anim) == types.IntType:
            anim = self.animId2animState[anim]
        if self.animFSM.getStateNamed(anim):
            self.animFSM.request(anim, [ts, callback, extraArgs])
        return

    def b_setAnimState(self, anim):
        self.d_setAnimState(anim)
        self.setAnimState(anim, None)
        return

    def d_setAnimState(self, anim):
        if type(anim) == types.StringType:
            anim = self.animState2animId[anim]
        timestamp = globalClockDelta.getFrameNetworkTime()
        self.sendUpdate('setAnimState', [anim, timestamp])

    def getAnimState(self):
        return self.anim

    def setName(self, name):
        Toon.Toon.setName(self, name)
        if self.cr.isShowingPlayerIds:
            self.showAvId()

    def d_setName(self, name):
        self.sendUpdate('setName', [name])

    def b_setName(self, name):
        self.d_setName(name)
        self.setName(name)

    def showAvId(self):
        self.setDisplayName(self.getName() + '\n' + str(self.doId))

    def showName(self):
        self.setDisplayName(self.getName())

    def setDisplayName(self, name):
        self.setupNameTag(tempName=name)

    def wrtReparentTo(self, parent):
        DistributedSmoothNode.wrtReparentTo(self, parent)

    def announceHealthAndPlaySound(self, level, hp):
        DistributedAvatar.announceHealth(self, level, hp)
        hpSfx = base.audio3d.loadSfx('phase_11/audio/sfx/LB_toonup.mp3')
        base.audio3d.attachSoundToObject(hpSfx, self)
        SoundInterval(hpSfx).start()
        del hpSfx

    def announceGenerate(self):
        DistributedAvatar.announceGenerate(self)
        if self.animFSM.getCurrentState().getName() == 'off':
            self.setAnimState('neutral')
        self.startBlink()

    def generate(self):
        DistributedAvatar.generate(self)
        DistributedSmoothNode.generate(self)
        self.startSmooth()

    def disable(self):
        self.busy = None
        taskMgr.remove(self.uniqueName('sBAL'))
        taskMgr.remove(self.uniqueName('blinkOnTurn'))
        if self.track != None:
            self.track.finish()
            DelayDelete.cleanupDelayDeletes(self.track)
            self.track = None
        self.stopBlink()
        self.__removeHeadMeter()
        self.ignore('showAvId')
        self.ignore('showName')
        self.token = None
        Toon.Toon.disable(self)
        DistributedAvatar.disable(self)
        return

    def delete(self):
        try:
            self.DistributedToon_deleted
        except:
            self.DistributedToon_deleted = 1
            self.tutDone = None
            self.stopSmooth()
            Toon.Toon.delete(self)
            DistributedAvatar.delete(self)
            DistributedSmoothNode.delete(self)

        return
class ToonBase:

	def __init__(self, cr, head, headtype, headcolor, torsocolor, legcolor,
				gender, torsotype, legtype, name, shirtcolor, shortscolor, shirt, short, sleeve):
		self.cr = cr
		self.head = head
		self.headtype = headtype
		self.hr, self.hg, self.hb, self.ha = headcolor
		self.tr, self.tg, self.tb, self.ta = torsocolor
		self.lr, self.lg, self.lb, self.la = legcolor
		self.shir, self.shig, self.shib, self.shia = shirtcolor
		self.shor, self.shog, self.shob, self.shoa = shortscolor
		self.shirt = shirt
		self.short = short
		self.sleeve = sleeve
		self.gender = gender
		self.torsotype = torsotype
		self.legtype = legtype
		self.name = name
		
		base.avatar = None
		self.sb = ShtickerBook(self)
		
		self.laffMeter = LaffOMeter()
		
		self.run_sfx = loader.loadSfx("phase_3.5/audio/sfx/AV_footstep_runloop.ogg")
		self.run_sfx.setLoop(True)
		self.walk_sfx = loader.loadSfx("phase_3.5/audio/sfx/AV_footstep_walkloop.ogg")
		self.walk_sfx.setLoop(True)
		
		self.hoodUtil = HoodUtil(self.cr)
		
		self.smart_cam = SmartCamera.SmartCamera()
		
		self.isThrowing = False
		
		self.controlManager = ControlManager.ControlManager(True, False)
		
		self.offset = 3.2375
		
		self.keyMap = {"forward":0,"backward":0, "left":0, "right":0, "jump":0}
		
		base.cTrav = CollisionTraverser('general_traverser')
		self.dFov = CIGlobals.DefaultCameraFov
		self.oFov = CIGlobals.OriginalCameraFov
		
		self.createReady()
			
	def createReady(self):
		base.avatar = self.cr.createDistributedObject(className="DistributedToon", zoneId=5)
		base.avatar.b_setToon(self.gender, self.headtype, self.head, self.legtype, self.torsotype, self.hr, self.hg, self.hb, self.tr, self.tg,
						self.tb, self.lr, self.lg, self.lb, self.shir, self.shig, self.shib, self.shor,	self.shog, self.shob, self.shirt,
						self.short, self.sleeve)
		#base.avatar.initializeLocalSensor(2, 3, "localAvatar")
		base.avatar.initCollisions()
		#base.avatar.startBlink()
		base.avatar.startLookAround()
		base.avatar.startPosHprBroadcast()
		base.avatar.setMoney(20)
		base.accept("loadedHood", self.enterTeleportIn)
		base.accept("gotLookSpot", self.handleLookSpot)
		#base.accept("alt-1", self.enterFirstPerson)
		#base.accept("alt-2", self.exitFirstPerson)
		self.sendSuitInfoRequest()
		self.sendBossInfoRequest()
		self.setAvatarName(self.name)
		taskMgr.add(self.checkHealth, "checkHealth")
		self.smart_cam.set_default_pos(0.0, math.sqrt(base.avatar.getPart('head').getZ(base.avatar)) / Y_FACTOR, 
									base.avatar.getPart('head').getZ(base.avatar) + 0.3)
		self.smart_cam.set_parent(base.avatar)
		self.smart_cam.initialize_smartcamera()
		self.smart_cam.initialize_smartcamera_collisions()
		self.initMovement()
		self.pieGui = PieGui.PieGui(base.avatar.pies)
		self.pieGui.createGui()
		self.pieGui.enableWeaponSwitch()
		self.moneyGui = MoneyGui.MoneyGui()
		self.moneyGui.createGui()
		self.moneyGui.update()
		self.gagShop = GagShop.GagShop()
		self.changeHood(10, base.avatar.zoneId)
		base.camLens.setMinFov(self.dFov/(4./3.))
		base.accept("SuitsActive", self.handleSuitsActive)
		base.accept("SuitsInactive", self.handleSuitsInactive)
		base.accept("fullTrolley", self.handleFullTrolley)
		base.accept("openTrolley", self.handleOpenTrolley)
		base.accept("tookDamage", self.handleTookDamage)
		base.accept("enterGagShop", self.enterGagShop)
		base.accept("exitGagShop", self.exitGagShop)
		base.accept("moneyChanged", self.moneyGui.update)
		base.accept("ammoChanged", self.pieGui.update)
		base.accept("collectedMoney", self.handleMoneyCollected)
		base.accept("restartGame", self.exitGame)
		base.accept("bossSpawned", self.handleBossSpawned)
		base.accept("lostConnection", self.delete)
		base.accept("MinigameStationSlotOpen", self.handleMinigameStationSlotOpen)
		base.accept("MinigameStationHeadOff", self.handleMinigameStationHeadOff)
		self.createGui()
		
	def enterFirstPerson(self):
		base.avatar.toon_head.hide()
		base.camLens.setMinFov(70.0 / (4./3.))
		base.avatar.deleteShadow()
		self.smart_cam.enterFirstPerson()
		
	def exitFirstPerson(self):
		base.avatar.toon_head.show()
		base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4./3.))
		base.avatar.initShadow(base.avatar.avatarType)
		self.smart_cam.exitFirstPerson()
		
	def delete(self):
		self.cr.getCurrentHood().unloadHood()
		self.pieGui.deleteGui()
		self.moneyGui.deleteGui()
		self.smart_cam.stop_smartcamera()
		self.chatInput.delete()
		self.disableMovement()
		base.avatar.stopLookAround()
		base.avatar.stopBlink()
		base.avatar.sendDeleteMsg()
		self.deleteLaffMeter()
		self.book_btn.destroy()
		self.book_gui.removeNode()
		base.ignore("exitGagShop")
		base.ignore("moneyChanged")
		base.ignore("ammoChanged")
		base.ignore("collectedMoney")
		base.ignore("restartGame")
		base.ignore("SuitsActive")
		base.ignore("SuitsInactive")
		base.ignore("fullTrolley")
		base.ignore("openTrolley")
		base.ignore("tookDamage")
		base.ignore("enterGagShop")
		base.ignore("loadedHood")
		base.ignore("gotLookSpot")
		base.ignore("bossSpawned")
		base.ignore("lostConnection")
		#base.ignore("alt-1")
		#base.ignore("alt-2")
		base.ignore("MinigameStationSlotOpen")
		base.ignore("MinigameStationHeadOff")
		taskMgr.remove("checkHealth")
		base.camLens.setMinFov(self.oFov/(4./3.))
		camera.reparentTo(render)
		camera.setPos(0,0,0)
		camera.setHpr(0,0,0)
		del base.avatar
		del self.laffMeter
		del self.pieGui
		del self.sb
		del self.smart_cam
		del self.controlManager
		del self.walkControls
		del self.hoodUtil
		del self.cr
		del self.head
		del self.headtype
		del self.hr, self.hg, self.hb, self.ha
		del self.tr, self.tg, self.tb, self.ta
		del self.lr, self.lg, self.lb, self.la
		del self.gender
		del self.torsotype
		del self.legtype
		del self.shir, self.shig, self.shib
		del self.shor, self.shog, self.shob
		del self.sleeve, self.shirt, self.short
		del self.name
		del self.keyMap
		del self.offset
		if hasattr(self, 'dmg2BeDone'):
			del self.dmg2BeDone
		del self.run_sfx
		del self.walk_sfx
		del self.isThrowing
		del self.book_btn
		del self.book_gui
		del self.chatInput
		return
	
	def handleBossSpawned(self):
		if base.avatar.zoneId == 20:
			self.hoodUtil.centralHood.bossSpawned()
			
	def handleMinigameStationSlotOpen(self, slot, sdoid, adoid):
		if adoid == base.avatar.doId:
			for key in self.cr.doId2do.keys():
				station = self.cr.doId2do[key]
				if station.__class__.__name__ == "DistributedMinigameStation":
					if station.doId == sdoid:
						if slot == 1:
							self.enterMinigameStationSlot(station.circle1, station)
						elif slot == 2:
							self.enterMinigameStationSlot(station.circle2, station)
						elif slot == 3:
							self.enterMinigameStationSlot(station.circle3, station)
					
	def enterMinigameStationSlot(self, circle, station):
		self.disableMovement()
		self.smart_cam.stop_smartcamera()
		camera.reparentTo(station)
		camera.setPos(0, 30.0, 22.5)
		camera.setPos(camera.getPos(render))
		camera.reparentTo(render)
		camera.lookAt(station.sign)
		self.book_btn.hide()
		base.avatar.headsUp(circle)
		base.avatar.b_setAnimState("run")
		runTrack = LerpPosInterval(base.avatar,
								1.0,
								circle.getPos(render),
								startPos=base.avatar.getPos(render))
		runTrack.start()
		Sequence(Wait(1), Func(self.createStationAbortGui), Func(base.avatar.b_setAnimState, "neutral"), Func(base.avatar.headsUp, station.sign)).start()
		
	def createStationAbortGui(self):
		qt_btn = loader.loadModel("phase_3/models/gui/quit_button.bam")
		self.abortBtn = DirectButton(text="Abort", geom=(qt_btn.find('**/QuitBtn_UP'),
											qt_btn.find('**/QuitBtn_DN'),
											qt_btn.find('**/QuitBtn_RLVR')), relief=None, scale=1.2, text_scale=0.055,
											pos=(0, 0, 0.85), command=self.sendStationAbort)
											
	def sendStationAbort(self):
		self.abortBtn.destroy()
		del self.abortBtn
		pkg = PyDatagram()
		pkg.addUint16(STATION_ABORT)
		pkg.addUint32(base.avatar.doId)
		self.cr.send(pkg)
		self.abortStation()
		
	def abortStation(self):
		self.enableMovement()
		self.book_btn.show()
		self.startSmartCam()
		
	def handleMinigameStationHeadOff(self, game, doid, zone):
		if doid == base.avatar.doId:
			self.abortBtn.destroy()
			del self.abortBtn
			self.startSmartCam()
			self.enterTeleportOut(None)
			Sequence(Wait(6.0), Func(self.changeHood, zone, base.avatar.zoneId, place="minigame")).start()
		
	def startSmartCam(self):
		self.smart_cam.initialize_smartcamera()
		self.smart_cam.initialize_smartcamera_collisions()
		self.smart_cam.start_smartcamera()
		
	def resetSmartCam(self):
		self.smart_cam.stop_smartcamera()
		self.startSmartCam()
		
	def enterGagShop(self):
		self.disableMovement()
		self.gagShop.enter()
		
	def exitGagShop(self):
		self.enableMovement()
		pkg = PyDatagram()
		pkg.addUint16(GAG_SHOP_EXIT)
		self.cr.send(pkg)
		
	def handleMoneyCollected(self, money):
		base.avatar.setMoney(base.avatar.getMoney() + money)
		
	def createGui(self):
		if base.config.GetBool('want-chat', True):
			self.chatInput = ChatInput.ChatInput()
			self.chatInput.createGui()
			self.chatInput.enableKeyboardShortcuts()
		self.book_gui = loader.loadModel("phase_3.5/models/gui/sticker_open_close_gui.bam")
		self.book_btn = DirectButton(geom=(self.book_gui.find('**/BookIcon_CLSD'),
											self.book_gui.find('**/BookIcon_OPEN'),
											self.book_gui.find('**/BookIcon_RLVR')), relief=None, pos=(-0.175, 0, 0.163), command=self.startBook, scale=(0.7, 0.8, 0.8), parent=base.a2dBottomRight)
		self.book_btn.hide()
		
	def createLaffMeter(self):
		self.laffMeter.generate(base.avatar.hr, base.avatar.hg, base.avatar.hb, base.avatar.head)
		self.laffMeter.start()
		
	def deleteLaffMeter(self):
		self.laffMeter.destroy()

	def setAvatarName(self, name):
		base.avatar.b_setName(name)
		base.avatar.tag['text_fg'] = CIGlobals.LocalNameTagColor

	def initMovement(self):
		self.walkControls = GravityWalker(legacyLifter=True)
		self.walkControls.setWallBitMask(CIGlobals.WallBitmask)
		self.walkControls.setFloorBitMask(CIGlobals.FloorBitmask)
		self.walkControls.setWalkSpeed(30, 30, 15, 75)
		self.walkControls.initializeCollisions(base.cTrav, base.avatar, floorOffset=0.025, reach=4.0)
		self.walkControls.setAirborneHeightFunc(self.getAirborneHeight)
		camera.reparent_to(base.avatar)
		self.smart_cam.start_smartcamera()

	def getAirborneHeight(self):
		return self.offset + 0.025000000000000001

	def enableMovement(self):
		self.movementEnabled = True
		self.walkControls.enableAvatarControls()
		base.accept("arrow_up", self.setKey, ["forward",1])
		base.accept("arrow_up-up", self.setKey, ["forward",0])
		base.accept("arrow_down", self.setKey, ["backward",1])
		base.accept("arrow_down-up", self.setKey, ["backward",0])
		base.accept("arrow_left", self.setKey, ["left", 1])
		base.accept("arrow_left-up", self.setKey, ["left", 0])
		base.accept("arrow_right", self.setKey, ["right",1])
		base.accept("arrow_right-up", self.setKey, ["right",0])
		base.accept("control", self.setKey, ["jump",1])
		base.accept("control-up", self.setKey, ["jump", 0])
		if base.config.GetBool('want-weapons', True):
			if base.config.GetBool('want-pies', True):
				base.accept("delete", self.startPie)
				base.accept("delete-up", self.throwPie)
		
		base.avatar.b_setAnimState("neutral")
		
		self.isMoving_forward = True
		self.isMoving_side = True
		
		taskMgr.add(self.move, "movetask")
		
	def startPie(self):
		if not base.avatar.pies.getAmmo() <= 0:
			# We need to store the damage amount to be done
			# so the avatar can't switch weapons while
			# the pie is airborne to do more damage without
			# losing the ammo.
			self.dmg2BeDone = base.avatar.pies.getDamage()
			self.isThrowing = True
			self.resetHeadHpr()
			base.avatar.stopLookAround()
			base.avatar.b_pieStart()
			base.avatar.pies.pieCollisions()

	def throwPie(self):
		base.avatar.b_pieThrow()
		self.disableThrow()
		taskMgr.doMethodLater(0.75, self.releasePie, "releasePie")
		taskMgr.doMethodLater(1.05, self.enableThrow, "enablepie")
		
	def disableThrow(self):
		base.ignore("delete")
		base.ignore("delete-up")

	def releasePie(self, task):
		base.avatar.b_pieRelease()
		self.isThrowing = False
		base.acceptOnce("pieSensor-into", self.checkPieCollisions)
		return task.done

	def enableThrow(self, task):
		if base.avatar.isDead():
			return
		base.avatar.startLookAround()
		base.accept("delete", self.startPie)
		base.accept("delete-up", self.throwPie)
		return

	def checkPieCollisions(self, entry):
		"""This method will figure out which CollisionNode the pie hit.
		If the hit CollisionNode is a Suit, then we'll send a datagram of
		the Suit's DoId to all clients. The client will then decide if
		the DoId sent matches its local DoId. If true, the Suit will take
		damage."""
		
		if base.avatar.pies.pie_state == 'start':
			return
		intoNP = entry.getIntoNodePath()
		suitNP = intoNP.getParent()
		for key in self.cr.doId2do.keys():
			val = self.cr.doId2do[key]
			# Let's see if the DoId ties into a Suit class.
			if "Suit" in val.__class__.__name__:
				if val.getKey() == suitNP.getKey():
					# It's true! Let's send a datagram of the DoId over the network.
					if val.getHealth() > 0:
						val.b_setDamage(self.dmg2BeDone)
						taskMgr.doMethodLater(0.1, self.checkSuitHealth, "checkSuitHealth", extraArgs=[val], appendTask=True)
			elif val.__class__.__name__ == "DistributedToon":
				if val.getKey() == suitNP.getKey():
					if not val.isDead():
						if val.getHealth() < 50:
							val.b_addHealth(1)
		base.avatar.b_handlePieSplat()
		
	def checkSuitHealth(self, suit, task):
		money = int(suit.maxHP / CIGlobals.SuitAttackDamageFactors['clipontie'])
		if suit.getHealth() <= 0:
			base.avatar.setMoney(base.avatar.getMoney() + money)
		return task.done
		
	def nul(self):
		pass
		
	def handleLookSpot(self, hpr):
		h, p, r = hpr
		base.avatar.d_lookAtObject(h, p, r)
		
	def startBook(self):
		self.resetHeadHpr()
		base.avatar.stopLookAround()
		self.book_btn.remove()
		self.disableMovement()
		base.avatar.b_openBook()
		taskMgr.doMethodLater(0.5, self.idleBook, "idlebook")

	def idleBook(self, task):
		self.sb.createBG()
		self.sb.zonePage()
		base.avatar.b_readBook()
		self.book_btn = DirectButton(geom=(self.book_gui.find('**/BookIcon_OPEN'),
											self.book_gui.find('**/BookIcon_CLSD'),
											self.book_gui.find('**/BookIcon_RLVR2')), relief=None, pos=(-0.175, 0, 0.163), command=self.endBook, extraArgs=["closebook"], scale=(0.7, 0.8, 0.8), parent=base.a2dBottomRight)
		self.book_btn.setBin('gui-popup', 60)
		return task.done

	def endBook(self, direction):
		self.sb.closeBook()
		self.book_btn.hide()
		base.avatar.b_closeBook()
		taskMgr.doMethodLater(2, self.finishBook, "finishBook", extraArgs=[None, direction])
		
	def finishBook(self, task, direction):
		base.avatar.startLookAround()
		self.book_btn['geom'] = (self.book_gui.find('**/BookIcon_CLSD'), self.book_gui.find('**/BookIcon_OPEN'), self.book_gui.find('**/BookIcon_RLVR'))
		self.book_btn['command'] = self.startBook
		self.book_btn['extraArgs'] = []
		if direction == "closebook":
			self.enableMovement()
			self.book_btn.show()

	def enterTeleportOut(self, task, place="hood"):
		base.avatar.stopLookAround()
		self.resetHeadHpr()
		base.avatar.b_teleportOut()
		self.moneyGui.deleteGui()
		self.pieGui.deleteGui()
		self.laffMeter.disable()

	def enterTeleportIn(self, place="hood"):
		base.avatar.setPos(0,0,0)
		base.avatar.setHpr(0,0,0)
		if place == "hood":
			base.avatar.b_teleportIn()
			taskMgr.doMethodLater(1, self.enableMovementAfterTele, "emat")
			self.pieGui.createGui()
			self.moneyGui.createGui()
			self.createLaffMeter()
			self.resetSmartCam()
		elif place == "minigame":
			self.smart_cam.stop_smartcamera()
			camera.setPos(0,0,0)
			camera.setHpr(0,0,0)
			base.avatar.d_clearSmoothing()
			base.avatar.b_setAnimState("neutral")
			self.pieGui.deleteGui()
			self.moneyGui.deleteGui()
			self.book_btn.hide()

	def enableMovementAfterTele(self, task):
		base.avatar.startLookAround()
		base.avatar.b_setAnimState("neutral")
		self.enableMovement()
		self.book_btn.show()
		return task.done
		
	def changeHoodTask(self, task, newzoneid, currentzoneid):
		self.changeHood(newzoneid, currentzoneid)
		
	def changeHood(self, newzoneid, currentzoneid, place="hood"):
		if currentzoneid == 10:
			self.hoodUtil.unload("home")
		elif currentzoneid == 20:
			self.hoodUtil.unload("TT")
		elif currentzoneid == 30:
			self.hoodUtil.unload("minigamearea")
		if newzoneid == 10:
			self.cr.setObjectZone(base.avatar, 10)
			self.hoodUtil.load("home")
			base.avatar.b_setPlace(CIGlobals.Estate)
		elif newzoneid == 20:
			self.cr.setObjectZone(base.avatar, 20)
			self.hoodUtil.load("TT")
			base.avatar.b_setPlace(CIGlobals.ToontownCentral)
			if self.cr.SuitsActive == 1:
				self.hoodUtil.enableSuitEffect(self.cr.invasionSize)
				if self.cr.BossActive == 1:
					self.handleBossSpawned()
		elif newzoneid == 30:
			self.cr.setObjectZone(base.avatar, 30)
			self.hoodUtil.load("minigamearea")
			base.avatar.b_setPlace(CIGlobals.MinigameArea)
		elif newzoneid == "exit":
			self.exitGame()
		else:
			self.cr.setObjectZone(base.avatar, newzoneid)
			messenger.send("loadedHood", [place])
		if newzoneid != "exit":
			self.spawn()
		
	def spawn(self):
		h = random.randint(0, 360)
		if base.avatar.zoneId == 20:
			point = random.randint(0, len(CIGlobals.SuitPaths) - 1)
			pos = CIGlobals.SuitPaths[point]
			base.avatar.setPos(pos)
		base.avatar.setH(h)
			
	def checkHealth(self, task):
		if base.avatar.getHealth() <= 0:
			base.avatar.b_toonLose()
			self.toonLose()
			return task.done
		return task.cont
		
	def exitGame(self):
		self.delete()
		messenger.send("enterPickAToon", [1])
		
	def toonLose(self):
		self.smart_cam.stop_smartcamera()
		self.disableMovement()
		aspect2d.hide()
		render2d.hide()
		camera.setPos(camera.getPos(render))
		camera.setHpr(camera.getHpr(render))
		camera.reparentTo(render)
		taskMgr.doMethodLater(8, self.leaveGame, "leaveGame")
		
	def leaveGame(self, task):
		self.delete()
		messenger.send("died")
		return task.done
		
	def handleSuitsActive(self, size):
		if base.avatar.zoneId == 20:
			self.hoodUtil.enableSuitEffect(size)
			
	def handleSuitsInactive(self):
		if base.avatar.zoneId == 20:
			self.hoodUtil.disableSuitEffect()
			
	def handleFullTrolley(self):
		notify.warning("Cannot enter full trolley!")

	def handleOpenTrolley(self):
		notify.info("Trolley is open!")
			
	def sendSuitInfoRequest(self):
		""" We have just arrived in-game, let's
		see if there are any active Suits. """
		
		pkg = PyDatagram()
		pkg.addUint16(WANTS_SUIT_INFO)
		self.cr.send(pkg)
		
	def sendBossInfoRequest(self):
		pkg = PyDatagram()
		pkg.addUint16(WANTS_BOSS_INFO)
		self.cr.send(pkg)
		
	def handleTrolleyEnter(self, entry):
		# Let's find out if we can join the trolley.
		pkg = PyDatagram()
		pkg.addUint16(TROLLEY_REQ_ENTER)
		self.cr.send(pkg)

	def handleTrolleyResponse(self):
		notify.info("Got response from trolley.")
		
	def resetHeadHpr(self):
		base.avatar.b_lookAtObject(0, 0, 0, blink=0)
		
	def handleTookDamage(self):
		if base.avatar.isDead():
			return
		base.avatar.stopLookAround()
		self.resetHeadHpr()
		self.disableMovement()
		if not base.avatar.isDead():
			taskMgr.doMethodLater(3, self.enableMovementTask, "enableMovementTask")
			
	def interruptPie(self):
		self.isThrowing = False
		self.cleanupPieModel()
		taskMgr.remove("releasePie")
		
	def cleanupPieModel(self):
		base.avatar.b_deletePie()
			
	def enableMovementTask(self, task):
		if base.avatar.isDead():
			return task.done
		base.avatar.startLookAround()
		self.enableMovement()
		return task.done
		
	def disableMovement(self):
		self.movementEnabled = False
		self.walkControls.disableAvatarControls()
		self.run_sfx.stop()
		self.walk_sfx.stop()
		base.ignore("arrow_up")
		base.ignore("arrow_up-up")
		base.ignore("arrow_down")
		base.ignore("arrow_down-up")
		base.ignore("arrow_left")
		base.ignore("arrow_left-up")
		base.ignore("arrow_right")
		base.ignore("arrow_right-up")
		base.ignore("control")
		base.ignore("control-up")
		base.ignore("delete")
		base.ignore("delete-up")
		
		self.isMoving_forward = True
		self.isMoving_side = True
		
	def setKey(self, key, value):
		self.keyMap[key] = value
		
	def move(self, task):
		if not self.movementEnabled:
			return task.done

		def checkIsAirborne(task):
			if not self.walkControls.isAirborne:
				if self.keyMap["forward"]!=0:
					if self.isMoving_forward is True:
						self.run_sfx.play()
						self.walk_sfx.stop()
						base.avatar.b_setAnimState("run")
						self.isMoving_forward = False
				elif (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0) or (self.keyMap["backward"]!=0):
					if self.isMoving_side is True:
						self.walk_sfx.play()
						self.run_sfx.stop()
						base.avatar.b_setAnimState("walk")
						self.isMoving_side = False
				else:
					base.avatar.b_setAnimState("neutral")
					self.isMoving_side = False
					self.isMoving_forward = False
				return task.done
			return task.cont

		if (self.keyMap["jump"]!=0):
			if self.isMoving_forward is False and self.isMoving_side is False:
				if not self.walkControls.isAirborne:
					if self.isThrowing:
						self.interruptPie()
					self.walk_sfx.stop()
					self.run_sfx.stop()
					base.avatar.b_setAnimState("jump")
					taskMgr.doMethodLater(0.01, checkIsAirborne, "checkisairborne")
			elif self.isMoving_forward is True or self.isMoving_side is True:
				if not self.walkControls.isAirborne:
					if self.isThrowing:
						self.interruptPie()
					self.walk_sfx.stop()
					self.run_sfx.stop()
					base.avatar.b_setAnimState("leap")
					taskMgr.doMethodLater(0.01, checkIsAirborne, "checkisairborne")

		elif (self.keyMap["forward"]!=0):
			if self.isMoving_forward is False:
				if not self.walkControls.isAirborne:
					if self.isThrowing:
						self.interruptPie()
					self.run_sfx.play()
					self.walk_sfx.stop()
					self.isMoving_side = False
					base.avatar.b_setAnimState("run")
					base.avatar.stopLookAround()
					self.resetHeadHpr()
					self.isMoving_forward = True

		elif (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0) or (self.keyMap["backward"]!=0):
			if self.isMoving_side is False:
				if not self.walkControls.isAirborne:
					if self.isThrowing:
						self.interruptPie()
					self.run_sfx.stop()
					self.walk_sfx.play()
					self.isMoving_forward = False
					base.avatar.stopLookAround()
					self.resetHeadHpr()
					base.avatar.setPlayRate(1.0, "walk")
					if self.keyMap["backward"] != 0 and self.keyMap["right"] == 0 and self.keyMap["left"] == 0:
						base.avatar.setPlayRate(-1.0, "walk")
					base.avatar.b_setAnimState("walk")
					self.isMoving_side = True

		else:
			if self.isMoving_forward or self.isMoving_side:
				if not self.walkControls.isAirborne:
					self.run_sfx.stop()
					self.walk_sfx.stop()
					base.avatar.b_setAnimState("neutral")
					base.avatar.startLookAround()
					self.resetHeadHpr()
					self.isMoving_side = False
					self.isMoving_forward = False
		
		return task.cont
Exemplo n.º 11
0
class ToonPanel(DirectFrame):
    notify = directNotify.newCategory('ToonPanel')
    animal2HeadData = {'dog': (0.125, 0.04),
     'duck': (0.1, 0.025),
     'cat': (0.115, 0.04),
     'rabbit': (0.115, 0.04),
     'horse': (0.115, 0.06),
     'monkey': (0.115, 0.06),
     'pig': (0.115, 0.07),
     'mouse': (0.09, 0.02),
     'bear': (0.125, 0.05)}
    State2Text = {'status': ('Seeing if %s is available...', '%s is busy right now; try again later.'),
     'teleport': ('Trying to go to %s...', 'Could not go to %s.'),
     'friend': ('Asking %s to be your friend...', '%s said no, thank you.', 'You are now friends with %s!'),
     'remove': ('Are you sure you want to remove %s from your friends list?', '%s left your friends list.')}

    def __init__(self):
        DirectFrame.__init__(self, scale=1.2)
        self['image'] = DGG.getDefaultDialogGeom()
        self['image_hpr'] = (0, 0, -90)
        self['image_scale'] = (0.62, 0.9, 0.325)
        self['image_color'] = (1, 1, 0.75, 1)
        self['image_pos'] = (0, 0, -0.065)
        self['relief'] = None
        self.reparentTo(base.a2dTopRight)
        self.setPos(-0.235, 0.0, -0.325)
        self.hide()
        self.head = None
        self.laffMeter = None
        self.exitButton = None
        self.friendButton = None
        self.teleportButton = None
        self.nameText = None
        self.actionFrame = None
        self.actionFrameText = None
        self.actionFrameButton = None
        self.actionFrameButton2 = None
        self.avatarInfo = None
        self.action = None
        self.fsm = ClassicFSM.ClassicFSM('ToonPanel', [State.State('off', self.enterOff, self.exitOff), State.State('waitOnAvatarInfoResponse', self.enterWaitOnAvatarInfoResponse, self.exitWaitOnAvatarInfoResponse, ['panel']), State.State('panel', self.enterPanel, self.exitPanel, ['off'])], 'off', 'off')
        self.fsm.enterInitialState()
        self.actionFSM = ClassicFSM.ClassicFSM('ToonPanelActionFSM', [State.State('off', self.enterOff, self.exitOff),
         State.State('waitOnAvatarStatusResponse', self.enterWaitOnAvatarStatusResponse, self.exitWaitOnAvatarStatusResponse, ['waitOnAvatarTeleportResponse',
          'waitOnAvatarFriendListResponse',
          'avatarBusy',
          'off']),
         State.State('avatarBusy', self.enterAvatarBusy, self.exitAvatarBusy, ['off']),
         State.State('waitOnAvatarTeleportResponse', self.enterWaitOnAvatarTeleportResponse, self.exitWaitOnAvatarTeleportResponse, ['unableToTP']),
         State.State('unableToTP', self.enterUnableToTP, self.exitUnableToTP, ['off']),
         State.State('waitOnAvatarFriendListResponse', self.enterWaitOnAvatarFriendListResponse, self.exitWaitOnAvatarFriendListResponse, ['fRequestA', 'fRequestR']),
         State.State('fRequestA', self.enterFriendRequestAccepted, self.exitFriendRequestAccepted, ['off']),
         State.State('fRequestR', self.enterFriendRequestRejected, self.exitFriendRequestRejected, ['off']),
         State.State('removeFriendConfirm', self.enterRemoveFriendConfirm, self.exitRemoveFriendConfirm, ['off', 'removedFriend']),
         State.State('removedFriend', self.enterRemovedFriend, self.exitRemovedFriend, ['off'])], 'off', 'off')
        self.actionFSM.enterInitialState()
        return

    def maybeUpdateFriendButton(self):
        if self.friendButton:
            if self.avatarInfo:
                if self.avatarInfo[0] not in base.localAvatar.friends:
                    self.friendButton['text'] = 'Add Friend'
                    self.friendButton['extraArgs'] = ['waitOnAvatarFriendListResponse']
                else:
                    self.friendButton['text'] = 'Remove Friend'
                    self.friendButton['extraArgs'] = ['removeFriendConfirm']

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterUnableToTP(self):
        pass

    def exitUnableToTP(self):
        pass

    def enterWaitOnAvatarTeleportResponse(self):
        self.setActionText(self.State2Text['teleport'][0] % self.getAvatarName())
        self.makeButtons('Cancel')
        self.acceptOnce('gotAvatarTeleportResponse', self.handleTeleportResponse)
        base.cr.friendsManager.d_iWantToTeleportToAvatar(self.avatarInfo[0])

    def handleTeleportResponse(self, avatarId, shardId, zoneId):
        if self.avatarInfo[0] == avatarId:
            requestStatus = {}
            whereName = ZoneUtil.getWhereName(zoneId)
            loaderName = ZoneUtil.getLoaderName(zoneId)
            requestStatus['zoneId'] = zoneId
            if base.localAvatar.parentId == shardId:
                requestStatus['shardId'] = None
            else:
                requestStatus['shardId'] = shardId
            requestStatus['hoodId'] = ZoneUtil.getHoodId(zoneId, 1)
            requestStatus['where'] = whereName
            requestStatus['loader'] = loaderName
            requestStatus['how'] = 'teleportIn'
            requestStatus['avId'] = avatarId
            base.cr.playGame.getPlace().fsm.request('teleportOut', [requestStatus])
            self.cleanup()
        return

    def exitWaitOnAvatarTeleportResponse(self):
        self.ignore('gotAvatarTeleportResponse')
        self.clearActionText()
        self.clearActionButtons()

    def setActionText(self, text):
        self.actionFrameText.setText(text)

    def clearActionText(self):
        self.actionFrameText.setText('')

    def makeButtons(self, button1, button2 = None):
        button2GeomFunc = {'Cancel': CIGlobals.getCancelBtnGeom,
         'No': CIGlobals.getCancelBtnGeom,
         'Okay': CIGlobals.getOkayBtnGeom,
         'Yes': CIGlobals.getOkayBtnGeom}
        if button1 and not button2:
            button1Pos = (0, 0, -0.1)
        elif button1 and button2:
            button1Pos = (-0.1, 0, -0.1)
        button2Pos = (0.1, 0, -0.1)
        if button1:
            self.actionFrameButton = DirectButton(text=button1, geom=button2GeomFunc[button1](), parent=self.actionFrame, pos=button1Pos, text_scale=0.045, text_pos=(0, -0.08), command=self.actionButtonPressed, extraArgs=[1], relief=None, geom_scale=0.75)
        if button2:
            self.actionFrameButton2 = DirectButton(text=button2, geom=button2GeomFunc[button2](), parent=self.actionFrame, pos=button2Pos, text_scale=0.045, text_pos=(0, -0.08), command=self.actionButtonPressed, extraArgs=[2], relief=None, geom_scale=0.75)
        return

    def actionButtonPressed(self, buttonNum):
        currentState = self.actionFSM.getCurrentState().getName()
        if buttonNum == 1:
            if currentState in ('waitOnAvatarStatusResponse', 'waitOnAvatarTeleportResponse', 'waitOnAvatarFriendListResponse', 'avatarBusy', 'unableToTP', 'fRequestA', 'fRequestR', 'removeFriendConfirm', 'removedFriend'):
                if currentState == 'waitOnAvatarFriendListResponse':
                    base.cr.friendsManager.d_iCancelledFriendRequest(self.avatarInfo[0])
                elif currentState == 'removeFriendConfirm':
                    self.actionFSM.request('removedFriend')
                    return
                self.actionFSM.request('off')
                self.removeActionPanel()
                self.action = None
        elif buttonNum == 2:
            self.actionFSM.request('off')
            self.removeActionPanel()
            self.action = None
        return

    def clearActionButtons(self):
        if self.actionFrameButton2:
            self.actionFrameButton2.destroy()
            self.actionFrameButton2 = None
        if self.actionFrameButton:
            self.actionFrameButton.destroy()
            self.actionFrameButton = None
        return

    def enterAvatarBusy(self):
        self.setActionText(self.State2Text['status'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitAvatarBusy(self):
        self.clearActionText()
        self.clearActionButtons()

    def getAvatarName(self):
        if self.avatarInfo:
            return self.avatarInfo[1]

    def enterWaitOnAvatarStatusResponse(self):
        self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse)
        base.cr.friendsManager.d_requestAvatarStatus(self.avatarInfo[0])
        self.setActionText(self.State2Text['status'][0] % self.getAvatarName())
        self.makeButtons('Cancel')

    def handleAvatarStatusResponse(self, avatarId, status):
        if avatarId == self.avatarInfo[0]:
            if status == 1:
                self.actionFSM.request('avatarBusy')
            else:
                self.actionFSM.request(self.action)
        else:
            self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse)

    def exitWaitOnAvatarStatusResponse(self):
        self.ignore('gotAvatarStatus')
        self.clearActionText()
        self.clearActionButtons()

    def enterWaitOnAvatarFriendListResponse(self):
        self.acceptOnce('friendRequestAccepted', self.handleFriendRequestAccepted)
        self.acceptOnce('friendRequestRejected', self.handleFriendRequestRejected)
        base.cr.friendsManager.d_askAvatarToBeFriends(self.avatarInfo[0])
        self.setActionText(self.State2Text['friend'][0] % self.getAvatarName())
        self.makeButtons('Cancel')

    def handleFriendRequestAccepted(self):
        self.actionFSM.request('fRequestA')

    def handleFriendRequestRejected(self):
        self.actionFSM.request('fRequestR')

    def exitWaitOnAvatarFriendListResponse(self):
        self.ignore('friendRequestAccepted')
        self.ignore('friendRequestRejected')
        self.clearActionText()
        self.clearActionButtons()

    def enterFriendRequestAccepted(self):
        self.setActionText(self.State2Text['friend'][2] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitFriendRequestAccepted(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterFriendRequestRejected(self):
        self.setActionText(self.State2Text['friend'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitFriendRequestRejected(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterRemoveFriendConfirm(self):
        self.setActionText(self.State2Text['remove'][0] % self.getAvatarName())
        self.makeButtons('Yes', 'No')

    def exitRemoveFriendConfirm(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterRemovedFriend(self):
        base.cr.friendsManager.d_iRemovedFriend(self.avatarInfo[0])
        self.setActionText(self.State2Text['remove'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitRemovedFriend(self):
        self.clearActionText()
        self.clearActionButtons()

    def makeActionPanel(self):
        self.actionFrame = DirectFrame(image=DGG.getDefaultDialogGeom(), image_scale=(0.7, 0.5, 0.45), image_color=(1, 1, 0.75, 1), relief=None)
        self.actionFrame.reparentTo(base.a2dTopRight)
        self.actionFrame.setPos(-0.815, 0, -0.31)
        self.actionFrameText = OnscreenText(text='', parent=self.actionFrame, scale=0.05, wordwrap=12, pos=(0, 0.1))
        return

    def removeActionPanel(self):
        self.clearActionButtons()
        if self.actionFrameText:
            self.actionFrameText.destroy()
            self.actionFrameText = None
        if self.actionFrame:
            self.actionFrame.destroy()
            self.actionFrame = None
        return

    def doAction(self, action):
        self.action = action
        self.actionFSM.requestFinalState()
        self.removeActionPanel()
        self.makeActionPanel()
        if action != 'removeFriendConfirm':
            self.actionFSM.request('waitOnAvatarStatusResponse')
        else:
            self.actionFSM.request(action)

    def enterWaitOnAvatarInfoResponse(self):
        self.label = OnscreenText(text='Retrieving Toon\ndetails...', parent=self, scale=0.04)
        self.acceptOnce('avatarInfoResponse', self.handleAvatarInfoResponse)
        base.cr.friendsManager.d_requestAvatarInfo(self.avatarInfo[0])

    def handleAvatarInfoResponse(self, name, dna, maxHealth, health):
        if self.avatarInfo:
            self.avatarInfo.append(name)
            self.avatarInfo.append(dna)
            self.avatarInfo.append(maxHealth)
            self.avatarInfo.append(health)
            self.fsm.request('panel')

    def exitWaitOnAvatarInfoResponse(self):
        self.label.destroy()
        del self.label
        self.ignore('avatarInfoResponse')

    def makePanel(self, avId):
        if self.avatarInfo:
            if self.avatarInfo[0] == avId:
                return
        self.cleanup()
        base.localAvatar.hideFriendButton()
        self.show()
        self.avatarInfo = []
        self.avatarInfo.append(avId)
        self.fsm.request('waitOnAvatarInfoResponse')

    def exitClicked(self):
        self.cleanup()
        base.localAvatar.showFriendButton()

    def cleanup(self):
        self.actionFSM.requestFinalState()
        self.fsm.requestFinalState()
        self.avatarInfo = None
        return

    def enterPanel(self):
        self.nameText = OnscreenText(text=self.avatarInfo[1], parent=self, pos=(0, 0.2), scale=0.035, wordwrap=8)
        self.nameText.setBin('gui-popup', 60)
        dna = ToonDNA.ToonDNA()
        dna.setDNAStrand(self.avatarInfo[2])
        self.head = ToonHead.ToonHead(base.cr)
        self.head.generateHead(dna.gender, dna.animal, dna.head, 1)
        self.head.setHeadColor(dna.headcolor)
        self.head.reparentTo(self)
        self.head.setDepthWrite(1)
        self.head.setDepthTest(1)
        self.head.setH(180)
        self.head.setScale(self.animal2HeadData[dna.animal][0])
        self.head.setZ(self.animal2HeadData[dna.animal][1])
        self.laffMeter = LaffOMeter()
        r, g, b, _ = dna.headcolor
        self.laffMeter.generate(r, g, b, dna.animal, self.avatarInfo[3], self.avatarInfo[4])
        self.laffMeter.reparentTo(self)
        self.laffMeter.setBin('gui-popup', 60)
        self.laffMeter.setScale(0.045)
        self.laffMeter.setPos(0, 0, -0.1)
        self.friendButton = DirectButton(geom=CIGlobals.getDefaultBtnGeom(), text='Add Friend', scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarFriendListResponse'])
        self.friendButton.setPos(0, 0.0, -0.225)
        self.maybeUpdateFriendButton()
        self.teleportButton = DirectButton(geom=CIGlobals.getDefaultBtnGeom(), text='Teleport', scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarTeleportResponse'])
        self.teleportButton.setPos(0, 0, -0.275)
        self.exitButton = DirectButton(geom=CIGlobals.getCancelBtnGeom(), parent=self, relief=None, scale=0.6, pos=(-0.127, 0.0, -0.3425), command=self.exitClicked)
        return

    def exitPanel(self):
        if self.actionFSM.getCurrentState().getName() == 'waitOnAvatarFriendListResponse':
            if self.avatarInfo:
                base.cr.friendsManager.d_iCancelledFriendRequest(self.avatarInfo[0])
        self.actionFSM.requestFinalState()
        self.action = None
        self.avatarInfo = None
        self.removeActionPanel()
        self.hide()
        if self.nameText:
            self.nameText.destroy()
            self.nameText = None
        if self.head:
            self.head.removeNode()
            self.head.delete()
            self.head = None
        if self.laffMeter:
            self.laffMeter.disable()
            self.laffMeter.delete()
            self.laffMeter = None
        if self.friendButton:
            self.friendButton.destroy()
            self.friendButton = None
        if self.teleportButton:
            self.teleportButton.destroy()
            self.teleportButton = None
        if self.exitButton:
            self.exitButton.destroy()
            self.exitButton = None
        return
Exemplo n.º 12
0
    def __init__(self, cr):
        try:
            self.LocalToon_initialized
            return
        except:
            self.LocalToon_initialized = 1
        DistributedToon.__init__(self, cr)
        self.gagStartKey = config.GetString('gag-start-key')
        self.gagThrowKey = config.GetString('gag-throw-key')
        self.avatarChoice = cr.localAvChoice
        self.smartCamera = SmartCamera()
        self.chatInput = ChatInput()
        self.moneyGui = MoneyGui()
        self.laffMeter = LaffOMeter()
        self.positionExaminer = PositionExaminer()
        self.friendRequestManager = FriendRequestManager()
        self.friendsList = FriendsList()
        self.panel = ToonPanel()
        friendsgui = loader.loadModel(
            'phase_3.5/models/gui/friendslist_gui.bam')
        self.friendButton = DirectButton(
            geom=(friendsgui.find('**/FriendsBox_Closed'),
                  friendsgui.find('**/FriendsBox_Rollover'),
                  friendsgui.find('**/FriendsBox_Rollover')),
            text=("", "Friends", "Friends", ""),
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 1),
            text_scale=0.065,
            text_pos=(0, -0.2),
            relief=None,
            parent=base.a2dTopRight,
            pos=(-0.18, 0.0, -0.17),
            command=self.friendsButtonClicked,
            scale=0.75)
        friendsgui.removeNode()
        del friendsgui
        self.hideFriendButton()
        self.runSfx = base.loadSfx(
            "phase_3.5/audio/sfx/AV_footstep_runloop.ogg")
        self.runSfx.setLoop(True)
        self.walkSfx = base.loadSfx(
            "phase_3.5/audio/sfx/AV_footstep_walkloop.ogg")
        self.walkSfx.setLoop(True)
        self.controlManager = ControlManager.ControlManager(True, False)
        self.offset = 3.2375
        self.firstPersonCamPos = None
        self.movementKeymap = {
            "forward": 0,
            "backward": 0,
            "left": 0,
            "right": 0,
            "jump": 0
        }
        self.avatarMovementEnabled = False
        self.isMoving_forward = False
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_jump = False
        self.gagThrowBtn = None
        self.myBattle = None
        self.gagsTimedOut = False
        self.needsToSwitchToGag = None
        self.gagsEnabled = False

        self.pickerTrav = None
        self.pickerRay = None
        self.pickerRayNode = None
        self.pickerHandler = None
        self.rolledOverTag = None

        self.inTutorial = False
        self.hasDoneJump = False
        self.lastState = None
        self.lastAction = None

        self.jumpHardLandIval = None
Exemplo n.º 13
0
class LocalToon(DistributedToon):
    neverDisable = 1

    def __init__(self, cr):
        try:
            self.LocalToon_initialized
            return
        except:
            self.LocalToon_initialized = 1

        DistributedToon.__init__(self, cr)
        self.avatarChoice = cr.localAvChoice
        self.smartCamera = SmartCamera()
        self.chatInput = ChatInput()
        self.moneyGui = MoneyGui()
        self.laffMeter = LaffOMeter()
        self.positionExaminer = PositionExaminer()
        self.friendRequestManager = FriendRequestManager()
        self.friendsList = FriendsList()
        self.panel = ToonPanel()
        friendsgui = loader.loadModel('phase_3.5/models/gui/friendslist_gui.bam')
        self.friendButton = DirectButton(geom=(friendsgui.find('**/FriendsBox_Closed'), friendsgui.find('**/FriendsBox_Rollover'), friendsgui.find('**/FriendsBox_Rollover')), text=('', 'Friends', 'Friends', ''), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), text_scale=0.065, text_pos=(0, -0.2), relief=None, parent=base.a2dTopRight, pos=(-0.18, 0.0, -0.17), command=self.friendsButtonClicked, scale=0.75)
        friendsgui.removeNode()
        del friendsgui
        self.hideFriendButton()
        self.runSfx = base.loadSfx('phase_3.5/audio/sfx/AV_footstep_runloop.wav')
        self.runSfx.setLoop(True)
        self.walkSfx = base.loadSfx('phase_3.5/audio/sfx/AV_footstep_walkloop.wav')
        self.walkSfx.setLoop(True)
        self.controlManager = ControlManager.ControlManager(True, False)
        self.offset = 3.2375
        self.movementKeymap = {'forward': 0,
         'backward': 0,
         'left': 0,
         'right': 0,
         'jump': 0}
        self.avatarMovementEnabled = False
        self.isMoving_forward = False
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_jump = False
        self.pieThrowBtn = None
        self.myBattle = None
        self.invGui = None
        self.pickerTrav = None
        self.pickerRay = None
        self.pickerRayNode = None
        self.pickerHandler = None
        self.rolledOverTag = None
        self.inTutorial = False
        self.hasDoneJump = False
        self.lastState = None
        self.lastAction = None
        return

    def hasDiscoveredHood(self, zoneId):
        return zoneId in self.hoodsDiscovered

    def hasTeleportAccess(self, zoneId):
        return zoneId in self.teleportAccess

    def tutorialCreated(self, zoneId):
        self.cr.tutorialCreated(zoneId)

    def friendsButtonClicked(self):
        self.hideFriendButton()
        self.friendsList.fsm.request('onlineFriendsList')

    def hideFriendButton(self):
        self.friendButton.hide()

    def showFriendButton(self):
        self.friendButton.show()

    def gotoNode(self, node, eyeHeight = 3):
        possiblePoints = (Point3(3, 6, 0),
         Point3(-3, 6, 0),
         Point3(6, 6, 0),
         Point3(-6, 6, 0),
         Point3(3, 9, 0),
         Point3(-3, 9, 0),
         Point3(6, 9, 0),
         Point3(-6, 9, 0),
         Point3(9, 9, 0),
         Point3(-9, 9, 0),
         Point3(6, 0, 0),
         Point3(-6, 0, 0),
         Point3(6, 3, 0),
         Point3(-6, 3, 0),
         Point3(9, 9, 0),
         Point3(-9, 9, 0),
         Point3(0, 12, 0),
         Point3(3, 12, 0),
         Point3(-3, 12, 0),
         Point3(6, 12, 0),
         Point3(-6, 12, 0),
         Point3(9, 12, 0),
         Point3(-9, 12, 0),
         Point3(0, -6, 0),
         Point3(-3, -6, 0),
         Point3(0, -9, 0),
         Point3(-6, -9, 0))
        for point in possiblePoints:
            pos = self.positionExaminer.consider(node, point, eyeHeight)
            if pos:
                self.setPos(node, pos)
                self.lookAt(node)
                self.setHpr(self.getH() + random.choice((-10, 10)), 0, 0)
                return

        self.setPos(node, 0, 0, 0)

    def setFriendsList(self, friends):
        DistributedToon.setFriendsList(self, friends)
        self.cr.friendsManager.d_requestFriendsList()
        self.panel.maybeUpdateFriendButton()

    def d_requestAddFriend(self, avId):
        self.sendUpdate('requestAddFriend', [avId])

    def setupPicker(self):
        self.pickerTrav = CollisionTraverser('LT.pickerTrav')
        self.pickerRay = CollisionRay()
        rayNode = CollisionNode('LT.pickerNode')
        rayNode.addSolid(self.pickerRay)
        rayNode.setCollideMask(BitMask32(0))
        rayNode.setFromCollideMask(CIGlobals.WallBitmask)
        self.pickerRayNode = base.camera.attachNewNode(rayNode)
        self.pickerHandler = CollisionHandlerQueue()
        self.pickerTrav.addCollider(self.pickerRayNode, self.pickerHandler)

    def enablePicking(self):
        self.accept('mouse1', self.pickedSomething_down)
        self.accept('mouse1-up', self.pickedSomething_up)
        base.taskMgr.add(self.__travMousePicker, 'LT.travMousePicker')

    def disablePicking(self):
        base.taskMgr.remove('LT.travMousePicker')
        self.ignore('mouse1')
        self.ignore('mouse1-up')

    def pickedSomething_down(self):
        if self.rolledOverTag:
            base.playSfx(DGG.getDefaultClickSound())
            avatar = self.cr.doId2do.get(self.rolledOverTag)
            avatar.nameTag.setPickerState('down')

    def pickedSomething_up(self):
        if self.rolledOverTag:
            avatar = self.cr.doId2do.get(self.rolledOverTag)
            avatar.nameTag.setPickerState('up')
            self.panel.makePanel(self.rolledOverTag)

    def __travMousePicker(self, task):
        if not base.mouseWatcherNode.hasMouse():
            return task.cont
        else:
            mpos = base.mouseWatcherNode.getMouse()
            self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
            self.pickerTrav.traverse(render)
            if self.pickerHandler.getNumEntries() > 0:
                self.pickerHandler.sortEntries()
                pickedObject = self.pickerHandler.getEntry(0).getIntoNodePath()
                avatarId = pickedObject.getParent().getPythonTag('avatar')
                if avatarId != None:
                    for do in self.cr.doId2do.values():
                        if do.__class__.__name__ == 'DistributedToon':
                            if do.doId == avatarId:
                                if do.nameTag.getClickable() == 1:
                                    if do.nameTag.fsm.getCurrentState().getName() != 'rollover' and do.nameTag.fsm.getCurrentState().getName() != 'down':
                                        do.nameTag.setPickerState('rollover')
                                        base.playSfx(DGG.getDefaultRolloverSound())
                                        self.rolledOverTag = avatarId
                                        break
                        elif do.__class__.__name__ == 'DistributedToon':
                            if do.nameTag.fsm.getCurrentState().getName() != 'up':
                                do.nameTag.setPickerState('up')

                elif self.rolledOverTag:
                    avatar = self.cr.doId2do.get(self.rolledOverTag)
                    if avatar:
                        if avatar.nameTag.fsm.getCurrentState().getName() != 'up':
                            avatar.nameTag.setPickerState('up')
                    self.rolledOverTag = None
            return task.cont

    def prepareToSwitchControlType(self):
        inputs = ['run',
         'forward',
         'reverse',
         'turnLeft',
         'turnRight',
         'slideLeft',
         'slideRight',
         'jump']
        for inputName in inputs:
            try:
                inputState.releaseInputs(inputName)
            except:
                pass

    def getBackpack(self):
        return DistributedToon.getBackpack(self)

    def setMyBattle(self, battle):
        self.myBattle = battle

    def getMyBattle(self):
        return self.myBattle

    def ghostOn(self):
        self.getGeomNode().setTransparency(1)
        self.getGeomNode().setColorScale(1, 1, 1, 0.25)

    def ghostOff(self):
        self.getGeomNode().setColorScale(1, 1, 1, 1)
        self.getGeomNode().setTransparency(0)

    def enterReadBook(self, ts = 0, callback = None, extraArgs = []):
        self.stopLookAround()
        self.b_lookAtObject(0, -45, 0)
        DistributedToon.enterReadBook(self, ts, callback, extraArgs)

    def exitReadBook(self):
        DistributedToon.exitReadBook(self)
        self.startLookAround()

    def getAirborneHeight(self):
        return self.offset + 0.025

    def setupControls(self):
        self.walkControls = GravityWalker(legacyLifter=False)
        self.walkControls.setWallBitMask(CIGlobals.WallBitmask)
        self.walkControls.setFloorBitMask(CIGlobals.FloorBitmask)
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSpeed, CIGlobals.ToonJumpForce, CIGlobals.ToonReverseSpeed, CIGlobals.ToonRotateSpeed)
        self.walkControls.initializeCollisions(base.cTrav, self, floorOffset=0.025, reach=4.0)
        self.walkControls.setAirborneHeightFunc(self.getAirborneHeight)

    def setWalkSpeedNormal(self):
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSpeed, CIGlobals.ToonJumpForce, CIGlobals.ToonReverseSpeed, CIGlobals.ToonRotateSpeed)

    def setWalkSpeedSlow(self):
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSlowSpeed, CIGlobals.ToonJumpSlowForce, CIGlobals.ToonReverseSlowSpeed, CIGlobals.ToonRotateSlowSpeed)

    def setupCamera(self):
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4.0 / 3.0))
        base.camLens.setNearFar(CIGlobals.DefaultCameraNear, CIGlobals.DefaultCameraFar)
        camHeight = max(self.getHeight(), 3.0)
        heightScaleFactor = camHeight * 0.3333333333
        defLookAt = Point3(0.0, 1.5, camHeight)
        camPos = (Point3(0.0, -9.0 * heightScaleFactor, camHeight),
         defLookAt,
         Point3(0.0, camHeight, camHeight * 4.0),
         Point3(0.0, camHeight, camHeight * -1.0),
         0)
        self.smartCamera.initializeSmartCamera()
        self.smartCamera.setIdealCameraPos(camPos[0])
        self.smartCamera.setLookAtPoint(defLookAt)

    def setDNAStrand(self, dnaStrand):
        DistributedToon.setDNAStrand(self, dnaStrand)
        self.initCollisions()
        self.setupCamera()

    def setMoney(self, money):
        DistributedToon.setMoney(self, money)
        self.moneyGui.update(money)

    def setupNameTag(self, tempName = None):
        DistributedToon.setupNameTag(self, tempName)
        if self.nameTag:
            self.nameTag.setColorLocal()

    def d_broadcastPositionNow(self):
        self.d_clearSmoothing()
        self.d_broadcastPosHpr()

    def b_setAnimState(self, anim, callback = None, extraArgs = []):
        if self.anim != anim:
            self.d_setAnimState(anim)
            DistributedToon.setAnimState(self, anim, callback=callback, extraArgs=extraArgs)

    def attachCamera(self):
        camera.reparentTo(self)
        camera.setPos(self.smartCamera.getIdealCameraPos())

    def startSmartCamera(self):
        self.smartCamera.startUpdateSmartCamera()

    def resetSmartCamera(self):
        self.stopSmartCamera()
        self.startSmartCamera()

    def stopSmartCamera(self):
        self.smartCamera.stopUpdateSmartCamera()

    def detachCamera(self):
        camera.reparentTo(render)
        camera.setPos(0, 0, 0)
        camera.setHpr(0, 0, 0)

    def handleSuitAttack(self, attack_id, suit_id):
        DistributedToon.handleSuitAttack(self, attack_id, suit_id)
        if not self.isDead() and base.config.GetBool('want-sa-reactions'):
            base.taskMgr.remove('LT.attackReactionDone')
            attack = SuitAttacks.SuitAttackLengths.keys()[attack_id]
            suit = self.cr.doId2do.get(suit_id)
            animToPlay = None
            timeToWait = 3.0
            if attack not in ('pickpocket', 'fountainpen'):
                suitH = suit.getH(render) % 360
                myH = self.getH(render) % 360
                if -90.0 <= suitH - myH <= 90.0:
                    animToPlay = 'fallFWD'
                else:
                    animToPlay = 'fallBCK'
            elif attack in ('pickpocket',):
                animToPlay = 'cringe'
            elif attack in ('fountainpen',):
                animToPlay = 'conked'
                timeToWait = 5.0
            self.cr.playGame.getPlace().fsm.request('stop')
            self.b_setAnimState(animToPlay)
            base.taskMgr.doMethodLater(timeToWait, self.__attackReactionDone, 'LT.attackReactionDone')
        return

    def __attackReactionDone(self, task):
        self.cr.playGame.hood.loader.place.fsm.request('walk')
        self.b_setAnimState('neutral')
        return Task.done

    def enableAvatarControls(self):
        self.walkControls.enableAvatarControls()
        self.accept('control', self.updateMovementKeymap, ['jump', 1])
        self.accept('control-up', self.updateMovementKeymap, ['jump', 0])
        taskMgr.add(self.movementTask, 'avatarMovementTask')
        self.avatarMovementEnabled = True
        self.playMovementSfx(None)
        return

    def disableAvatarControls(self):
        self.walkControls.disableAvatarControls()
        self.ignore('arrow_up')
        self.ignore('arrow_up-up')
        self.ignore('arrow_down')
        self.ignore('arrow_down-up')
        self.ignore('arrow_left')
        self.ignore('arrow_left-up')
        self.ignore('arrow_right')
        self.ignore('arrow_right-up')
        self.ignore('control')
        self.ignore('control-up')
        taskMgr.remove('avatarMovementTask')
        self.isMoving_forward = False
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_jump = False
        self.avatarMovementEnabled = False
        self.playMovementSfx(None)
        for k, _ in self.movementKeymap.items():
            self.updateMovementKeymap(k, 0)

        return

    def updateMovementKeymap(self, key, value):
        self.movementKeymap[key] = value

    def getMovementKeyValue(self, key):
        return self.movementKeymap[key]

    def playMovementSfx(self, movement):
        if movement == 'run':
            self.walkSfx.stop()
            self.runSfx.play()
        elif movement == 'walk':
            self.runSfx.stop()
            self.walkSfx.play()
        else:
            self.runSfx.stop()
            self.walkSfx.stop()

    def __forward(self):
        self.resetHeadHpr()
        self.stopLookAround()
        if self.getHealth() < 1:
            self.playMovementSfx('walk')
            self.setPlayRate(1.2, 'dwalk')
            self.setAnimState('deadWalk')
        else:
            self.playMovementSfx('run')
            self.setAnimState('run')
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_forward = True
        self.isMoving_jump = False

    def __turn(self):
        self.resetHeadHpr()
        self.stopLookAround()
        self.playMovementSfx('walk')
        if self.getHealth() < 1:
            self.setPlayRate(1.2, 'dwalk')
            self.setAnimState('deadWalk')
        else:
            self.setPlayRate(1.0, 'walk')
            self.setAnimState('walk')
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_side = True
        self.isMoving_jump = False

    def __reverse(self):
        self.resetHeadHpr()
        self.stopLookAround()
        self.playMovementSfx('walk')
        if self.getHealth() < 1:
            self.setPlayRate(-1.0, 'dwalk')
            self.setAnimState('deadWalk')
        else:
            self.setAnimState('walkBack')
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = True
        self.isMoving_jump = False

    def __jump(self):
        self.playMovementSfx(None)
        if base.localAvatar.getHealth() > 0:
            if self.playingAnim == 'run' or self.playingAnim == 'walk':
                self.b_setAnimState('leap')
            else:
                self.b_setAnimState('jump')
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_jump = True
        return

    def __neutral(self):
        self.resetHeadHpr()
        self.startLookAround()
        self.playMovementSfx(None)
        if base.localAvatar.getHealth() > 0:
            self.setAnimState('neutral')
        else:
            self.setPlayRate(1.0, 'dneutral')
            self.setAnimState('deadNeutral')
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_jump = False
        return

    def movementTask(self, task):
        if self.getMovementKeyValue('jump') == 1:
            if not self.walkControls.isAirborne:
                if self.walkControls.mayJump:
                    self.__jump()
                    self.hasDoneJump = True
                elif self.hasDoneJump:
                    if self.getHealth() > 0:
                        self.b_setAnimState('Happy')
                    self.hasDoneJump = False
        elif not self.walkControls.isAirborne:
            if self.hasDoneJump:
                if self.getHealth() > 0:
                    self.b_setAnimState('Happy')
                self.hasDoneJump = False
        return task.cont

    def startTrackAnimToSpeed(self):
        base.taskMgr.add(self.trackAnimToSpeed, self.uniqueName('trackAnimToSpeed'))

    def stopTrackAnimToSpeed(self):
        base.taskMgr.remove(self.uniqueName('trackAnimToSpeed'))

    def trackAnimToSpeed(self, task):
        speed, rotSpeed, slideSpeed = self.walkControls.getSpeeds()
        state = None
        if self.getHealth() > 0:
            state = 'Happy'
        else:
            state = 'Sad'
        if state != self.lastState:
            self.lastState = state
            self.b_setAnimState(state)
            if state == 'Sad':
                self.setWalkSpeedSlow()
            else:
                self.setWalkSpeedNormal()
        action = self.setSpeed(speed, rotSpeed)
        if action != self.lastAction:
            self.lastAction = action
            if action == CIGlobals.WALK_INDEX or action == CIGlobals.REVERSE_INDEX:
                self.resetHeadHpr()
                self.stopLookAround()
                self.playMovementSfx('walk')
            elif action == CIGlobals.RUN_INDEX:
                self.resetHeadHpr()
                self.stopLookAround()
                self.playMovementSfx('run')
            else:
                self.resetHeadHpr()
                self.startLookAround()
                self.playMovementSfx(None)
        return task.cont

    def createLaffMeter(self):
        r, g, b, _ = self.getHeadColor()
        animal = self.getAnimal()
        maxHp = self.getMaxHealth()
        hp = self.getHealth()
        self.laffMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp)
        self.laffMeter.start()

    def disableLaffMeter(self):
        self.laffMeter.stop()
        self.laffMeter.disable()

    def deleteLaffMeter(self):
        self.laffMeter.delete()

    def setLoadout(self, gagIds):
        DistributedToon.setLoadout(self, gagIds)
        if base.cr.playGame.getPlace() and base.cr.playGame.getPlace().fsm.getCurrentState().getName() == 'shtickerBook':
            if hasattr(base.cr.playGame.getPlace(), 'shtickerBookStateData'):
                if base.cr.playGame.getPlace().shtickerBookStateData.fsm.getCurrentState().getName() == 'inventoryPage':
                    base.cr.playGame.getPlace().shtickerBookStateData.gui.fsm.request('idle')

    def enablePies(self, andKeys = 0):
        if self.avatarMovementEnabled and andKeys:
            self.enablePieKeys()
        self.backpack = DistributedToon.getBackpack(self)
        self.invGui = InventoryGui()
        self.invGui.createGui()
        self.invGui.setBackpack(self.backpack)
        for gag in self.backpack.getGags():
            gag.setAvatar(self)

        self.backpack.setGagGUI(self.invGui)
        if self.backpack.getCurrentGag():
            self.invGui.setWeapon(self.backpack.getCurrentGag().getName(), playSound=False)

    def enablePieKeys(self):
        if self.pieThrowBtn:
            if not self.backpack:
                self.backpack = DistributedToon.getBackpack(self)
            self.pieThrowBtn.bind(DGG.B1PRESS, self.startGag)
            self.pieThrowBtn.bind(DGG.B1RELEASE, self.throwGag)
        self.accept('delete', self.startGag)
        self.accept('delete-up', self.throwGag)

    def disablePieKeys(self):
        if self.pieThrowBtn:
            self.pieThrowBtn.unbind(DGG.B1PRESS)
            self.pieThrowBtn.unbind(DGG.B1RELEASE)
        self.ignore('delete')
        self.ignore('delete-up')

    def disablePies(self):
        self.disablePieKeys()
        self.invGui.deleteGui()
        if hasattr(self, 'backpack'):
            if self.backpack:
                self.backpack.setCurrentGag(None)
        return

    def setWeaponType(self, weaponType):
        enableKeysAgain = 0
        if weaponType != self.weaponType:
            enableKeysAgain = 1
        self.weaponType = weaponType
        if enableKeysAgain:
            self.disablePieKeys()
            self.enablePieKeys()

    def createMoney(self):
        self.moneyGui.createGui()
        self.moneyGui.update(self.money)

    def handleMoneyChanged(self):
        self.moneyGui.update()

    def disableMoney(self):
        self.moneyGui.deleteGui()

    def resetHeadHpr(self):
        self.b_lookAtObject(0, 0, 0, blink=0)

    def startGag(self, start = True):
        if not self.backpack or not self.backpack.getCurrentGag():
            return
        if self.backpack.getSupply() > 0:
            if self.pieThrowBtn:
                self.pieThrowBtn.unbind(DGG.B1PRESS)
            if self.backpack.getActiveGag():
                if self.backpack.getActiveGag().getState() != GagState.LOADED:
                    return
            self.ignore('delete')
            self.backpack.getCurrentGag().setAvatar(self)
            self.resetHeadHpr()
            self.b_gagStart(self.backpack.getCurrentGag().getID())

    def throwGag(self, start = True):
        if not self.backpack or not self.backpack.getCurrentGag() or not self.backpack.getActiveGag():
            return
        if self.backpack.getSupply() > 0:
            if self.pieThrowBtn:
                self.pieThrowBtn.unbind(DGG.B1RELEASE)
            self.ignore('delete-up')
            if self.backpack.getActiveGag().getType() == GagType.SQUIRT and self.backpack.getActiveGag().getName() == CIGlobals.SeltzerBottle:
                self.b_gagRelease(self.backpack.getActiveGag().getID())
            else:
                self.b_gagThrow(self.backpack.getActiveGag().getID())
            activeGag = self.backpack.getActiveGag()
            if not activeGag:
                activeGag = self.backpack.getCurrentGag()
            if not activeGag.doesAutoRelease():
                Sequence(Wait(0.75), Func(self.releaseGag), Wait(0.3), Func(self.enablePieKeys)).start()

    def releaseGag(self):
        if not self.backpack or not self.backpack.getActiveGag():
            return
        if self.backpack.getSupply() > 0:
            gag = self.backpack.getActiveGag()
            if not gag:
                gag = self.backpack.getCurrentGag()
            if gag.getState() != GagState.RELEASED:
                gagName = gag.getName()
                self.b_gagRelease(GagGlobals.getIDByName(gagName))

    def checkSuitHealth(self, suit):
        pass

    def handleLookSpot(self, hpr):
        h, p, r = hpr
        self.d_lookAtObject(h, p, r, blink=1)

    def showPieButton(self):
        geom = CIGlobals.getDefaultBtnGeom()
        self.pieThrowBtn = DirectButton(geom=geom, geom_scale=(0.75, 1, 1), text='Throw Gag', text_scale=0.05, text_pos=(0, -0.01), relief=None, parent=base.a2dTopCenter, pos=(0, 0, -0.1))
        self.pieThrowBtn.setBin('gui-popup', 60)
        return

    def hidePieButton(self):
        self.pieThrowBtn.removeNode()
        self.pieThrowBtn = None
        return

    def showBookButton(self, inBook = 0):
        self.book_gui = loader.loadModel('phase_3.5/models/gui/sticker_open_close_gui.bam')
        self.book_btn = DirectButton(geom=(self.book_gui.find('**/BookIcon_CLSD'), self.book_gui.find('**/BookIcon_OPEN'), self.book_gui.find('**/BookIcon_RLVR')), relief=None, pos=(-0.175, 0, 0.163), command=self.bookButtonClicked, scale=(0.7, 0.8, 0.8), parent=base.a2dBottomRight)
        self.book_btn.setBin('gui-popup', 60)
        if inBook:
            self.book_btn['geom'] = (self.book_gui.find('**/BookIcon_OPEN'), self.book_gui.find('**/BookIcon_CLSD'), self.book_gui.find('**/BookIcon_RLVR2'))
            self.book_btn['command'] = self.bookButtonClicked
            self.book_btn['extraArgs'] = [0]
        return

    def hideBookButton(self):
        if hasattr(self, 'book_gui'):
            self.book_gui.removeNode()
            del self.book_gui
        if hasattr(self, 'book_btn'):
            self.book_btn.destroy()
            del self.book_btn

    def bookButtonClicked(self, openIt = 1):
        if openIt:
            base.cr.playGame.getPlace().fsm.request('shtickerBook')
        else:
            base.cr.playGame.getPlace().shtickerBookStateData.finished('resume')

    def startMonitoringHP(self):
        taskMgr.add(self.monitorHealth, 'localToon-monitorHealth')

    def monitorHealth(self, task):
        if self.isDead():
            base.taskMgr.remove('LT.attackReactionDone')
            if self.cr.playGame.hood.id != ZoneUtil.getHoodId(self.zoneId):
                self.cr.playGame.getPlace().fsm.request('died', [{}, self.diedStateDone])
            return task.done
        return task.cont

    def stopMonitoringHP(self):
        taskMgr.remove('localToon-monitorHealth')

    def setHealth(self, hp):
        if hp > 0 and self.getHealth() < 1:
            if self.cr.playGame.getPlace():
                if self.cr.playGame.getPlace().fsm.getCurrentState().getName() == 'walk':
                    if self.cr.playGame.getPlace().walkStateData.fsm.getCurrentState().getName() == 'deadWalking':
                        self.cr.playGame.getPlace().walkStateData.fsm.request('walking')
            if self.animFSM.getCurrentState().getName() == 'deadNeutral':
                self.playMovementSfx(None)
                self.b_setAnimState('neutral')
            elif self.animFSM.getCurrentState().getName() == 'deadWalk':
                self.playMovementSfx('run')
                self.b_setAnimState('run')
        DistributedToon.setHealth(self, hp)
        return

    def diedStateDone(self, requestStatus):
        hood = self.cr.playGame.hood.id
        if hood == CIGlobals.BattleTTC:
            hood = CIGlobals.ToontownCentral
        toZone = ZoneUtil.getZoneId(hood)
        if self.zoneId != toZone:
            requestStatus = {'zoneId': toZone,
             'hoodId': hood,
             'where': ZoneUtil.getWhereName(toZone),
             'avId': self.doId,
             'loader': ZoneUtil.getLoaderName(toZone),
             'shardId': None,
             'wantLaffMeter': 1,
             'how': 'teleportIn'}
            self.cr.playGame.getPlace().doneStatus = requestStatus
            messenger.send(self.cr.playGame.getPlace().doneEvent)
        else:
            return
        return

    def teleportToCT(self):
        toZone = CIGlobals.CogTropolisId
        hood = CIGlobals.CogTropolis
        requestStatus = {'zoneId': toZone,
         'hoodId': hood,
         'where': ZoneUtil.getWhereName(toZone),
         'avId': self.doId,
         'loader': ZoneUtil.getLoaderName(toZone),
         'shardId': None,
         'wantLaffMeter': 1,
         'how': 'teleportIn'}
        self.cr.playGame.getPlace().fsm.request('teleportOut', [requestStatus])
        return

    def createChatInput(self):
        self.chatInput.load()
        self.chatInput.enter()

    def disableChatInput(self):
        self.chatInput.exit()
        self.chatInput.unload()

    def collisionsOn(self):
        self.controlManager.collisionsOn()

    def collisionsOff(self):
        self.controlManager.collisionsOff()

    def generate(self):
        DistributedToon.generate(self)

    def delete(self):
        DistributedToon.delete(self)
        self.deleteLaffMeter()

    def disable(self):
        base.camLens.setMinFov(CIGlobals.OriginalCameraFov / (4.0 / 3.0))
        self.friendsList.destroy()
        self.friendsList = None
        self.positionExaminer.delete()
        self.positionExaminer = None
        self.disablePicking()
        self.stopMonitoringHP()
        taskMgr.remove('resetHeadColorAfterFountainPen')
        taskMgr.remove('LT.attackReactionDone')
        self.stopLookAround()
        DistributedToon.disable(self)
        self.disableAvatarControls()
        self.disableLaffMeter()
        self.disablePies()
        self.disableChatInput()
        self.weaponType = None
        self.pieType = None
        self.myBattle = None
        self.ignore('gotLookSpot')
        return

    def announceGenerate(self):
        DistributedToon.announceGenerate(self)
        self.setupPicker()
        self.setupControls()
        self.startLookAround()
        self.friendRequestManager.watch()
        self.accept('gotLookSpot', self.handleLookSpot)

    def printAvPos(self):
        print 'Pos: %s, Hpr: %s' % (self.getPos(), self.getHpr())
Exemplo n.º 14
0
class LocalToon(DistributedToon):
    neverDisable = 1

    def __init__(self, cr):
        try:
            self.LocalToon_initialized
            return
        except:
            self.LocalToon_initialized = 1
        DistributedToon.__init__(self, cr)
        self.avatarChoice = cr.localAvChoice
        self.smartCamera = SmartCamera()
        self.chatInput = ChatInput()
        self.moneyGui = MoneyGui()
        self.pieGui = PieGui(self.pies)
        self.laffMeter = LaffOMeter()
        self.runSfx = base.loadSfx(
            "phase_3.5/audio/sfx/AV_footstep_runloop.ogg")
        self.runSfx.setLoop(True)
        self.walkSfx = base.loadSfx(
            "phase_3.5/audio/sfx/AV_footstep_walkloop.ogg")
        self.walkSfx.setLoop(True)
        self.controlManager = ControlManager.ControlManager(True, False)
        self.offset = 3.2375
        self.movementKeymap = {
            "forward": 0,
            "backward": 0,
            "left": 0,
            "right": 0,
            "jump": 0
        }
        self.avatarMovementEnabled = False
        self.isMoving_forward = False
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_jump = False
        base.cTrav = CollisionTraverser()
        #base.cTrav.showCollisions(render)

    def getAirborneHeight(self):
        return self.offset + 0.025000000000000001

    def setupControls(self):
        self.walkControls = GravityWalker(legacyLifter=False)
        self.walkControls.setWallBitMask(CIGlobals.WallBitmask)
        self.walkControls.setFloorBitMask(CIGlobals.FloorBitmask)
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSpeed,
                                       CIGlobals.ToonJumpForce,
                                       CIGlobals.ToonReverseSpeed,
                                       CIGlobals.ToonRotateSpeed)
        self.walkControls.initializeCollisions(base.cTrav,
                                               self,
                                               floorOffset=0.025,
                                               reach=4.0)
        self.walkControls.setAirborneHeightFunc(self.getAirborneHeight)

    def setWalkSpeedNormal(self):
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSpeed,
                                       CIGlobals.ToonJumpForce,
                                       CIGlobals.ToonReverseSpeed,
                                       CIGlobals.ToonRotateSpeed)

    def setWalkSpeedSlow(self):
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSlowSpeed,
                                       CIGlobals.ToonJumpSlowForce,
                                       CIGlobals.ToonReverseSlowSpeed,
                                       CIGlobals.ToonRotateSlowSpeed)

    def setupCamera(self):
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4. / 3.))
        base.camLens.setNearFar(CIGlobals.DefaultCameraNear,
                                CIGlobals.DefaultCameraFar)
        camHeight = max(self.getHeight(), 3.0)
        heightScaleFactor = camHeight * 0.3333333333
        defLookAt = Point3(0.0, 1.5, camHeight)
        camPos = (Point3(0.0, -9.0 * heightScaleFactor, camHeight), defLookAt,
                  Point3(0.0, camHeight, camHeight * 4.0),
                  Point3(0.0, camHeight, camHeight * -1.0), 0)
        self.smartCamera.set_default_pos(camPos)
        self.smartCamera.set_parent(self)

    def setDNAStrand(self, dnaStrand):
        DistributedToon.setDNAStrand(self, dnaStrand)
        self.initCollisions()
        self.setupCamera()

    def setMoney(self, money):
        DistributedToon.setMoney(self, money)
        self.moneyGui.update()

    def setGagAmmo(self, ammoList):
        DistributedToon.setGagAmmo(self, ammoList)
        self.pieGui.update()

    def setupNameTag(self):
        DistributedToon.setupNameTag(self)
        if self.tag:
            self.tag['text_fg'] = CIGlobals.LocalNameTagColor

    def d_broadcastPositionNow(self):
        self.d_clearSmoothing()
        self.d_broadcastPosHpr()

    def b_setAnimState(self, anim, callback=None, extraArgs=[]):
        if self.anim != anim:
            self.d_setAnimState(anim)
            DistributedToon.setAnimState(self,
                                         anim,
                                         callback=callback,
                                         extraArgs=extraArgs)

    def attachCamera(self):
        self.smartCamera.initialize_smartcamera()

    def startSmartCamera(self):
        self.smartCamera.initialize_smartcamera_collisions()
        self.smartCamera.start_smartcamera()

    def resetSmartCamera(self):
        self.stopSmartCamera()
        self.startSmartCamera()

    def stopSmartCamera(self):
        self.smartCamera.stop_smartcamera()

    def detachCamera(self):
        camera.reparentTo(render)
        camera.setPos(0, 0, 0)
        camera.setHpr(0, 0, 0)

    def enableAvatarControls(self):
        self.walkControls.enableAvatarControls()
        self.accept("arrow_up", self.updateMovementKeymap, ["forward", 1])
        self.accept("arrow_up-up", self.updateMovementKeymap, ["forward", 0])
        self.accept("arrow_down", self.updateMovementKeymap, ["backward", 1])
        self.accept("arrow_down-up", self.updateMovementKeymap,
                    ["backward", 0])
        self.accept("arrow_left", self.updateMovementKeymap, ["left", 1])
        self.accept("arrow_left-up", self.updateMovementKeymap, ["left", 0])
        self.accept("arrow_right", self.updateMovementKeymap, ["right", 1])
        self.accept("arrow_right-up", self.updateMovementKeymap, ["right", 0])
        self.accept("control", self.updateMovementKeymap, ["jump", 1])
        self.accept("control-up", self.updateMovementKeymap, ["jump", 0])
        taskMgr.add(self.movementTask, "avatarMovementTask")
        self.avatarMovementEnabled = True
        self.playMovementSfx(None)

    def disableAvatarControls(self):
        self.walkControls.disableAvatarControls()
        self.ignore("arrow_up")
        self.ignore("arrow_up-up")
        self.ignore("arrow_down")
        self.ignore("arrow_down-up")
        self.ignore("arrow_left")
        self.ignore("arrow_left-up")
        self.ignore("arrow_right")
        self.ignore("arrow_right-up")
        self.ignore("control")
        self.ignore("control-up")
        taskMgr.remove("avatarMovementTask")
        self.isMoving_forward = False
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_jump = False
        self.avatarMovementEnabled = False
        self.playMovementSfx(None)
        for k, v in self.movementKeymap.items():
            self.updateMovementKeymap(k, 0)

    def updateMovementKeymap(self, key, value):
        self.movementKeymap[key] = value

    def getMovementKeyValue(self, key):
        return self.movementKeymap[key]

    def playMovementSfx(self, movement):
        if movement == "run":
            self.walkSfx.stop()
            self.runSfx.play()
        elif movement == "walk":
            self.runSfx.stop()
            self.walkSfx.play()
        else:
            self.runSfx.stop()
            self.walkSfx.stop()

    def __forward(self):
        self.resetHeadHpr()
        self.stopLookAround()
        self.playMovementSfx("run")
        self.b_setAnimState("run")
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_forward = True
        self.isMoving_jump = False

    def __turn(self):
        self.resetHeadHpr()
        self.stopLookAround()
        self.playMovementSfx("walk")
        self.setPlayRate(1.0, "walk")
        self.b_setAnimState("walk")
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_side = True
        self.isMoving_jump = False

    def __reverse(self):
        self.resetHeadHpr()
        self.stopLookAround()
        self.playMovementSfx("walk")
        self.setPlayRate(-1.0, "walk")
        self.b_setAnimState("walk")
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = True
        self.isMoving_jump = False

    def __jump(self):
        self.playMovementSfx(None)
        if self.isMoving_forward or self.isMoving_side or self.isMoving_back:
            self.b_setAnimState("leap")
        else:
            self.b_setAnimState("jump")
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_jump = True

    def __neutral(self):
        self.resetHeadHpr()
        self.startLookAround()
        self.playMovementSfx(None)
        self.b_setAnimState("neutral")
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_jump = False

    def movementTask(self, task):
        if self.getMovementKeyValue("jump") == 1:
            if not self.isMoving_jump:
                if not self.walkControls.isAirborne:
                    if self.walkControls.mayJump:
                        self.__jump()
                    else:
                        if self.getMovementKeyValue("forward") == 1:
                            if not self.isMoving_forward:
                                self.__forward()
                        elif self.getMovementKeyValue("backward") == 1:
                            if not self.isMoving_back:
                                self.__reverse()
                        elif self.getMovementKeyValue(
                                "left") == 1 or self.getMovementKeyValue(
                                    "right") == 1:
                            if not self.isMoving_side:
                                self.__turn()
                        else:
                            if self.isMoving_side or self.isMoving_forward or self.isMoving_back:
                                self.__neutral()
        elif self.getMovementKeyValue("forward") == 1:
            if not self.isMoving_forward:
                if not self.walkControls.isAirborne:
                    self.__forward()
        elif self.getMovementKeyValue("backward") == 1:
            if not self.isMoving_back:
                if not self.walkControls.isAirborne:
                    self.__reverse()
        elif self.getMovementKeyValue("left") == 1 or self.getMovementKeyValue(
                "right") == 1:
            if not self.isMoving_side:
                if not self.walkControls.isAirborne:
                    self.__turn()
        else:
            if self.isMoving_side or self.isMoving_forward or self.isMoving_back or self.isMoving_jump:
                if not self.walkControls.isAirborne:
                    self.__neutral()
        return task.cont

    def createLaffMeter(self):
        r, g, b, a = self.getHeadColor()
        animal = self.getAnimal()
        maxHp = self.getMaxHealth()
        hp = self.getHealth()
        self.laffMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp)
        self.laffMeter.start()

    def disableLaffMeter(self):
        self.laffMeter.stop()
        self.laffMeter.disable()

    def deleteLaffMeter(self):
        self.laffMeter.delete()

    def enablePies(self, andKeys=0):
        if self.avatarMovementEnabled and andKeys:
            self.enablePieKeys()
        self.pieGui.createGui()
        self.pieGui.setWeapon("tart")

    def enablePieKeys(self):
        self.accept("delete", self.startPie)
        self.accept("delete-up", self.throwPie)

    def disablePieKeys(self):
        self.ignore("delete")
        self.ignore("delete-up")

    def disablePies(self):
        self.disablePieKeys()
        self.pieGui.deleteGui()

    def createMoney(self):
        self.moneyGui.createGui()
        # Automatically update incase we missed the db field.
        self.moneyGui.update()

    def handleMoneyChanged(self):
        self.moneyGui.update()

    def disableMoney(self):
        self.moneyGui.deleteGui()

    def resetHeadHpr(self):
        self.b_lookAtObject(0, 0, 0, blink=0)

    def startPie(self):
        if self.pies.getAmmo() > 0:
            self.ignore("delete")
            self.dmg2BeDone = self.pies.getDamage()
            self.resetHeadHpr()
            self.b_pieStart()
            self.pies.pie.pieCollisions()

    def throwPie(self):
        if self.pies.getAmmo() > 0:
            self.ignore("delete-up")
            self.b_pieThrow()
            Sequence(Wait(0.75), Func(self.releasePie), Wait(0.3),
                     Func(self.enablePieKeys)).start()

    def releasePie(self):
        if self.pies.getAmmo() > 0:
            self.b_pieRelease()
            sensorName = self.pies.pie.getSensorName()
            self.acceptOnce(sensorName + "-into",
                            self.pies.pie.handlePieCollisions)

    def checkSuitHealth(self, suit):
        if suit.getHealth() <= 0:
            self.sendUpdate('suitKilled', [suit.doId])

    def handleLookSpot(self, hpr):
        h, p, r = hpr
        self.d_lookAtObject(h, p, r, blink=1)

    def showBookButton(self, inBook=0):
        self.book_gui = loader.loadModel(
            "phase_3.5/models/gui/sticker_open_close_gui.bam")
        self.book_btn = DirectButton(
            geom=(self.book_gui.find('**/BookIcon_CLSD'),
                  self.book_gui.find('**/BookIcon_OPEN'),
                  self.book_gui.find('**/BookIcon_RLVR')),
            relief=None,
            pos=(-0.175, 0, 0.163),
            command=self.bookButtonClicked,
            scale=(0.7, 0.8, 0.8),
            parent=base.a2dBottomRight)
        self.book_btn.setBin('gui-popup', 60)
        if inBook:
            self.book_btn["geom"] = (self.book_gui.find('**/BookIcon_OPEN'),
                                     self.book_gui.find('**/BookIcon_CLSD'),
                                     self.book_gui.find('**/BookIcon_RLVR2'))
            self.book_btn["command"] = self.bookButtonClicked
            self.book_btn["extraArgs"] = [0]

    def hideBookButton(self):
        self.book_gui.removeNode()
        del self.book_gui
        self.book_btn.destroy()
        del self.book_btn

    def bookButtonClicked(self, openIt=1):
        if openIt:
            base.cr.playGame.getPlace().fsm.request('shtickerBook')
        else:
            base.cr.playGame.getPlace().shtickerBookStateData.finished(
                "resume")

    def handleHitByWeapon(self):
        self.b_lookAtObject(0, 0, 0, blink=1)
        self.cr.playGame.hood.loader.place.fsm.request('stop')
        if not self.isDead():
            self.b_setAnimState('fallBCK')
            taskMgr.doMethodLater(3.0, self.fallDone, "fallDone")

    def monitorHealth(self, task):
        if self.isDead():
            taskMgr.remove("fallDone")
            self.cr.playGame.hood.loader.place.fsm.request(
                'died', [{}, self.diedStateDone])
            return task.done
        return task.cont

    def diedStateDone(self, requestStatus):
        # TODO: Make the toon go to the estate where they
        # can collect ice cream to replenish health.

        # Tell the ai we're dead so they can refill our hp.
        self.sendUpdate("died", [])
        # Then, log out and notify the client that they're dead.
        self.cr.gameFSM.request("closeShard", ['died'])

    def fallDone(self, task):
        self.cr.playGame.hood.loader.place.fsm.request('walk')
        self.b_setAnimState('neutral')
        return task.done

    def createChatInput(self):
        self.chatInput.load()
        self.chatInput.enter()

    def disableChatInput(self):
        self.chatInput.exit()
        self.chatInput.unload()

    def collisionsOn(self):
        self.controlManager.collisionsOn()

    def collisionsOff(self):
        self.controlManager.collisionsOff()

    def generate(self):
        DistributedToon.generate(self)

    def delete(self):
        DistributedToon.delete(self)
        self.deleteLaffMeter()
        return

    def disable(self):
        taskMgr.remove("localToon-monitorHealth")
        taskMgr.remove("fallDone")
        DistributedToon.disable(self)
        self.disableAvatarControls()
        self.disableLaffMeter()
        self.disablePies()
        self.disableChatInput()
        self.stopLookAround()
        self.ignore("gotLookSpot")
        return

    def announceGenerate(self):
        DistributedToon.announceGenerate(self)
        self.setupControls()
        self.createChatInput()
        self.startLookAround()
        taskMgr.add(self.monitorHealth, "localToon-monitorHealth")
        self.accept("gotLookSpot", self.handleLookSpot)
Exemplo n.º 15
0
class DistributedToon(Toon.Toon, DistributedAvatar, DistributedSmoothNode,
                      DelayDeletable):
    def __init__(self, cr):
        try:
            self.DistributedToon_initialized
            return
        except:
            self.DistributedToon_initialized = 1

        Toon.Toon.__init__(self, cr)
        DistributedAvatar.__init__(self, cr)
        DistributedSmoothNode.__init__(self, cr)
        self.questManager = QuestManager.QuestManager()
        self.token = -1
        self.ghost = 0
        self.puInventory = []
        self.equippedPU = -1
        self.backpack = None
        self.animState2animId = {}
        self.battleMeter = None
        for index in range(len(self.animFSM.getStates())):
            self.animState2animId[self.animFSM.getStates()
                                  [index].getName()] = index

        self.animId2animState = {
            v: k
            for k, v in self.animState2animId.items()
        }
        self.headMeter = None
        self.firstTimeChangingHP = True
        self.quests = []
        self.tier = None
        self.questHistory = None
        self.busy = 1
        self.friends = None
        self.tutDone = 0
        self.hoodsDiscovered = []
        self.teleportAccess = []
        self.lastHood = 0
        self.defaultShard = 0
        self.dmgFadeIval = None
        self.tunnelTrack = None
        return

    def goThroughTunnel(self, toZone, inOrOut, requestStatus=None):
        if self.tunnelTrack:
            self.ignore(self.tunnelTrack.getDoneEvent())
            self.tunnelTrack.finish()
            self.tunnelTrack = None
        linkTunnel = LinkTunnel.getTunnelThatGoesToZone(toZone)
        if not linkTunnel:
            return
        self.tunnelTrack = Parallel(
            name=self.uniqueName('Place.goThroughTunnel'))
        if inOrOut == 0:
            pivotPoint = linkTunnel.inPivotPoint
            pivotPointNode = linkTunnel.tunnel.attachNewNode(
                'tunnelPivotPoint')
            pivotPointNode.setPos(pivotPoint)
            self.stopSmooth()
            self.wrtReparentTo(pivotPointNode)
            if linkTunnel.__class__.__name__ == 'SafeZoneLinkTunnel':
                self.setHpr(180, 0, 0)
            else:
                self.setHpr(0, 0, 0)
            if base.localAvatar.doId == self.doId:
                doneMethod = self._handleWentInTunnel
                extraArgs = [requestStatus]
                self.walkControls.setCollisionsActive(0)
                camera.wrtReparentTo(linkTunnel.tunnel)
                currCamPos = camera.getPos()
                currCamHpr = camera.getHpr()
                tunnelCamPos = linkTunnel.camPos
                tunnelCamHpr = linkTunnel.camHpr
                self.tunnelTrack.append(
                    LerpPosInterval(camera,
                                    duration=0.7,
                                    pos=tunnelCamPos,
                                    startPos=currCamPos,
                                    blendType='easeOut'))
                self.tunnelTrack.append(
                    LerpQuatInterval(camera,
                                     duration=0.7,
                                     quat=tunnelCamHpr,
                                     startHpr=currCamHpr,
                                     blendType='easeOut'))
            exitSeq = Sequence(Func(self.loop, 'run'))
            if base.localAvatar.doId == self.doId:
                exitSeq.append(Wait(2.0))
                exitSeq.append(Func(base.transitions.irisOut))
            self.tunnelTrack.append(exitSeq)
            self.tunnelTrack.append(
                Sequence(
                    LerpHprInterval(pivotPointNode,
                                    duration=2.0,
                                    hpr=linkTunnel.inPivotEndHpr,
                                    startHpr=linkTunnel.inPivotStartHpr),
                    LerpPosInterval(pivotPointNode,
                                    duration=1.0,
                                    pos=(linkTunnel.inPivotEndX,
                                         pivotPointNode.getY(),
                                         pivotPointNode.getZ()),
                                    startPos=(linkTunnel.inPivotStartX,
                                              pivotPointNode.getY(),
                                              pivotPointNode.getZ()))))
        else:
            if inOrOut == 1:
                pivotPoint = linkTunnel.outPivotPoint
                pivotPointNode = linkTunnel.tunnel.attachNewNode(
                    'tunnelPivotPoint')
                pivotPointNode.setPos(pivotPoint)
                pivotPointNode.setHpr(linkTunnel.outPivotStartHpr)
                if base.localAvatar.doId == self.doId:
                    base.localAvatar.walkControls.setCollisionsActive(0)
                    base.localAvatar.detachCamera()
                    camera.reparentTo(linkTunnel.tunnel)
                    tunnelCamPos = linkTunnel.camPos
                    tunnelCamHpr = linkTunnel.camHpr
                    camera.setPos(tunnelCamPos)
                    camera.setHpr(tunnelCamHpr)
                    doneMethod = self._handleCameOutTunnel
                    extraArgs = []
                self.reparentTo(pivotPointNode)
                self.setHpr(linkTunnel.toonOutHpr)
                self.setPos(linkTunnel.toonOutPos)
                exitSeq = Sequence(
                    Func(self.loop, 'run'),
                    LerpPosInterval(pivotPointNode,
                                    duration=1.0,
                                    pos=(linkTunnel.outPivotEndX,
                                         pivotPointNode.getY(),
                                         pivotPointNode.getZ()),
                                    startPos=(linkTunnel.outPivotStartX,
                                              pivotPointNode.getY(),
                                              pivotPointNode.getZ())),
                    LerpHprInterval(pivotPointNode,
                                    duration=2.0,
                                    hpr=linkTunnel.outPivotEndHpr,
                                    startHpr=linkTunnel.outPivotStartHpr),
                    Func(self.wrtReparentTo, render), Func(self.startSmooth))
                self.tunnelTrack.append(exitSeq)
        if base.localAvatar.doId == self.doId:
            self.tunnelTrack.setDoneEvent(self.tunnelTrack.getName())
            self.acceptOnce(self.tunnelTrack.getDoneEvent(), doneMethod,
                            extraArgs)
        self.tunnelTrack.start()
        return

    def setupNameTag(self, tempName=None):
        Toon.Toon.setupNameTag(self, tempName)
        self.nametag.getNametag3d().setClickEvent('toonClicked', [self.doId])
        self.nametag.getNametag2d().setClickEvent('toonClicked', [self.doId])

    def setDefaultShard(self, shardId):
        self.defaultShard = shardId

    def getDefaultShard(self):
        return self.defaultShard

    def doSmoothTask(self, task):
        self.smoother.computeAndApplySmoothPosHpr(self, self)
        if not hasattr(base, 'localAvatar'):
            return task.done
        if self.doId != base.localAvatar.doId:
            self.setSpeed(self.smoother.getSmoothForwardVelocity(),
                          self.smoother.getSmoothRotationalVelocity(),
                          self.smoother.getSmoothLateralVelocity())
        return task.cont

    def setLastHood(self, zoneId):
        self.lastHood = zoneId

    def b_setLastHood(self, zoneId):
        self.sendUpdate('setLastHood', [zoneId])
        self.setLastHood(zoneId)

    def getLastHood(self):
        return self.lastHood

    def setTeleportAccess(self, array):
        self.teleportAccess = array

    def getTeleportAccess(self):
        return self.teleportAccess

    def setHoodsDiscovered(self, array):
        self.hoodsDiscovered = array

    def b_setHoodsDiscovered(self, array):
        self.sendUpdate('setHoodsDiscovered', [array])
        self.setHoodsDiscovered(array)

    def getHoodsDiscovered(self):
        return self.hoodsDiscovered

    def setTutorialCompleted(self, value):
        self.tutDone = value

    def getTutorialCompleted(self):
        return self.tutDone

    def setFriendsList(self, friends):
        self.friends = friends

    def getFriendsList(self):
        return self.friends

    def setBusy(self, busy):
        self.busy = busy

    def getBusy(self):
        return self.busy

    def setTier(self, tier):
        self.tier = tier

    def getTier(self):
        return self.tier

    def setQuestHistory(self, array):
        self.questHistory = array

    def getQuestHistrory(self):
        return self.questHistory

    def setQuests(self, questIds, currentObjectives,
                  currentObjectivesProgress):
        self.quests = [questIds, currentObjectives, currentObjectivesProgress]
        self.questManager.makeQuestsFromData()

    def getQuests(self):
        return self.quests

    def maybeMakeHeadMeter(self):
        if base.localAvatar.doId != self.doId:
            if self.health < self.getMaxHealth():
                if not self.headMeter:
                    self.__makeHeadMeter()

    def __makeHeadMeter(self):
        self.headMeter = LaffOMeter(forRender=True)
        r, g, b, _ = self.getHeadColor()
        animal = self.getAnimal()
        maxHp = self.getMaxHealth()
        hp = self.getHealth()
        self.headMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp)
        self.headMeter.reparentTo(self)
        self.headMeter.setZ(self.getHeight() + 2)
        self.headMeter.setScale(0.4)
        self.headMeter.setBillboardAxis()
        self.__updateHeadMeter()

    def __removeHeadMeter(self):
        if self.headMeter:
            self.headMeter.disable()
            self.headMeter.delete()
            self.headMeter = None
        return

    def __updateHeadMeter(self):
        if self.headMeter:
            self.headMeter.updateMeter(self.getHealth())

    def setHealth(self, health):
        if self.doId != base.localAvatar.doId:
            if not self.firstTimeChangingHP:
                if health < self.getMaxHealth():
                    if not self.headMeter:
                        self.__makeHeadMeter()
                    else:
                        self.__updateHeadMeter()
                else:
                    self.__removeHeadMeter()
        self.health = health
        self.firstTimeChangingHP = False

    def d_createBattleMeter(self):
        self.sendUpdate('makeBattleMeter', [])

    def b_createBattleMeter(self):
        self.makeBattleMeter()
        self.d_createBattleMeter()

    def d_cleanupBattleMeter(self):
        self.sendUpdate('destroyBattleMeter', [])

    def b_cleanupBattleMeter(self):
        self.destroyBattleMeter()
        self.d_cleanupBattleMeter()

    def makeBattleMeter(self):
        if self.getHealth() < self.getMaxHealth():
            if not self.battleMeter:
                self.battleMeter = LaffOMeter()
                r, g, b, _ = self.getHeadColor()
                animal = self.getAnimal()
                maxHp = self.getMaxHealth()
                hp = self.getHealth()
                self.battleMeter.generate(r,
                                          g,
                                          b,
                                          animal,
                                          maxHP=maxHp,
                                          initialHP=hp)
                self.battleMeter.reparentTo(self)
                self.battleMeter.setZ(self.getHeight() + 5)
                self.battleMeter.setScale(0.5)
                self.battleMeter.start()

    def destroyBattleMeter(self):
        if self.battleMeter:
            self.battleMeter.stop()
            self.battleMeter.disable()
            self.battleMeter.delete()
            self.battleMeter = None
        return

    def setEquippedPU(self, index):
        self.equippedPU = index

    def getEquippedPU(self):
        return self.equippedPU

    def setPUInventory(self, array):
        self.puInventory = array

    def getPUInventory(self):
        return self.puInventory

    def setGhost(self, value):
        self.ghost = value
        if value:
            self.ghostOn()
        else:
            self.ghostOff()

    def d_setGhost(self, value):
        self.sendUpdate('setGhost', [value])

    def b_setGhost(self, value):
        self.d_setGhost(value)
        self.setGhost(value)

    def getGhost(self):
        return self.ghost

    def setDNAStrand(self, dnaStrand):
        Toon.Toon.setDNAStrand(self, dnaStrand)
        self.maybeMakeHeadMeter()

    def d_setDNAStrand(self, dnaStrand):
        self.sendUpdate('setDNAStrand', [dnaStrand])

    def b_setDNAStrand(self, dnaStrand):
        self.setDNAStrand(dnaStrand)
        self.d_setDNAStrand(dnaStrand)

    def lookAtObject(self, h, p, r, blink=1):
        if self.getPart('head').getHpr() == (h, p, r):
            return
        Toon.Toon.lerpLookAt(self, self.getPart('head'), tuple((h, p, r)))
        if blink:
            self.stopBlink()
            maxBlinks = random.randint(1, 2)
            numBlinks = 0
            delay = 0
            for blink in range(maxBlinks):
                if numBlinks == 0:
                    taskMgr.add(self.doBlink, self.uniqueName('blinkOnTurn'))
                else:
                    delay += 0.22
                    taskMgr.doMethodLater(delay, self.doBlink,
                                          self.doBlinkTaskName)
                numBlinks += 1

            taskMgr.doMethodLater(delay, self.__startBlinkAfterLook,
                                  self.uniqueName('sBAL'))

    def __startBlinkAfterLook(self, task):
        self.startBlink()
        return task.done

    def toonUp(self):
        pass

    def b_lookAtObject(self, h, p, r, blink=1):
        self.d_lookAtObject(h, p, r, blink)
        self.lookAtObject(h, p, r, blink)

    def d_lookAtObject(self, h, p, r, blink=1):
        self.sendUpdate('lookAtObject', [h, p, r, blink])

    def setChat(self, chat):
        chat = ChatGlobals.filterChat(chat, self.animal)
        Toon.Toon.setChat(self, chat)

    def setTarget(self, gagId, targetId):
        gag = self.backpack.getGagByID(gagId)
        target = self.cr.doId2do.get(targetId, None)
        gag.setTarget(target)
        return

    def trapActivate(self, gagId, avId, entityId, suitId):
        sender = self.cr.doId2do.get(avId, None)
        suit = self.cr.doId2do.get(suitId, None)
        if sender:
            backpack = sender.getBackpack()
            trapGag = backpack.getGagByID(gagId)
            if backpack and trapGag:
                entity = None
                if hasattr(trapGag, 'getEntities') and 0 <= entityId <= len(
                        trapGag.getEntities()) - 1:
                    entity = trapGag.getEntities()[entityId]
                    trapGag.onActivate(entity, suit)
        return

    def b_trapActivate(self, gagId, avId, entityId, suitId):
        self.trapActivate(gagId, avId, entityId, suitId)
        self.d_trapActivate(gagId, avId, entityId, suitId)

    def d_trapActivate(self, gagId, avId, entityId, suitId):
        self.sendUpdate('trapActivate', [gagId, avId, entityId, suitId])

    def gagCollision(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        gag.doCollision()

    def b_gagCollision(self, gagId):
        self.sendUpdate('gagCollision', [gagId])
        self.gagCollision(gagId)

    def gagActivate(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if hasattr(gag, 'activate'):
            gag.activate()

    def b_gagActivate(self, gagId):
        self.sendUpdate('gagActivate', [gagId])
        self.gagActivate(gagId)

    def setDropLoc(self, gagId, x, y, z):
        gag = self.backpack.getGagByID(gagId)
        gag.setEndPos(x, y, z)

    def setGagPos(self, gagId, x, y, z):
        pos = Point3(x, y, z)
        gag = self.backpack.getGagByID(gagId)
        ent = gag.getGag()
        if ent:
            ent.setPos(pos)

    def setThrowPower(self, gagId, power):
        gag = self.backpack.getGagByID(gagId)
        if gag:
            gag.setPower(power)

    def gagStart(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if gag:
            gag.start()

    def b_gagStart(self, gagId):
        self.sendUpdate('gagStart', [gagId])
        self.gagStart(gagId)

    def gagThrow(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if gag:
            gag.throw()

    def b_gagThrow(self, gagId):
        self.sendUpdate('gagThrow', [gagId])
        self.gagThrow(gagId)

    def gagRelease(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if gag and hasattr(gag, 'name'):
            gag.release()

    def b_gagRelease(self, gagId):
        self.sendUpdate('gagRelease', [gagId])
        self.gagRelease(gagId)

    def setSplatPos(self, gagId, x, y, z):
        splatGag = self.backpack.getGagByID(gagId)
        if splatGag:
            splatGag.setSplatPos(x, y, z)

    def d_setSplatPos(self, gagId, x, y, z):
        self.sendUpdate('setSplatPos', [gagId, x, y, z])

    def gagBuild(self, gagId):
        gag = self.backpack.getGagByID(gagId)
        if gag:
            gag.build()

    def b_gagBuild(self, gagId):
        self.gagBuild(gagId)
        self.sendUpdate('gagBuild', [gagId])

    def handleSuitAttack(self, attack_id, suit_id):
        attack = SuitAttacks.SuitAttackLengths.keys()[attack_id]
        if attack == 'canned':
            sfx = base.audio3d.loadSfx(
                'phase_5/audio/sfx/SA_canned_impact_only.ogg')
            base.audio3d.attachSoundToObject(sfx, self)
            SoundInterval(sfx, node=self).start()
        else:
            if attack == 'playhardball':
                sfx = base.audio3d.loadSfx(
                    'phase_5/audio/sfx/SA_hardball_impact_only_alt.ogg')
                base.audio3d.attachSoundToObject(sfx, self)
                SoundInterval(sfx, node=self).start()
            else:
                if attack == 'clipontie':
                    sfx = base.audio3d.loadSfx(
                        'phase_5/audio/sfx/SA_powertie_impact.ogg')
                    base.audio3d.attachSoundToObject(sfx, self)
                    SoundInterval(sfx, node=self).start()
        if not self.isDead():
            if attack in ('fountainpen', ):
                self.getPart('head').setColorScale(0, 0, 0, 1)
                Sequence(Wait(3.0), Func(self.resetHeadColor)).start()
        if self.dmgFadeIval:
            self.dmgFadeIval.finish()
            self.dmgFadeIval = None
        geomNode = self.getGeomNode()
        self.dmgFadeIval = Sequence(
            Func(geomNode.setTransparency, 1),
            LerpColorScaleInterval(geomNode,
                                   0.3, (1, 1, 1, 0.5), (1, 1, 1, 1),
                                   blendType='easeOut'),
            LerpColorScaleInterval(geomNode,
                                   0.3, (1, 1, 1, 1), (1, 1, 1, 0.5),
                                   blendType='easeIn'),
            Func(geomNode.setTransparency, 0))
        self.dmgFadeIval.start()
        return

    def resetHeadColor(self):
        head = self.getPart('head')
        if head:
            head.setColorScale(1, 1, 1, 1)

    def b_handleSuitAttack(self, attack_id, suit_id):
        self.handleSuitAttack(attack_id, suit_id)
        self.b_lookAtObject(0, 0, 0, blink=1)
        self.sendUpdate('handleSuitAttack', [attack_id, suit_id])

    def equip(self, gagId):
        if self.backpack:
            self.backpack.setCurrentGag(gagId)

    def unEquip(self):
        if self.backpack:
            self.backpack.setCurrentGag(None)
        return

    def b_unEquip(self):
        self.unEquip()
        self.sendUpdate('unEquip', [])

    def b_equip(self, gag_id):
        self.equip(gag_id)
        self.sendUpdate('equip', [gag_id])

    def getBackpack(self):
        return self.backpack

    def setLoadout(self, gagIds):
        if self.backpack:
            loadout = []
            for i in range(len(gagIds)):
                gagId = gagIds[i]
                gag = self.backpack.getGagByID(gagId)
                if gag:
                    loadout.append(gag)

            self.backpack.setLoadout(loadout)

    def setBackpackAmmo(self, gagIds, ammoList):
        if not self.backpack:
            self.backpack = Backpack(self)
        for i in xrange(len(gagIds)):
            gagId = gagIds[i]
            ammo = ammoList[i]
            if not self.backpack.hasGag(gagId):
                self.backpack.addGag(
                    gagId, ammo,
                    GagGlobals.getGagData(gagId).get('maxSupply'))
            else:
                self.backpack.setSupply(gagId, ammo)

    def getBackpackAmmo(self):
        return ([], [])

    def setGagAmmo(self, gagId, ammo):
        self.backpack.setSupply(gagId, ammo)

    def setMoney(self, money):
        self.money = money

    def getMoney(self):
        return self.money

    def setAdminToken(self, value):
        self.token = value
        if value > -1:
            Toon.Toon.setAdminToken(self, value)
        else:
            Toon.Toon.removeAdminToken(self)

    def getAdminToken(self):
        return self.token

    def setAnimState(self, anim, timestamp=None, callback=None, extraArgs=[]):
        self.anim = anim
        if timestamp == None:
            ts = 0.0
        else:
            ts = globalClockDelta.localElapsedTime(timestamp)
        if type(anim) == types.IntType:
            anim = self.animId2animState[anim]
        if self.animFSM.getStateNamed(anim):
            self.animFSM.request(anim, [ts, callback, extraArgs])
        return

    def b_setAnimState(self, anim):
        self.d_setAnimState(anim)
        self.setAnimState(anim, None)
        return

    def d_setAnimState(self, anim):
        if type(anim) == types.StringType:
            anim = self.animState2animId[anim]
        timestamp = globalClockDelta.getFrameNetworkTime()
        self.sendUpdate('setAnimState', [anim, timestamp])

    def getAnimState(self):
        return self.anim

    def setName(self, name):
        Toon.Toon.setName(self, name)
        if self.cr.isShowingPlayerIds:
            self.showAvId()

    def d_setName(self, name):
        self.sendUpdate('setName', [name])

    def b_setName(self, name):
        self.d_setName(name)
        self.setName(name)

    def showAvId(self):
        self.setDisplayName(self.getName() + '\n' + str(self.doId))

    def showName(self):
        self.setDisplayName(self.getName())

    def setDisplayName(self, name):
        self.setupNameTag(tempName=name)

    def wrtReparentTo(self, parent):
        DistributedSmoothNode.wrtReparentTo(self, parent)

    def announceHealthAndPlaySound(self, level, hp):
        DistributedAvatar.announceHealth(self, level, hp)
        hpSfx = base.audio3d.loadSfx('phase_11/audio/sfx/LB_toonup.ogg')
        base.audio3d.attachSoundToObject(hpSfx, self)
        SoundInterval(hpSfx, node=self).start()
        del hpSfx

    def announceGenerate(self):
        DistributedAvatar.announceGenerate(self)
        if self.animFSM.getCurrentState().getName() == 'off':
            self.setAnimState('neutral')
        self.startBlink()

    def generate(self):
        DistributedAvatar.generate(self)
        DistributedSmoothNode.generate(self)
        self.startSmooth()

    def disable(self):
        if self.tunnelTrack:
            self.ignore(self.tunnelTrack.getDoneEvent())
            self.tunnelTrack.finish()
            self.tunnelTrack = None
        if self.dmgFadeIval:
            self.dmgFadeIval.finish()
            self.dmgFadeIval = None
        self.busy = None
        taskMgr.remove(self.uniqueName('sBAL'))
        taskMgr.remove(self.uniqueName('blinkOnTurn'))
        if self.track != None:
            self.track.finish()
            DelayDelete.cleanupDelayDeletes(self.track)
            self.track = None
        self.stopBlink()
        self.__removeHeadMeter()
        self.ignore('showAvId')
        self.ignore('showName')
        self.token = None
        self.stopSmooth()
        Toon.Toon.disable(self)
        DistributedAvatar.disable(self)
        return

    def delete(self):
        try:
            self.DistributedToon_deleted
        except:
            self.DistributedToon_deleted = 1
            self.tutDone = None
            self.defaultShard = None
            Toon.Toon.delete(self)
            DistributedAvatar.delete(self)
            DistributedSmoothNode.delete(self)

        return
class ToonPanel(DirectFrame):
    notify = directNotify.newCategory("ToonPanel")

    animal2HeadData = {
        'dog': (0.125, 0.04),
        'duck': (0.1, 0.025),
        'cat': (0.115, 0.04),
        'rabbit': (0.115, 0.04),
        'horse': (0.115, 0.06),
        'monkey': (0.115, 0.06),
        'pig': (0.115, 0.07),
        'mouse': (0.09, 0.02),
        'bear': (0.125, 0.05)
    }

    State2Text = {
        'status': ('Seeing if %s is available...',
                   '%s is busy right now; try again later.'),
        'teleport': ('Trying to go to %s...', 'Could not go to %s.'),
        'friend': ('Asking %s to be your friend...', '%s said no, thank you.',
                   'You are now friends with %s!'),
        'remove':
        ('Are you sure you want to remove %s from your friends list?',
         '%s left your friends list.')
    }

    def __init__(self):
        DirectFrame.__init__(self, scale=1.2)
        self['image'] = DGG.getDefaultDialogGeom()
        self['image_hpr'] = (0, 0, -90)
        self['image_scale'] = (0.67, 0.9, 0.325)
        self['image_color'] = (1, 1, 0.75, 1)
        self['image_pos'] = (0, 0, -0.09)
        self['relief'] = None
        self.reparentTo(base.a2dTopRight)
        self.setPos(-0.235, 0.0, -0.325)
        self.hide()
        self.head = None
        self.laffMeter = None
        self.exitButton = None
        self.friendButton = None
        self.teleportButton = None
        self.whisperButton = None
        self.nameText = None
        self.actionFrame = None
        self.actionFrameText = None
        self.actionFrameButton = None
        self.actionFrameButton2 = None
        self.avatarInfo = None
        self.action = None
        self.locationText = None
        self.shardText = None
        self.detailsExitBtn = None

        self.fsm = ClassicFSM.ClassicFSM('ToonPanel', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('waitOnAvatarInfoResponse',
                        self.enterWaitOnAvatarInfoResponse,
                        self.exitWaitOnAvatarInfoResponse, ['panel']),
            State.State('panel', self.enterPanel, self.exitPanel, ['off'])
        ], 'off', 'off')
        self.fsm.enterInitialState()

        self.actionFSM = ClassicFSM.ClassicFSM('ToonPanelActionFSM', [
            State.State('off', self.enterOff, self.exitOff),
            State.State(
                'waitOnAvatarStatusResponse',
                self.enterWaitOnAvatarStatusResponse,
                self.exitWaitOnAvatarStatusResponse, [
                    'waitOnAvatarTeleportResponse',
                    'waitOnAvatarFriendListResponse', 'avatarBusy', 'off'
                ]),
            State.State('avatarBusy', self.enterAvatarBusy,
                        self.exitAvatarBusy, ['off']),
            State.State('waitOnAvatarTeleportResponse',
                        self.enterWaitOnAvatarTeleportResponse,
                        self.exitWaitOnAvatarTeleportResponse, ['unableToTP']),
            State.State('unableToTP', self.enterUnableToTP,
                        self.exitUnableToTP, ['off']),
            State.State('waitOnAvatarFriendListResponse',
                        self.enterWaitOnAvatarFriendListResponse,
                        self.exitWaitOnAvatarFriendListResponse,
                        ['fRequestA', 'fRequestR']),
            State.State('fRequestA', self.enterFriendRequestAccepted,
                        self.exitFriendRequestAccepted, ['off']),
            State.State('fRequestR', self.enterFriendRequestRejected,
                        self.exitFriendRequestRejected, ['off']),
            State.State('removeFriendConfirm', self.enterRemoveFriendConfirm,
                        self.exitRemoveFriendConfirm,
                        ['off', 'removedFriend']),
            State.State('removedFriend', self.enterRemovedFriend,
                        self.exitRemovedFriend, ['off'])
        ], 'off', 'off')
        self.actionFSM.enterInitialState()

    def makeMoreDetailsPanel(self):
        self.actionFSM.request('off')
        self.removeMoreDetailsPanel()
        self.removeActionPanel()
        self.makeActionPanel()
        zoneId = self.avatarInfo[5]
        shardId = self.avatarInfo[6]
        isOnline = self.avatarInfo[7]
        shardName = 'Unknown District'
        hoodName = ZoneUtil.getHoodId(zoneId, 1)
        for district in base.cr.activeDistricts.values():
            if district.doId == shardId:
                shardName = district.getDistrictName()
                break
        if not isOnline:
            hoodName = 'Offline'
            shardName = 'Offline'
        self.locationText = OnscreenText('Location: {0}'.format(hoodName),
                                         parent=self.actionFrame,
                                         pos=(-0.3, 0.05, 0),
                                         align=TextNode.ALeft,
                                         scale=0.04)
        self.shardText = OnscreenText('District: {0}'.format(shardName),
                                      parent=self.actionFrame,
                                      pos=(-0.3, 0.0, 0),
                                      align=TextNode.ALeft,
                                      scale=0.04)
        self.detailsExitBtn = DirectButton(geom=CIGlobals.getCancelBtnGeom(),
                                           parent=self.actionFrame,
                                           relief=None,
                                           scale=0.8,
                                           pos=(-0.3, 0.0, -0.175),
                                           command=self.removeMoreDetailsPanel)

    def removeMoreDetailsPanel(self):
        if self.locationText:
            self.locationText.destroy()
            self.locationText = None
        if self.shardText:
            self.shardText.destroy()
            self.shardText = None
        if self.detailsExitBtn:
            self.detailsExitBtn.destroy()
            self.detailsExitBtn = None
        self.removeActionPanel()

    def maybeUpdateFriendButton(self):
        if self.friendButton:
            if self.avatarInfo:
                if not self.avatarInfo[0] in base.localAvatar.friends:
                    self.friendButton['text'] = 'Add Friend'
                    self.friendButton['extraArgs'] = [
                        'waitOnAvatarFriendListResponse'
                    ]
                else:
                    self.friendButton['text'] = 'Remove Friend'
                    self.friendButton['extraArgs'] = ['removeFriendConfirm']

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterUnableToTP(self):
        pass

    def exitUnableToTP(self):
        pass

    def enterWaitOnAvatarTeleportResponse(self):
        self.setActionText(self.State2Text['teleport'][0] %
                           self.getAvatarName())
        self.makeButtons('Cancel')
        self.acceptOnce('gotAvatarTeleportResponse',
                        self.handleTeleportResponse)
        base.cr.friendsManager.d_iWantToTeleportToAvatar(self.avatarInfo[0])

    def handleTeleportResponse(self, avatarId, shardId, zoneId):
        if self.avatarInfo[0] == avatarId:
            requestStatus = {}
            whereName = ZoneUtil.getWhereName(zoneId)
            loaderName = ZoneUtil.getLoaderName(zoneId)
            requestStatus['zoneId'] = zoneId
            if base.localAvatar.parentId == shardId:
                requestStatus['shardId'] = None
            else:
                requestStatus['shardId'] = shardId
            requestStatus['hoodId'] = ZoneUtil.getHoodId(zoneId, 1)
            requestStatus['where'] = whereName
            requestStatus['loader'] = loaderName
            requestStatus['how'] = 'teleportIn'
            requestStatus['avId'] = avatarId
            base.cr.playGame.getPlace().fsm.request('teleportOut',
                                                    [requestStatus])
            self.cleanup()

    def exitWaitOnAvatarTeleportResponse(self):
        self.ignore('gotAvatarTeleportResponse')
        self.clearActionText()
        self.clearActionButtons()

    def setActionText(self, text):
        self.actionFrameText.setText(text)

    def clearActionText(self):
        self.actionFrameText.setText("")

    def makeButtons(self, button1, button2=None):
        button2GeomFunc = {
            'Cancel': CIGlobals.getCancelBtnGeom,
            'No': CIGlobals.getCancelBtnGeom,
            'Okay': CIGlobals.getOkayBtnGeom,
            'Yes': CIGlobals.getOkayBtnGeom
        }
        if button1 and not button2:
            button1Pos = (0, 0, -0.1)
        elif button1 and button2:
            button1Pos = (-0.1, 0, -0.1)
        button2Pos = (0.1, 0, -0.1)
        if button1:
            self.actionFrameButton = DirectButton(
                text=button1,
                geom=button2GeomFunc[button1](),
                parent=self.actionFrame,
                pos=button1Pos,
                text_scale=0.045,
                text_pos=(0, -0.08),
                command=self.actionButtonPressed,
                extraArgs=[1],
                relief=None,
                geom_scale=0.75)
        if button2:
            self.actionFrameButton2 = DirectButton(
                text=button2,
                geom=button2GeomFunc[button2](),
                parent=self.actionFrame,
                pos=button2Pos,
                text_scale=0.045,
                text_pos=(0, -0.08),
                command=self.actionButtonPressed,
                extraArgs=[2],
                relief=None,
                geom_scale=0.75)

    def actionButtonPressed(self, buttonNum):
        currentState = self.actionFSM.getCurrentState().getName()
        if buttonNum == 1:
            if currentState in [
                    'waitOnAvatarStatusResponse',
                    'waitOnAvatarTeleportResponse',
                    'waitOnAvatarFriendListResponse', 'avatarBusy',
                    'unableToTP', 'fRequestA', 'fRequestR',
                    'removeFriendConfirm', 'removedFriend'
            ]:
                if currentState == 'waitOnAvatarFriendListResponse':
                    base.cr.friendsManager.d_iCancelledFriendRequest(
                        self.avatarInfo[0])
                elif currentState == 'removeFriendConfirm':
                    self.actionFSM.request('removedFriend')
                    return
                self.actionFSM.request('off')
                self.removeActionPanel()
                self.action = None
        elif buttonNum == 2:
            self.actionFSM.request('off')
            self.removeActionPanel()
            self.action = None

    def clearActionButtons(self):
        if self.actionFrameButton2:
            self.actionFrameButton2.destroy()
            self.actionFrameButton2 = None
        if self.actionFrameButton:
            self.actionFrameButton.destroy()
            self.actionFrameButton = None

    def enterAvatarBusy(self):
        self.setActionText(self.State2Text['status'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitAvatarBusy(self):
        self.clearActionText()
        self.clearActionButtons()

    def getAvatarName(self):
        if self.avatarInfo:
            return self.avatarInfo[1]

    def enterWaitOnAvatarStatusResponse(self):
        self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse)
        base.cr.friendsManager.d_requestAvatarStatus(self.avatarInfo[0])
        self.setActionText(self.State2Text['status'][0] % self.getAvatarName())
        self.makeButtons('Cancel')

    def handleAvatarStatusResponse(self, avatarId, status):
        if avatarId == self.avatarInfo[0]:

            # Busy
            if status == 1:
                self.actionFSM.request('avatarBusy')

            # Not busy
            else:
                self.actionFSM.request(self.action)
        else:
            self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse)

    def exitWaitOnAvatarStatusResponse(self):
        self.ignore('gotAvatarStatus')
        self.clearActionText()
        self.clearActionButtons()

    def enterWaitOnAvatarFriendListResponse(self):
        self.acceptOnce('friendRequestAccepted',
                        self.handleFriendRequestAccepted)
        self.acceptOnce('friendRequestRejected',
                        self.handleFriendRequestRejected)
        base.cr.friendsManager.d_askAvatarToBeFriends(self.avatarInfo[0])
        self.setActionText(self.State2Text['friend'][0] % self.getAvatarName())
        self.makeButtons('Cancel')

    def handleFriendRequestAccepted(self):
        self.actionFSM.request('fRequestA')

    def handleFriendRequestRejected(self):
        self.actionFSM.request('fRequestR')

    def exitWaitOnAvatarFriendListResponse(self):
        self.ignore('friendRequestAccepted')
        self.ignore('friendRequestRejected')
        self.clearActionText()
        self.clearActionButtons()

    def enterFriendRequestAccepted(self):
        self.setActionText(self.State2Text['friend'][2] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitFriendRequestAccepted(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterFriendRequestRejected(self):
        self.setActionText(self.State2Text['friend'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitFriendRequestRejected(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterRemoveFriendConfirm(self):
        self.setActionText(self.State2Text['remove'][0] % self.getAvatarName())
        self.makeButtons('Yes', 'No')

    def exitRemoveFriendConfirm(self):
        self.clearActionText()
        self.clearActionButtons()

    def enterRemovedFriend(self):
        base.cr.friendsManager.d_iRemovedFriend(self.avatarInfo[0])
        self.setActionText(self.State2Text['remove'][1] % self.getAvatarName())
        self.makeButtons('Okay')

    def exitRemovedFriend(self):
        self.clearActionText()
        self.clearActionButtons()

    def makeActionPanel(self):
        self.actionFrame = DirectFrame(image=DGG.getDefaultDialogGeom(),
                                       image_scale=(0.7, 0.5, 0.45),
                                       image_color=(1, 1, 0.75, 1),
                                       relief=None)
        self.actionFrame.reparentTo(base.a2dTopRight)
        self.actionFrame.setPos(-0.815, 0, -0.31)
        self.actionFrameText = OnscreenText(text="",
                                            parent=self.actionFrame,
                                            scale=0.05,
                                            wordwrap=12,
                                            pos=(0, 0.1))

    def removeActionPanel(self):
        self.clearActionButtons()
        if self.actionFrameText:
            self.actionFrameText.destroy()
            self.actionFrameText = None
        if self.actionFrame:
            self.actionFrame.destroy()
            self.actionFrame = None

    def doAction(self, action):
        self.action = action
        self.actionFSM.requestFinalState()
        self.removeMoreDetailsPanel()
        self.removeActionPanel()
        self.makeActionPanel()
        if action != 'removeFriendConfirm':
            self.actionFSM.request('waitOnAvatarStatusResponse')
        else:
            self.actionFSM.request(action)

    def enterWaitOnAvatarInfoResponse(self):
        self.label = OnscreenText(text='Retrieving Toon\ndetails...',
                                  parent=self,
                                  scale=0.04)
        self.acceptOnce('avatarInfoResponse', self.handleAvatarInfoResponse)
        base.cr.friendsManager.d_requestAvatarInfo(self.avatarInfo[0])

    def handleAvatarInfoResponse(self, name, dna, maxHealth, health, zoneId,
                                 shardId, isOnline, adminToken):
        if self.avatarInfo:
            self.avatarInfo.append(name)
            self.avatarInfo.append(dna)
            self.avatarInfo.append(maxHealth)
            self.avatarInfo.append(health)
            self.avatarInfo.append(zoneId)
            self.avatarInfo.append(shardId)
            self.avatarInfo.append(isOnline)
            self.avatarInfo.append(adminToken)
            self.fsm.request('panel')

    def exitWaitOnAvatarInfoResponse(self):
        self.label.destroy()
        del self.label
        self.ignore('avatarInfoResponse')

    def makePanel(self, avId):
        if self.avatarInfo:
            if self.avatarInfo[0] == avId:
                # They clicked on the same toon without closing the
                # previous panel, maybe they're spamming?
                return

        self.cleanup()

        base.localAvatar.hideFriendButton()

        self.show()
        self.avatarInfo = []
        self.avatarInfo.append(avId)
        self.fsm.request('waitOnAvatarInfoResponse')

    def exitClicked(self):
        self.cleanup()
        base.localAvatar.showFriendButton()

    def cleanup(self):
        self.actionFSM.requestFinalState()
        self.fsm.requestFinalState()
        self.avatarInfo = None

    def enterPanel(self):
        adminToken = self.avatarInfo[8]
        text_color = CIGlobals.TextColorByAdminToken[adminToken]
        self.nameText = OnscreenText(text=self.avatarInfo[1],
                                     parent=self,
                                     pos=(0, 0.2),
                                     scale=0.035,
                                     wordwrap=8,
                                     fg=text_color)
        self.nameText.setBin('gui-popup', 60)

        dna = ToonDNA.ToonDNA()
        dna.setDNAStrand(self.avatarInfo[2])

        self.head = ToonHead.ToonHead(base.cr)
        self.head.generateHead(dna.gender, dna.animal, dna.head, 1)
        self.head.setHeadColor(dna.headcolor)
        self.head.reparentTo(self)
        self.head.setDepthWrite(1)
        self.head.setDepthTest(1)
        self.head.setH(180)
        self.head.setScale(self.animal2HeadData[dna.animal][0])
        self.head.setZ(self.animal2HeadData[dna.animal][1])

        self.laffMeter = LaffOMeter()
        r, g, b, _ = dna.headcolor
        self.laffMeter.generate(r, g, b, dna.animal, self.avatarInfo[3],
                                self.avatarInfo[4])
        self.laffMeter.reparentTo(self)
        self.laffMeter.setBin('gui-popup', 60)
        self.laffMeter.setScale(0.045)
        self.laffMeter.setPos(0, 0, -0.1)

        self.friendButton = DirectButton(
            geom=CIGlobals.getDefaultBtnGeom(),
            text="Add Friend",
            scale=0.58,
            relief=None,
            text_scale=0.058,
            geom_scale=(1.25, 0, 0.9),
            text_pos=(0, -0.0125),
            parent=self,
            pos=(0, 0, -0.12),
            command=self.doAction,
            extraArgs=['waitOnAvatarFriendListResponse'])
        self.friendButton.setPos(0, 0.0, -0.225)
        self.maybeUpdateFriendButton()

        self.teleportButton = DirectButton(
            geom=CIGlobals.getDefaultBtnGeom(),
            text="Teleport",
            scale=0.58,
            relief=None,
            text_scale=0.058,
            geom_scale=(1.25, 0, 0.9),
            text_pos=(0, -0.0125),
            parent=self,
            pos=(0, 0, -0.12),
            command=self.doAction,
            extraArgs=['waitOnAvatarTeleportResponse'])
        self.teleportButton.setPos(0, 0, -0.275)

        self.whisperButton = DirectButton(
            geom=CIGlobals.getDefaultBtnGeom(),
            text="Whisper",
            scale=0.58,
            relief=None,
            text_scale=0.058,
            geom_scale=(1.25, 0, 0.9),
            text_pos=(0, -0.0125),
            parent=self,
            pos=(0, 0, -0.12),
            command=base.localAvatar.handleClickedWhisper,
            extraArgs=[self.avatarInfo[1], self.avatarInfo[0], 1])
        self.whisperButton.setPos(0, 0, -0.325)

        self.exitButton = DirectButton(geom=CIGlobals.getCancelBtnGeom(),
                                       parent=self,
                                       relief=None,
                                       scale=0.6,
                                       pos=(0, 0.0, -0.39),
                                       command=self.exitClicked)
        gui = loader.loadModel("phase_3.5/models/gui/friendslist_gui.bam")
        self.moreDetailsBtn = DirectButton(
            geom=(gui.find('**/Horiz_Arrow_UP'), gui.find('**/Horiz_Arrow_DN'),
                  gui.find('**/Horiz_Arrow_Rllvr'),
                  gui.find('**/Horiz_Arrow_UP')),
            relief=None,
            parent=self,
            pos=(-0.127, 0.0, -0.39),
            geom_hpr=(180, 0, 0),
            command=self.makeMoreDetailsPanel,
            scale=0.77,
            text=('', 'More Details', 'More Details', ''),
            text_scale=0.045,
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 1),
            text_pos=(-0.08, -0.01),
            text_align=TextNode.ARight)

    def exitPanel(self):
        if self.actionFSM.getCurrentState().getName(
        ) == 'waitOnAvatarFriendListResponse':
            if self.avatarInfo:
                base.cr.friendsManager.d_iCancelledFriendRequest(
                    self.avatarInfo[0])
        self.actionFSM.requestFinalState()
        self.action = None
        self.avatarInfo = None
        self.removeActionPanel()
        self.removeMoreDetailsPanel()
        self.hide()
        if self.nameText:
            self.nameText.destroy()
            self.nameText = None
        if self.head:
            self.head.removeNode()
            self.head.delete()
            self.head = None
        if self.laffMeter:
            self.laffMeter.disable()
            self.laffMeter.delete()
            self.laffMeter = None
        if self.friendButton:
            self.friendButton.destroy()
            self.friendButton = None
        if self.teleportButton:
            self.teleportButton.destroy()
            self.teleportButton = None
        if self.whisperButton:
            self.whisperButton.destroy()
            self.whisperButton = None
        if self.exitButton:
            self.exitButton.destroy()
            self.exitButton = None
        if self.moreDetailsBtn:
            self.moreDetailsBtn.destroy()
            self.moreDetailsBtn = None
    def enterPanel(self):
        adminToken = self.avatarInfo[8]
        text_color = CIGlobals.TextColorByAdminToken[adminToken]
        self.nameText = OnscreenText(text=self.avatarInfo[1],
                                     parent=self,
                                     pos=(0, 0.2),
                                     scale=0.035,
                                     wordwrap=8,
                                     fg=text_color)
        self.nameText.setBin('gui-popup', 60)

        dna = ToonDNA.ToonDNA()
        dna.setDNAStrand(self.avatarInfo[2])

        self.head = ToonHead.ToonHead(base.cr)
        self.head.generateHead(dna.gender, dna.animal, dna.head, 1)
        self.head.setHeadColor(dna.headcolor)
        self.head.reparentTo(self)
        self.head.setDepthWrite(1)
        self.head.setDepthTest(1)
        self.head.setH(180)
        self.head.setScale(self.animal2HeadData[dna.animal][0])
        self.head.setZ(self.animal2HeadData[dna.animal][1])

        self.laffMeter = LaffOMeter()
        r, g, b, _ = dna.headcolor
        self.laffMeter.generate(r, g, b, dna.animal, self.avatarInfo[3],
                                self.avatarInfo[4])
        self.laffMeter.reparentTo(self)
        self.laffMeter.setBin('gui-popup', 60)
        self.laffMeter.setScale(0.045)
        self.laffMeter.setPos(0, 0, -0.1)

        self.friendButton = DirectButton(
            geom=CIGlobals.getDefaultBtnGeom(),
            text="Add Friend",
            scale=0.58,
            relief=None,
            text_scale=0.058,
            geom_scale=(1.25, 0, 0.9),
            text_pos=(0, -0.0125),
            parent=self,
            pos=(0, 0, -0.12),
            command=self.doAction,
            extraArgs=['waitOnAvatarFriendListResponse'])
        self.friendButton.setPos(0, 0.0, -0.225)
        self.maybeUpdateFriendButton()

        self.teleportButton = DirectButton(
            geom=CIGlobals.getDefaultBtnGeom(),
            text="Teleport",
            scale=0.58,
            relief=None,
            text_scale=0.058,
            geom_scale=(1.25, 0, 0.9),
            text_pos=(0, -0.0125),
            parent=self,
            pos=(0, 0, -0.12),
            command=self.doAction,
            extraArgs=['waitOnAvatarTeleportResponse'])
        self.teleportButton.setPos(0, 0, -0.275)

        self.whisperButton = DirectButton(
            geom=CIGlobals.getDefaultBtnGeom(),
            text="Whisper",
            scale=0.58,
            relief=None,
            text_scale=0.058,
            geom_scale=(1.25, 0, 0.9),
            text_pos=(0, -0.0125),
            parent=self,
            pos=(0, 0, -0.12),
            command=base.localAvatar.handleClickedWhisper,
            extraArgs=[self.avatarInfo[1], self.avatarInfo[0], 1])
        self.whisperButton.setPos(0, 0, -0.325)

        self.exitButton = DirectButton(geom=CIGlobals.getCancelBtnGeom(),
                                       parent=self,
                                       relief=None,
                                       scale=0.6,
                                       pos=(0, 0.0, -0.39),
                                       command=self.exitClicked)
        gui = loader.loadModel("phase_3.5/models/gui/friendslist_gui.bam")
        self.moreDetailsBtn = DirectButton(
            geom=(gui.find('**/Horiz_Arrow_UP'), gui.find('**/Horiz_Arrow_DN'),
                  gui.find('**/Horiz_Arrow_Rllvr'),
                  gui.find('**/Horiz_Arrow_UP')),
            relief=None,
            parent=self,
            pos=(-0.127, 0.0, -0.39),
            geom_hpr=(180, 0, 0),
            command=self.makeMoreDetailsPanel,
            scale=0.77,
            text=('', 'More Details', 'More Details', ''),
            text_scale=0.045,
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 1),
            text_pos=(-0.08, -0.01),
            text_align=TextNode.ARight)
Exemplo n.º 18
0
class LocalToon(DistributedToon):
    neverDisable = 1

    def __init__(self, cr):
        try:
            self.LocalToon_initialized
            return
        except:
            self.LocalToon_initialized = 1
        DistributedToon.__init__(self, cr)
        self.gagStartKey = config.GetString('gag-start-key')
        self.gagThrowKey = config.GetString('gag-throw-key')
        self.avatarChoice = cr.localAvChoice
        self.smartCamera = SmartCamera()
        self.chatInput = ChatInput()
        self.moneyGui = MoneyGui()
        self.laffMeter = LaffOMeter()
        self.positionExaminer = PositionExaminer()
        self.friendRequestManager = FriendRequestManager()
        self.friendsList = FriendsList()
        self.panel = ToonPanel()
        friendsgui = loader.loadModel(
            'phase_3.5/models/gui/friendslist_gui.bam')
        self.friendButton = DirectButton(
            geom=(friendsgui.find('**/FriendsBox_Closed'),
                  friendsgui.find('**/FriendsBox_Rollover'),
                  friendsgui.find('**/FriendsBox_Rollover')),
            text=("", "Friends", "Friends", ""),
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 1),
            text_scale=0.065,
            text_pos=(0, -0.2),
            relief=None,
            parent=base.a2dTopRight,
            pos=(-0.18, 0.0, -0.17),
            command=self.friendsButtonClicked,
            scale=0.75)
        friendsgui.removeNode()
        del friendsgui
        self.hideFriendButton()
        self.runSfx = base.loadSfx(
            "phase_3.5/audio/sfx/AV_footstep_runloop.ogg")
        self.runSfx.setLoop(True)
        self.walkSfx = base.loadSfx(
            "phase_3.5/audio/sfx/AV_footstep_walkloop.ogg")
        self.walkSfx.setLoop(True)
        self.controlManager = ControlManager.ControlManager(True, False)
        self.offset = 3.2375
        self.firstPersonCamPos = None
        self.movementKeymap = {
            "forward": 0,
            "backward": 0,
            "left": 0,
            "right": 0,
            "jump": 0
        }
        self.avatarMovementEnabled = False
        self.isMoving_forward = False
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_jump = False
        self.gagThrowBtn = None
        self.myBattle = None
        self.gagsTimedOut = False
        self.needsToSwitchToGag = None
        self.gagsEnabled = False

        self.pickerTrav = None
        self.pickerRay = None
        self.pickerRayNode = None
        self.pickerHandler = None
        self.rolledOverTag = None

        self.inTutorial = False
        self.hasDoneJump = False
        self.lastState = None
        self.lastAction = None

        self.jumpHardLandIval = None

        #base.cTrav.showCollisions(render)

    def _handleWentInTunnel(self, requestStatus):
        self.cr.playGame.getPlace().doneStatus = requestStatus
        messenger.send(self.cr.playGame.getPlace().doneEvent)

    def _handleCameOutTunnel(self):
        self.walkControls.setCollisionsActive(1)
        self.cr.playGame.getPlace().fsm.request(
            self.cr.playGame.getPlace().nextState)

    def handleClickedWhisper(self,
                             senderName,
                             fromId,
                             isPlayer,
                             openPanel=False):
        if self.cr.playGame.getPlace() == None or not hasattr(
                self.cr.playGame.getPlace(),
                'fsm') or self.cr.playGame.getPlace().fsm == None:
            return
        if openPanel and self.cr.playGame.getPlace().fsm.getCurrentState(
        ).getName() in ['walk', 'shtickerBook']:
            self.panel.makePanel(fromId)
        self.chatInput.disableKeyboardShortcuts()
        self.chatInput.fsm.request('input', ["", self.sendWhisper, [fromId]])

    def handleClickedSentWhisper(self, senderName, fromId, isPlayer):
        self.handleClickedWhisper(senderName, fromId, isPlayer, True)

    def sendWhisper(self, message, target):
        message = self.chatInput.chatInput.get()
        self.cr.friendsManager.d_sendWhisper(target, message)
        self.chatInput.fsm.request('idle')
        self.chatInput.enableKeyboardShortcuts()

    def hasDiscoveredHood(self, zoneId):
        return zoneId in self.hoodsDiscovered

    def hasTeleportAccess(self, zoneId):
        return zoneId in self.teleportAccess

    def tutorialCreated(self, zoneId):
        self.cr.tutorialCreated(zoneId)

    def friendsButtonClicked(self):
        self.hideFriendButton()
        self.friendsList.fsm.request('onlineFriendsList')

    def hideFriendButton(self):
        self.friendButton.hide()

    def showFriendButton(self):
        self.friendButton.show()

    def gotoNode(self, node, eyeHeight=3):
        possiblePoints = (Point3(3, 6, 0), Point3(-3, 6, 0), Point3(6, 6, 0),
                          Point3(-6, 6, 0), Point3(3, 9, 0), Point3(-3, 9, 0),
                          Point3(6, 9, 0), Point3(-6, 9, 0), Point3(9, 9, 0),
                          Point3(-9, 9, 0), Point3(6, 0, 0), Point3(-6, 0, 0),
                          Point3(6, 3, 0), Point3(-6, 3, 0), Point3(9, 9, 0),
                          Point3(-9, 9, 0), Point3(0, 12, 0), Point3(3, 12, 0),
                          Point3(-3, 12, 0), Point3(6, 12,
                                                    0), Point3(-6, 12, 0),
                          Point3(9, 12, 0), Point3(-9, 12,
                                                   0), Point3(0, -6, 0),
                          Point3(-3, -6, 0), Point3(0, -9,
                                                    0), Point3(-6, -9, 0))
        for point in possiblePoints:
            pos = self.positionExaminer.consider(node, point, eyeHeight)
            if pos:
                self.setPos(node, pos)
                self.lookAt(node)
                self.setHpr(self.getH() + random.choice((-10, 10)), 0, 0)
                return

        self.setPos(node, 0, 0, 0)

    def setFriendsList(self, friends):
        DistributedToon.setFriendsList(self, friends)
        self.cr.friendsManager.d_requestFriendsList()
        self.panel.maybeUpdateFriendButton()

    def d_requestAddFriend(self, avId):
        self.sendUpdate('requestAddFriend', [avId])

    def enablePicking(self):
        self.accept('toonClicked', self.toonClicked)

    def disablePicking(self):
        self.ignore('toonClicked')

    def toonClicked(self, avId):
        self.panel.makePanel(avId)

    def prepareToSwitchControlType(self):
        # Hack fix for getting stuck moving in one direction without pressing the movement keys.
        inputs = [
            "run", "forward", "reverse", "turnLeft", "turnRight", "slideLeft",
            "slideRight", "jump"
        ]
        for inputName in inputs:
            try:
                inputState.releaseInputs(inputName)
            except:
                pass

    def getBackpack(self):
        return DistributedToon.getBackpack(self)

    def setMyBattle(self, battle):
        self.myBattle = battle

    def getMyBattle(self):
        return self.myBattle

    def ghostOn(self):
        self.getGeomNode().setTransparency(1)
        self.getGeomNode().setColorScale(1, 1, 1, 0.25)

    def ghostOff(self):
        self.getGeomNode().setColorScale(1, 1, 1, 1)
        self.getGeomNode().setTransparency(0)

    def enterReadBook(self, ts=0, callback=None, extraArgs=[]):
        self.stopLookAround()
        self.b_lookAtObject(0, -45, 0)
        DistributedToon.enterReadBook(self, ts, callback, extraArgs)

    def exitReadBook(self):
        DistributedToon.exitReadBook(self)
        self.startLookAround()

    def getAirborneHeight(self):
        return self.offset + 0.025000000000000001

    def setupControls(self):
        self.walkControls = GravityWalker(legacyLifter=False)
        self.walkControls.setWallBitMask(CIGlobals.WallBitmask)
        self.walkControls.setFloorBitMask(CIGlobals.FloorBitmask)
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSpeed,
                                       CIGlobals.ToonJumpForce,
                                       CIGlobals.ToonReverseSpeed,
                                       CIGlobals.ToonRotateSpeed)
        self.walkControls.initializeCollisions(base.cTrav,
                                               self,
                                               floorOffset=0.025,
                                               reach=4.0)
        self.walkControls.cEventSphereNodePath.node().setFromCollideMask(
            CIGlobals.WallBitmask | CIGlobals.WeaponBitmask
            | GunGameGlobals.HILL_BITMASK)
        self.walkControls.setAirborneHeightFunc(self.getAirborneHeight)

    def setWalkSpeedNormal(self):
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSpeed,
                                       CIGlobals.ToonJumpForce,
                                       CIGlobals.ToonReverseSpeed,
                                       CIGlobals.ToonRotateSpeed)

    def setWalkSpeedSlow(self):
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSlowSpeed,
                                       CIGlobals.ToonJumpSlowForce,
                                       CIGlobals.ToonReverseSlowSpeed,
                                       CIGlobals.ToonRotateSlowSpeed)

    def setupCamera(self):
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4. / 3.))
        base.camLens.setNearFar(CIGlobals.DefaultCameraNear,
                                CIGlobals.DefaultCameraFar)
        self.smartCamera.initializeSmartCamera()
        self.smartCamera.initCameraPositions()
        self.smartCamera.setCameraPositionByIndex(0)

    def setDNAStrand(self, dnaStrand):
        DistributedToon.setDNAStrand(self, dnaStrand)
        self.initCollisions()
        self.setupCamera()

    def setMoney(self, money):
        DistributedToon.setMoney(self, money)
        self.moneyGui.update(money)

    def setupNameTag(self, tempName=None):
        DistributedToon.setupNameTag(self, tempName)
        self.nametag.setNametagColor(
            NametagGlobals.NametagColors[NametagGlobals.CCLocal])
        self.nametag.unmanage(base.marginManager)
        self.nametag.setActive(0)
        self.nametag.updateAll()

    def d_broadcastPositionNow(self):
        self.d_clearSmoothing()
        self.d_broadcastPosHpr()

    def b_setAnimState(self, anim, callback=None, extraArgs=[]):
        if self.anim != anim:
            self.d_setAnimState(anim)
            DistributedToon.setAnimState(self,
                                         anim,
                                         callback=callback,
                                         extraArgs=extraArgs)

    def attachCamera(self):
        #self.notify.info("Attaching camera...")
        camera.reparentTo(self)
        camera.setPos(self.smartCamera.getIdealCameraPos())

    def startSmartCamera(self):
        #self.notify.info("Starting camera...")
        self.smartCamera.startUpdateSmartCamera()

    def resetSmartCamera(self):
        #self.notify.info("Resetting camera...")
        self.stopSmartCamera()
        self.startSmartCamera()

    def stopSmartCamera(self):
        #self.notify.info("Stopping camera...")
        self.smartCamera.stopUpdateSmartCamera()

    def detachCamera(self):
        #self.notify.info("Detaching camera...")
        camera.reparentTo(render)
        camera.setPos(0, 0, 0)
        camera.setHpr(0, 0, 0)

    def handleSuitAttack(self, attack_id, suit_id):
        DistributedToon.handleSuitAttack(self, attack_id, suit_id)

        if not self.isDead() and base.config.GetBool('want-sa-reactions'):
            base.taskMgr.remove('LT.attackReactionDone')
            attack = SuitAttacks.SuitAttackLengths.keys()[attack_id]
            suit = self.cr.doId2do.get(suit_id)
            animToPlay = None
            timeToWait = 3.0
            if not attack in ["pickpocket", "fountainpen"]:
                suitH = suit.getH(render) % 360
                myH = self.getH(render) % 360
                if -90.0 <= (suitH - myH) <= 90.0:
                    animToPlay = "fallFWD"
                else:
                    animToPlay = "fallBCK"
            elif attack in ["pickpocket"]:
                animToPlay = "cringe"
            elif attack in ["fountainpen"]:
                animToPlay = "conked"
                timeToWait = 5.0
            self.cr.playGame.getPlace().fsm.request('stop')
            self.b_setAnimState(animToPlay)
            base.taskMgr.doMethodLater(timeToWait, self.__attackReactionDone,
                                       'LT.attackReactionDone')

    def __attackReactionDone(self, task):
        self.cr.playGame.hood.loader.place.fsm.request('walk')
        self.b_setAnimState('neutral')
        return Task.done

    def printPos(self):
        x, y, z = self.getPos(render)
        h, p, r = self.getHpr(render)
        print "Pos: (%s, %s, %s), Hpr: (%s, %s, %s)" % (x, y, z, h, p, r)

    def enableAvatarControls(self):
        self.walkControls.enableAvatarControls()
        self.accept("control", self.updateMovementKeymap, ["jump", 1])
        self.accept("control-up", self.updateMovementKeymap, ["jump", 0])
        self.accept('tab', self.smartCamera.nextCameraPos, [1])
        self.accept('shift-tab', self.smartCamera.nextCameraPos, [0])
        self.accept('page_up', self.smartCamera.pageUp)
        self.accept('page_down', self.smartCamera.pageDown)
        self.accept('p', self.printPos)
        self.accept('jumpStart', self.__jump)
        self.accept('jumpLand', self.__handleJumpLand)
        self.accept('jumpHardLand', self.__handleJumpHardLand)
        self.avatarMovementEnabled = True
        self.playMovementSfx(None)

    def __handleJumpLand(self):
        if self.jumpHardLandIval:
            self.jumpHardLandIval.finish()
            self.jumpHardLandIval = None
        if self.getHealth() > 0:
            self.b_setAnimState('Happy')

    def __handleJumpHardLand(self):
        if self.jumpHardLandIval:
            self.jumpHardLandIval.finish()
            self.jumpHardLandIval = None
        self.jumpHardLandIval = ActorInterval(self, 'zend')
        self.jumpHardLandIval.setDoneEvent('LT::zend-done')
        self.acceptOnce('LT::zend-done', self.__handleJumpLand)
        self.jumpHardLandIval.start()

    def disableAvatarControls(self):
        self.walkControls.disableAvatarControls()
        self.ignore('tab')
        self.ignore('shift-tab')
        self.ignore('page_up')
        self.ignore('page_down')
        self.ignore("arrow_up")
        self.ignore("arrow_up-up")
        self.ignore("arrow_down")
        self.ignore("arrow_down-up")
        self.ignore("arrow_left")
        self.ignore("arrow_left-up")
        self.ignore("arrow_right")
        self.ignore("arrow_right-up")
        self.ignore("control")
        self.ignore("control-up")
        self.ignore('jumpStart')
        self.ignore('jumpLand')
        self.ignore('jumpHardLand')
        taskMgr.remove("avatarMovementTask")
        self.isMoving_forward = False
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_jump = False
        self.avatarMovementEnabled = False
        self.playMovementSfx(None)
        for k, _ in self.movementKeymap.items():
            self.updateMovementKeymap(k, 0)

    def updateMovementKeymap(self, key, value):
        self.movementKeymap[key] = value

    def getMovementKeyValue(self, key):
        return self.movementKeymap[key]

    def playMovementSfx(self, movement):
        if movement == "run":
            self.walkSfx.stop()
            self.runSfx.play()
        elif movement == "walk":
            self.runSfx.stop()
            self.walkSfx.play()
        else:
            self.runSfx.stop()
            self.walkSfx.stop()

    def __forward(self):
        self.resetHeadHpr()
        self.stopLookAround()
        if self.getHealth() < 1:
            self.playMovementSfx("walk")
            self.setPlayRate(1.2, 'dwalk')
            self.setAnimState('deadWalk')
        else:
            self.playMovementSfx("run")
            self.setAnimState('run')
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_forward = True
        self.isMoving_jump = False

    def __turn(self):
        self.resetHeadHpr()
        self.stopLookAround()
        self.playMovementSfx("walk")
        if self.getHealth() < 1:
            self.setPlayRate(1.2, 'dwalk')
            self.setAnimState('deadWalk')
        else:
            self.setPlayRate(1.0, "walk")
            self.setAnimState("walk")
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_side = True
        self.isMoving_jump = False

    def __reverse(self):
        self.resetHeadHpr()
        self.stopLookAround()
        self.playMovementSfx("walk")
        if self.getHealth() < 1:
            self.setPlayRate(-1.0, 'dwalk')
            self.setAnimState('deadWalk')
        else:
            self.setAnimState("walkBack")
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = True
        self.isMoving_jump = False

    def __jump(self):
        self.playMovementSfx(None)
        if base.localAvatar.getHealth() > 0:
            if self.playingAnim in ['run', 'walk']:
                self.b_setAnimState("leap")
            else:
                self.b_setAnimState("jump")
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_jump = True

    def __neutral(self):
        self.resetHeadHpr()
        self.startLookAround()
        self.playMovementSfx(None)
        if base.localAvatar.getHealth() > 0:
            self.setAnimState("neutral")
        else:
            self.setPlayRate(1.0, 'dneutral')
            self.setAnimState("deadNeutral")
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_jump = False

    def movementTask(self, task):
        if self.getMovementKeyValue("jump") == 1:
            if not self.walkControls.isAirborne:
                if self.walkControls.mayJump:
                    self.__jump()
                    self.hasDoneJump = True
                else:
                    if self.hasDoneJump:
                        if self.getHealth() > 0:
                            self.b_setAnimState('Happy')
                        self.hasDoneJump = False
        else:
            if not self.walkControls.isAirborne:
                if self.hasDoneJump:
                    if self.getHealth() > 0:
                        self.b_setAnimState('Happy')
                    self.hasDoneJump = False
        return task.cont

    def startTrackAnimToSpeed(self):
        if not base.taskMgr.hasTaskNamed(self.uniqueName('trackAnimToSpeed')):
            base.taskMgr.add(self.trackAnimToSpeed,
                             self.uniqueName('trackAnimToSpeed'))

    def stopTrackAnimToSpeed(self):
        base.taskMgr.remove(self.uniqueName('trackAnimToSpeed'))

    def trackAnimToSpeed(self, task):
        speed, rotSpeed, slideSpeed = self.walkControls.getSpeeds()
        state = None
        if self.getHealth() > 0:
            state = 'Happy'
        else:
            state = 'Sad'
        if state != self.lastState:
            self.lastState = state
            self.b_setAnimState(state)
            if base.minigame is None:
                if state == 'Sad':
                    self.setWalkSpeedSlow()
                else:
                    self.setWalkSpeedNormal()
        action = self.setSpeed(speed, rotSpeed)
        if action != self.lastAction:
            self.lastAction = action
            if action == CIGlobals.WALK_INDEX or action == CIGlobals.REVERSE_INDEX:
                self.resetHeadHpr()
                self.stopLookAround()
                self.playMovementSfx("walk")
            elif action == CIGlobals.RUN_INDEX:
                self.resetHeadHpr()
                self.stopLookAround()
                self.playMovementSfx("run")
            else:
                self.resetHeadHpr()
                self.startLookAround()
                self.playMovementSfx(None)
        return task.cont

    def createLaffMeter(self):
        r, g, b, _ = self.getHeadColor()
        animal = self.getAnimal()
        maxHp = self.getMaxHealth()
        hp = self.getHealth()
        self.laffMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp)
        self.laffMeter.start()

    def disableLaffMeter(self):
        self.laffMeter.stop()
        self.laffMeter.disable()

    def deleteLaffMeter(self):
        self.laffMeter.delete()

    def setLoadout(self, gagIds):
        DistributedToon.setLoadout(self, gagIds)
        if base.cr.playGame.getPlace() and base.cr.playGame.getPlace(
        ).fsm.getCurrentState().getName() == 'shtickerBook':
            if hasattr(base.cr.playGame.getPlace(), 'shtickerBookStateData'):
                if base.cr.playGame.getPlace(
                ).shtickerBookStateData.fsm.getCurrentState().getName(
                ) == 'inventoryPage':
                    base.cr.playGame.getPlace(
                    ).shtickerBookStateData.gui.fsm.request('idle')

    def enableGags(self, andKeys=0):
        if self.avatarMovementEnabled and andKeys:
            self.enableGagKeys()
        self.invGui.createGui()
        self.invGui.updateLoadout()
        self.backpack.loadoutGUI = self.invGui
        if self.backpack.getCurrentGag():
            self.invGui.setWeapon(self.backpack.getCurrentGag().getName(),
                                  playSound=False)

    def enableGagKeys(self):
        if self.gagThrowBtn:
            self.gagThrowBtn.bind(DGG.B1PRESS, self.startGag)
            self.gagThrowBtn.bind(DGG.B1RELEASE, self.throwGag)
        self.accept(self.gagStartKey, self.startGag)
        self.accept(self.gagThrowKey, self.throwGag)
        self.gagsEnabled = True

    def disableGagKeys(self):
        self.gagsEnabled = False
        if self.gagThrowBtn:
            self.gagThrowBtn.unbind(DGG.B1PRESS)
            self.gagThrowBtn.unbind(DGG.B1RELEASE)
        self.ignore(self.gagStartKey)
        self.ignore(self.gagThrowKey)

    def disableGags(self):
        self.disableGagKeys()
        if self.invGui:
            self.invGui.deleteGui()
        if hasattr(self, 'backpack'):
            if self.backpack:
                self.backpack.setCurrentGag()

    def setWeaponType(self, weaponType):
        enableKeysAgain = 0
        if weaponType != self.weaponType:
            enableKeysAgain = 1
        self.weaponType = weaponType
        if enableKeysAgain:
            self.disableGagKeys()
            self.enableGagKeys()

    def createMoney(self):
        self.moneyGui.createGui()
        # Automatically update incase we missed the db field.
        self.moneyGui.update(self.money)

    def handleMoneyChanged(self):
        self.moneyGui.update()

    def disableMoney(self):
        self.moneyGui.deleteGui()

    def resetHeadHpr(self):
        self.b_lookAtObject(0, 0, 0, blink=0)

    def canUseGag(self, preActive):
        if preActive:

            # We're checking if we can call `startGag` (before the gag gets activated)
            return (self.backpack is not None
                    and self.backpack.getCurrentGag() is not None
                    and self.backpack.getSupply() > 0 and self.gagsEnabled)

        else:

            # We're checking if we can call `throwGag` or `releaseGag` (after the gag gets activated)
            return (self.backpack is not None
                    and self.backpack.getCurrentGag() is not None
                    and self.backpack.getActiveGag() is not None
                    and self.backpack.getSupply() > 0 and self.gagsEnabled)

    def startGag(self, start=True):
        if not self.canUseGag(True) or self.backpack.getCurrentGag(
        ).__class__.__name__ == 'BananaPeel':
            return

        if self.gagThrowBtn:
            self.gagThrowBtn.unbind(DGG.B1PRESS)

        self.ignore(self.gagStartKey)
        self.resetHeadHpr()
        self.b_gagStart(self.backpack.getCurrentGag().getID())

    def throwGag(self, start=True):
        if not self.canUseGag(False):
            return

        if self.gagThrowBtn:
            self.gagThrowBtn.unbind(DGG.B1RELEASE)

        self.ignore(self.gagThrowKey)

        if self.backpack.getActiveGag().getType(
        ) == GagType.SQUIRT and self.backpack.getActiveGag().getName() in [
                CIGlobals.SeltzerBottle
        ]:
            self.b_gagRelease(self.backpack.getActiveGag().getID())
        else:
            self.b_gagThrow(self.backpack.getActiveGag().getID())

        activeGag = self.backpack.getActiveGag()
        if not activeGag:
            activeGag = self.backpack.getCurrentGag()

        if not activeGag.doesAutoRelease():
            Sequence(Wait(0.75), Func(self.releaseGag)).start()

    def releaseGag(self):
        if not self.canUseGag(False) or self.backpack.getCurrentGag(
        ).__class__.__name__ == 'BananaPeel':
            return
        gag = self.backpack.getActiveGag()
        if not gag:
            gag = self.backpack.getCurrentGag()
        if gag.getState() != GagState.RELEASED:
            gagName = gag.getName()
            self.b_gagRelease(GagGlobals.getIDByName(gagName))

    def checkSuitHealth(self, suit):
        pass

    def handleLookSpot(self, hpr):
        h, p, r = hpr
        self.d_lookAtObject(h, p, r, blink=1)

    def showGagButton(self):
        geom = CIGlobals.getDefaultBtnGeom()
        self.gagThrowBtn = DirectButton(geom=geom,
                                        geom_scale=(0.75, 1, 1),
                                        text="Throw Gag",
                                        text_scale=0.05,
                                        text_pos=(0, -0.01),
                                        relief=None,
                                        parent=base.a2dTopCenter,
                                        pos=(0, 0, -0.1))
        self.gagThrowBtn.setBin('gui-popup', 60)
        self.gagThrowBtn.hide()

    def hideGagButton(self):
        self.gagThrowBtn.removeNode()
        self.gagThrowBtn = None

    def showBookButton(self, inBook=0):
        self.book_gui = loader.loadModel(
            "phase_3.5/models/gui/sticker_open_close_gui.bam")
        self.book_btn = DirectButton(
            geom=(self.book_gui.find('**/BookIcon_CLSD'),
                  self.book_gui.find('**/BookIcon_OPEN'),
                  self.book_gui.find('**/BookIcon_RLVR')),
            relief=None,
            pos=(-0.175, 0, 0.163),
            command=self.bookButtonClicked,
            scale=(0.7, 0.8, 0.8),
            parent=base.a2dBottomRight)
        self.book_btn.setBin('gui-popup', 60)
        if inBook:
            self.book_btn["geom"] = (self.book_gui.find('**/BookIcon_OPEN'),
                                     self.book_gui.find('**/BookIcon_CLSD'),
                                     self.book_gui.find('**/BookIcon_RLVR2'))
            self.book_btn["command"] = self.bookButtonClicked
            self.book_btn["extraArgs"] = [0]

    def hideBookButton(self):
        if hasattr(self, 'book_gui'):
            self.book_gui.removeNode()
            del self.book_gui
        if hasattr(self, 'book_btn'):
            self.book_btn.destroy()
            del self.book_btn

    def bookButtonClicked(self, openIt=1):
        if openIt:
            base.cr.playGame.getPlace().fsm.request('shtickerBook')
        else:
            base.cr.playGame.getPlace().shtickerBookStateData.finished(
                "resume")

    def startMonitoringHP(self):
        taskMgr.add(self.monitorHealth, "localToon-monitorHealth")

    def monitorHealth(self, task):
        if self.isDead():
            base.taskMgr.remove("LT.attackReactionDone")
            if (self.cr.playGame.hood.id != ZoneUtil.getHoodId(self.zoneId)):
                self.cr.playGame.getPlace().fsm.request(
                    'died', [{}, self.diedStateDone])
                messenger.send(PCTMM.getLocalAvDiedEvent())
            return task.done
        return task.cont

    def stopMonitoringHP(self):
        taskMgr.remove("localToon-monitorHealth")

    def setHealth(self, hp):
        if hp > 0 and self.getHealth() < 1:
            if self.cr.playGame and self.cr.playGame.getPlace():
                if self.cr.playGame.getPlace().fsm.getCurrentState().getName(
                ) == 'walk':
                    if self.cr.playGame.getPlace(
                    ).walkStateData.fsm.getCurrentState().getName(
                    ) == 'deadWalking':
                        self.cr.playGame.getPlace().walkStateData.fsm.request(
                            'walking')
            if self.animFSM.getCurrentState().getName() == 'deadNeutral':
                self.playMovementSfx(None)
                self.b_setAnimState("neutral")
            elif self.animFSM.getCurrentState().getName() == 'deadWalk':
                self.playMovementSfx("run")
                self.b_setAnimState("run")
        DistributedToon.setHealth(self, hp)

    def diedStateDone(self, requestStatus):
        hood = self.cr.playGame.hood.id
        if hood == CIGlobals.BattleTTC:
            hood = CIGlobals.ToontownCentral
        toZone = ZoneUtil.getZoneId(hood)
        if self.zoneId != toZone:
            requestStatus = {
                'zoneId': toZone,
                'hoodId': hood,
                'where': ZoneUtil.getWhereName(toZone),
                'avId': self.doId,
                'loader': ZoneUtil.getLoaderName(toZone),
                'shardId': None,
                'wantLaffMeter': 1,
                'how': 'teleportIn'
            }
            self.cr.playGame.getPlace().doneStatus = requestStatus
            messenger.send(self.cr.playGame.getPlace().doneEvent)

        else:
            return

        ## Tell the ai we're dead so they can refill our hp.
        #self.sendUpdate("died", [])
        ## Then, log out and notify the client that they're dead.
        # self.cr.gameFSM.request("closeShard", ['died'])

    def teleportToCT(self):
        toZone = CIGlobals.CogTropolisId
        hood = CIGlobals.CogTropolis
        requestStatus = {
            'zoneId': toZone,
            'hoodId': hood,
            'where': ZoneUtil.getWhereName(toZone),
            'avId': self.doId,
            'loader': ZoneUtil.getLoaderName(toZone),
            'shardId': None,
            'wantLaffMeter': 1,
            'how': 'teleportIn',
            'world': CIGlobals.OToontown
        }
        self.cr.playGame.getPlace().fsm.request('teleportOut', [requestStatus])

    def createChatInput(self):
        self.chatInput.load()
        self.chatInput.enter()

    def disableChatInput(self):
        self.chatInput.exit()
        self.chatInput.unload()

    def collisionsOn(self):
        self.controlManager.collisionsOn()

    def collisionsOff(self):
        self.controlManager.collisionsOff()

    def toggleAspect2d(self):
        if base.aspect2d.isHidden():
            base.aspect2d.show()
        else:
            base.aspect2d.hide()

    def generate(self):
        DistributedToon.generate(self)

    def delete(self):
        DistributedToon.delete(self)
        self.deleteLaffMeter()
        return

    def disable(self):
        base.camLens.setMinFov(CIGlobals.OriginalCameraFov / (4. / 3.))
        if self.jumpHardLandIval:
            self.ignore('LT::zend-done')
            self.jumpHardLandIval.finish()
            self.jumpHardLandIval = None
        self.friendsList.destroy()
        self.friendsList = None
        self.panel.cleanup()
        self.panel = None
        self.positionExaminer.delete()
        self.positionExaminer = None
        self.disablePicking()
        self.stopMonitoringHP()
        taskMgr.remove("resetHeadColorAfterFountainPen")
        taskMgr.remove("LT.attackReactionDone")
        self.stopLookAround()
        DistributedToon.disable(self)
        self.disableAvatarControls()
        self.disableLaffMeter()
        self.disableGags()
        self.disableChatInput()
        self.weaponType = None
        self.myBattle = None
        self.ignore("gotLookSpot")
        self.ignore("clickedWhisper")
        self.ignore('f2')
        return

    def announceGenerate(self):
        DistributedToon.announceGenerate(self)
        self.setupControls()
        self.startLookAround()
        self.friendRequestManager.watch()
        self.accept("gotLookSpot", self.handleLookSpot)
        self.accept("clickedWhisper", self.handleClickedSentWhisper)
        self.accept('f2', self.toggleAspect2d)

        #self.accept('c', self.walkControls.setCollisionsActive, [0])

        self.invGui = InventoryGui()

        # Unused developer methods.
        #self.accept('enter', self.printAvPos)
        #self.accept('p', self.enterPictureMode)
        #self.accept('c', self.teleportToCT)
        #posBtn = DirectButton(text = "Get Pos", scale = 0.08, pos = (0.3, 0, 0), parent = base.a2dLeftCenter, command = self.printAvPos)

    def enterHiddenToonMode(self):
        self.laffMeter.stop()
        self.laffMeter.disable()
        self.laffMeter.destroy()
        self.getGeomNode().hide()
        self.deleteNameTag()
        self.moneyGui.deleteGui()
        self.invGui.deleteGui()
        self.hideGagButton()
        self.hideFriendButton()
        self.hideBookButton()
        self.removeAdminToken()

    def printAvPos(self):
        print "Pos: %s, Hpr: %s" % (self.getPos(), self.getHpr())