Esempio n. 1
0
class KartGlobals:
    ENTER_MOVIE = 1
    EXIT_MOVIE = 2
    COUNTDOWN_TIME = 30
    BOARDING_TIME = 10.0
    ENTER_RACE_TIME = 6.0
    ERROR_CODE = PythonUtil.Enum(
        'success, eGeneric, eTickets, eBoardOver, eNoKart, eOccupied, eTrackClosed, eTooLate, eUnpaid'
    )
    FRONT_LEFT_SPOT = 0
    FRONT_RIGHT_SPOT = 1
    REAR_LEFT_SPOT = 2
    REAR_RIGHT_SPOT = 3
    PAD_GROUP_NUM = 4

    def getPadLocation(padId):
        return padId % KartGlobals.PAD_GROUP_NUM

    getPadLocation = staticmethod(getPadLocation)
Esempio n. 2
0
 (40, 50, 60, 70, 300),
 (60, 80, 100, 120, 500),
 (100, 130, 160, 190, 800),
 (160, 210, 260, 310, 1300),
 (260, 340, 420, 500, 2100),
 (420, 550, 680, 810, 3400),
 (680, 890, 1100, 1310, 5500, 680, 5500, 680, 890, 1100, 1310, 5500, 680, 890, 1100, 1310, 1520, 1730, 1940, 2150, 2360, 5500, 680, 890, 1100, 1310, 1520, 1730, 1940, 2150, 2360, 5500, 680, 890, 1100, 1310, 1520, 1730, 1940, 2150, 2360, 5500, 0),
 (160, 210, 260, 310, 1300),
 (260, 340, 420, 500, 2100),
 (420, 550, 680, 810, 3400),
 (680, 890, 1100, 1310, 5500),
 (1100, 1440, 1780, 2120, 8900),
 (1780, 2330, 2880, 34300, 14400),
 (2880, 3770, 4660, 5500, 23300),
 (4660, 6100, 7540, 8930, 37700, 4660, 37700, 4660, 6100, 7540, 8930, 37700, 4660, 6100, 7540, 8930, 10420, 11860, 13300, 14740, 16180, 37700, 4660, 6100, 7540, 8930, 10420, 11860, 13300, 14740, 16180, 37700, 4660, 6100, 7540, 8930, 10420, 11860, 13300, 14740, 16180, 37700, 0))
suitTypes = PythonUtil.Enum(('NoSuit', 'NoMerits', 'FullSuit'))

def getNextPart(parts, partIndex, dept):
    dept = dept2deptIndex(dept)
    suitBitMask = PartsPerSuitBitmasks[dept]
    queryMask = PartsQueryMasks[partIndex]
    needMask = queryMask & suitBitMask
    parts = parts[dept]
    haveMask = parts & queryMask
    nextPart = ~needMask | haveMask
    nextPart = nextPart ^ nextPart + 1
    nextPart = nextPart + 1 >> 1
    return nextPart


def getPartName(partArray):
Esempio n. 3
0
class CogdoFlyingObstacle(DirectObject):
    EnterEventName = 'CogdoFlyingObstacle_Enter'
    ExitEventName = 'CogdoFlyingObstacle_Exit'
    MotionTypes = PythonUtil.Enum(('BackForth', 'Loop'))

    def __init__(self,
                 type,
                 index,
                 model,
                 collSolid,
                 motionPath=None,
                 motionPattern=None,
                 blendMotion=True,
                 instanceModel=True):
        self.type = type
        self.index = index
        name = 'CogdoFlyingObstacle-%s-%i' % (self.type, self.index)
        if instanceModel:
            self.model = NodePath(name)
            model.instanceTo(self.model)
        else:
            self.model = model
            self.model.setName(name)
        self.currentT = 0.0
        self.direction = 1.0
        self.collNode = None
        self._initCollisions(name, collSolid)
        self.motionPath = motionPath
        self.motionPattern = motionPattern
        self.motionSequence = None
        if blendMotion:
            blendType = 'easeInOut'
        else:
            blendType = 'noBlend'
        if motionPath is not None:

            def moveObstacle(value):
                self.motionPath.goTo(self.model, value)

            self.motionPath = Mopath.Mopath(name='obstacle-%i' % self.index)
            self.motionPath.loadNodePath(motionPath)
            dur = self.motionPath.getMaxT()
            self.motionSequence = Sequence(
                name='%s.obstacle-%i-motionSequence' %
                (self.__class__.__name__, self.index))
            movePart1 = LerpFunc(moveObstacle,
                                 fromData=0.0,
                                 toData=self.motionPath.getMaxT(),
                                 duration=dur,
                                 blendType=blendType)
            self.motionSequence.append(movePart1)
            if self.motionPattern == CogdoFlyingObstacle.MotionTypes.BackForth:
                movePart2 = LerpFunc(moveObstacle,
                                     fromData=self.motionPath.getMaxT(),
                                     toData=0.0,
                                     duration=dur,
                                     blendType=blendType)
                self.motionSequence.append(movePart2)

    def _initCollisions(self, name, collSolid):
        self.collName = name
        self.collSolid = collSolid
        self.collSolid.setTangible(0)
        self.collNode = CollisionNode(self.collName)
        self.collNode.setIntoCollideMask(ToontownGlobals.WallBitmask)
        self.collNode.addSolid(self.collSolid)
        self.collNodePath = self.model.attachNewNode(self.collNode)
        self.collNodePath.hide()
        self.accept('enter' + self.collName, self._handleEnterCollision)
        self.accept('exit' + self.collName, self._handleExitCollision)

    def disable(self):
        if self.collNode is not None:
            self.collNode.setIntoCollideMask(BitMask32(0))

    def enable(self):
        if self.collNode is not None:
            self.collNode.setIntoCollideMask(ToontownGlobals.WallBitmask)

    def startMoving(self, elapsedTime=0.0):
        if self.motionSequence is not None:
            self.motionSequence.loop()
            self.motionSequence.setT(elapsedTime %
                                     self.motionSequence.getDuration())

    def stopMoving(self):
        if self.motionSequence is not None:
            self.motionSequence.pause()

    def destroy(self):
        self.ignoreAll()
        if self.motionSequence is not None:
            self.motionSequence.clearToInitial()
            del self.motionSequence
        del self.collSolid
        self.collNodePath.removeNode()
        del self.collNodePath
        del self.collNode
        self.model.removeNode()
        del self.model
        del self.motionPath

    def update(self, dt):
        pass

    def hide(self):
        self.ignoreAll()
        self.model.hide()
        self.collNode.setIntoCollideMask(BitMask32(0))

    def _handleEnterCollision(self, collEntry):
        messenger.send(CogdoFlyingObstacle.EnterEventName, [self, collEntry])

    def _handleExitCollision(self, collEntry):
        messenger.send(CogdoFlyingObstacle.ExitEventName, [self, collEntry])
Esempio n. 4
0
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *
from toontown.toonbase import ToonPythonUtil as PythonUtil
from toontown.battle.BattleProps import globalPropPool
from direct.directnotify import DirectNotifyGlobal
SFX = PythonUtil.Enum('poof, magic')
SFXPATHS = {
    SFX.poof: 'phase_4/audio/sfx/firework_distance_02.ogg',
    SFX.magic: 'phase_4/audio/sfx/SZ_DD_treasure.ogg'
}


class DustCloud(NodePath):
    dustCloudCount = 0
    sounds = {}
    notify = DirectNotifyGlobal.directNotify.newCategory('DustCloud')

    def __init__(self, parent=hidden, fBillboard=1, wantSound=0):
        NodePath.__init__(self)
        self.assign(globalPropPool.getProp('suit_explosion_dust'))
        if fBillboard:
            self.setBillboardAxis()
        self.reparentTo(parent)
        self.seqNode = self.find('**/+SequenceNode').node()
        self.seqNode.setFrameRate(0)
        self.wantSound = wantSound
        if self.wantSound and not DustCloud.sounds:
            DustCloud.sounds[SFX.poof] = loader.loadSfx(SFXPATHS[SFX.poof])
        self.track = None
        self.trackId = DustCloud.dustCloudCount
        DustCloud.dustCloudCount += 1
    PartyEditorGridBounds[0][0] +
    (PartyEditorGridBounds[1][0] - PartyEditorGridBounds[0][0]) / 2.0,
    PartyEditorGridBounds[1][1] +
    (PartyEditorGridBounds[0][1] - PartyEditorGridBounds[1][1]) / 2.0)
PartyEditorGridSize = (18, 15)
PartyEditorGridSquareSize = (
    (PartyEditorGridBounds[1][0] - PartyEditorGridBounds[0][0]) /
    float(PartyEditorGridSize[0]),
    (PartyEditorGridBounds[0][1] - PartyEditorGridBounds[1][1]) /
    float(PartyEditorGridSize[1]))
PartyEditorGridRotateThreshold = 0.08
AvailableGridSquares = 202
TrashCanPosition = (-0.24, 0.0, -0.65)
TrashCanScale = 0.7
PartyEditorTrashBounds = ((-0.16, -0.38), (-0.05, -0.56))
ActivityRequestStatus = PythonUtil.Enum(('Joining', 'Exiting'))
InviteStatus = PythonUtil.Enum(
    ('NotRead', 'ReadButNotReplied', 'Accepted', 'Rejected'))
InviteTheme = PythonUtil.Enum(
    ('Birthday', 'GenericMale', 'GenericFemale', 'Racing', 'Valentoons',
     'VictoryParty', 'Winter'))
PartyStatus = PythonUtil.Enum(('Pending', 'Cancelled', 'Finished', 'CanStart',
                               'Started', 'NeverStarted'))
AddPartyErrorCode = PythonUtil.Enum(
    ('AllOk', 'ValidationError', 'DatabaseError', 'TooManyHostedParties'))
ChangePartyFieldErrorCode = PythonUtil.Enum(
    ('AllOk', 'ValidationError', 'DatabaseError', 'AlreadyStarted',
     'AlreadyRefunded'))
ActivityTypes = PythonUtil.Enum(
    ('HostInitiated', 'GuestInitiated', 'Continuous'))
PartyGateDenialReasons = PythonUtil.Enum(('Unavailable', 'Full'))
from toontown.toonbase import ToonPythonUtil as PythonUtil
from pandac.PandaModules import VBase4, Vec3, Point3
from toontown.cogdominium.CogdoUtil import VariableContainer, DevVariableContainer

AI = VariableContainer()

AI.GameActions = PythonUtil.Enum(
    ('LandOnWinPlatform', 'WinStateFinished', 'GotoWinState', 'HitWhirlwind',
     'HitLegalEagle', 'HitMinion', 'DebuffInvul', 'RequestEnterEagleInterest',
     'RequestExitEagleInterest', 'RanOutOfTimePenalty', 'Died', 'Spawn',
     'SetBlades', 'BladeLost'))

AI.BroadcastPeriod = 0.3
AI.SafezoneId2DeathDamage = {
    2000: 1,
    1000: 2,
    5000: 4,
    4000: 8,
    3000: 12,
    9000: 16
}
AI.SafezoneId2WhirlwindDamage = {
    2000: 1,
    1000: 2,
    5000: 4,
    4000: 8,
    3000: 12,
    9000: 16
}
AI.SafezoneId2LegalEagleDamage = {
    2000: 2,
class Pet(Avatar.Avatar):
    notify = DirectNotifyGlobal.directNotify.newCategory('Pet')
    SerialNum = 0
    Interactions = PythonUtil.Enum('SCRATCH, BEG, EAT, NEUTRAL')
    InteractAnims = {Interactions.SCRATCH: ('toPet', 'pet', 'fromPet'),
     Interactions.BEG: ('toBeg', 'beg', 'fromBeg'),
     Interactions.EAT: ('eat', 'swallow', 'neutral'),
     Interactions.NEUTRAL: 'neutral'}

    def __init__(self, forGui = 0):
        self.doodleChat = base.config.GetBool('want-doodle-chat', False)
        Avatar.Avatar.__init__(self)
        self.serialNum = Pet.SerialNum
        Pet.SerialNum += 1
        self.lockedDown = 0
        self.setPickable(1)
        self.setPlayerType(NametagGlobals.CCNonPlayer)
        self.animFSM = ClassicFSM('petAnimFSM', [State('off', self.enterOff, self.exitOff),
         State('neutral', self.enterNeutral, self.exitNeutral),
         State('neutralHappy', self.enterNeutralHappy, self.exitNeutralHappy),
         State('neutralSad', self.enterNeutralSad, self.exitNeutralSad),
         State('run', self.enterRun, self.exitRun),
         State('swim', self.enterSwim, self.exitSwim),
         State('teleportIn', self.enterTeleportIn, self.exitTeleportOut),
         State('teleportOut', self.enterTeleportOut, self.exitTeleportOut),
         State('walk', self.enterWalk, self.exitWalk),
         State('walkHappy', self.enterWalkHappy, self.exitWalkHappy),
         State('walkSad', self.enterWalkSad, self.exitWalkSad)], 'off', 'off')
        self.animFSM.enterInitialState()
        self.forGui = forGui
        self.moodModel = None
        self.__blinkName = 'petblink-' + str(self.this)
        self.track = None
        self.soundBackflip = None
        self.soundRollover = None
        self.soundPlaydead = None
        self.soundTeleportIn = None
        self.soundTeleportOut = None
        self.teleportHole = None
        return

    def isPet(self):
        return True

    def stopAnimations(self):
        if self.track:
            self.track.pause()
        self.stopBlink()
        self.animFSM.request('off')

    def delete(self):
        self.stopAnimations()
        self.track = None
        self.soundBackflip = None
        self.soundRollover = None
        self.soundPlaydead = None
        self.soundTeleportIn = None
        self.soundTeleportOut = None
        if self.teleportHole:
            self.teleportHole.cleanup()
            self.teleportHole = None
        self.eyesOpenTexture = None
        self.eyesClosedTexture = None
        self.animFSM = None
        self.eyes = None
        self.rightPupil = None
        self.rightHighlight = None
        self.rightBrow = None
        self.leftPupil = None
        self.leftHighlight = None
        self.leftBrow = None
        self.color = None
        Avatar.Avatar.delete(self)

    def getDNA(self):
        return self.style

    def setDNA(self, dna):
        if self.style:
            pass
        else:
            self.style = dna
            self.generatePet()
            self.initializeDropShadow()
            self.initializeNametag3d()
            self.generateMoods()
            self.dropShadow.setScale(0.75)

    def generatePet(self):
        self.loadModel('phase_4/models/char/TT_pets-mod')
        self.loadAnims({'toBeg': 'phase_5/models/char/TT_pets-intoBeg',
         'beg': 'phase_5/models/char/TT_pets-beg',
         'fromBeg': 'phase_5/models/char/TT_pets-begOut',
         'backflip': 'phase_5/models/char/TT_pets-backflip',
         'dance': 'phase_5/models/char/TT_pets-heal',
         'toDig': 'phase_5/models/char/TT_pets-intoDig',
         'dig': 'phase_5/models/char/TT_pets-dig',
         'fromDig': 'phase_5/models/char/TT_pets-digToNeutral',
         'disappear': 'phase_5/models/char/TT_pets-disappear',
         'eat': 'phase_5.5/models/char/TT_pets-eat',
         'jump': 'phase_5/models/char/TT_pets-jump',
         'neutral': 'phase_4/models/char/TT_pets-neutral',
         'neutralHappy': 'phase_4/models/char/TT_pets-neutralHappy',
         'neutralSad': 'phase_4/models/char/TT_pets-neutral_sad',
         'toPet': 'phase_5.5/models/char/TT_pets-petin',
         'pet': 'phase_5.5/models/char/TT_pets-petloop',
         'fromPet': 'phase_5.5/models/char/TT_pets-petend',
         'playDead': 'phase_5/models/char/TT_pets-playdead',
         'fromPlayDead': 'phase_5/models/char/TT_pets-deadend',
         'reappear': 'phase_5/models/char/TT_pets-reappear',
         'run': 'phase_5.5/models/char/TT_pets-run',
         'rollover': 'phase_5/models/char/TT_pets-rollover',
         'walkSad': 'phase_5.5/models/char/TT_pets-sadwalk',
         'speak': 'phase_5/models/char/TT_pets-speak',
         'swallow': 'phase_5.5/models/char/TT_pets-swallow',
         'swim': 'phase_5.5/models/char/TT_pets-swim',
         'toBall': 'phase_5.5/models/char/TT_pets-toBall',
         'walk': 'phase_5.5/models/char/TT_pets-walk',
         'walkHappy': 'phase_5.5/models/char/TT_pets-walkHappy'})
        self.setHeight(2)
        color = None
        colorIndex = self.style[5]
        color = AllPetColors[colorIndex]
        self.color = color
        bodyType = self.style[4]
        body = self.find('**/body')
        tex = loader.loadTexture(BodyTextures[BodyTypes[bodyType]])
        tex.setMinfilter(Texture.FTLinear)
        tex.setMagfilter(Texture.FTLinear)
        body.setTexture(tex, 1)
        body.setColor(color)
        leftFoot = self.find('**/leftFoot')
        rightFoot = self.find('**/rightFoot')
        texName = getFootTexture(bodyType)
        tex = loader.loadTexture(texName)
        tex.setMinfilter(Texture.FTLinear)
        tex.setMagfilter(Texture.FTLinear)
        leftFoot.setTexture(tex, 1)
        rightFoot.setTexture(tex, 1)
        leftFoot.setColor(color)
        rightFoot.setColor(color)
        for part in HeadParts + EarParts + NoseParts + TailParts:
            self.find('**/' + part).stash()

        colorScale = ColorScales[self.style[6]]
        partColor = self.amplifyColor(color, colorScale)
        headIndex = self.style[0]
        if headIndex != -1:
            head = self.find('**/@@' + HeadParts[headIndex])
            head.setColor(partColor)
            head.unstash()
        earsIndex = self.style[1]
        if earsIndex != -1:
            ears = self.find('**/@@' + EarParts[earsIndex])
            ears.setColor(partColor)
            texName = getEarTexture(bodyType, EarParts[earsIndex])
            if texName:
                tex = loader.loadTexture(texName)
                tex.setMinfilter(Texture.FTLinear)
                tex.setMagfilter(Texture.FTLinear)
                ears.setTexture(tex, 1)
            ears.unstash()
        noseIndex = self.style[2]
        if noseIndex != -1:
            nose = self.find('**/@@' + NoseParts[noseIndex])
            nose.setColor(partColor)
            nose.unstash()
        tailIndex = self.style[3]
        if tailIndex != -1:
            tail = self.find('**/@@' + TailParts[tailIndex])
            tail.setColor(partColor)
            texName = TailTextures[TailParts[tailIndex]]
            if texName:
                if BodyTypes[bodyType] == 'giraffe':
                    texName = GiraffeTail
                elif BodyTypes[bodyType] == 'leopard':
                    texName = LeopardTail
                tex = loader.loadTexture(texName)
                tex.setMinfilter(Texture.FTLinear)
                tex.setMagfilter(Texture.FTLinear)
                tail.setTexture(tex, 1)
            tail.unstash()
        if not self.forGui:
            self.drawInFront('eyeWhites', 'body', 1)
            self.drawInFront('rightPupil', 'eyeWhites', 2)
            self.drawInFront('leftPupil', 'eyeWhites', 2)
            self.drawInFront('rightHighlight', 'rightPupil', 3)
            self.drawInFront('leftHighlight', 'leftPupil', 3)
        else:
            self.drawInFront('eyeWhites', 'body', -2)
            self.drawInFront('rightPupil', 'eyeWhites', -2)
            self.drawInFront('leftPupil', 'eyeWhites', -2)
            self.find('**/rightPupil').adjustAllPriorities(1)
            self.find('**/leftPupil').adjustAllPriorities(1)
        eyes = self.style[7]
        eyeColor = PetEyeColors[eyes]
        self.eyes = self.find('**/eyeWhites')
        self.rightPupil = self.find('**/rightPupil')
        self.leftPupil = self.find('**/leftPupil')
        self.rightHighlight = self.find('**/rightHighlight')
        self.leftHighlight = self.find('**/leftHighlight')
        self.rightBrow = self.find('**/rightBrow')
        self.leftBrow = self.find('**/leftBrow')
        self.eyes.setColor(1, 1, 1, 1)
        self.rightPupil.setColor(eyeColor, 2)
        self.leftPupil.setColor(eyeColor, 2)
        self.rightHighlight.setColor(1, 1, 1, 1)
        self.leftHighlight.setColor(1, 1, 1, 1)
        self.rightBrow.setColor(0, 0, 0, 1)
        self.leftBrow.setColor(0, 0, 0, 1)
        self.eyes.setTwoSided(1, 1)
        self.rightPupil.setTwoSided(1, 1)
        self.leftPupil.setTwoSided(1, 1)
        self.rightHighlight.setTwoSided(1, 1)
        self.leftHighlight.setTwoSided(1, 1)
        self.rightBrow.setTwoSided(1, 1)
        self.leftBrow.setTwoSided(1, 1)
        if self.forGui:
            self.rightHighlight.hide()
            self.leftHighlight.hide()
        if self.style[8]:
            self.eyesOpenTexture = loader.loadTexture('phase_4/maps/BeanEyeBoys2.jpg', 'phase_4/maps/BeanEyeBoys2_a.rgb')
            self.eyesClosedTexture = loader.loadTexture('phase_4/maps/BeanEyeBoysBlink.jpg', 'phase_4/maps/BeanEyeBoysBlink_a.rgb')
        else:
            self.eyesOpenTexture = loader.loadTexture('phase_4/maps/BeanEyeGirlsNew.jpg', 'phase_4/maps/BeanEyeGirlsNew_a.rgb')
            self.eyesClosedTexture = loader.loadTexture('phase_4/maps/BeanEyeGirlsBlinkNew.jpg', 'phase_4/maps/BeanEyeGirlsBlinkNew_a.rgb')
        self.eyesOpenTexture.setMinfilter(Texture.FTLinear)
        self.eyesOpenTexture.setMagfilter(Texture.FTLinear)
        self.eyesClosedTexture.setMinfilter(Texture.FTLinear)
        self.eyesClosedTexture.setMagfilter(Texture.FTLinear)
        self.eyesOpen()

    def initializeBodyCollisions(self, collIdStr):
        Avatar.Avatar.initializeBodyCollisions(self, collIdStr)
        if not self.ghostMode:
            self.collNode.setCollideMask(self.collNode.getIntoCollideMask() | ToontownGlobals.PieBitmask)

    def amplifyColor(self, color, scale):
        color = color * scale
        for i in (0, 1, 2):
            if color[i] > 1.0:
                color.setCell(i, 1.0)

        return color

    def generateMoods(self):
        nodePath = NodePath(self.nametag.getNameIcon())

        if not nodePath:
            return

        moodIcons = loader.loadModel('phase_4/models/char/petEmotes')
        self.moodIcons = nodePath.attachNewNode('moodIcons')
        self.moodIcons.setScale(6.0)
        self.moodIcons.setZ(3.5)

        moods = moodIcons.findAllMatches('**/+GeomNode')
        for moodNum in xrange(0, moods.getNumPaths()):
            mood = moods.getPath(moodNum)
            mood.reparentTo(self.moodIcons)
            mood.setBillboardPointEye()
            mood.hide()

        moodIcons.removeNode()

    def clearMood(self):
        if self.moodModel:
            self.moodModel.hide()
        self.moodModel = None
        return

    def showMood(self, mood):
        #if base.cr.newsManager.isHolidayRunning(ToontownGlobals.APRIL_TOONS_WEEK) and mood != 'confusion':
        if self.doodleChat and mood != 'confusion':
            self.speakMood(mood)
        else:
            self.clearChat()
        mood = Component2IconDict[mood]
        if mood is None:
            moodModel = None
        else:
            moodModel = self.moodIcons.find('**/*' + mood + '*')
            if moodModel.isEmpty():
                self.notify.warning('No such mood!: %s' % mood)
                return
        if self.moodModel == moodModel:
            return
        if self.moodModel:
            self.moodModel.hide()
        self.moodModel = moodModel
        if self.moodModel:
            self.moodModel.show()
        self.moodModel.setScale(0, 0, 0)
        Sequence(
            self.moodModel.scaleInterval(.2, VBase3(1.1, 1.1, 1.1), blendType = 'easeInOut'),
            self.moodModel.scaleInterval(.09, VBase3(1, 1, 1), blendType = 'easeInOut')).start()
        return

    def speakMood(self, mood):
        self.setChatAbsolute(random.choice(TTLocalizer.SpokenMoods[mood]), CFSpeech)

    def getGenderString(self):
        if self.style:
            if self.style[8]:
                return TTLocalizer.GenderShopBoyButtonText
            else:
                return TTLocalizer.GenderShopGirlButtonText

    def getShadowJoint(self):
        if hasattr(self, 'shadowJoint'):
            return self.shadowJoint
        shadowJoint = self.find('**/attachShadow')
        if shadowJoint.isEmpty():
            self.shadowJoint = self
        else:
            self.shadowJoint = shadowJoint
        return self.shadowJoint

    def getNametagJoints(self):
        joints = []
        bundle = self.getPartBundle('modelRoot')
        joint = bundle.findChild('attachNametag')
        if joint:
            joints.append(joint)
        return joints

    def fitAndCenterHead(self, maxDim, forGui = 0):
        p1 = Point3()
        p2 = Point3()
        self.calcTightBounds(p1, p2)
        if forGui:
            h = 180
            t = p1[0]
            p1.setX(-p2[0])
            p2.setX(-t)
            self.getGeomNode().setDepthWrite(1)
            self.getGeomNode().setDepthTest(1)
        else:
            h = 0
        d = p2 - p1
        biggest = max(d[0], d[2])
        s = (maxDim + 0.0) / biggest
        mid = (p1 + d / 2.0) * s
        self.setPosHprScale(-mid[0], -mid[1] + 1, -mid[2], h, 0, 0, s, s, s)

    def makeRandomPet(self):
        dna = PetDNA.getRandomPetDNA()
        self.setDNA(dna)

    def enterOff(self):
        self.stop()

    def exitOff(self):
        pass

    def enterBall(self):
        self.setPlayRate(1, 'toBall')
        self.play('toBall')

    def exitBall(self):
        self.setPlayRate(-1, 'toBall')
        self.play('toBall')

    def enterBackflip(self):
        self.play('backflip')

    def exitBackflip(self):
        self.stop('backflip')

    def enterBeg(self):
        delay = self.getDuration('toBeg')
        self.track = Sequence(Func(self.play, 'toBeg'), Wait(delay), Func(self.loop, 'beg'))
        self.track.start()

    def exitBeg(self):
        self.track.pause()
        self.play('fromBeg')

    def enterEat(self):
        self.loop('eat')

    def exitEat(self):
        self.stop('swallow')

    def enterDance(self):
        self.loop('dance')

    def exitDance(self):
        self.stop('dance')

    def enterNeutral(self):
        anim = 'neutral'
        self.pose(anim, random.choice(range(0, self.getNumFrames(anim))))
        self.loop(anim, restart=0)

    def exitNeutral(self):
        self.stop('neutral')

    def enterNeutralHappy(self):
        anim = 'neutralHappy'
        self.pose(anim, random.choice(range(0, self.getNumFrames(anim))))
        self.loop(anim, restart=0)

    def exitNeutralHappy(self):
        self.stop('neutralHappy')

    def enterNeutralSad(self):
        anim = 'neutralSad'
        self.pose(anim, random.choice(range(0, self.getNumFrames(anim))))
        self.loop(anim, restart=0)

    def exitNeutralSad(self):
        self.stop('neutralSad')

    def enterRun(self):
        self.loop('run')

    def exitRun(self):
        self.stop('run')

    def enterSwim(self):
        self.loop('swim')

    def exitSwim(self):
        self.stop('swim')

    def getTeleportInTrack(self):
        if not self.teleportHole:
            self.teleportHole = Actor.Actor('phase_3.5/models/props/portal-mod', {'hole': 'phase_3.5/models/props/portal-chan'})
        track = Sequence(Wait(1.0), Parallel(self.getTeleportInSoundInterval(), Sequence(Func(self.showHole), ActorInterval(self.teleportHole, 'hole', startFrame=81, endFrame=71), ActorInterval(self, 'reappear'), ActorInterval(self.teleportHole, 'hole', startFrame=71, endFrame=81), Func(self.cleanupHole), Func(self.loop, 'neutral')), Sequence(Func(self.dropShadow.hide), Wait(1.0), Func(self.dropShadow.show))))
        return track

    def enterTeleportIn(self, timestamp):
        self.track = self.getTeleportInTrack()
        self.track.start(globalClockDelta.localElapsedTime(timestamp))

    def exitTeleportIn(self):
        self.track.pause()

    def getTeleportOutTrack(self):
        if not self.teleportHole:
            self.teleportHole = Actor.Actor('phase_3.5/models/props/portal-mod', {'hole': 'phase_3.5/models/props/portal-chan'})
        track = Sequence(Wait(1.0), Parallel(self.getTeleportOutSoundInterval(), Sequence(ActorInterval(self, 'toDig'), Parallel(ActorInterval(self, 'dig'), Func(self.showHole), ActorInterval(self.teleportHole, 'hole', startFrame=81, endFrame=71)), ActorInterval(self, 'disappear'), ActorInterval(self.teleportHole, 'hole', startFrame=71, endFrame=81), Func(self.cleanupHole)), Sequence(Wait(1.0), Func(self.dropShadow.hide))))
        return track

    def enterTeleportOut(self, timestamp):
        self.track = self.getTeleportOutTrack()
        self.track.start(globalClockDelta.localElapsedTime(timestamp))

    def exitTeleportOut(self):
        self.track.pause()

    def showHole(self):
        if self.teleportHole:
            self.teleportHole.setBin('shadow', 0)
            self.teleportHole.setDepthTest(0)
            self.teleportHole.setDepthWrite(0)
            self.teleportHole.reparentTo(self)
            self.teleportHole.setScale(0.75)
            self.teleportHole.setPos(0, -1, 0)

    def cleanupHole(self):
        if self.teleportHole:
            self.teleportHole.reparentTo(hidden)
            self.teleportHole.clearBin()
            self.teleportHole.clearDepthTest()
            self.teleportHole.clearDepthWrite()

    def getTeleportInSoundInterval(self):
        if not self.soundTeleportIn:
            self.soundTeleportIn = loader.loadSfx('phase_5/audio/sfx/teleport_reappear.ogg')
        return SoundInterval(self.soundTeleportIn)

    def getTeleportOutSoundInterval(self):
        if not self.soundTeleportOut:
            self.soundTeleportOut = loader.loadSfx('phase_5/audio/sfx/teleport_disappear.ogg')
        return SoundInterval(self.soundTeleportOut)

    def enterWalk(self):
        self.loop('walk')

    def exitWalk(self):
        self.stop('walk')

    def enterWalkHappy(self):
        self.loop('walkHappy')

    def exitWalkHappy(self):
        self.stop('walkHappy')

    def enterWalkSad(self):
        self.loop('walkSad')

    def exitWalkSad(self):
        self.stop('walkSad')

    def trackAnimToSpeed(self, forwardVel, rotVel, inWater = 0):
        action = 'neutral'
        if self.isInWater():
            action = 'swim'
        elif forwardVel > 0.1 or abs(rotVel) > 0.1:
            action = 'walk'
        self.setAnimWithMood(action)

    def setAnimWithMood(self, action):
        how = ''
        if self.isExcited():
            how = 'Happy'
        elif self.isSad():
            how = 'Sad'
        if action == 'swim':
            anim = action
        else:
            anim = '%s%s' % (action, how)
        if anim != self.animFSM.getCurrentState().getName():
            self.animFSM.request(anim)

    def isInWater(self):
        return 0

    def isExcited(self):
        return 0

    def isSad(self):
        return 0

    def startTrackAnimToSpeed(self):
        self.lastPos = self.getPos(render)
        self.lastH = self.getH(render)
        taskMgr.add(self._trackAnimTask, self.getTrackAnimTaskName())

    def stopTrackAnimToSpeed(self):
        taskMgr.remove(self.getTrackAnimTaskName())
        del self.lastPos
        del self.lastH

    def getTrackAnimTaskName(self):
        return 'trackPetAnim-%s' % self.serialNum

    def _trackAnimTask(self, task):
        curPos = self.getPos(render)
        curH = self.getH(render)
        self.trackAnimToSpeed(curPos - self.lastPos, curH - self.lastH)
        self.lastPos = curPos
        self.lastH = curH
        return Task.cont

    def __blinkOpen(self, task):
        self.eyesOpen()
        r = random.random()
        if r < 0.1:
            t = 0.2
        else:
            t = r * 4.0 + 1
        taskMgr.doMethodLater(t, self.__blinkClosed, self.__blinkName)
        return Task.done

    def __blinkClosed(self, task):
        self.eyesClose()
        taskMgr.doMethodLater(0.125, self.__blinkOpen, self.__blinkName)
        return Task.done

    def startBlink(self):
        taskMgr.remove(self.__blinkName)
        self.eyesOpen()
        t = random.random() * 4.0 + 1
        taskMgr.doMethodLater(t, self.__blinkClosed, self.__blinkName)

    def stopBlink(self):
        taskMgr.remove(self.__blinkName)
        self.eyesOpen()

    def eyesOpen(self):
        self.eyes.setColor(1, 1, 1, 1)
        self.eyes.setTexture(self.eyesOpenTexture, 1)
        self.rightPupil.show()
        self.leftPupil.show()
        if not self.forGui:
            self.rightHighlight.show()
            self.leftHighlight.show()

    def eyesClose(self):
        self.eyes.setColor(self.color)
        self.eyes.setTexture(self.eyesClosedTexture, 1)
        self.rightPupil.hide()
        self.leftPupil.hide()
        if not self.forGui:
            self.rightHighlight.hide()
            self.leftHighlight.hide()

    def lockPet(self):
        if not self.lockedDown:
            self.prevAnimState = self.animFSM.getCurrentState().getName()
            self.animFSM.request('neutral')
        self.lockedDown += 1

    def isLockedDown(self):
        return self.lockedDown != 0

    def unlockPet(self):
        self.lockedDown -= 1
        if not self.lockedDown:
            self.animFSM.request(self.prevAnimState)
            self.prevAnimState = None
        return

    def getInteractIval(self, interactId):
        anims = self.InteractAnims[interactId]
        if type(anims) == types.StringType:
            animIval = ActorInterval(self, anims)
        else:
            animIval = Sequence()
            for anim in anims:
                animIval.append(ActorInterval(self, anim))

        return animIval
Esempio n. 8
0
#Embedded file name: toontown.cogdominium.CogdoMazeGameGlobals
from toontown.toonbase import ToonPythonUtil as PythonUtil
from pandac.PandaModules import VBase4

GameActions = PythonUtil.Enum(
    ('EnterDoor', 'RevealDoor', 'OpenDoor', 'Countdown', 'TimeAlert'))
SecondsUntilTimeout = 240.0
SecondsUntilGameEnds = 60.0
SecondsForTimeAlert = 60.0
MaxPlayers = 4
IntroDurationSeconds = 24.0
FinishDurationSeconds = 5.0
PlayerCollisionName = 'CogdoMazePlayer_Collision'
LocalPlayerCollisionName = 'CogdoMazeLocalPlayer_Collision'
PlayerCollisionRadius = 1.0
HitCooldownTime = 2.0
HintTimeout = 6.0
NumQuadrants = (3, 3)
FrameWallThickness = 1
QuadrantUnitGap = 3
TotalBarriers = 12
NumBarriers = 3
MazeBarriers = ([(7, 34), (8, 34), (9, 34),
                 (10, 34)], [(24, 34), (25, 34), (26, 34),
                             (27, 34)], [(41, 34), (42, 34), (43, 34),
                                         (44, 34)], [(7, 17), (8, 17), (9, 17),
                                                     (10, 17)], [(24, 17),
                                                                 (25, 17),
                                                                 (26, 17),
                                                                 (27, 17)],
                [(41, 17), (42, 17), (43, 17),
Esempio n. 9
0
from toontown.toonbase import ToonPythonUtil as PythonUtil
from otp.speedchat.SCMenu import SCMenu
from otp.speedchat.SCMenuHolder import SCMenuHolder
from otp.speedchat.SCStaticTextTerminal import SCStaticTextTerminal
from otp.otpbase import OTPLocalizer
JellybeanJamMenu = [(OTPLocalizer.JellybeanJamMenuSections[0],
                     [30180, 30181, 30182, 30183, 30184, 30185]),
                    (OTPLocalizer.JellybeanJamMenuSections[1],
                     [30186, 30187, 30188, 30189, 30190])]
JellybeanJamPhases = PythonUtil.Enum('TROLLEY, FISHING, PARTIES')
PhaseSpecifPhrases = [30180, 30181, 30182]


class TTSCJellybeanJamMenu(SCMenu):
    def __init__(self, phase):
        SCMenu.__init__(self)
        if phase in JellybeanJamPhases:
            self.__messagesChanged(phase)
        else:
            print 'warning: tried to add Jellybean Jam phase %s which does not seem to exist' % phase

    def destroy(self):
        SCMenu.destroy(self)

    def clearMenu(self):
        SCMenu.clearMenu(self)

    def __messagesChanged(self, phase):
        self.clearMenu()
        try:
            lt = base.localAvatar
from direct.directnotify import DirectNotifyGlobal
from direct.gui.DirectGui import *
from pandac.PandaModules import *
from toontown.toonbase import ToonPythonUtil as PythonUtil
from direct.task import Task
from toontown.fishing.FishPhoto import DirectRegion
from toontown.shtiker.ShtikerPage import ShtikerPage
from toontown.toonbase import ToontownGlobals, TTLocalizer
from FishPage import FishingTrophy
from toontown.golf import GolfGlobals
if (__debug__):
    import pdb

PageMode = PythonUtil.Enum('Records, Trophy')

class GolfPage(ShtikerPage):
    notify = DirectNotifyGlobal.directNotify.newCategory('GolfPage')

    def __init__(self):
        ShtikerPage.__init__(self)
        self.avatar = None
        self.mode = PageMode.Trophy
        return

    def enter(self):
        if not hasattr(self, 'title'):
            self.load()
        self.setMode(self.mode, 1)
        ShtikerPage.enter(self)

    def exit(self):
Esempio n. 11
0
#Embedded file name: toontown.racing.KartDNA
from direct.directnotify import DirectNotifyGlobal
from toontown.toonbase import ToonPythonUtil as PythonUtil
from toontown.toonbase import TTLocalizer
from pandac.PandaModules import *
from toontown.racing.KartShopGlobals import *
import types
import copy
KartDNA = PythonUtil.Enum(
    'bodyType, bodyColor, accColor,                             ebType, spType, fwwType,                             bwwType, rimsType, decalType'
)
InvalidEntry = -1
KartInfo = PythonUtil.Enum(
    'name, model, cost, viewDist, decalId, LODmodel1, LODmodel2')
AccInfo = PythonUtil.Enum('name, model, cost, texCard, attach')
kNames = TTLocalizer.KartDNA_KartNames
KartDict = {
    0: (kNames[0], 'phase_6/models/karting/Kart1_Final', 100, 7.0, 'kart1',
        'phase_6/models/karting/Kart1_LOD_Final',
        'phase_6/models/karting/Kart1_LOD_Final', (Point3(1.5, 8.0, -0.5),
                                                   Point3(1.5, 0.0, 2.0))),
    1: (kNames[1], 'phase_6/models/karting/Kart2_Final', 7500, 7.0, 'kart2',
        'phase_6/models/karting/Kart2_LOD2_Final',
        'phase_6/models/karting/Kart2_LOD3_Final', (Point3(0.25, 7, -2),
                                                    Point3(1.25, -3, 0))),
    2: (kNames[2], 'phase_6/models/karting/Kart3_Final', 2500, 8.5, 'kart3',
        'phase_6/models/karting/Kart3_Final_LOD2',
        'phase_6/models/karting/Kart3_Final_LOD3', (Point3(1.25, 4.0, 1.0),
                                                    Point3(1.25, -3.0, 2.5)))
}
aNames = TTLocalizer.KartDNA_AccNames
class CogdoFlyingLocalPlayer(CogdoFlyingPlayer):
    notify = DirectNotifyGlobal.directNotify.newCategory('CogdoFlyingLocalPlayer')
    BroadcastPosTask = 'CogdoFlyingLocalPlayerBroadcastPos'
    PlayWaitingMusicEventName = 'PlayWaitingMusicEvent'
    RanOutOfTimeEventName = 'RanOutOfTimeEvent'
    PropStates = PythonUtil.Enum(('Normal', 'Overdrive', 'Off'))

    def __init__(self, toon, game, level, guiMgr):
        CogdoFlyingPlayer.__init__(self, toon)
        self.defaultTransitions = {'Inactive': ['FreeFly', 'Running'],
         'FreeFly': ['Inactive',
                     'OutOfTime',
                     'Death',
                     'FlyingUp',
                     'Running',
                     'HitWhileFlying',
                     'InWhirlwind'],
         'FlyingUp': ['Inactive',
                      'OutOfTime',
                      'Death',
                      'FreeFly',
                      'Running',
                      'HitWhileFlying',
                      'InWhirlwind'],
         'InWhirlwind': ['Inactive',
                         'OutOfTime',
                         'Death',
                         'FreeFly',
                         'HitWhileFlying'],
         'HitWhileFlying': ['Inactive',
                            'OutOfTime',
                            'Death',
                            'FreeFly',
                            'InWhirlwind'],
         'Death': ['Inactive', 'OutOfTime', 'Spawn'],
         'Running': ['Inactive',
                     'OutOfTime',
                     'FreeFly',
                     'FlyingUp',
                     'Refuel',
                     'WaitingForWin',
                     'HitWhileRunning'],
         'HitWhileRunning': ['Inactive',
                             'OutOfTime',
                             'Death',
                             'Running',
                             'FreeFly'],
         'Spawn': ['Inactive',
                   'OutOfTime',
                   'Running',
                   'WaitingForWin'],
         'OutOfTime': ['Inactive', 'Spawn'],
         'WaitingForWin': ['Inactive', 'Win'],
         'Win': ['Inactive']}
        self.game = game
        self._level = level
        self._guiMgr = guiMgr
        self._inputMgr = CogdoFlyingInputManager()
        self._cameraMgr = CogdoFlyingCameraManager(camera, render, self, self._level)
        self.velocity = Vec3(0.0, 0.0, 0.0)
        self.instantaneousVelocity = Vec3(0.0, 0.0, 0.0)
        self.controlVelocity = Vec3(0.0, 0.0, 0.0)
        self.fanVelocity = Vec3(0.0, 0.0, 0.0)
        self.activeFans = []
        self.fansStillHavingEffect = []
        self.fanIndex2ToonVelocity = {}
        self.legalEagleInterestRequest = {}
        self.activeWhirlwind = None
        self.oldPos = Vec3(0.0, 0.0, 0.0)
        self.checkpointPlatform = None
        self.isHeadInCeiling = False
        self.isToonOnFloor = False
        self.fuel = 0.0
        self.score = 0
        self.postSpawnState = 'Running'
        self.didTimeRunOut = False
        self.hasPressedCtrlYet = False
        self.hasPickedUpFirstPropeller = False
        self.surfacePoint = None
        self.legalEagleHitting = False
        self.propState = None
        self.broadcastPeriod = Globals.AI.BroadcastPeriod
        self.initSfx()
        self.initLocalPlayerIntervals()
        self.initCollisions()
        self.initOrthoWalker()
        self.playerNumber = -1
        self.fuel = 0.0
        self._guiMgr.setFuel(self.fuel)
        self.setCheckpointPlatform(self._level.startPlatform)

    def initSfx(self):
        audioMgr = base.cogdoGameAudioMgr
        self._deathSfx = audioMgr.createSfx('death')
        self._hitByWhirlwindSfx = audioMgr.createSfx('toonInWhirlwind')
        self._bladeBreakSfx = audioMgr.createSfx('bladeBreak')
        self._collideSfx = audioMgr.createSfx('collide')
        self._toonHitSfx = audioMgr.createSfx('toonHit')
        self._getMemoSfx = audioMgr.createSfx('getMemo')
        self._getLaffSfx = audioMgr.createSfx('getLaff')
        self._getRedTapeSfx = audioMgr.createSfx('getRedTape')
        self._refuelSfx = audioMgr.createSfx('refuel')
        self._fanSfx = audioMgr.createSfx('fan')
        self._invulDebuffSfx = audioMgr.createSfx('invulDebuff')
        self._invulBuffSfx = audioMgr.createSfx('invulBuff')
        self._winSfx = audioMgr.createSfx('win')
        self._loseSfx = audioMgr.createSfx('lose')
        self._refuelSpinSfx = audioMgr.createSfx('refuelSpin')
        self._propellerSfx = audioMgr.createSfx('propeller', self.toon)

    def destroySfx(self):
        del self._deathSfx
        del self._hitByWhirlwindSfx
        del self._bladeBreakSfx
        del self._collideSfx
        del self._toonHitSfx
        del self._propellerSfx
        del self._getMemoSfx
        del self._getLaffSfx
        del self._refuelSfx
        del self._fanSfx
        del self._invulBuffSfx
        del self._invulDebuffSfx
        del self._getRedTapeSfx
        del self._refuelSpinSfx

    def setPlayerNumber(self, num):
        self.playerNumber = num

    def getPlayerNumber(self):
        return self.playerNumber

    def initOrthoWalker(self):
        orthoDrive = OrthoDrive(9.778, maxFrameMove=0.5, wantSound=True)
        self.orthoWalk = OrthoWalk(orthoDrive, broadcast=False, collisions=False, broadcastPeriod=Globals.AI.BroadcastPeriod)

    def initLocalPlayerIntervals(self):
        self.coolDownAfterHitInterval = Sequence(Wait(Globals.Gameplay.HitCooldownTime), Func(self.setEnemyHitting, False), name='coolDownAfterHitInterval-%i' % self.toon.doId)
        self.deathInterval = Sequence(Func(self.resetVelocities), Parallel(Parallel(Func(self._deathSfx.play), LerpHprInterval(self.toon, 1.0, Vec3(720, 0, 0)), LerpFunctionInterval(self.toon.setScale, fromData=1.0, toData=0.1, duration=1.0), self.toon.posInterval(0.5, Vec3(0, 0, -25), other=self.toon)), Sequence(Wait(0.5), Func(base.transitions.irisOut))), Func(self.toon.stash), Wait(1.0), Func(self.toonSpawnFunc), name='%s.deathInterval' % self.__class__.__name__)
        self.outOfTimeInterval = Sequence(Func(messenger.send, CogdoFlyingLocalPlayer.PlayWaitingMusicEventName), Func(self._loseSfx.play), Func(base.transitions.irisOut), Wait(1.0), Func(self.resetVelocities), Func(self._guiMgr.setMessage, '', transition=None), Func(self.toon.stash), Func(self.toonSpawnFunc), name='%s.outOfTimeInterval' % self.__class__.__name__)
        self.spawnInterval = Sequence(Func(self.resetToonFunc), Func(self._cameraMgr.update, 0.0), Func(self._level.update), Func(self.toon.cnode.broadcastPosHprFull), Func(base.transitions.irisIn), Wait(0.5), Func(self.toon.setAnimState, 'TeleportIn'), Func(self.toon.unstash), Wait(1.5), Func(self.requestPostSpawnState), name='%s.spawnInterval' % self.__class__.__name__)
        self.waitingForWinInterval = Sequence(Func(self._guiMgr.setMessage, TTLocalizer.CogdoFlyingGameWaiting % '.'), Wait(1.5), Func(self._guiMgr.setMessage, TTLocalizer.CogdoFlyingGameWaiting % '..'), Wait(1.5), Func(self._guiMgr.setMessage, TTLocalizer.CogdoFlyingGameWaiting % '...'), Wait(1.5), name='%s.waitingForWinInterval' % self.__class__.__name__)
        self.waitingForWinSeq = Sequence(Func(self.setWaitingForWinState), Wait(4.0), Func(self.removeAllMemos), Wait(2.0), Func(self.game.distGame.d_sendRequestAction, Globals.AI.GameActions.LandOnWinPlatform, 0), Func(self.playWaitingForWinInterval), name='%s.waitingForWinSeq' % self.__class__.__name__)
        self.winInterval = Sequence(Func(self._guiMgr.setMessage, ''), Wait(4.0), Func(self.game.distGame.d_sendRequestAction, Globals.AI.GameActions.WinStateFinished, 0), name='%s.winInterval' % self.__class__.__name__)
        self.goSadSequence = Sequence(Wait(2.5), Func(base.transitions.irisOut, 1.5), name='%s.goSadSequence' % self.__class__.__name__)
        self.introGuiSeq = Sequence(Wait(0.5), Parallel(Func(self._guiMgr.setTemporaryMessage, TTLocalizer.CogdoFlyingGameMinimapIntro, duration=5.0), Sequence(Wait(1.0), Func(self._guiMgr.presentProgressGui))), Wait(5.0), Func(self._guiMgr.setMessage, TTLocalizer.CogdoFlyingGamePickUpAPropeller), name='%s.introGuiSeq' % self.__class__.__name__)

    def goSad(self):
        self.goSadSequence.start()

    def setWaitingForWinState(self):
        if self.didTimeRunOut:
            self.toon.b_setAnimState('Sad')
            self._guiMgr.setMessage(TTLocalizer.CogdoFlyingGameOutOfTime, transition='blink')
        else:
            self._winSfx.play()
            messenger.send(CogdoFlyingLocalPlayer.PlayWaitingMusicEventName)
            self.toon.b_setAnimState('victory')
            self._guiMgr.setMessage(TTLocalizer.CogdoFlyingGameYouMadeIt)

    def removeAllMemos(self):
        if self.didTimeRunOut:
            messenger.send(CogdoFlyingLocalPlayer.RanOutOfTimeEventName)

    def playWaitingForWinInterval(self):
        if not self.game.distGame.isSinglePlayer():
            self.waitingForWinInterval.loop()

    def resetToonFunc(self):
        self.resetToon(resetFuel=self.hasPickedUpFirstPropeller)

    def _loopPropellerSfx(self, playRate = 1.0, volume = 1.0):
        self._propellerSfx.loop(playRate=playRate, volume=1.0)

    def initCollisions(self):
        avatarRadius = 2.0
        reach = 4.0
        self.flyerCollisions = CogdoFlyingCollisions()
        self.flyerCollisions.setWallBitMask(OTPGlobals.WallBitmask)
        self.flyerCollisions.setFloorBitMask(OTPGlobals.FloorBitmask)
        self.flyerCollisions.initializeCollisions(base.cTrav, self.toon, avatarRadius, OTPGlobals.FloorOffset, reach)
        self.flyerCollisions.setCollisionsActive(0)
        floorColl = CogdoFlyingPlatform.FloorCollName
        ceilingColl = CogdoFlyingPlatform.CeilingCollName
        self.accept('Flyer.cHeadCollSphere-enter-%s' % ceilingColl, self.__handleHeadCollisionIntoCeiling)
        self.accept('Flyer.cHeadCollSphere-exit-%s' % ceilingColl, self.__handleHeadCollisionExitCeiling)
        self.accept('Flyer.cFloorEventSphere-exit-%s' % floorColl, self.__handleEventCollisionExitFloor)
        self.accept('Flyer.cRayNode-enter-%s' % floorColl, self.__handleRayCollisionEnterFloor)
        self.accept('Flyer.cRayNode-again-%s' % floorColl, self.__handleRayCollisionAgainFloor)

    def enable(self):
        CogdoFlyingPlayer.enable(self)
        self.toon.hideName()

    def disable(self):
        CogdoFlyingPlayer.disable(self)

    def isLegalEagleInterestRequestSent(self, index):
        if index in self.legalEagleInterestRequest:
            return True

        return False

    def setLegalEagleInterestRequest(self, index):
        if index not in self.legalEagleInterestRequest:
            self.legalEagleInterestRequest[index] = True
        else:
            CogdoFlyingLocalPlayer.notify.warning('Attempting to set an legal eagle interest request when one already exists:%s' % index)

    def clearLegalEagleInterestRequest(self, index):
        if index in self.legalEagleInterestRequest:
            del self.legalEagleInterestRequest[index]

    def setBackpackState(self, state):
        if state == self.backpackState:
            return
        CogdoFlyingPlayer.setBackpackState(self, state)
        if state in Globals.Gameplay.BackpackStates:
            if state == Globals.Gameplay.BackpackStates.Normal:
                messenger.send(CogdoFlyingGuiManager.ClearMessageDisplayEventName)
            elif state == Globals.Gameplay.BackpackStates.Targeted:
                messenger.send(CogdoFlyingGuiManager.EagleTargetingLocalPlayerEventName)
            elif state == Globals.Gameplay.BackpackStates.Attacked:
                messenger.send(CogdoFlyingGuiManager.EagleAttackingLocalPlayerEventName)

    def requestPostSpawnState(self):
        self.request(self.postSpawnState)

    def toonSpawnFunc(self):
        self.game.distGame.b_toonSpawn(self.toon.doId)

    def __handleHeadCollisionIntoCeiling(self, collEntry):
        self.isHeadInCeiling = True
        self.surfacePoint = self.toon.getPos()
        self._collideSfx.play()
        if self.controlVelocity[2] > 0.0:
            self.controlVelocity[2] = -self.controlVelocity[2] / 2.0

    def __handleHeadCollisionExitCeiling(self, collEntry):
        self.isHeadInCeiling = False
        self.surfacePoint = None

    def landOnPlatform(self, collEntry):
        surfacePoint = collEntry.getSurfacePoint(render)
        intoNodePath = collEntry.getIntoNodePath()
        platform = CogdoFlyingPlatform.getFromNode(intoNodePath)
        if platform is not None:
            if not platform.isStartOrEndPlatform():
                taskMgr.doMethodLater(0.5, self.delayedLandOnPlatform, 'delayedLandOnPlatform', extraArgs=[platform])
            elif platform.isEndPlatform():
                taskMgr.doMethodLater(1.0, self.delayedLandOnWinPlatform, 'delayedLandOnWinPlatform', extraArgs=[platform])
        self.isToonOnFloor = True
        self.controlVelocity = Vec3(0.0, 0.0, 0.0)
        self.toon.setPos(render, surfacePoint)
        self.toon.setHpr(0, 0, 0)
        self.request('Running')

    def __handleRayCollisionEnterFloor(self, collEntry):
        fromNodePath = collEntry.getFromNodePath()
        intoNodePath = collEntry.getIntoNodePath()
        intoName = intoNodePath.getName()
        fromName = fromNodePath.getName()
        toonPos = self.toon.getPos(render)
        collPos = collEntry.getSurfacePoint(render)
        if toonPos.getZ() < collPos.getZ() + Globals.Gameplay.RayPlatformCollisionThreshold:
            if not self.isToonOnFloor and self.state in ['FreeFly', 'FlyingUp']:
                self.landOnPlatform(collEntry)

    def __handleRayCollisionAgainFloor(self, collEntry):
        fromNodePath = collEntry.getFromNodePath()
        intoNodePath = collEntry.getIntoNodePath()
        intoName = intoNodePath.getName()
        fromName = fromNodePath.getName()
        toonPos = self.toon.getPos(render)
        collPos = collEntry.getSurfacePoint(render)
        if toonPos.getZ() < collPos.getZ() + Globals.Gameplay.RayPlatformCollisionThreshold:
            if not self.isToonOnFloor and self.state in ['FreeFly', 'FlyingUp']:
                self.landOnPlatform(collEntry)

    def __handleEventCollisionExitFloor(self, collEntry):
        fromNodePath = collEntry.getFromNodePath()
        intoNodePath = collEntry.getIntoNodePath()
        intoName = intoNodePath.getName()
        fromName = fromNodePath.getName()
        if self.isToonOnFloor:
            self.notify.debug('~~~Exit Floor:%s -> %s' % (intoName, fromName))
            self.isToonOnFloor = False
            taskMgr.remove('delayedLandOnPlatform')
            taskMgr.remove('delayedLandOnWinPlatform')
            if self.state not in ['FlyingUp', 'Spawn']:
                self.notify.debug('Exited floor')
                self.request('FreeFly')

    def delayedLandOnPlatform(self, platform):
        self.setCheckpointPlatform(platform)
        return Task.done

    def delayedLandOnWinPlatform(self, platform):
        self.setCheckpointPlatform(self._level.endPlatform)
        self.request('WaitingForWin')
        return Task.done

    def handleTimerExpired(self):
        if self.state not in ['WaitingForWin', 'Win']:
            self.setCheckpointPlatform(self._level.endPlatform)
            self.postSpawnState = 'WaitingForWin'
            self.didTimeRunOut = True
            if self.state not in ['Death']:
                self.request('OutOfTime')

    def ready(self):
        self.resetToon(resetFuel=False)
        self._cameraMgr.enable()
        self._cameraMgr.update()

    def start(self):
        CogdoFlyingPlayer.start(self)
        self.toon.collisionsOff()
        self.flyerCollisions.setAvatar(self.toon)
        self.flyerCollisions.setCollisionsActive(1)
        self._levelBounds = self._level.getBounds()
        self.introGuiSeq.start()
        self.request('Running')

    def exit(self):
        self.request('Inactive')
        CogdoFlyingPlayer.exit(self)
        self._cameraMgr.disable()
        self.flyerCollisions.setCollisionsActive(0)
        self.flyerCollisions.setAvatar(None)
        taskMgr.remove('delayedLandOnFuelPlatform')
        taskMgr.remove('delayedLandOnWinPlatform')
        self.ignoreAll()

    def unload(self):
        self.toon.showName()
        self.toon.collisionsOn()
        self._destroyEventIval()
        self._destroyEnemyHitIval()
        CogdoFlyingPlayer.unload(self)
        self._fanSfx.stop()
        self.flyerCollisions.deleteCollisions()
        del self.flyerCollisions
        self.ignoreAll()
        taskMgr.remove('delayedLandOnPlatform')
        taskMgr.remove('delayedLandOnWinPlatform')
        self.checkpointPlatform = None
        self._cameraMgr.disable()
        del self._cameraMgr
        del self.game
        self._inputMgr.destroy()
        del self._inputMgr
        self.introGuiSeq.clearToInitial()
        del self.introGuiSeq
        if self.goSadSequence:
            self.goSadSequence.clearToInitial()
            del self.goSadSequence
        if self.coolDownAfterHitInterval:
            self.coolDownAfterHitInterval.clearToInitial()
            del self.coolDownAfterHitInterval
        if self.deathInterval:
            self.deathInterval.clearToInitial()
            del self.deathInterval
        if self.spawnInterval:
            self.spawnInterval.clearToInitial()
            del self.spawnInterval
        if self.outOfTimeInterval:
            self.outOfTimeInterval.clearToInitial()
            del self.outOfTimeInterval
        if self.winInterval:
            self.winInterval.clearToInitial()
            del self.winInterval
        if self.waitingForWinInterval:
            self.waitingForWinInterval.clearToInitial()
            del self.waitingForWinInterval
        if self.waitingForWinSeq:
            self.waitingForWinSeq.clearToInitial()
            del self.waitingForWinSeq
        del self.activeFans[:]
        del self.fansStillHavingEffect[:]
        self.fanIndex2ToonVelocity.clear()
        self.orthoWalk.stop()
        self.orthoWalk.destroy()
        del self.orthoWalk
        self.destroySfx()

    def setCheckpointPlatform(self, platform):
        self.checkpointPlatform = platform

    def resetVelocities(self):
        self.fanVelocity = Vec3(0.0, 0.0, 0.0)
        self.controlVelocity = Vec3(0.0, 0.0, 0.0)
        self.velocity = Vec3(0.0, 0.0, 0.0)

    def resetToon(self, resetFuel = True):
        CogdoFlyingPlayer.resetToon(self)
        self.resetVelocities()
        del self.activeFans[:]
        del self.fansStillHavingEffect[:]
        self.fanIndex2ToonVelocity.clear()
        self._fanSfx.stop()
        spawnPos = self.checkpointPlatform.getSpawnPosForPlayer(self.getPlayerNumber(), render)
        self.activeWhirlwind = None
        self.toon.setPos(render, spawnPos)
        self.toon.setHpr(render, 0, 0, 0)
        if resetFuel:
            self.resetFuel()
        
        self.isHeadInCeiling = False
        self.isToonOnFloor = True

    def activateFlyingBroadcast(self):
        self.timeSinceLastPosBroadcast = 0.0
        self.lastPosBroadcast = self.toon.getPos()
        self.lastHprBroadcast = self.toon.getHpr()
        toon = self.toon
        toon.d_clearSmoothing()
        toon.sendCurrentPosition()
        taskMgr.remove(self.BroadcastPosTask)
        taskMgr.add(self.doBroadcast, self.BroadcastPosTask)

    def shutdownFlyingBroadcast(self):
        taskMgr.remove(self.BroadcastPosTask)

    def doBroadcast(self, task):
        dt = globalClock.getDt()
        self.timeSinceLastPosBroadcast += dt
        if self.timeSinceLastPosBroadcast >= self.broadcastPeriod:
            self.timeSinceLastPosBroadcast = 0.0
            self.toon.cnode.broadcastPosHprFull()
        
        return Task.cont

    def died(self, timestamp):
        self.request('Death')

    def spawn(self, timestamp):
        self.request('Spawn')

    def updateToonFlyingState(self, dt):
        leftPressed = self._inputMgr.arrowKeys.leftPressed()
        rightPressed = self._inputMgr.arrowKeys.rightPressed()
        upPressed = self._inputMgr.arrowKeys.upPressed()
        downPressed = self._inputMgr.arrowKeys.downPressed()
        jumpPressed = self._inputMgr.arrowKeys.jumpPressed()
        if not self.hasPressedCtrlYet and jumpPressed and self.isFuelLeft():
            self.hasPressedCtrlYet = True
            messenger.send(CogdoFlyingGuiManager.FirstPressOfCtrlEventName)
        if jumpPressed and self.isFuelLeft():
            if self.state == 'FreeFly' and self.isInTransition() == False:
                self.notify.debug('FreeFly -> FlyingUp')
                self.request('FlyingUp')
        elif self.state == 'FlyingUp' and self.isInTransition() == False:
            self.notify.debug('FlyingUp -> FreeFly')
            self.request('FreeFly')
        if leftPressed and not rightPressed:
            self.toon.setH(self.toon, Globals.Gameplay.ToonTurning['turningSpeed'] * dt)
            max = Globals.Gameplay.ToonTurning['maxTurningAngle']
            if self.toon.getH() > max:
                self.toon.setH(max)
        elif rightPressed and not leftPressed:
            self.toon.setH(self.toon, -1.0 * Globals.Gameplay.ToonTurning['turningSpeed'] * dt)
            min = -1.0 * Globals.Gameplay.ToonTurning['maxTurningAngle']
            if self.toon.getH() < min:
                self.toon.setH(min)

    def updateControlVelocity(self, dt):
        leftPressed = self._inputMgr.arrowKeys.leftPressed()
        rightPressed = self._inputMgr.arrowKeys.rightPressed()
        upPressed = self._inputMgr.arrowKeys.upPressed()
        downPressed = self._inputMgr.arrowKeys.downPressed()
        jumpPressed = self._inputMgr.arrowKeys.jumpPressed()
        if leftPressed:
            self.controlVelocity[0] -= Globals.Gameplay.ToonAcceleration['turning'] * dt
        if rightPressed:
            self.controlVelocity[0] += Globals.Gameplay.ToonAcceleration['turning'] * dt
        if upPressed:
            self.controlVelocity[1] += Globals.Gameplay.ToonAcceleration['forward'] * dt
        if downPressed:
            self.controlVelocity[2] -= Globals.Gameplay.ToonAcceleration['activeDropDown'] * dt
            self.controlVelocity[1] -= Globals.Gameplay.ToonAcceleration['activeDropBack'] * dt
        if jumpPressed and self.isFuelLeft():
            self.controlVelocity[2] += Globals.Gameplay.ToonAcceleration['boostUp'] * dt
        minVal = -Globals.Gameplay.ToonVelMax['turning']
        maxVal = Globals.Gameplay.ToonVelMax['turning']
        if not leftPressed and not rightPressed or self.controlVelocity[0] > maxVal or self.controlVelocity[0] < minVal:
            x = self.dampenVelocityVal(self.controlVelocity[0], 'turning', 'turning', minVal, maxVal, dt)
            self.controlVelocity[0] = x
        minVal = -Globals.Gameplay.ToonVelMax['backward']
        maxVal = Globals.Gameplay.ToonVelMax['forward']
        if not upPressed and not downPressed or self.controlVelocity[1] > maxVal or self.controlVelocity[1] < minVal:
            y = self.dampenVelocityVal(self.controlVelocity[1], 'backward', 'forward', minVal, maxVal, dt)
            self.controlVelocity[1] = y
        if self.isFuelLeft():
            minVal = -Globals.Gameplay.ToonVelMax['fall']
        else:
            minVal = -Globals.Gameplay.ToonVelMax['fallNoFuel']
        maxVal = Globals.Gameplay.ToonVelMax['boost']
        if self.controlVelocity[2] > minVal:
            if (not self._inputMgr.arrowKeys.jumpPressed() or not self.isFuelLeft()) and not self.isToonOnFloor:
                self.controlVelocity[2] -= Globals.Gameplay.ToonAcceleration['fall'] * dt
        if self.controlVelocity[2] < 0.0 and self.isToonOnFloor:
            self.controlVelocity[2] = 0.0
        minVal = -Globals.Gameplay.ToonVelMax['turning']
        maxVal = Globals.Gameplay.ToonVelMax['turning']
        self.controlVelocity[0] = clamp(self.controlVelocity[0], minVal, maxVal)
        minVal = -Globals.Gameplay.ToonVelMax['backward']
        maxVal = Globals.Gameplay.ToonVelMax['forward']
        self.controlVelocity[1] = clamp(self.controlVelocity[1], minVal, maxVal)
        if self.isFuelLeft():
            minVal = -Globals.Gameplay.ToonVelMax['fall']
        else:
            minVal = -Globals.Gameplay.ToonVelMax['fallNoFuel']
        maxVal = Globals.Gameplay.ToonVelMax['boost']
        self.controlVelocity[2] = clamp(self.controlVelocity[2], minVal, maxVal)

    def updateFanVelocity(self, dt):
        fanHeight = Globals.Gameplay.FanCollisionTubeHeight
        min = Globals.Gameplay.FanMinPower
        max = Globals.Gameplay.FanMaxPower
        powerRange = max - min
        for fan in self.activeFans:
            blowVec = fan.getBlowDirection()
            blowVec *= Globals.Gameplay.ToonAcceleration['fan'] * dt
            if Globals.Gameplay.UseVariableFanPower:
                distance = fan.model.getDistance(self.toon)
                power = math.fabs(distance / fanHeight - 1.0) * powerRange + min
                power = clamp(power, min, max)
                blowVec *= power
            if fan.index in self.fanIndex2ToonVelocity:
                fanVelocity = self.fanIndex2ToonVelocity[fan.index]
                fanVelocity += blowVec

        removeList = []
        for fan in self.fansStillHavingEffect:
            if fan not in self.activeFans:
                blowVec = fan.getBlowDirection()
                blowVec *= Globals.Gameplay.ToonDeceleration['fan'] * dt
                if fan.index in self.fanIndex2ToonVelocity:
                    fanVelocity = Vec3(self.fanIndex2ToonVelocity[fan.index])
                    lastLen = fanVelocity.length()
                    fanVelocity -= blowVec
                    if fanVelocity.length() > lastLen:
                        removeList.append(fan)
                    else:
                        self.fanIndex2ToonVelocity[fan.index] = fanVelocity

        for fan in removeList:
            self.fansStillHavingEffect.remove(fan)
            if fan.index in self.fanIndex2ToonVelocity:
                del self.fanIndex2ToonVelocity[fan.index]

        self.fanVelocity = Vec3(0.0, 0.0, 0.0)
        for fan in self.fansStillHavingEffect:
            if fan.index in self.fanIndex2ToonVelocity:
                self.fanVelocity += self.fanIndex2ToonVelocity[fan.index]

        minVal = -Globals.Gameplay.ToonVelMax['fan']
        maxVal = Globals.Gameplay.ToonVelMax['fan']
        self.fanVelocity[0] = clamp(self.fanVelocity[0], minVal, maxVal)
        self.fanVelocity[1] = clamp(self.fanVelocity[1], minVal, maxVal)
        self.fanVelocity[2] = clamp(self.fanVelocity[2], minVal, maxVal)

    def dampenVelocityVal(self, velocityVal, typeNeg, typePos, minVal, maxVal, dt):
        if velocityVal > 0.0:
            velocityVal -= Globals.Gameplay.ToonDeceleration[typePos] * dt
            velocityVal = clamp(velocityVal, 0.0, maxVal)
        elif velocityVal < 0.0:
            velocityVal += Globals.Gameplay.ToonDeceleration[typeNeg] * dt
            velocityVal = clamp(velocityVal, minVal, 0.0)
        return velocityVal

    def allowFuelDeath(self):
        if Globals.Gameplay.DoesToonDieWithFuel:
            return True

        return not self.isFuelLeft()

    def updateToonPos(self, dt):
        toonWorldY = self.toon.getY(render)
        if self.hasPickedUpFirstPropeller == False:
            if toonWorldY > -7.6:
                self.toon.setY(-7.6)
            elif toonWorldY < -35.0:
                self.toon.setY(-35.0)
            return
        self.velocity = self.controlVelocity + self.fanVelocity
        vel = self.velocity * dt
        self.toon.setPos(self.toon, vel[0], vel[1], vel[2])
        toonPos = self.toon.getPos()
        if Globals.Dev.DisableDeath:
            pass
        elif toonPos[2] < 0.0 and self.state in ['FreeFly', 'FlyingUp'] and self.allowFuelDeath():
            self.postSpawnState = 'Running'
            self.game.distGame.b_toonDied(self.toon.doId)
        if toonPos[2] > self._levelBounds[2][1]:
            self.controlVelocity[2] = 0.0
            self.fanVelocity[2] = 0.0
        toonPos = Vec3(clamp(toonPos[0], self._levelBounds[0][0], self._levelBounds[0][1]), clamp(toonPos[1], self._levelBounds[1][0], self._levelBounds[1][1]), clamp(toonPos[2], self._levelBounds[2][0], self._levelBounds[2][1]))
        if self.isHeadInCeiling and toonPos[2] > self.surfacePoint[2]:
            toonPos[2] = self.surfacePoint[2]
        self.toon.setPos(toonPos)
        if self.toon.getY(render) < -10:
            self.toon.setY(-10.0)

    def printFanInfo(self, string):
        if len(self.fanIndex2ToonVelocity) > 0:
            self.notify.info('==AFTER %s==' % string)
            self.notify.info('Fan velocity:%s' % self.fanVelocity)
        if len(self.activeFans) > 0:
            self.notify.info('%s' % self.activeFans)
        if len(self.fanIndex2ToonVelocity) > 0:
            self.notify.info('%s' % self.fanIndex2ToonVelocity)
        if len(self.fansStillHavingEffect) > 0:
            self.notify.info('%s' % self.fansStillHavingEffect)

    def resetFuel(self):
        self.setFuel(Globals.Gameplay.FuelNormalAmt)

    def isFuelLeft(self):
        return self.fuel > 0.0

    def setFuel(self, fuel):
        self.fuel = fuel
        self._guiMgr.setFuel(fuel)
        if self.fuel <= 0.0:
            fuelState = Globals.Gameplay.FuelStates.FuelEmpty
        elif self.fuel < Globals.Gameplay.FuelVeryLowAmt:
            fuelState = Globals.Gameplay.FuelStates.FuelVeryLow
        elif self.fuel < Globals.Gameplay.FuelLowAmt:
            fuelState = Globals.Gameplay.FuelStates.FuelLow
        else:
            fuelState = Globals.Gameplay.FuelStates.FuelNormal
        if fuelState > self.fuelState:
            self.game.distGame.b_toonSetBlades(self.toon.doId, fuelState)
        if fuelState < self.fuelState:
            if self.state in ['FlyingUp', 'FreeFly', 'Running']:
                self.game.distGame.b_toonBladeLost(self.toon.doId)

    def resetBlades(self):
        CogdoFlyingPlayer.resetBlades(self)
        self._guiMgr.resetBlades()

    def setBlades(self, fuelState):
        CogdoFlyingPlayer.setBlades(self, fuelState)
        self._guiMgr.setBlades(fuelState)

    def bladeLost(self):
        CogdoFlyingPlayer.bladeLost(self)
        self._bladeBreakSfx.play(volume=0.35)
        self._guiMgr.bladeLost()

    def updateFuel(self, dt):
        if Globals.Dev.InfiniteFuel:
            self.setFuel(Globals.Gameplay.FuelNormalAmt)
        elif self.state in Globals.Gameplay.DepleteFuelStates and self.fuel > 0.0:
            self.setFuel(self.fuel - Globals.Gameplay.FuelBurnRate * dt)
        elif self.fuel < 0.0:
            self.setFuel(0.0)

    def update(self, dt = 0.0):
        self.instantaneousVelocity = (self.toon.getPos() - self.oldPos) / dt
        self.oldPos = self.toon.getPos()
        self.updateFuel(dt)
        if self.isFlying():
            self.updateToonFlyingState(dt)
        if self.state in ['FreeFly', 'FlyingUp', 'Death']:
            self.updateControlVelocity(dt)
        self.updateFanVelocity(dt)
        self.updateToonPos(dt)
        self._cameraMgr.update(dt)

    def isFlying(self):
        if self.state in ['FreeFly', 'FlyingUp']:
            return True

        return False

    def pressedControlWhileRunning(self):
        if self.isFuelLeft() and self.state == 'Running':
            self.notify.debug('Pressed Control and have fuel')
            self.request('FlyingUp')
        else:
            self.ignore(base.JUMP)
            self.acceptOnce(base.JUMP, self.pressedControlWhileRunning)

    def setPropellerState(self, propState):
        if not self.hasPickedUpFirstPropeller:
            propState = CogdoFlyingLocalPlayer.PropStates.Off
        if self.propState != propState:
            oldState = self.propState
            self.propState = propState
            if self.propState == CogdoFlyingLocalPlayer.PropStates.Normal:
                if not self.propellerSpinLerp.isPlaying():
                    self.propellerSpinLerp.loop()
                self.setPropellerSpinRate(Globals.Gameplay.NormalPropSpeed)
                self._guiMgr.setPropellerSpinRate(Globals.Gameplay.NormalPropSpeed)
                self._loopPropellerSfx(playRate=0.7, volume=0.8)
            elif self.propState == CogdoFlyingLocalPlayer.PropStates.Overdrive:
                if not self.propellerSpinLerp.isPlaying():
                    self.propellerSpinLerp.loop()
                self.setPropellerSpinRate(Globals.Gameplay.OverdrivePropSpeed)
                self._guiMgr.setPropellerSpinRate(Globals.Gameplay.OverdrivePropSpeed)
                self._loopPropellerSfx(playRate=1.1)
            elif self.propState == CogdoFlyingLocalPlayer.PropStates.Off:
                self.propellerSpinLerp.pause()
                self._propellerSfx.stop()

    def enterInactive(self):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self._inputMgr.disable()
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Off)
        self.shutdownFlyingBroadcast()

    def filterInactive(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitInactive(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))
        self._inputMgr.enable()
        self.activateFlyingBroadcast()

    def enterSpawn(self):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self.toon.b_setAnimState('Happy', 1.0)
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Normal)
        self.spawnInterval.start()

    def filterSpawn(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitSpawn(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))

    def enterFreeFly(self):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Normal)
        if self.oldState in ['Running', 'HitWhileRunning']:
            self.toon.jumpStart()
            self.toon.setHpr(render, 0, 0, 0)

    def filterFreeFly(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitFreeFly(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))

    def enterFlyingUp(self):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Overdrive)
        if self.oldState in ['Running']:
            self.toon.jumpStart()
            self.toon.setHpr(render, 0, 0, 0)

    def filterFlyingUp(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitFlyingUp(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))

    def enterHitWhileFlying(self, elapsedTime = 0.0):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self.setEnemyHitting(True)
        self._toonHitSfx.play()
        self.startHitFlyingToonInterval()
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Normal)

    def filterHitWhileFlying(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitHitWhileFlying(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))
        self.enemyHitIval.clearToInitial()
        self.coolDownAfterHitInterval.clearToInitial()
        self.coolDownAfterHitInterval.start()

    def enterInWhirlwind(self, elapsedTime = 0.0):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self._hitByWhirlwindSfx.play()
        self.startHitByWhirlwindInterval()
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Normal)

    def filterInWhirlwind(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitInWhirlwind(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))
        self.eventIval.clearToInitial()

    def enterHitWhileRunning(self, elapsedTime = 0.0):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self.setEnemyHitting(True)
        self._toonHitSfx.play()
        self.toon.b_setAnimState('FallDown')
        self.startHitRunningToonInterval()
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Normal)

    def filterHitWhileRunning(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitHitWhileRunning(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))
        self.enemyHitIval.clearToInitial()
        self.coolDownAfterHitInterval.clearToInitial()
        self.coolDownAfterHitInterval.start()

    def enterRunning(self):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self.toon.b_setAnimState('Happy', 1.0)
        if self.oldState not in ['Spawn', 'HitWhileRunning', 'Inactive']:
            self.toon.jumpHardLand()
            self._collideSfx.play()
        self.orthoWalk.start()
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Normal)
        self.ignore(base.JUMP)
        self.acceptOnce(base.JUMP, self.pressedControlWhileRunning)

    def filterRunning(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitRunning(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))
        self.orthoWalk.stop()
        self.ignore(base.JUMP)

    def enterOutOfTime(self):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        if self.spawnInterval.isPlaying():
            self.spawnInterval.clearToInitial()
        self.ignoreAll()
        self.introGuiSeq.clearToInitial()
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Off)
        if not Globals.Dev.NoLegalEagleAttacks:
            for eagle in self.legalEaglesTargeting:
                messenger.send(CogdoFlyingLegalEagle.RequestRemoveTargetEventName, [eagle.index])

        taskMgr.remove('delayedLandOnPlatform')
        taskMgr.remove('delayedLandOnWinPlatform')
        self.outOfTimeInterval.start()

    def filterOutOfTime(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
       
        return None

    def exitOutOfTime(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))

    def enterDeath(self):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self.propellerSmoke.stop()
        self.deathInterval.start()
        self.toon.b_setAnimState('jumpAirborne', 1.0)
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Off)
        if not Globals.Dev.NoLegalEagleAttacks:
            for eagle in self.legalEaglesTargeting:
                messenger.send(CogdoFlyingLegalEagle.RequestRemoveTargetEventName, [eagle.index])

    def filterDeath(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitDeath(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))
        self.deathInterval.clearToInitial()

    def enterWaitingForWin(self):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self.resetFuel()
        self._guiMgr.hideRefuelGui()
        self.waitingForWinSeq.start()
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Normal)
        if not Globals.Dev.NoLegalEagleAttacks:
            self.game.forceClearLegalEagleInterestInToon(self.toon.doId)

    def filterWaitingForWin(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitWaitingForWin(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))
        self.waitingForWinSeq.finish()
        self.waitingForWinInterval.clearToInitial()

    def enterWin(self):
        CogdoFlyingLocalPlayer.notify.info("enter%s: '%s' -> '%s'" % (self.newState, self.oldState, self.newState))
        self._guiMgr.stopTimer()
        self.winInterval.start()
        self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Normal)

    def filterWin(self, request, args):
        if request == self.state:
            return None
        else:
            return self.defaultFilter(request, args)
        
        return None

    def exitWin(self):
        CogdoFlyingLocalPlayer.notify.debug("exit%s: '%s' -> '%s'" % (self.oldState, self.oldState, self.newState))

    def _destroyEventIval(self):
        if hasattr(self, 'eventIval'):
            self.eventIval.clearToInitial()
            del self.eventIval

    def startEventIval(self, ival):
        self._destroyEventIval()
        self.eventIval = ival
        self.eventIval.start()

    def _destroyEnemyHitIval(self):
        if hasattr(self, 'enemyHitIval'):
            self.enemyHitIval.clearToInitial()
            del self.enemyHitIval

    def startEnemyHitIval(self, ival):
        self._destroyEnemyHitIval()
        self.enemyHitIval = ival
        self.enemyHitIval.start()

    def isEnemyHitting(self):
        return self.legalEagleHitting

    def setEnemyHitting(self, value):
        self.legalEagleHitting = value

    def shouldLegalEagleBeInFrame(self):
        if not self.isLegalEagleTarget():
            return False
        else:
            index = len(self.legalEaglesTargeting) - 1
            eagle = self.legalEaglesTargeting[index]
            return eagle.shouldBeInFrame()

    def startHitRunningToonInterval(self):
        dur = self.toon.getDuration('slip-backward')
        self.startEnemyHitIval(Sequence(Wait(dur), Func(self.request, 'Running'), name='hitByLegalEagleIval-%i' % self.toon.doId))

    def startHitFlyingToonInterval(self):
        hitByEnemyPos = self.toon.getPos(render)
        collVec = hitByEnemyPos - self.collPos
        collVec[2] = 0.0
        collVec.normalize()
        collVec *= Globals.Gameplay.HitKnockbackDist

        def spinPlayer(t, rand):
            if rand == 0:
                self.toon.setH(-(t * 720.0))
            else:
                self.toon.setH(t * 720.0)

        direction = random.randint(0, 1)
        self.startEnemyHitIval(Sequence(Parallel(LerpFunc(spinPlayer, fromData=0.0, toData=1.0, duration=Globals.Gameplay.HitKnockbackTime, blendType='easeInOut', extraArgs=[direction]), LerpPosInterval(self.toon, duration=Globals.Gameplay.HitKnockbackTime, pos=hitByEnemyPos + collVec, blendType='easeOut')), Func(self.request, 'FreeFly'), name='hitByLegalEagleIval-%i' % self.toon.doId))

    def startHitByWhirlwindInterval(self):

        def spinPlayer(t):
            self.controlVelocity[2] = 1.0
            angle = math.radians(t * (720.0 * 2 - 180))
            self.toon.setPos(self.activeWhirlwind.model.getX(self.game.level.root) + math.cos(angle) * 2, self.activeWhirlwind.model.getY(self.game.level.root) + math.sin(angle) * 2, self.toon.getZ())

        def movePlayerBack(t):
            self.toon.setY(self.activeWhirlwind.model.getY(self.game.level.root) - t * Globals.Gameplay.WhirlwindMoveBackDist)

        self.startEventIval(Sequence(Func(self._cameraMgr.freeze), Func(self.activeWhirlwind.disable), LerpFunc(spinPlayer, fromData=0.0, toData=1.0, duration=Globals.Gameplay.WhirlwindSpinTime), LerpFunc(movePlayerBack, fromData=0.0, toData=1.0, duration=Globals.Gameplay.WhirlwindMoveBackTime, blendType='easeOut'), Func(self.activeWhirlwind.enable), Func(self._cameraMgr.unfreeze), Func(self.request, 'FreeFly'), name='spinPlayerIval-%i' % self.toon.doId))

    def handleEnterWhirlwind(self, whirlwind):
        self.activeWhirlwind = whirlwind
        self.request('InWhirlwind')

    def handleEnterEnemyHit(self, enemy, collPos):
        self.collPos = collPos
        if self.state in ['FlyingUp', 'FreeFly']:
            self.request('HitWhileFlying')
        elif self.state in ['Running']:
            self.request('HitWhileRunning')

    def handleEnterFan(self, fan):
        if fan in self.activeFans:
            return
        if len(self.activeFans) == 0:
            self._fanSfx.loop()
        self.activeFans.append(fan)
        if fan.index not in self.fanIndex2ToonVelocity:
            self.fanIndex2ToonVelocity[fan.index] = Vec3(0.0, 0.0, 0.0)
        if fan not in self.fansStillHavingEffect:
            self.fansStillHavingEffect.append(fan)

    def handleExitFan(self, fan):
        if fan in self.activeFans:
            self.activeFans.remove(fan)
        if len(self.activeFans) == 0:
            self._fanSfx.stop()

    def handleDebuffPowerup(self, pickupType, elapsedTime):
        self._invulDebuffSfx.play()
        CogdoFlyingPlayer.handleDebuffPowerup(self, pickupType, elapsedTime)
        messenger.send(CogdoFlyingGuiManager.ClearMessageDisplayEventName)

    def handleEnterGatherable(self, gatherable, elapsedTime):
        CogdoFlyingPlayer.handleEnterGatherable(self, gatherable, elapsedTime)
        if gatherable.type == Globals.Level.GatherableTypes.Memo:
            self.handleEnterMemo(gatherable)
        elif gatherable.type == Globals.Level.GatherableTypes.Propeller:
            self.handleEnterPropeller(gatherable)
        elif gatherable.type == Globals.Level.GatherableTypes.LaffPowerup:
            self.handleEnterLaffPowerup(gatherable)
        elif gatherable.type == Globals.Level.GatherableTypes.InvulPowerup:
            self.handleEnterInvulPowerup(gatherable)

    def handleEnterMemo(self, gatherable):
        self.score += 1
        if self.score == 1:
            self._guiMgr.presentMemoGui()
            self._guiMgr.setTemporaryMessage(TTLocalizer.CogdoFlyingGameMemoIntro, 4.0)
        self._guiMgr.setMemoCount(self.score)
        self._getMemoSfx.play()

    def handleEnterPropeller(self, gatherable):
        if self.fuel < 1.0:
            if not self.hasPickedUpFirstPropeller:
                messenger.send(CogdoFlyingGuiManager.PickedUpFirstPropellerEventName)
                self.introGuiSeq.clearToInitial()
                self.hasPickedUpFirstPropeller = True
                self.setPropellerState(CogdoFlyingLocalPlayer.PropStates.Normal)
            self.setFuel(1.0)
            self._guiMgr.update()
            self._refuelSfx.play()
            self._refuelSpinSfx.play(volume=0.15)

    def handleEnterLaffPowerup(self, gatherable):
        self._getLaffSfx.play()

    def handleEnterInvulPowerup(self, gatherable):
        messenger.send(CogdoFlyingGuiManager.InvulnerableEventName)
        self._getRedTapeSfx.play()