コード例 #1
0
class Megaphone(ToonUpGag):
    def __init__(self):
        ToonUpGag.__init__(self, CIGlobals.Megaphone,
                           'phase_5/models/props/megaphone.bam', 10, 20, 100,
                           GagGlobals.TELLJOKE_SFX, 1)
        self.setImage('phase_3.5/maps/megaphone.png')
        self.track = None
        self.soundInterval = None
        self.timeout = 5.0

    def start(self):
        super(Megaphone, self).start()
        if not self.gag:
            self.build()
        if self.avatar == base.localAvatar:
            question, answer = random.choice(CIGlobals.ToonHealJokes)
        self.setupHandJoints()
        self.placeProp(self.handJoint, self.gag)
        self.soundInterval = self.getSoundTrack(
            self.avatar.getDuration('shout', fromFrame=0, toFrame=18),
            self.gag, 5.5)
        propInterval = Sequence()
        propInterval.append(
            Wait(self.avatar.getDuration('shout', fromFrame=0, toFrame=25)))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(base.localAvatar.b_setChat, question))
        propInterval.append(
            Wait(self.avatar.getDuration('shout', fromFrame=26, toFrame=75)))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(base.localAvatar.b_setChat, answer))
        propInterval.append(
            Wait(self.avatar.getDuration('shout', fromFrame=76, toFrame=118)))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(self.setHealAmount))
            propInterval.append(Func(self.healNearbyAvatars, 20))
        propInterval.append(
            Wait(self.avatar.getDuration('shout', fromFrame=118)))
        propInterval.append(Func(self.cleanupGag))
        propInterval.append(Func(self.reset))
        self.track = Parallel(propInterval,
                              ActorInterval(self.avatar,
                                            'shout'), self.soundInterval)
        self.track.start()

    def equip(self):
        super(Megaphone, self).equip()
        self.build()

    def unEquip(self):
        if self.track:
            self.track.finish()
            self.track = None
            self.soundInterval = None
        self.cleanupGag()
        self.reset()

    def cleanupGag(self):
        if self.gag:
            self.gag.removeNode()
            self.gag = None
コード例 #2
0
ファイル: JugglingBalls.py プロジェクト: coginvasion/src
class JugglingBalls(ToonUpGag):

    def __init__(self):
        ToonUpGag.__init__(self, CIGlobals.JugglingBalls, 'phase_5/models/props/cubes-mod.bam', 90, 120, 100, GagGlobals.JUGGLE_SFX, 1, anim='phase_5/models/props/cubes-chan.bam')
        self.setImage('phase_3.5/maps/juggling-cubes.png')
        self.track = None
        self.soundInterval = None
        return

    def start(self):
        super(JugglingBalls, self).start()
        self.setupHips()
        self.build()
        self.placeProp(self.hips, self.gag)
        self.soundInterval = self.getSoundTrack(0.7, self.gag, 7.7)
        propInterval = Sequence()
        propInterval.append(ActorInterval(self.gag, 'chan'))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(self.setHealAmount))
            propInterval.append(Func(self.healNearbyAvatars, 25))
        propInterval.append(Func(self.cleanupGag))
        propInterval.append(Func(self.reset))
        self.track = Parallel(ActorInterval(self.avatar, 'juggle'), propInterval, Func(self.soundInterval.start))
        self.track.start()

    def equip(self):
        super(JugglingBalls, self).equip()

    def unEquip(self):
        if self.track:
            self.soundInterval.finish()
            self.track.finish()
            self.track = None
        self.reset()
        return
コード例 #3
0
ファイル: Megaphone.py プロジェクト: coginvasion/src
class Megaphone(ToonUpGag):

    def __init__(self):
        ToonUpGag.__init__(self, CIGlobals.Megaphone, 'phase_5/models/props/megaphone.bam', 10, 20, 100, GagGlobals.TELLJOKE_SFX, 1)
        self.setImage('phase_3.5/maps/megaphone.png')
        self.track = None
        self.soundInterval = None
        return

    def start(self):
        super(Megaphone, self).start()
        if not self.gag:
            self.build()
        if self.avatar == base.localAvatar:
            question, answer = random.choice(CIGlobals.ToonHealJokes)
        self.setupHandJoints()
        self.placeProp(self.handJoint, self.gag)
        self.soundInterval = self.getSoundTrack(self.avatar.getDuration('shout', fromFrame=0, toFrame=18), self.gag, 5.5)
        propInterval = Sequence()
        propInterval.append(Wait(self.avatar.getDuration('shout', fromFrame=0, toFrame=25)))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(base.localAvatar.b_setChat, question))
        propInterval.append(Wait(self.avatar.getDuration('shout', fromFrame=26, toFrame=75)))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(base.localAvatar.b_setChat, answer))
        propInterval.append(Wait(self.avatar.getDuration('shout', fromFrame=76, toFrame=118)))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(self.setHealAmount))
            propInterval.append(Func(self.healNearbyAvatars, 20))
        propInterval.append(Wait(self.avatar.getDuration('shout', fromFrame=118)))
        propInterval.append(Func(self.cleanupGag))
        propInterval.append(Func(self.reset))
        self.track = Parallel(propInterval, ActorInterval(self.avatar, 'shout'), self.soundInterval)
        self.track.start()

    def equip(self):
        super(Megaphone, self).equip()
        self.build()

    def unEquip(self):
        if self.track:
            self.track.finish()
            self.track = None
            self.soundInterval = None
        self.cleanupGag()
        self.reset()
        return

    def cleanupGag(self):
        if self.gag:
            self.gag.removeNode()
            self.gag = None
        return
コード例 #4
0
class JugglingBalls(ToonUpGag):

    name = GagGlobals.JugglingBalls
    model = 'phase_5/models/props/cubes-mod.bam'
    minHeal = 90
    maxHeal = 120
    efficiency = 100
    hitSfxPath = GagGlobals.JUGGLE_SFX
    anim = 'phase_5/models/props/cubes-chan.bam'

    def __init__(self):
        ToonUpGag.__init__(self)
        self.setImage('phase_3.5/maps/juggling-cubes.png')
        self.track = None
        self.soundInterval = None
        self.timeout = 8.0

    def start(self):
        super(JugglingBalls, self).start()
        self.setupHips()
        self.build()
        self.placeProp(self.hips, self.gag)
        self.soundInterval = self.getSoundTrack(0.7, self.gag, 7.7)

        BSPUtility.applyUnlitOverride(self.gag)

        propInterval = Sequence()
        propInterval.append(ActorInterval(self.gag, 'chan'))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(self.setHealAmount))
            propInterval.append(Func(self.healNearbyAvatars, 25))
        propInterval.append(Func(self.cleanupGag))
        propInterval.append(Func(self.reset))
        self.track = Parallel(ActorInterval(self.avatar, 'juggle'),
                              propInterval, Func(self.soundInterval.start))
        self.track.start()

    def equip(self):
        # self.gag returns the juggling balls.
        super(JugglingBalls, self).equip()

    def unEquip(self):
        if self.track:
            self.soundInterval.finish()
            self.track.finish()
            self.track = None
        self.reset()
コード例 #5
0
class JugglingBalls(ToonUpGag):
    def __init__(self):
        ToonUpGag.__init__(self,
                           CIGlobals.JugglingBalls,
                           'phase_5/models/props/cubes-mod.bam',
                           90,
                           120,
                           100,
                           GagGlobals.JUGGLE_SFX,
                           1,
                           anim='phase_5/models/props/cubes-chan.bam')
        self.setImage('phase_3.5/maps/juggling-cubes.png')
        self.track = None
        self.soundInterval = None
        self.timeout = 8.0
        return

    def start(self):
        super(JugglingBalls, self).start()
        self.setupHips()
        self.build()
        self.placeProp(self.hips, self.gag)
        self.soundInterval = self.getSoundTrack(0.7, self.gag, 7.7)
        propInterval = Sequence()
        propInterval.append(ActorInterval(self.gag, 'chan'))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(self.setHealAmount))
            propInterval.append(Func(self.healNearbyAvatars, 25))
        propInterval.append(Func(self.cleanupGag))
        propInterval.append(Func(self.reset))
        self.track = Parallel(ActorInterval(self.avatar, 'juggle'),
                              propInterval, Func(self.soundInterval.start))
        self.track.start()

    def equip(self):
        super(JugglingBalls, self).equip()

    def unEquip(self):
        if self.track:
            self.soundInterval.finish()
            self.track.finish()
            self.track = None
        self.reset()
        return
コード例 #6
0
class DistributedBoat(DistributedObject):
    notify = directNotify.newCategory("DistributedBoat")

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.fsm = ClassicFSM('DistributedBoat', [
            State('off', self.enterOff, self.exitOff),
            State('eastToWest', self.enterEastToWest, self.exitEastToWest),
            State('westToEast', self.enterWestToEast, self.exitWestToEast)
        ], 'off', 'off')
        self.boat = None
        self.eastPier = None
        self.eastPierPath = 'east_pier'
        self.westPier = None
        self.westPierPath = 'west_pier'
        self.pierUpP = 0.0
        self.pierDownP = -45.0
        self.fogHorn = 'phase_5/audio/sfx/SZ_DD_foghorn.ogg'
        self.shipBell = 'phase_6/audio/sfx/SZ_DD_shipbell.ogg'
        self.waterLap = 'phase_6/audio/sfx/SZ_DD_waterlap.ogg'
        self.dockCreak = 'phase_6/audio/sfx/SZ_DD_dockcreak.ogg'
        self.eastWest = 'phase_6/paths/dd-e-w.bam'
        self.westEast = 'phase_6/paths/dd-w-e.bam'
        self.boatPath = '*donalds_boat*'
        self.track = None
        self.state = None

    def __handleOnBoat(self, entry):
        base.localAvatar.b_setParent(CIGlobals.SPDonaldsBoat)
        base.playSfx(self.soundWaterLap, looping=1)

    def __handleOffBoat(self, entry):
        base.localAvatar.b_setParent(CIGlobals.SPRender)
        self.soundWaterLap.stop()

    def __pollBoat(self, task):
        try:
            self.boat = self.cr.playGame.hood.loader.geom.find('**/' +
                                                               self.boatPath)
        except:
            return task.cont
        self.generated()
        return task.done

    def generate(self):
        DistributedObject.generate(self)
        self.soundFogHorn = base.loadSfx(self.fogHorn)
        self.soundShipBell = base.loadSfx(self.shipBell)
        self.soundWaterLap = base.loadSfx(self.waterLap)
        self.soundDockCreak = base.loadSfx(self.dockCreak)
        #try:
        #    self.boat = self.cr.playGame.hood.loader.geom.find('**/' + self.boatPath)
        #except:
        #        base.taskMgr.add(self.__pollBoat, self.uniqueName('__pollBoat'))
        #        return
        self.boat = self.cr.playGame.hood.loader.geom.find('**/' +
                                                           self.boatPath)
        self.generated()

    def generated(self):
        self.eastPier = self.cr.playGame.hood.loader.geom.find(
            '**/' + self.eastPierPath)
        self.westPier = self.cr.playGame.hood.loader.geom.find(
            '**/' + self.westPierPath)
        base.cr.parentMgr.registerParent(CIGlobals.SPDonaldsBoat, self.boat)
        self.accept('enterdonalds_boat_floor', self.__handleOnBoat)
        self.accept('exitdonalds_boat_floor', self.__handleOffBoat)
        self.d_requestCurrentStateAndTimestamp()
        self.fsm.enterInitialState()

    def disable(self):
        base.taskMgr.remove(self.uniqueName('__pollBoat'))
        base.cr.parentMgr.unregisterParent(CIGlobals.SPDonaldsBoat)
        self.ignore('enterdonalds_boat_floor')
        self.ignore('exitdonalds_boat_floor')
        self.fsm.requestFinalState()
        del self.fsm
        del self.soundFogHorn
        del self.soundShipBell
        del self.soundWaterLap
        del self.soundDockCreak
        self.fogHorn = None
        self.shipBell = None
        self.waterLap = None
        self.dockCreak = None
        self.boat = None
        self.track = None
        self.pierDownP = None
        self.pierUpP = None
        self.eastPier = None
        self.eastPierPath = None
        self.westPier = None
        self.westPierPath = None
        self.boatPath = None
        self.westEast = None
        self.eastWest = None
        DistributedObject.disable(self)

    def currentStateAndTimestamp(self, state, timestamp):
        self.setState(state, timestamp)

    def d_requestCurrentStateAndTimestamp(self):
        self.sendUpdate('requestCurrentStateAndTimestamp', [])

    def setState(self, state, timestamp=None):
        if timestamp == None:
            ts = 0.0
        else:
            ts = globalClockDelta.localElapsedTime(timestamp)
        self.state = state
        if self.boat:
            self.fsm.request(state, [ts])

    def enterEastToWest(self, ts=0):
        moPath = Mopath.Mopath()
        moPath.loadFile(self.eastWest)
        moIval = MopathInterval(moPath, self.boat)

        self.track = Parallel(
            SoundInterval(self.soundShipBell, node=self.boat),
            SoundInterval(self.soundDockCreak, node=self.eastPier), moIval,
            LerpQuatInterval(self.eastPier,
                             duration=5.0,
                             quat=(90, self.pierDownP, 0),
                             startHpr=(90, self.pierUpP, 0)),
            Sequence(
                Wait(15.0),
                Parallel(
                    LerpQuatInterval(self.westPier,
                                     duration=5.0,
                                     quat=(-90, self.pierUpP, 0),
                                     startHpr=(-90, self.pierDownP, 0)),
                    Sequence(
                        Wait(2.0),
                        SoundInterval(self.soundDockCreak,
                                      node=self.westPier))),
                SoundInterval(self.soundFogHorn, node=self.boat)))
        self.track.start(ts)

    def exitEastToWest(self):
        if self.track:
            self.track.finish()
            self.track = None

    def enterWestToEast(self, ts=0):
        moPath = Mopath.Mopath()
        moPath.loadFile(self.westEast)
        moIval = MopathInterval(moPath, self.boat)

        self.track = Parallel(
            SoundInterval(self.soundShipBell, node=self.boat),
            SoundInterval(self.soundDockCreak, node=self.westPier), moIval,
            LerpQuatInterval(self.westPier,
                             duration=5.0,
                             quat=(-90, self.pierDownP, 0),
                             startHpr=(-90, self.pierUpP, 0)),
            Sequence(
                Wait(15.0),
                Parallel(
                    LerpQuatInterval(self.eastPier,
                                     duration=5.0,
                                     quat=(90, self.pierUpP, 0),
                                     startHpr=(90, self.pierDownP, 0)),
                    Sequence(
                        Wait(2.0),
                        SoundInterval(self.soundDockCreak,
                                      node=self.eastPier))),
                SoundInterval(self.soundFogHorn, node=self.boat)))
        self.track.start(ts)

    def exitWestToEast(self):
        if self.track:
            self.track.finish()
            self.track = None

    def enterOff(self):
        pass

    def exitOff(self):
        pass
class DistributedPieTurret(DistributedAvatar, DistributedSmoothNode):
    notify = directNotify.newCategory('DistributedPieTurret')

    def __init__(self, cr):
        DistributedAvatar.__init__(self, cr)
        DistributedSmoothNode.__init__(self, cr)
        self.fsm = ClassicFSM(
            'DistributedPieTurret',
            [
                State('off', self.enterOff, self.exitOff),
                State('scan', self.enterScan, self.exitScan),
                State('shoot', self.enterShoot, self.exitShoot)
             ],
             'off', 'off'
         )
        self.fsm.enterInitialState()
        self.reloadTime = 0.25
        self.cannon = None
        self.track = None
        self.owner = None
        self.gag = None
        self.readyGag = None
        self.hitGag = None
        self.explosion = None
        self.wallCollNode = None
        self.eventCollNode = None
        self.event = None
        self.suit = None
        self.eventId = None
        self.entities = []
        self.upgradeID = None
        self.deathEvent = None

    def setOwner(self, avatar):
        self.owner = avatar

    def getOwner(self):
        return self.owner

    def setGag(self, upgradeId):
        gags = {0 : CIGlobals.WholeCreamPie, 1 : CIGlobals.WholeFruitPie, 2 : CIGlobals.BirthdayCake, 3 : CIGlobals.WeddingCake}
        self.gag = gags.get(upgradeId)
        if not self.readyGag:
            self.loadGagInTurret()

    def b_setGag(self, upgradeId):
        self.sendUpdate('setGag', [upgradeId])
        self.setGag(upgradeId)
        self.upgradeID = upgradeId

    def getGag(self):
        return self.gag

    def getGagID(self):
        return self.upgradeID

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

    def announceGenerate(self):
        DistributedAvatar.announceGenerate(self)
        DistributedSmoothNode.announceGenerate(self)
        self.healthLabel.setScale(1.1)
        self.deathEvent = self.uniqueName('DistributedPieTurret-death')
        self.makeTurret()

    def disable(self):
        self.fsm.requestFinalState()
        del self.fsm

        # This should fix crashes related to Sequences.
        if self.track:
            self.track.pause()
            self.track = None

        # Cleanup entities.
        for ent in self.entities:
            ent.cleanup()
        self.entities = None

        # Get rid of explosions.
        if self.explosion:
            self.explosion.removeNode()
            self.explosion = None

        self.removeTurret()
        DistributedSmoothNode.disable(self)
        DistributedAvatar.disable(self)

    def showAndMoveHealthLabel(self):
        self.unstashHpLabel()
        self.stopMovingHealthLabel()
        moveTrack = LerpPosInterval(self.healthLabel,
                                duration = 0.5,
                                pos = Point3(0, 0, 5),
                                startPos = Point3(0, 0, 0),
                                blendType = 'easeOut')
        self.healthLabelTrack = Sequence(moveTrack, Wait(1.0), Func(self.stashHpLabel))
        self.healthLabelTrack.start()

    # BEGIN STATES

    def enterShoot(self, suitId):
        if self.cannon:
            smoke = loader.loadModel("phase_4/models/props/test_clouds.bam")
            smoke.setBillboardPointEye()
            smoke.reparentTo(self.cannon.find('**/cannon'))
            smoke.setPos(0, 6, -3)
            smoke.setScale(0.5)
            smoke.wrtReparentTo(render)
            self.suit = self.cr.doId2do.get(suitId)
            self.cannon.find('**/cannon').lookAt(self.suit.find('**/joint_head'))
            self.cannon.find('**/square_drop_shadow').headsUp(self.suit.find('**/joint_head'))
            self.track = Sequence(Parallel(LerpScaleInterval(smoke, 0.5, 3), LerpColorScaleInterval(smoke, 0.5, Vec4(2, 2, 2, 0))), Func(smoke.removeNode))
            self.track.start()
            self.createAndShootGag()

    def exitShoot(self):
        if hasattr(self, 'suit'):
            del self.suit

    def shoot(self, suitId):
        self.fsm.request('shoot', [suitId])

    def scan(self, timestamp = None, afterShooting = 0):
        if timestamp == None:
            ts = 0.0
        else:
            ts = globalClockDelta.localElapsedTime(timestamp)

        self.fsm.request('scan', [ts, afterShooting])
        
    def buildScanTrack(self, ts = None):
        if self.track:
            self.track.pause()
            self.track = None
        self.track = Parallel(
            Sequence(
                LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (60, 0, 0),
                    startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'),
                LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0),
                    startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'),
            ),
            Sequence(
                LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (60, 0, 0),
                    startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'),
                LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0),
                    startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'),
            )
        )
        if ts:
            self.track.loop(ts)
        else:
            self.track.loop()

    def enterScan(self, ts = 0, afterShooting = 0):
        if afterShooting:
            self.track = Parallel(
                LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0),
                    startHpr = self.cannon.find('**/cannon').getHpr(), blendType = 'easeInOut'),
                LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0),
                    startHpr = self.cannon.find('**/square_drop_shadow').getHpr(), blendType = 'easeInOut'),
                name = "afterShootTrack" + str(id(self))
            )
            self.track.setDoneEvent(self.track.getName())
            self.acceptOnce(self.track.getDoneEvent(), self._afterShootTrackDone)
            self.track.start(ts)
        else:
            self.buildScanTrack(ts)

    def exitScan(self):
        if self.track:
            self.ignore(self.track.getDoneEvent())
            self.track.finish()
            self.track = None

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    # END STATES

    def _afterShootTrackDone(self):
        self.buildScanTrack()

    def makeTurret(self):
        self.cannon = loader.loadModel('phase_4/models/minigames/toon_cannon.bam')
        self.cannon.reparentTo(self)
        self.loadGagInTurret()
        self.setupWallSphere()
        if self.isLocal():
            self.setupEventSphere()

    def removeTurret(self):
        self.removeWallSphere()
        self.removeGagInTurret()
        if self.cannon:
            self.cannon.removeNode()
            self.cannon = None

    def getCannon(self):
        return self.cannon.find('**/cannon')

    def setupWallSphere(self):
        sphere = CollisionSphere(0.0, 0.0, 0.0, 3.0)
        node = CollisionNode('DistributedPieTurret.WallSphere')
        node.addSolid(sphere)
        node.setCollideMask(CIGlobals.WallBitmask)
        self.wallCollNode = self.cannon.attachNewNode(node)
        self.wallCollNode.setZ(2)
        self.wallCollNode.setY(1.0)

    def removeWallSphere(self):
        if self.wallCollNode:
            self.wallCollNode.removeNode()
            self.wallCollNode = None

    def createAndShootGag(self):
        if not self.readyGag:
            self.loadGagInTurret()
        if self.readyGag:
            self.readyGag.shoot(Point3(0, 200, -90))
            self.entities.append(self.readyGag)
            collideEventName = self.readyGag.getCollideEventName()
            self.readyGag = None
            if self.isLocal():
                self.acceptOnce(collideEventName, self.handleGagCollision)
        Sequence(Wait(self.reloadTime), Func(self.loadGagInTurret)).start()

    def loadGagInTurret(self):
        if self.cannon and self.gag:
            self.removeGagInTurret()
            self.eventId = random.uniform(0, 100000000)
            self.readyGag = TurretGag(self, self.uniqueName('pieTurretCollision') + str(self.eventId), self.gag)
            self.readyGag.build()

    def removeGagInTurret(self):
        if self.readyGag:
            self.readyGag.cleanup()
            self.readyGag = None

    def makeSplat(self, index, pos):
        if index >= len(self.entities):
            return
        ent = self.entities[index]
        gagClass = ent.gagClass
        splat = gagClass.buildSplat(gagClass.splatScale, gagClass.splatColor)
        base.audio3d.attachSoundToObject(gagClass.hitSfx, splat)
        splat.reparentTo(render)
        splat.setPos(pos[0], pos[1], pos[2])
        gagClass.hitSfx.play()
        Sequence(Wait(0.5), Func(splat.cleanup)).start()
        self.hitGag = None

    def d_makeSplat(self, index, pos):
        self.sendUpdate('makeSplat', [index, pos])

    def b_makeSplat(self, index, pos):
        self.d_makeSplat(index, pos)
        self.makeSplat(index, pos)

    def handleGagCollision(self, entry, ent):
        x, y, z = ent.getGag().getPos(render)
        self.b_makeSplat(self.entities.index(ent), [x, y, z])
        if self.isLocal():
            intoNP = entry.getIntoNodePath()
            avNP = intoNP.getParent()
            for key in self.cr.doId2do.keys():
                obj = self.cr.doId2do[key]
                if obj.__class__.__name__ == 'DistributedSuit':
                    if obj.getKey() == avNP.getKey():
                        if obj.getHealth() > 0:
                            obj.sendUpdate('hitByGag', [ent.getID()])
        ent.cleanup()

    def setHealth(self, hp):
        DistributedAvatar.setHealth(self, hp)
        if self.isLocal():
            base.localAvatar.getMyBattle().getTurretManager().updateTurretGui()

    def die(self):
        self.fsm.requestFinalState()
        turretPos = self.cannon.getPos(render)
        self.removeTurret()
        self.explosion = loader.loadModel("phase_3.5/models/props/explosion.bam")
        self.explosion.setScale(0.5)
        self.explosion.reparentTo(render)
        self.explosion.setBillboardPointEye()
        self.explosion.setPos(turretPos + (0, 0, 5))
        sfx = base.audio3d.loadSfx("phase_3.5/audio/sfx/ENC_cogfall_apart.ogg")
        base.audio3d.attachSoundToObject(sfx, self)
        base.playSfx(sfx)
        messenger.send(self.deathEvent)

    def isLocal(self):
        return self.getOwner() == base.localAvatar.doId

    def getDeathEvent(self):
        return self.deathEvent
コード例 #8
0
ファイル: PairingGameCard.py プロジェクト: satire6/Anesidora
class PairingGameCard(PlayingCardNodePath):
    """
    The specifc class used for the pairing game
    """
    DoIntervalDefault = True
    FlipTime = 0.25
    UseDifferentCardColors = True

    # these color values were taken from ToonDNA.py
    CardColors = [
        (0.933594, 0.265625, 0.28125, 1.0),  # bright red
        (0.550781, 0.824219, 0.324219, 1.0),  # light green
        (0.347656, 0.820312, 0.953125, 1.0),  # light blue
        (0.460938, 0.378906, 0.824219, 1.0),  # purple blue
        (0.710938, 0.234375, 0.4375, 1.0),  # plum
        (0.285156, 0.328125, 0.726562, 1.0),  # blue
        (0.242188, 0.742188, 0.515625, 1.0),  # seafoam
        (0.96875, 0.691406, 0.699219, 1.0),  # light pink
        (0.996094, 0.957031, 0.597656, 1.0),  # light yellow
        (0.992188, 0.480469, 0.167969, 1.0),  # orange
    ]

    def __init__(self, value):
        """Constructor, value should be [0..51]."""
        style = PlayingCardGlobals.Styles[0]
        PlayingCardNodePath.__init__(self, style, value)
        self.enterCallback = None
        self.exitCallback = None

    def load(self):
        """Load the assets."""
        # these are just temp assets
        oneCard = loader.loadModel(
            "phase_4/models/minigames/garden_sign_memory")

        # grab the gag icon
        prop = self.attachNewNode('prop')
        PlayingCardGlobals.getImage(self.style, self.suit,
                                    self.rank).copyTo(prop)
        prop.setScale(7)

        # remove the bits we don't want
        oneCard.find('**/glow').removeNode()
        #oneCard.find('**/shadow').removeNode()
        # munge the collision to fit just the sign
        cs = oneCard.find('**/collision')
        #cs.setScale(1, 1.0, 0.5)
        #cs.setPos(0,0, 0.9)
        for solidIndex in range(cs.node().getNumSolids()):
            cs.node().modifySolid(solidIndex).setTangible(False)
        cs.node().setName('cardCollision-%d' % self.value)

        # munge the sign to fit the rank
        sign = oneCard.find('**/sign1')
        if self.UseDifferentCardColors:
            index = self.rank % len(self.CardColors)
            color = self.CardColors[index]
            sign.setColorScale(*color)

        # set up the prop that shows which tree it is
        prop.setPos(0.0, 0.0, 0.08)
        prop.setP(-90)
        prop.reparentTo(oneCard)

        oneCard.reparentTo(self)

        #set up the back of the card
        cardBack = oneCard.find('**/sign2')
        cardBack.setColorScale(0.12, 0.35, 0.5, 1.0)
        cardModel = loader.loadModel('phase_3.5/models/gui/playingCard')
        logo = cardModel.find('**/logo')
        logo.reparentTo(self)
        logo.setScale(0.45)
        logo.setP(90)
        logo.setZ(0.025)
        logo.setX(-0.05)
        logo.setH(180)

        cardModel.remove()

        self.setR(0)  # the default value is face Up
        self.setScale(2.5)

        self.flipIval = None

        self.turnUpSound = base.loadSfx(
            "phase_4/audio/sfx/MG_pairing_card_flip_face_up.mp3")
        self.turnDownSound = base.loadSfx(
            "phase_4/audio/sfx/MG_pairing_card_flip_face_down.mp3")

    def unload(self):
        """Unload the assets."""
        self.clearFlipIval()
        self.removeNode()
        del self.turnUpSound
        del self.turnDownSound

    def turnUp(self, doInterval=DoIntervalDefault):
        """Turn up the card.

        doInterval -- if true do a sound and flip up animation
        
        """
        assert self.value != PlayingCardGlobals.Unknown
        self.faceUp = 1
        if doInterval:
            self.clearFlipIval()
            self.flipIval = Parallel(
                LerpHprInterval(self, self.FlipTime, Vec3(0, 0, 0)),
                SoundInterval(self.turnUpSound,
                              node=self,
                              listenerNode=base.localAvatar,
                              cutOff=240))
            self.flipIval.start()
        else:
            self.setR(0)

    def clearFlipIval(self):
        """Clear any flip intervals on this card."""
        if self.flipIval:
            self.flipIval.finish()
            self.flipIval = None

    def turnDown(self, doInterval=DoIntervalDefault):
        """Turn up the card.

        doInterval -- if true do a sound and flip up animation
        
        """
        self.faceUp = 0
        if doInterval:
            self.clearFlipIval()
            self.flipIval = Parallel(
                LerpHprInterval(self, self.FlipTime, Vec3(0, 0, 180)),
                SoundInterval(self.turnDownSound,
                              node=self,
                              listenerNode=base.localAvatar,
                              cutOff=240))
            self.flipIval.start()
        else:
            self.setR(180)
class DistributedDodgeballGame(DistributedToonFPSGame, TeamMinigame):
    notify = directNotify.newCategory('DistributedDodgeballGame')
    TreeData = [
     [
      'prop_snow_tree_small_ur', Point3(23.23, 66.52, 7.46)],
     [
      'prop_snow_tree_small_ul', Point3(-34.03, 88.02, 24.17)],
     [
      'prop_snow_tree_small_ur', Point3(-54.8, 0, 4.19)],
     [
      'prop_snow_tree_small_ul', Point3(54.8, -5, 4.19)],
     [
      'prop_snow_tree_small_ur', Point3(62.71, 62.66, 16.8)],
     [
      'prop_snow_tree_small_ul', Point3(-23.23, -66.52, 6)],
     [
      'prop_snow_tree_small_ur', Point3(34.03, -88.02, 23)],
     [
      'prop_snow_tree_small_ul', Point3(-62.71, -62.66, 16)]]
    SnowballData = [
     Point3(30, 0, 0.75),
     Point3(22.5, 0, 0.75),
     Point3(15, 0, 0.75),
     Point3(7.5, 0, 0.75),
     Point3(0, 0, 0.75),
     Point3(-7.5, 0, 0.75),
     Point3(-15, 0, 0.75),
     Point3(-22.5, 0, 0.75),
     Point3(-30, 0, 0.75)]
    GameSong = 'phase_4/audio/bgm/MG_Dodgeball.ogg'
    GameDesc = 'Welcome to the north! You have been invited to play dodgeball with the penguins!\n\nHow To Play\nWASD to Move and use the mouse to aim.\nLeft click to Throw!\nThrow a snowball at a teammate to unfreeze them!\n\nObjective\nThe first team to freeze everyone!'
    InitCamTrans = [
     Point3(25, 45, 19.5317), Vec3(154.001, -15, 0)]
    SnowBallDmg = 25
    GetSnowBalls = 'Pick up a snowball from the center!'
    Team2OtherBarrier = {BLUE: 'red_barrier_coll', RED: 'blue_barrier_coll'}

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

        DistributedToonFPSGame.__init__(self, cr)
        TeamMinigame.__init__(self, 'BlueSnow', ('phase_4/maps/db_blue_neutral.png',
                                                 'phase_4/maps/db_blue_hover.png',
                                                 'phase_4/maps/db_blue_hover.png'), 'RedIce', ('phase_4/maps/db_red_neutral.png',
                                                                                               'phase_4/maps/db_red_hover.png',
                                                                                               'phase_4/maps/db_red_hover.png'))
        self.fsm.addState(State('chooseTeam', self.enterChooseTeam, self.exitChooseTeam, ['waitForOthers']))
        self.fsm.addState(State('scrollBy', self.enterScrollBy, self.exitScrollBy, ['countdown']))
        self.fsm.addState(State('countdown', self.enterCountdown, self.exitCountdown, ['play']))
        self.fsm.addState(State('announceGameOver', self.enterAnnGameOver, self.exitAnnGameOver, ['displayWinners']))
        self.fsm.addState(State('displayWinners', self.enterDisplayWinners, self.exitDisplayWinners, ['gameOver']))
        self.fsm.getStateNamed('waitForOthers').addTransition('chooseTeam')
        self.fsm.getStateNamed('waitForOthers').addTransition('scrollBy')
        self.fsm.getStateNamed('play').addTransition('announceGameOver')
        self.firstPerson = DodgeballFirstPerson(self)
        self.scrollBySeq = None
        self.infoText = None
        self.redScoreLbl = None
        self.blueScoreLbl = None
        self.infoText = getAlertText()
        self.spawnPointsByTeam = {BLUE: [
                [
                 Point3(5, 15, 0), Vec3(180, 0, 0)],
                [
                 Point3(15, 15, 0), Vec3(180, 0, 0)],
                [
                 Point3(-5, 15, 0), Vec3(180, 0, 0)],
                [
                 Point3(-15, 15, 0), Vec3(180, 0, 0)]], 
           RED: [
               [
                Point3(5, -15, 0), Vec3(0, 0, 0)],
               [
                Point3(15, -15, 0), Vec3(0, 0, 0)],
               [
                Point3(-5, -15, 0), Vec3(0, 0, 0)],
               [
                Point3(-15, -15, 0), Vec3(0, 0, 0)]]}
        self.winnerMusic = base.loadMusic('phase_9/audio/bgm/encntr_hall_of_fame.mid')
        self.loserMusic = base.loadMusic('phase_9/audio/bgm/encntr_sting_announce.mid')
        self.danceSound = base.loadSfx('phase_3.5/audio/sfx/ENC_Win.ogg')
        self.sky = None
        self.arena = None
        self.fog = None
        self.snow = None
        self.snowRender = None
        self.trees = []
        self.snowballs = []
        return

    def getTeamDNAColor(self, team):
        print 'getTeamDNAColor'
        if team == TEAM1:
            print 'blue'
            return ToonDNA.colorName2DNAcolor['blue']
        if team == TEAM2:
            print 'bright red'
            return ToonDNA.colorName2DNAcolor['bright red']

    def enterDisplayWinners(self):
        base.localAvatar.stopLookAround()
        base.localAvatar.resetHeadHpr()
        base.localAvatar.getGeomNode().show()
        camera.reparentTo(render)
        camera.setPos((-2.5, 12, 3.5))
        camera.setHpr((-175.074, -5.47218, 0))
        base.transitions.fadeIn()
        base.playSfx(self.danceSound, looping=1)
        if self.winnerTeam == self.team:
            base.playMusic(self.winnerMusic, volume=0.8)
        else:
            base.playMusic(self.loserMusic, volume=0.8)
        winnerPositions = [(-2, 0, 0), (2, 0, 0), (6, 0, 0), (-6, 0, 0)]
        loserPositions = [(-3.5, -10, 0), (-1.5, -15, 0), (3.0, -8, 0), (5.5, -12, 0)]
        for team in [RED, BLUE]:
            for avId in self.playerListByTeam[team]:
                av = self.cr.doId2do.get(avId)
                if av:
                    av.stopSmooth()
                    av.setHpr(0, 0, 0)
                    if team == self.winnerTeam:
                        posList = winnerPositions
                        av.setAnimState('off')
                        av.stop()
                        if not self.getRemoteAvatar(avId).isFrozen:
                            av.loop('win')
                    else:
                        posList = loserPositions
                        av.setAnimState('off')
                        av.stop()
                        if not self.getRemoteAvatar(avId).isFrozen:
                            av.loop('pout')
                    pos = random.choice(posList)
                    posList.remove(pos)
                    av.setPos(pos)

        if self.winnerTeam == team:
            text = 'YOU WIN!'
        else:
            text = 'YOU LOSE!'
        self.gameOverLbl.setText(text)
        self.track = Sequence(Wait(2.0), Func(self.gameOverLbl.setScale, 0.01), Func(self.gameOverLbl.show), getAlertPulse(self.gameOverLbl, 0.27, 0.25))
        self.track.start()

    def exitDisplayWinners(self):
        base.transitions.noTransitions()
        self.danceSound.stop()
        if hasattr(self, 'track'):
            self.track.finish()
            self.track = None
        self.gameOverLbl.hide()
        return

    def enterAnnGameOver(self, timeRanOut=0):
        self.firstPerson.vModel.hide()
        text = 'GAME\nOVER'
        if timeRanOut:
            text = "TIME's\nUP"
        self.gameOverLbl.setText(text)
        self.gameOverLbl.show()
        base.transitions.fadeScreen()
        taskMgr.doMethodLater(3.0, self.__annGameOverTask, self.uniqueName('annGameOverTask'))

    def __annGameOverTask(self, task):
        self.gameOverLbl.hide()
        self.ival = Sequence(base.transitions.getFadeOutIval(), Func(self.fsm.request, 'displayWinners'))
        self.ival.start()
        return task.done

    def exitAnnGameOver(self):
        taskMgr.remove(self.uniqueName('annGameOverTask'))
        if hasattr(self, 'ival'):
            self.ival.finish()
            del self.ival
        self.gameOverLbl.hide()

    def teamWon(self, team):
        self.winnerTeam = team
        base.localAvatar.disableAvatarControls()
        self.firstPerson.end()
        self.deleteTimer()
        self.fsm.request('announceGameOver')

    def incrementTeamScore(self, team):
        TeamMinigame.incrementTeamScore(self, team)
        if team == BLUE:
            self.blueScoreLbl.setText('BLUE: ' + str(self.scoreByTeam[team]))
            ToontownIntervals.start(ToontownIntervals.getPulseLargerIval(self.blueScoreLbl, 'blueScorePulse'))
        else:
            if team == RED:
                self.redScoreLbl.setText('RED: ' + str(self.scoreByTeam[team]))
                ToontownIntervals.start(ToontownIntervals.getPulseLargerIval(self.redScoreLbl, 'redScorePulse'))

    def getWinterDodgeballScoreText(self, color):
        text = OnscreenText(fg=color, font=CIGlobals.getMinnieFont(), scale=0.15, shadow=(0,
                                                                                          0,
                                                                                          0,
                                                                                          1))
        return text

    def snowballHitWall(self, snowballIndex):
        snowball = self.snowballs[snowballIndex]
        snowball.handleHitWallOrPlayer()
        base.playSfx(snowball.impactSound, node=snowball, volume=1.5)

    def snowballHitGround(self, snowballIndex):
        snowball = self.snowballs[snowballIndex]
        snowball.handleHitGround()
        base.playSfx(snowball.impactSound, node=snowball, volume=1.5)

    def snowballHitPlayer(self, damagedPlayer, throwerTeam, snowballIndex):
        av = self.getRemoteAvatar(damagedPlayer)
        if av:
            if throwerTeam == av.team:
                if av.unFreeze():
                    if damagedPlayer == base.localAvatar.doId:
                        self.showAlert('A team member has unfroze you!')
                        self.firstPerson.camFSM.request('unfrozen')
                        self.sendUpdate('teamMateUnfrozeMe', [self.team])
            elif av.freeze():
                if damagedPlayer == base.localAvatar.doId:
                    self.showAlert("You've been frozen by an enemy!")
                    self.firstPerson.camFSM.request('frozen')
                    self.sendUpdate('enemyFrozeMe', [self.team, throwerTeam])
        snowball = self.snowballs[snowballIndex]
        snowball.handleHitWallOrPlayer()
        base.playSfx(snowball.impactSound, node=snowball, volume=1.5)

    def playerCaughtSnowball(self, snowballIndex, catcherId):
        av = self.getRemoteAvatar(catcherId)
        if av:
            snowball = self.snowballs[snowballIndex]
            snowball.pauseThrowIval()
            snowball.pickup(av)

    def setupRemoteAvatar(self, avId):
        av = RemoteDodgeballAvatar(self, self.cr, avId)
        if avId == self.cr.localAvId:
            self.myRemoteAvatar = av
        self.remoteAvatars.append(av)

    def __getSnowTree(self, path):
        trees = loader.loadModel('phase_8/models/props/snow_trees.bam')
        tree = trees.find('**/' + path)
        tree.find('**/*shadow*').removeNode()
        return tree

    def load(self):
        self.setMinigameMusic(DistributedDodgeballGame.GameSong)
        self.setDescription(DistributedDodgeballGame.GameDesc)
        self.setWinnerPrize(200)
        self.setLoserPrize(0)
        self.createWorld()
        self.blueScoreLbl = self.getWinterDodgeballScoreText(VBase4(0, 0, 1, 1))
        self.blueScoreLbl.reparentTo(base.a2dTopLeft)
        self.blueScoreLbl['align'] = TextNode.ALeft
        self.blueScoreLbl.setText('Blue: 0')
        self.blueScoreLbl.setZ(-0.17)
        self.blueScoreLbl.setX(0.05)
        self.blueScoreLbl.hide()
        self.redScoreLbl = self.getWinterDodgeballScoreText(VBase4(1, 0, 0, 1))
        self.redScoreLbl.reparentTo(base.a2dTopLeft)
        self.redScoreLbl['align'] = TextNode.ALeft
        self.redScoreLbl.setText('Red: 0')
        self.redScoreLbl.setZ(-0.35)
        self.redScoreLbl.setX(0.05)
        self.redScoreLbl.hide()
        trans = DistributedDodgeballGame.InitCamTrans
        camera.setPos(trans[0])
        camera.setHpr(trans[1])
        DistributedToonFPSGame.load(self)

    def createWorld(self):
        self.deleteWorld()
        self.sky = loader.loadModel('phase_3.5/models/props/BR_sky.bam')
        self.sky.reparentTo(render)
        self.sky.setZ(-40)
        self.sky.setFogOff()
        self.arena = loader.loadModel('phase_4/models/minigames/dodgeball_arena.egg')
        self.arena.reparentTo(render)
        self.arena.setScale(0.75)
        self.arena.find('**/team_divider').setBin('ground', 18)
        self.arena.find('**/floor').setBin('ground', 18)
        self.arena.find('**/team_divider_coll').setCollideMask(CIGlobals.FloorBitmask)
        for data in DistributedDodgeballGame.TreeData:
            code = data[0]
            pos = data[1]
            tree = self.__getSnowTree(code)
            tree.reparentTo(self.arena)
            tree.setPos(pos)
            self.trees.append(tree)

        for i in xrange(len(DistributedDodgeballGame.SnowballData)):
            snowdata = DistributedDodgeballGame.SnowballData[i]
            snowball = Snowball(self, i)
            snowball.load()
            snowball.reparentTo(render)
            snowball.setPos(snowdata)
            self.snowballs.append(snowball)

        self.snow = ParticleLoader.loadParticleEffect('phase_8/etc/snowdisk.ptf')
        self.snow.setPos(0, 0, 5)
        self.snowRender = self.arena.attachNewNode('snowRender')
        self.snowRender.setDepthWrite(0)
        self.snowRender.setBin('fixed', 1)
        self.snow.start(camera, self.snowRender)
        self.fog = Fog('snowFog')
        self.fog.setColor(0.486, 0.784, 1)
        self.fog.setExpDensity(0.003)
        render.setFog(self.fog)

    def throw(self, snowballIndex, p):
        snowball = self.snowballs[snowballIndex]
        snowball.throw(p)

    def snowballPickup(self, snowballIndex, pickerUpperAvId):
        remoteAv = self.getRemoteAvatar(pickerUpperAvId)
        if remoteAv:
            snowball = self.snowballs[snowballIndex]
            snowball.pickup(remoteAv)

    def deleteWorld(self):
        if self.redScoreLbl:
            self.redScoreLbl.destroy()
            self.redScoreLbl = None
        if self.blueScoreLbl:
            self.blueScoreLbl.destroy()
            self.blueScoreLbl = None
        for snowball in self.snowballs:
            snowball.removeNode()

        self.snowballs = []
        for tree in self.trees:
            tree.removeNode()

        self.trees = []
        if self.snow:
            self.snow.cleanup()
            self.snow = None
        if self.snowRender:
            self.snowRender.removeNode()
            self.snowRender = None
        self.fog = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.arena:
            self.arena.removeNode()
            self.arena = None
        render.clearFog()
        return

    def enterPlay(self):
        self.createTimer()
        self.redScoreLbl.show()
        self.blueScoreLbl.show()
        self.firstPerson.camFSM.request('unfrozen')
        self.arena.find('**/' + self.Team2OtherBarrier[self.team]).stash()

    def exitPlay(self):
        self.firstPerson.crosshair.destroy()
        self.firstPerson.crosshair = None
        self.firstPerson.camFSM.request('off')
        DistributedToonFPSGame.exitPlay(self)
        return

    def enterCountdown(self):
        self.firstPerson.start()
        self.firstPerson.disableMouse()
        self.infoText.setText(DistributedDodgeballGame.GetSnowBalls)
        self.countdownText = getGameText()
        self.countdownIval = Parallel(Sequence(Func(self.countdownText.setText, '5'), getCountdownIval(self.countdownText), Func(self.countdownText.setText, '4'), getCountdownIval(self.countdownText), Func(self.countdownText.setText, '3'), getCountdownIval(self.countdownText), Func(self.countdownText.setText, '2'), getCountdownIval(self.countdownText), Func(self.countdownText.setText, '1'), getCountdownIval(self.countdownText)), getAlertPulse(self.infoText), name='COUNTDOWNIVAL')
        self.countdownIval.setDoneEvent(self.countdownIval.getName())
        self.acceptOnce(self.countdownIval.getDoneEvent(), self.__handleCountdownDone)
        self.countdownIval.start()

    def __handleCountdownDone(self):
        self.fsm.request('play')

    def exitCountdown(self):
        if hasattr(self, 'countdownText'):
            self.countdownText.destroy()
            del self.countdownText
        if hasattr(self, 'countdownIval'):
            self.ignore(self.countdownIval.getDoneEvent())
            self.countdownIval.finish()
            del self.countdownIval

    def enterScrollBy(self):
        BLUE_START_POS = Point3(-20, 0, 4)
        BLUE_END_POS = Point3(20, 0, 4)
        BLUE_HPR = Vec3(0, 0, 0)
        RED_START_POS = Point3(20, 0, 4)
        RED_END_POS = Point3(-20, 0, 4)
        RED_HPR = Vec3(180, 0, 0)
        self.playMinigameMusic()
        self.scrollBySeq = Sequence(Func(camera.setHpr, BLUE_HPR), LerpPosInterval(camera, duration=5.0, pos=BLUE_END_POS, startPos=BLUE_START_POS, blendType='easeOut'), Func(base.transitions.fadeOut, 0.4), Wait(0.5), Func(base.transitions.fadeIn, 0.4), Func(camera.setHpr, RED_HPR), LerpPosInterval(camera, duration=5.0, pos=RED_END_POS, startPos=RED_START_POS, blendType='easeOut'), name='SCROLLBYSEQ')
        self.scrollBySeq.setDoneEvent(self.scrollBySeq.getName())
        self.acceptOnce(self.scrollBySeq.getDoneEvent(), self.__handleScrollByDone)
        self.scrollBySeq.start()

    def __handleScrollByDone(self):
        self.fsm.request('countdown')

    def exitScrollBy(self):
        if self.scrollBySeq:
            self.ignore(self.scrollBySeq.getDoneEvent())
            self.scrollBySeq.finish()
            self.scrollBySeq = None
        return

    def allPlayersReady(self):
        self.fsm.request('scrollBy')

    def chooseUrTeam(self):
        self.fsm.request('chooseTeam')

    def enterChooseTeam(self):
        self.makeSelectionGUI()

    def acceptedIntoTeam(self, spawnPoint):
        TeamMinigame.acceptedIntoTeam(self)
        self.sendUpdate('readyToStart')
        self.fsm.request('waitForOthers')
        pos, hpr = self.spawnPointsByTeam[self.team][spawnPoint]
        base.localAvatar.setPos(pos)
        base.localAvatar.setHpr(hpr)

    def exitChooseTeam(self):
        self.destroySelectionGUI()

    def announceGenerate(self):
        DistributedToonFPSGame.announceGenerate(self)
        base.camLens.setMinFov(CIGlobals.GunGameFOV / (4.0 / 3.0))
        self.load()

    def disable(self):
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4.0 / 3.0))
        self.fsm.requestFinalState()
        self.deleteWorld()
        self.trees = None
        self.snowballs = None
        self.spawnPointsByTeam = None
        if self.firstPerson:
            self.firstPerson.reallyEnd()
            self.firstPerson.cleanup()
            self.firstPerson = None
        self.scrollBySeq = None
        self.winnerMusic = None
        self.loserMusic = None
        self.danceSound = None
        self.infoText = None
        base.localAvatar.setWalkSpeedNormal()
        DistributedToonFPSGame.disable(self)
        return
コード例 #10
0
class Suit(Avatar):
    notify = directNotify.newCategory('Suit')
    audio3d = Audio3DManager(base.sfxManagerList[0], camera)
    audio3d.setDistanceFactor(25)
    audio3d.setDropOffFactor(audio3d.getDistanceFactor() / 1000)

    def __init__(self):
        Avatar.__init__(self)
        self.dept = None
        self.suit = None
        self.head = None
        self.headModel = None
        self.variant = None
        self.handColor = None
        self.voice = None
        self.chat = None
        self.chatDial = None
        self.shadow = None
        self.propeller = None
        self.smallExp = None
        self.largeExp = None
        self.explosion = None
        self.hasSpawned = False
        self.suitTrack = None
        self.timestampAnimTrack = None
        self.propellerSounds = {}
        self.healthBar = None
        self.healthBarGlow = None
        self.condition = 0
        self.avatarType = CIGlobals.Suit
        self.suitPlan = None
        self.animFSM = ClassicFSM('Suit', [
            State('off', self.enterOff, self.exitOff),
            State('neutral', self.enterNeutral, self.exitNeutral),
            State('walk', self.enterWalk, self.exitWalk),
            State('die', self.enterDie, self.exitDie),
            State('win', self.enterWin, self.exitWin),
            State('attack', self.enterAttack, self.exitAttack),
            State('flail', self.enterFlail, self.exitFlail),
            State('flyDown', self.enterFlyDown, self.exitFlyDown),
            State('flyAway', self.enterFlyAway, self.exitFlyAway),
            State('flyNeutral', self.enterFlyNeutral, self.exitFlyNeutral),
            State('trayWalk', self.enterTrayWalk, self.exitTrayWalk),
            State('trayNeutral', self.enterTrayNeutral, self.exitTrayNeutral)
        ], 'off', 'off')
        self.animFSM.enterInitialState()
        self.initializeBodyCollisions()

    def getNametagJoints(self):
        return []

    # BEGIN STATES

    def enterOff(self, ts=0):
        self.anim = None
        return

    def exitOff(self):
        pass

    def exitGeneral(self):
        self.stop()

    def enterTrayWalk(self, ts=0):
        self.show()
        self.loop('tray-walk')

    def exitTrayWalk(self):
        self.exitGeneral()

    def enterTrayNeutral(self, ts=0):
        self.loop('tray-neutral')

    def exitTrayNeutral(self):
        self.stop()

    def enterNeutral(self, ts=0):
        self.show()
        self.loop("neutral")

    def exitNeutral(self):
        self.exitTimestampAnimTrack()
        self.exitGeneral()

    def enterWalk(self, ts=0):
        self.show()
        self.loop("walk")
        self.disableShadowRay()

    def exitWalk(self):
        self.exitTimestampAnimTrack()
        self.exitGeneral()
        self.enableShadowRay()

    def enterFlail(self, ts=0):
        self.pingpong('flail', fromFrame=30, toFrame=35)

    def exitFlail(self):
        self.stop()

    def exitTimestampAnimTrack(self):
        if self.timestampAnimTrack:
            self.timestampAnimTrack.pause()
            self.timestampAnimTrack = None

    def enterAttack(self, attack, target, ts=0):
        self.show()

        if hasattr(self, 'uniqueName'):
            doneEvent = self.uniqueName('suitAttackDone')
        else:
            doneEvent = 'suitAttackDone'
        self.suitAttackState = SuitAttacks(doneEvent, self, target)
        self.suitAttackState.load(attack)
        self.suitAttackState.enter(ts)
        self.headsUp(target)
        self.acceptOnce(doneEvent, self.handleSuitAttackDone)

    def handleSuitAttackDone(self):
        self.exitAttack()

    def exitAttack(self):
        if hasattr(self, 'uniqueName'):
            self.ignore(self.uniqueName('suitAttackDone'))
        else:
            self.ignore('suitAttackDone')
        if hasattr(self, 'suitAttackState'):
            self.suitAttackState.exit()
        if hasattr(self, 'suitAttackState'):
            self.suitAttackState.unload()
        if hasattr(self, 'suitAttackState'):
            del self.suitAttackState

    def interruptAttack(self):
        if hasattr(self, 'suitAttackState'):
            self.suitAttackState.currentAttack.interruptAttack()
            self.clearChatbox()

    def handleWeaponTouch(self):
        if hasattr(self, 'suitAttackState'):
            currentAttack = self.suitAttackState.currentAttack
            if hasattr(currentAttack, 'handleWeaponTouch'):
                currentAttack.handleWeaponTouch()

    def enterFlyNeutral(self, ts=0):
        self.disableRay()
        if not self.propeller:
            self.generatePropeller()
        sfx = self.propellerSounds['neutral']
        sfx.setLoop(True)
        base.playSfx(sfx, node=self)
        self.propeller.loop('chan', fromFrame=0, toFrame=3)
        self.setPlayRate(0.8, 'land')
        self.pingpong('land', fromFrame=0, toFrame=10)

    def exitFlyNeutral(self):
        self.cleanupPropeller()

    def enterFlyDown(self, ts=0):
        self.disableRay()
        if not self.propeller:
            self.generatePropeller()
        sfx = self.propellerSounds['in']
        base.playSfx(sfx, node=self)
        groundF = 28
        dur = self.getDuration('land')
        fr = self.getFrameRate('land')
        if fr:
            animTimeInAir = groundF / fr
        else:
            animTimeInAir = groundF
        impactLength = dur - animTimeInAir
        timeTillLanding = 6.5 - impactLength
        waitTime = timeTillLanding - animTimeInAir
        lastSpinFrame = 8
        propDur = self.propeller.getDuration('chan')
        fr = self.propeller.getFrameRate('chan')
        spinTime = lastSpinFrame / fr
        openTime = (lastSpinFrame + 1) / fr
        if hasattr(self, 'uniqueName'):
            name = self.uniqueName('enterFlyDown')
        else:
            name = 'enterFlyDown'
        animTrack = Sequence(Func(self.pose, 'land', 0), Wait(waitTime),
                             ActorInterval(self, 'land', duration=dur))
        propTrack = Parallel(
            SoundInterval(sfx, duration=waitTime + dur, node=self),
            Sequence(
                ActorInterval(self.propeller,
                              'chan',
                              constrainedLoop=1,
                              duration=waitTime + spinTime,
                              startTime=0.0,
                              endTime=spinTime),
                ActorInterval(self.propeller,
                              'chan',
                              duration=propDur - openTime,
                              startTime=openTime)))
        self.suitTrack = Parallel(animTrack,
                                  propTrack,
                                  name=self.taskName('flyDown'))
        if not self.hasSpawned:
            self.show()
            fadeInTrack = Sequence(
                Func(self.setTransparency, 1),
                self.colorScaleInterval(1,
                                        colorScale=VBase4(1, 1, 1, 1),
                                        startColorScale=VBase4(1, 1, 1, 0)),
                Func(self.clearColorScale), Func(self.clearTransparency))
            self.hasSpawned = True
            self.suitTrack.append(fadeInTrack)
        self.suitTrack.setDoneEvent(self.suitTrack.getName())
        self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyDown)
        self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name)
        self.suitTrack.start(ts)

    def exitFlyDown(self):
        self.initializeRay(self.avatarType, 2)
        if self.suitTrack != None:
            self.ignore(self.suitTrack.getDoneEvent())
            self.suitTrack.finish()
            DelayDelete.cleanupDelayDeletes(self.suitTrack)
            self.suitTrack = None
        self.exitGeneral()
        self.cleanupPropeller()

    def enterFlyAway(self, ts=0, doFadeOut=0):
        self.show()
        if not self.propeller:
            self.generatePropeller()
        sfx = self.propellerSounds['out']
        if hasattr(self, 'uniqueName'):
            name = self.uniqueName('enterFlyAway')
        else:
            name = 'enterFlyAway'
        dur = self.getDuration('land')
        actInt = ActorInterval(self,
                               'land',
                               loop=0,
                               startTime=dur,
                               endTime=0.0)
        lastSpinFrame = 8
        propDur = self.propeller.getDuration('chan')
        fr = self.propeller.getFrameRate('chan')
        spinTime = lastSpinFrame / fr
        openTime = (lastSpinFrame + 1) / fr
        propTrack = Parallel(
            SoundInterval(sfx, node=self),
            Sequence(
                Func(self.propeller.show),
                ActorInterval(self.propeller,
                              'chan',
                              endTime=openTime,
                              startTime=propDur),
                ActorInterval(self.propeller,
                              'chan',
                              constrainedLoop=1,
                              duration=propDur - openTime,
                              startTime=spinTime,
                              endTime=0.0)))
        self.suitTrack = Parallel(actInt,
                                  propTrack,
                                  name=self.taskName('trackName'))
        if doFadeOut:
            fadeOut = Sequence(
                Wait(4.0), Func(self.setTransparency, 1),
                self.colorScaleInterval(1,
                                        colorScale=VBase4(1, 1, 1, 0),
                                        startColorScale=VBase4(1, 1, 1, 1)),
                Func(self.clearColorScale), Func(self.clearTransparency),
                Func(self.reparentTo, hidden))
            self.suitTrack.append(fadeOut)
        self.suitTrack.setDoneEvent(self.suitTrack.getName())
        self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyAway)
        self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name)
        self.suitTrack.start(ts)
        self.disableRay()

    def exitFlyAway(self):
        if self.suitTrack:
            self.ignore(self.suitTrack.getDoneEvent())
            self.suitTrack.finish()
            DelayDelete.cleanupDelayDeletes(self.suitTrack)
            self.suitTrack = None
        self.cleanupPropeller()
        self.exitGeneral()

    def enterDie(self, ts=0):
        self.show()
        self.generateCog(isLose=1)
        self.nametag.clearChatText()
        self.deleteNameTag()
        deathSound = base.audio3d.loadSfx(
            "phase_3.5/audio/sfx/Cog_Death_Full.ogg")
        base.audio3d.attachSoundToObject(deathSound, self)
        trackName = self.uniqueName('enterDie')

        smallGears = ParticleLoader.loadParticleEffect(
            'phase_3.5/etc/gearExplosionSmall.ptf')
        smallGears.getParticlesNamed('particles-1').setPoolSize(30)

        singleGear = ParticleLoader.loadParticleEffect(
            'phase_3.5/etc/gearExplosion.ptf')
        singleGear.getParticlesNamed('particles-1').setPoolSize(1)

        smallGearExplosion = ParticleLoader.loadParticleEffect(
            'phase_3.5/etc/gearExplosion.ptf')
        smallGearExplosion.getParticlesNamed('particles-1').setPoolSize(10)

        bigGearExplosion = ParticleLoader.loadParticleEffect(
            'phase_3.5/etc/gearExplosionBig.ptf')
        bigGearExplosion.getParticlesNamed('particles-1').setPoolSize(30)

        smallGears.setDepthWrite(False)
        singleGear.setDepthWrite(False)
        smallGearExplosion.setDepthWrite(False)
        bigGearExplosion.setDepthWrite(False)

        self.smallGears = smallGears
        self.smallGears.setPos(self.find('**/joint_head').getPos() + (0, 0, 2))
        self.singleGear = singleGear
        self.smallGearExp = smallGearExplosion
        self.bigGearExp = bigGearExplosion

        gearTrack = Sequence(Wait(0.7), Func(self.doSingleGear), Wait(1.5),
                             Func(self.doSmallGears), Wait(3.0),
                             Func(self.doBigExp))
        self.suitTrack = Parallel(Sequence(
            Wait(0.8),
            SoundInterval(deathSound,
                          node=self,
                          duration=deathSound.length() / 2)),
                                  Sequence(Wait(0.7), Func(self.doSingleGear),
                                           Wait(4.3), Func(self.suitExplode),
                                           Wait(1.0),
                                           Func(self.disableBodyCollisions),
                                           Func(self.__cleanupExplosion)),
                                  gearTrack,
                                  Sequence(
                                      ActorInterval(self, 'lose', duration=6),
                                      Func(self.getGeomNode().hide)),
                                  name=trackName)
        self.suitTrack.setDoneEvent(self.suitTrack.getName())
        self.acceptOnce(self.suitTrack.getName(), self.exitDie)
        self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, trackName)
        self.suitTrack.start(ts)
        del deathSound

    def doSingleGear(self):
        self.singleGear.start(self.getGeomNode())

    def doSmallGears(self):
        self.smallGears.start(self.getGeomNode())

    def doSmallExp(self):
        self.smallGearExp.start(self.getGeomNode())

    def doBigExp(self):
        self.bigGearExp.start(self.getGeomNode())

    def suitExplode(self):
        self.explosion = loader.loadModel(
            'phase_3.5/models/props/explosion.bam')
        self.explosion.setScale(0.5)
        self.explosion.reparentTo(render)
        self.explosion.setBillboardPointEye()
        if self.variant == Variant.SKELETON:
            self.explosion.setPos(
                self.getPart('body').find('**/joint_head').getPos(render) +
                (0, 0, 2))
        else:
            self.explosion.setPos(self.headModel.getPos(render) + (0, 0, 2))

    def __cleanupExplosion(self):
        if self.explosion:
            self.explosion.removeNode()
            self.explosion = None

    def exitDie(self):
        if self.suitTrack != None:
            self.ignore(self.suitTrack.getName())
            self.suitTrack.finish()
            DelayDelete.cleanupDelayDeletes(self.suitTrack)
            self.suitTrack = None
        if hasattr(self, 'singleGear'):
            self.singleGear.cleanup()
            del self.singleGear
        if hasattr(self, 'smallGears'):
            self.smallGears.cleanup()
            del self.smallGears
        if hasattr(self, 'smallGearExp'):
            self.smallGearExp.cleanup()
            del self.smallGearExp
        if hasattr(self, 'bigGearExp'):
            self.bigGearExp.cleanup()
            del self.bigGearExp
        self.__cleanupExplosion()

    def enterWin(self, ts=0):
        self.play('win')

    def exitWin(self):
        self.exitGeneral()

    # END STATES

    def generate(self, suitPlan, variant, voice=None, hideFirst=True):
        self.suitPlan = suitPlan
        self.suit = suitPlan.getSuitType()
        self.head = suitPlan.getHead()
        self.dept = suitPlan.getDept()
        self.handColor = suitPlan.getHandColor()
        self.variant = variant
        self.setVoice(voice)
        self.generateCog()
        if hideFirst:
            self.hide()

    def __blinkRed(self, task):
        self.healthBar.setColor(SuitGlobals.healthColors[3], 1)
        self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[3], 1)
        if self.condition == 5:
            self.healthBar.setScale(1.17)
        return Task.done

    def __blinkGray(self, task):
        if not self.healthBar:
            return
        self.healthBar.setColor(SuitGlobals.healthColors[4], 1)
        self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[4], 1)
        if self.condition == 5:
            self.healthBar.setScale(1.0)
        return Task.done

    def generateHealthBar(self):
        self.removeHealthBar()
        button = loader.loadModel('phase_3.5/models/gui/matching_game_gui.bam'
                                  ).find('**/minnieCircle')
        button.setScale(3.0)
        button.setH(180)
        button.setColor(SuitGlobals.healthColors[0])
        chestNull = self.find('**/def_joint_attachMeter')
        if chestNull.isEmpty():
            chestNull = self.find('**/joint_attachMeter')
        button.reparentTo(chestNull)
        self.healthBar = button
        self.healthBarGlow = loader.loadModel(
            'phase_3.5/models/props/glow.bam')
        self.healthBarGlow.reparentTo(self.healthBar)
        self.healthBarGlow.setScale(0.28)
        self.healthBarGlow.setPos(-0.005, 0.01, 0.015)
        self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[0])
        button.flattenLight()
        self.condition = 0
        if hasattr(self, 'getHealth'):
            self.updateHealthBar(self.getHealth())

    def updateHealthBar(self, hp):
        if not self.healthBar:
            return
        if hp > self.health:
            self.health = hp
        health = 0.0
        try:
            health = float(hp) / float(self.maxHealth)
        except:
            pass
        if health > 0.95:
            condition = 0
        elif health > 0.7:
            condition = 1
        elif health > 0.3:
            condition = 2
        elif health > 0.05:
            condition = 3
        elif health > 0.0:
            condition = 4
        else:
            condition = 5
        if self.condition != condition:
            if condition == 4:
                blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75),
                                      Task(self.__blinkGray), Task.pause(0.1))
                taskMgr.add(blinkTask, self.taskName('blink-task'))
            elif condition == 5:
                if self.condition == 4:
                    taskMgr.remove(self.taskName('blink-task'))
                blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25),
                                      Task(self.__blinkGray), Task.pause(0.1))
                taskMgr.add(blinkTask, self.taskName('blink-task'))
            else:
                self.healthBar.setColor(SuitGlobals.healthColors[condition], 1)
                self.healthBarGlow.setColor(
                    SuitGlobals.healthGlowColors[condition], 1)
            self.condition = condition

    def removeHealthBar(self):
        if self.healthBar:
            self.healthBar.removeNode()
            self.healthBar = None
        if self.condition == 4 or self.condition == 5:
            taskMgr.remove(self.taskName('blink-task'))
        self.healthCondition = 0
        return

    def initializeLocalCollisions(self, name):
        self.notify.info('Initializing Local Collisions!')
        Avatar.initializeLocalCollisions(self, 1, 3, name)

    def initializeBodyCollisions(self):
        self.notify.info('Initializing Body Collisions!')
        Avatar.initializeBodyCollisions(self, self.avatarType, 6, 2)
        self.initializeRay(self.avatarType, 2)

    def hideSuit(self):
        self.hide()

    def showSuit(self):
        self.show()
        fadeIn = Sequence(
            Func(self.setTransparency, 1),
            self.colorScaleInterval(0.6,
                                    colorScale=Vec4(1, 1, 1, 1),
                                    startColorScale=Vec4(1, 1, 1, 0)),
            Func(self.clearColorScale), Func(self.clearTransparency),
            Func(self.reparentTo, render))
        fadeIn.start()

    def generateCog(self, isLose=0):
        self.cleanup()
        if not isLose:
            if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE:
                self.loadModel(
                    'phase_5/models/char/cog%s_robot-zero.bam' %
                    (str(self.suit)), 'body')
            else:
                self.loadModel(
                    'phase_3.5/models/char/suit%s-mod.bam' % (str(self.suit)),
                    'body')
            animations = SuitGlobals.animations
            anims = {}
            for anim in animations:
                if not self.suit in anim.getSuitTypes():
                    continue
                path = 'phase_%s/models/char/suit%s-%s.bam' % (
                    anim.getPhase(), self.suit, anim.getFile())
                anims[anim.getName()] = path
            self.loadAnims(anims, 'body')
            self.generateHealthBar()
            self.generatePropeller()
        else:
            if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE:
                self.loadModel(
                    'phase_5/models/char/cog%s_robot-lose-mod.bam' %
                    (str(self.suit)), 'body')
            else:
                self.loadModel(
                    'phase_4/models/char/suit%s-lose-mod.bam' %
                    (str(self.suit)), 'body')
            self.loadAnims(
                {
                    'lose':
                    'phase_4/models/char/suit%s-lose.bam' % (str(self.suit))
                }, 'body')
        if self.variant != Variant.SKELETON:
            self.headModel = self.head.generate()
            self.headModel.reparentTo(self.find('**/joint_head'))
        if self.suitPlan.getName() == SuitGlobals.VicePresident:
            self.headModel.setScale(0.35)
            self.headModel.setHpr(270, 0, 270)
            self.headModel.setZ(-0.10)
            self.headModel.loop('neutral')
        self.setClothes()
        self.setAvatarScale(self.suitPlan.getScale() /
                            SuitGlobals.scaleFactors[self.suit])
        self.setHeight(self.suitPlan.getHeight())
        self.setupNameTag()
        Avatar.initShadow(self)

    def cleanup(self):
        self.cleanupPropeller()
        self.clearChatbox()
        if self.shadow:
            self.deleteShadow()
        if self.getPart('body'):
            self.removePart('body')
        if self.headModel:
            self.headModel.removeNode()
            self.headModel = None
        self.timestampAnimTrack = None

    def generatePropeller(self):
        self.cleanupPropeller()
        self.propeller = Actor(
            'phase_4/models/props/propeller-mod.bam',
            {'chan': 'phase_4/models/props/propeller-chan.bam'})
        self.propeller.reparentTo(self.find('**/joint_head'))
        self.propellerSounds['in'] = self.audio3d.loadSfx(
            SuitGlobals.propellerInSfx)
        self.propellerSounds['out'] = self.audio3d.loadSfx(
            SuitGlobals.propellerOutSfx)
        self.propellerSounds['neutral'] = self.audio3d.loadSfx(
            SuitGlobals.propellerNeutSfx)
        for sound in self.propellerSounds.values():
            self.audio3d.attachSoundToObject(sound, self.propeller)

    def cleanupPropeller(self):
        for sound in self.propellerSounds.values():
            self.audio3d.detachSound(sound)
            sound.stop()
        self.propellerSounds = {}
        if self.propeller:
            self.propeller.cleanup()
            self.propeller = None

    def setVoice(self, voice):
        if not voice:
            if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE:
                self.voice = Voice.SKELETON
            else:
                self.voice = Voice.NORMAL
        else:
            self.voice = voice

    def setClothes(self):
        if self.variant == Variant.SKELETON:
            parts = self.findAllMatches('**/pPlane*')
            for partNum in range(0, parts.getNumPaths()):
                bb = parts.getPath(partNum)
                bb.setTwoSided(1)
            tie = loader.loadTexture('phase_5/maps/cog_robot_tie_%s.jpg' %
                                     self.dept.getTie())
            tie.setMinfilter(Texture.FTLinearMipmapLinear)
            tie.setMagfilter(Texture.FTLinear)
            self.find('**/tie').setTexture(tie, 1)
        else:
            prefix = 'phase_3.5/maps/' + self.dept.getClothingPrefix(
            ) + '_%s.jpg'
            if self.variant == Variant.WAITER:
                prefix = 'phase_3.5/maps/waiter_m_%s.jpg'
            self.find('**/legs').setTexture(loader.loadTexture(prefix % 'leg'),
                                            1)
            self.find('**/arms').setTexture(
                loader.loadTexture(prefix % 'sleeve'), 1)
            self.find('**/torso').setTexture(
                loader.loadTexture(prefix % 'blazer'), 1)
            self.find('**/hands').setColor(self.handColor)

    def setName(self, nameString, charName):
        Avatar.setName(self,
                       nameString,
                       avatarType=self.avatarType,
                       charName=charName,
                       createNow=1)

    def setupNameTag(self, tempName=None):
        Avatar.setupNameTag(self, tempName=tempName)
        if self.nametag:
            if self.level > 0:
                self.nametag.setText(self.nametag.getText() +
                                     '\n%s\nLevel %s' %
                                     (self.dept.getName(), self.level))
            else:
                self.nametag.setText(self.nametag.getText() + '\n%s' %
                                     (self.dept.getName()))

    def setChat(self, chat):
        self.clearChatbox()
        Avatar.setChat(self, chat)
        self.chat = chat
        chatDial = None
        questionDial = self.voice.getSoundFile('question')
        question02Dial = None
        gruntDial = self.voice.getSoundFile('grunt')
        statementDial = self.voice.getSoundFile('statement')
        if self.voice == Voice.NORMAL:
            question02Dial = self.voice.getSoundFile('question_2')

        if '!' in self.chat:
            chatDial = self.audio3d.loadSfx(gruntDial)
        elif '?' in self.chat:
            questionDials = [questionDial]
            if self.voice == Voice.NORMAL:
                questionDials.append(question02Dial)
            chatDial = self.audio3d.loadSfx(random.choice(questionDials))
        else:
            chatDial = self.audio3d.loadSfx(statementDial)
        self.chatDial = chatDial

        if self.variant == Variant.SKELETON:
            self.audio3d.attachSoundToObject(self.chatDial, self)
        else:
            self.audio3d.attachSoundToObject(self.chatDial, self.headModel)
        base.playSfx(self.chatDial, node=self)

    def clearChatbox(self):
        self.clearChat()
        self.chat = None
        if self.chatDial:
            self.chatDial.stop()
            self.chatDial = None

    def getDept(self):
        return self.dept

    def getVariant(self):
        return self.variant

    def disable(self):
        if self.suitTrack:
            self.suitTrack.finish()
            DelayDelete.cleanupDelayDeletes(self.suitTrack)
            self.suitTrack = None
        self.animFSM.requestFinalState()
        self.cleanup()
        Avatar.disable(self)

    def delete(self):
        Avatar.delete(self)
        self.cleanup()
コード例 #11
0
class DistributedTutorial(DistributedObject):
    notify = directNotify.newCategory('DistributedTutorial')
    GUIDE_NAME = 'Professor Prepostera'
    GUIDE_START_POS = (5, 10, -0.5)
    GUIDE_WATCH_POS = (12.4, 27.92, 0)
    GUIDE_WATCH_HPR = (41.63, 0, 0)
    GUIDE_INTRO_SPEECH = ['Hey, looks like you made it!',
     'So, welcome to OToontown.',
     'OToontown is short for Old Toontown, or Toontown from the past.',
     'Not long ago, Toons used to live present day Toontown.',
     'Unfortunately, the Cogs planned a mega-invasion that was sure to be a complete takeover of Toontown and make all Toons go sad for good.',
     "There was no way we could have let that happen, so we built a time machine, and sent every Toon back in time to OToontown, where Cogs didn't exist yet.",
     'The Cogs completely took over present day Toontown, and turned it into what they wanted it to be - a business metropolis.',
     'Toons happily live and play in OToontown now, but we want to learn about present day Toontown...',
     ' ...or as we now call it, CogTropolis.',
     "We've built time machines that send Toons back to CogTropolis to fight Cogs and to see what the Cogs have done.",
     "We know that the Cogs took over Toontown and turned it into a grey business city, but we don't know how they did it.",
     'Shopkeepers around OToontown will reward you for finding evidence that may help solve the mystery of how the Cogs turned Toontown into CogTropolis.',
     'Before you are able to head to CogTropolis, you need to be trained for battle.',
     'The Cogs have become much more skilled battlers and no longer wait for you to throw a gag before attacking you.',
     'This is much more difficult for Toons, and it may take some time to get used to.',
     "I'm going to give you 4 gags to start...",
     'A Toon-Up megaphone, a cupcake, a fruit pie slice, and a cream pie slice.',
     'Equip Gags in your loadout to use by pressing the corresponding key on your keyboard.',
     'You can use or throw the Gag that you have equipped by pressing the Delete key...',
     ' ...or by pressing the Throw Gag button at the top of your screen.',
     'Also, use the Arrow Keys on your keyboard to move, and press CTRL to jump.',
     "I'm going to summon one of our dummy bots for you to practice battling.",
     "Click your mouse when you're ready."]
    GUIDE_PT2_INFO = ["Now it'll get a tad bit tougher.",
     'This next dummy bot will be walking around.',
     'This will test your aiming skills.',
     "Click your mouse when you're ready."]
    GUIDE_PT3_INFO = ['This final dummy bot will walk around and try to attack you at times.', 'Defeat this Cog, and you should be ready to go.']
    GUIDE_DONE = ['Wow, you did great!', "You're definitely ready for battle in CogTropolis.", 'Click your mouse to head to OToontown.']
    GUIDE_START_TRAINING = "Alright! Let's do this!"

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.fsm = ClassicFSM.ClassicFSM('TutorialFSM', [State.State('off', self.enterOff, self.exitOff),
         State.State('newPlayerEmerge', self.enterPlayerEmerge, self.exitPlayerEmerge, ['off', 'introSpeech']),
         State.State('introSpeech', self.enterGuideIntroSpeech, self.exitGuideIntroSpeech, ['off', 'introSpeech2Training']),
         State.State('introSpeech2Training', self.enterIntroSpeech2Training, self.exitIntroSpeech2Training, ['off', 'training1']),
         State.State('training1', self.enterTrainingPT1, self.exitTrainingPT1, ['off', 'training2info']),
         State.State('training2info', self.enterTraining2Info, self.exitTraining2Info, ['off', 'training2']),
         State.State('training2', self.enterTrainingPT2, self.exitTrainingPT2, ['off', 'training3info']),
         State.State('training3info', self.enterTraining3Info, self.exitTraining3Info, ['off', 'training3']),
         State.State('training3', self.enterTrainingPT3, self.exitTrainingPT3, ['off', 'trainingDone']),
         State.State('trainingDone', self.enterTrainingDone, self.exitTrainingDone, ['off', 'leaveTutorial']),
         State.State('leaveTutorial', self.enterLeaveTutorial, self.exitLeaveTutorial, ['off'])], 'off', 'off')
        self.fsm.enterInitialState()
        self.dnaStore = DNAStorage()
        self.streetGeom = None
        self.sky = None
        self.skyUtil = SkyUtil()
        self.guide = None
        self.music = None
        self.battleMusic = None
        self.playerCamPos = None
        self.playerCamHpr = None
        return

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def introStuff(self):
        base.localAvatar.getGeomNode().hide()
        base.localAvatar.setPos(0, 0, -0.5)
        base.localAvatar.setHpr(0, 0, 0)
        self.guide.setPos(self.GUIDE_START_POS)
        self.guide.headsUp(base.localAvatar)
        base.localAvatar.attachCamera()

    def enterPlayerEmerge(self):
        self.introStuff()
        self.guide.loop('neutral')
        base.transitions.irisIn()
        base.taskMgr.doMethodLater(1.0, self.__playerEmerge, 'playerEmergeTask')

    def __playerEmerge(self, task):
        base.localAvatar.setAnimState('teleportIn', callback=self.__playerEmergeFinished)
        return Task.done

    def __playerEmergeFinished(self):
        base.localAvatar.setAnimState('neutral')
        self.fsm.request('introSpeech')

    def exitPlayerEmerge(self):
        base.localAvatar.detachCamera()
        base.taskMgr.remove('playerEmergeTask')
        base.transitions.noTransitions()

    def enterGuideIntroSpeech(self):
        base.localAvatar.attachCamera()
        renderPos = base.camera.getPos(render)
        renderHpr = base.camera.getHpr(render)
        base.localAvatar.detachCamera()
        endPos = base.localAvatar.getPos(render) + (0, 0, 4)
        base.camera.setPos(endPos)
        base.camera.lookAt(self.guide, 0, 0, 3)
        endHpr = base.camera.getHpr(render)
        base.camera.setPos(renderPos)
        base.camera.setHpr(renderHpr)
        self.chatIndex = -1
        self.doNextIntroSpeech()
        self.camMoveTrack = Sequence(Parallel(LerpPosInterval(base.camera, duration=3.0, pos=endPos, startPos=renderPos, blendType='easeOut'), LerpQuatInterval(base.camera, duration=3.0, hpr=endHpr, startHpr=renderHpr, blendType='easeOut')), Func(base.localAvatar.getGeomNode().hide))
        self.camMoveTrack.start()

    def __finishedReadingGuideIntroSpeech(self):
        self.guide.autoClearChat = True
        self.guide.setChat(self.GUIDE_START_TRAINING)
        self.fsm.request('introSpeech2Training')

    def doNextIntroSpeech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_INTRO_SPEECH):
            self.__finishedReadingGuideIntroSpeech()
            return
        self.guide.setChat(self.GUIDE_INTRO_SPEECH[self.chatIndex])
        Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextIntroSpeech)).start()

    def exitGuideIntroSpeech(self):
        self.camMoveTrack.finish()
        base.localAvatar.getGeomNode().show()
        del self.camMoveTrack
        del self.chatIndex

    def enterIntroSpeech2Training(self):
        startCamPos = base.camera.getPos(render)
        startCamHpr = base.camera.getHpr(render)
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        base.localAvatar.attachCamera()
        endCamPos = base.camera.getPos(render)
        endCamHpr = base.camera.getHpr(render)
        base.localAvatar.detachCamera()
        startHpr = self.guide.getHpr(render)
        self.guide.headsUp(self.GUIDE_WATCH_POS)
        endHpr = self.guide.getHpr(render)
        self.guide.loop('run')
        self.camMoveIval = Parallel(LerpPosInterval(base.camera, duration=2.0, pos=endCamPos, startPos=startCamPos, blendType='easeOut'), LerpQuatInterval(base.camera, duration=2.0, hpr=endCamHpr, startHpr=startCamHpr, blendType='easeOut'), Sequence(LerpPosInterval(self.guide, duration=2.0, pos=self.GUIDE_WATCH_POS, startPos=self.guide.getPos(render)), Func(self.guide.loop, 'walk'), LerpHprInterval(self.guide, duration=1.0, hpr=self.GUIDE_WATCH_HPR, startHpr=endHpr), Func(self.guide.loop, 'neutral')), LerpHprInterval(self.guide, duration=1.0, hpr=endHpr, startHpr=startHpr))
        self.camMoveIval.setDoneEvent('introSpeech2TrainingDone')
        self.acceptOnce('introSpeech2TrainingDone', self.__handleIS2TDone)
        self.camMoveIval.start()

    def __handleIS2TDone(self):
        self.fsm.request('training1')

    def exitIntroSpeech2Training(self):
        self.ignore('introSpeech2TrainingDone')
        self.camMoveIval.finish()
        del self.camMoveIval

    def enterTrainingPT1(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [0])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enablePies(1)
        Whisper().createSystemMessage('This should be pretty simple. Just throw a gag at this dummy bot to defeat it.')

    def suitNoHealth(self, index):
        if index == 0:
            Whisper().createSystemMessage('Good job, {0}!'.format(base.localAvatar.getName()))
        elif index == 1:
            Whisper().createSystemMessage("Wow, you're doing very well!")

    def suitExploded(self, index):
        if index == 0:
            Whisper().createSystemMessage('Pick up the jellybean that he dropped. You can use them to buy more gags for your Toon.')
        self.battleMusic.stop()
        base.playMusic(self.music, looping=1, volume=0.8)

    def pickedUpJellybean(self):
        if self.fsm.getCurrentState().getName() == 'training1':
            self.fsm.request('training2info')
        elif self.fsm.getCurrentState().getName() == 'training2':
            self.fsm.request('training3info')
        elif self.fsm.getCurrentState().getName() == 'training3':
            self.fsm.request('trainingDone')

    def exitTrainingPT1(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disablePies()
        return

    def enterTraining2Info(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTraining2Speech()

    def __finishedReadingGuideTraining2Speech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('training2')

    def doNextTraining2Speech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_PT2_INFO):
            self.__finishedReadingGuideTraining2Speech()
            return
        self.guide.setChat(self.GUIDE_PT2_INFO[self.chatIndex])
        Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTraining2Speech)).start()

    def exitTraining2Info(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterTrainingPT2(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [1])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enablePies(1)

    def exitTrainingPT2(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disablePies()
        return

    def enterTraining3Info(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTraining3Speech()

    def __finishedReadingGuideTraining3Speech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('training3')

    def doNextTraining3Speech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_PT3_INFO):
            self.__finishedReadingGuideTraining3Speech()
            return
        self.guide.setChat(self.GUIDE_PT3_INFO[self.chatIndex])
        Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTraining3Speech)).start()

    def exitTraining3Info(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterTrainingPT3(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [2])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enablePies(1)

    def exitTrainingPT3(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disablePies()
        return

    def enterTrainingDone(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTrainingDoneSpeech()

    def __finishedReadingGuideTrainingDoneSpeech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('leaveTutorial')

    def doNextTrainingDoneSpeech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_DONE):
            self.__finishedReadingGuideTrainingDoneSpeech()
            return
        self.guide.setChat(self.GUIDE_DONE[self.chatIndex])
        Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTrainingDoneSpeech)).start()

    def exitTrainingDone(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterLeaveTutorial(self):
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.b_setAnimState('teleportOut', callback=self.__teleOutDone)

    def __teleOutDone(self):
        zoneId = CIGlobals.ToontownCentralId
        hoodId = CIGlobals.ToontownCentral
        whereName = 'playground'
        avId = base.localAvatar.doId
        loaderName = 'safeZoneLoader'
        self.sendUpdate('finishedTutorial')
        self.cr.playGame.fsm.request('quietZone', [{'zoneId': zoneId,
          'hoodId': hoodId,
          'where': whereName,
          'how': 'teleportIn',
          'avId': avId,
          'shardId': None,
          'loader': loaderName}])
        return

    def exitLeaveTutorial(self):
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()

    def announceGenerate(self):
        DistributedObject.announceGenerate(self)
        base.transitions.fadeScreen(0.0)
        self.guide = Toon(base.cr)
        self.guide.autoClearChat = False
        self.guide.parseDNAStrand(NPCGlobals.NPC_DNA[self.GUIDE_NAME])
        self.guide.setName(self.GUIDE_NAME)
        self.guide.generateToon()
        self.guide.startBlink()
        self.guide.reparentTo(render)
        base.localAvatar.reparentTo(render)
        loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/storage_tutorial.dna')
        node = loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/tutorial_street.dna')
        if node.getNumParents() == 1:
            self.streetGeom = NodePath(node.getParent(0))
            self.streetGeom.reparentTo(hidden)
        else:
            self.streetGeom = hidden.attachNewNode(node)
        self.streetGeom.flattenMedium()
        gsg = base.win.getGsg()
        if gsg:
            self.streetGeom.prepareScene(gsg)
        self.streetGeom.reparentTo(render)
        self.streetGeom.setPos(20.5, -20, 0)
        self.streetGeom.setH(90)
        self.sky = loader.loadModel('phase_3.5/models/props/TT_sky.bam')
        self.skyUtil.startSky(self.sky)
        self.sky.reparentTo(camera)
        ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ)
        self.sky.node().setEffect(ce)
        self.music = base.loadMusic('phase_3.5/audio/bgm/TC_SZ.mid')
        base.playMusic(self.music, volume=0.8, looping=1)
        self.battleMusic = base.loadMusic('phase_3.5/audio/bgm/encntr_general_bg.mid')
        self.fsm.request('newPlayerEmerge')
        base.localAvatar.inTutorial = True

    def disable(self):
        self.fsm.requestFinalState()
        del self.fsm
        if self.guide:
            self.guide.disable()
            self.guide.delete()
            self.guide = None
        if self.streetGeom:
            self.streetGeom.removeNode()
            self.streetGeom = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.music:
            self.music.stop()
            self.music = None
        if self.battleMusic:
            self.battleMusic.stop()
            self.battleMusic = None
        self.dnaStore = None
        self.skyUtil = None
        base.localAvatar.inTutorial = False
        DistributedObject.disable(self)
        return
コード例 #12
0
ファイル: CogThief.py プロジェクト: satire6/Anesidora
class CogThief(DirectObject):
    """This represents a single cog thief in the cog thief game"""
    notify = directNotify.newCategory("CogThief")
    DefaultSpeedWalkAnim = 4.
    CollisionRadius = 1.25
    MaxFriendsVisible = 4
    Infinity = 100000.0  # just a really big number
    SeparationDistance = 6.0
    MinUrgency = 0.5
    MaxUrgency = 0.75

    def __init__(self, cogIndex, suitType, game, cogSpeed):
        self.cogIndex = cogIndex
        self.suitType = suitType
        self.game = game
        self.cogSpeed = cogSpeed
        suit = Suit.Suit()
        d = SuitDNA.SuitDNA()
        d.newSuit(suitType)
        suit.setDNA(d)
        # cache the walk anim
        suit.pose('walk', 0)
        self.suit = suit
        self.goal = CTGG.NoGoal
        self.goalId = CTGG.InvalidGoalId
        self.lastLocalTimeStampFromAI = 0
        self.lastPosFromAI = Point3(0, 0, 0)
        self.lastThinkTime = 0
        self.doneAdjust = False
        self.barrel = CTGG.NoBarrelCarried
        self.signalledAtReturnPos = False
        self.defaultPlayRate = 1.0
        self.netTimeSentToStartByHit = 0

        # steering loosely based on boid code game programming gems #1
        # "Portions Copyright (C) Steven Woodcock, 2000"
        self.velocity = Vec3(0, 0, 0)
        self.oldVelocity = Vec3(0, 0, 0)
        self.acceleration = Vec3(0, 0, 0)
        self.bodyLength = self.CollisionRadius * 2
        # Desired distance from closest neighbor when flying.
        self.cruiseDistance = 2 * self.bodyLength
        self.maxVelocity = self.cogSpeed
        # Maximum magnitude of acceleration as a fraction of maxSpeed.
        self.maxAcceleration = 5.0
        self.perceptionRange = 6
        self.notify.debug('cogSpeed=%s' % self.cogSpeed)

        self.kaboomSound = loader.loadSfx(
            "phase_4/audio/sfx/MG_cannon_fire_alt.mp3")
        self.kaboom = loader.loadModel(
            'phase_4/models/minigames/ice_game_kaboom')
        self.kaboom.setScale(2.0)
        self.kaboom.setBillboardPointEye()
        self.kaboom.hide()
        self.kaboomTrack = None

        splatName = 'splat-creampie'
        self.splat = globalPropPool.getProp(splatName)
        self.splat.setBillboardPointEye()
        self.splatType = globalPropPool.getPropType(splatName)

        self.pieHitSound = globalBattleSoundCache.getSound(
            'AA_wholepie_only.mp3')

    def destroy(self):
        self.ignoreAll()
        self.suit.delete()
        self.game = None

    def uniqueName(self, baseStr):
        return baseStr + '-' + str(self.game.doId)

    def handleEnterSphere(self, collEntry):
        """Handle the suit colliding with localToon."""
        #assert self.notify.debugStateCall(self)
        intoNp = collEntry.getIntoNodePath()
        self.notify.debug('handleEnterSphere suit %d hit %s' %
                          (self.cogIndex, intoNp))
        if self.game:
            self.game.handleEnterSphere(collEntry)

    def gameStart(self, gameStartTime):
        self.gameStartTime = gameStartTime

        self.initCollisions()
        self.startWalkAnim()

    def gameEnd(self):
        self.moveIval.pause()
        del self.moveIval

        self.shutdownCollisions()

        # keep the suits from walking in place
        self.suit.loop('neutral')

    def initCollisions(self):
        # Make a sphere, give it a unique name, and parent it
        # to the suit.
        self.collSphere = CollisionSphere(0, 0, 0, 1.25)
        # Make he sphere intangible
        self.collSphere.setTangible(1)
        name = "CogThiefSphere-%d" % self.cogIndex
        self.collSphereName = self.uniqueName(name)
        self.collNode = CollisionNode(self.collSphereName)
        self.collNode.setIntoCollideMask(CTGG.BarrelBitmask
                                         | ToontownGlobals.WallBitmask)
        self.collNode.addSolid(self.collSphere)
        self.collNodePath = self.suit.attachNewNode(self.collNode)
        #self.collNodePath.hide()

        # Add a hook looking for collisions with localToon
        self.accept('enter' + self.collSphereName, self.handleEnterSphere)

        # we need a taller collision tube to collide against for pie
        self.pieCollSphere = CollisionTube(0, 0, 0, 0, 0, 4,
                                           self.CollisionRadius)
        # Make he sphere intangible
        self.pieCollSphere.setTangible(1)
        name = "CogThiefPieSphere-%d" % self.cogIndex
        self.pieCollSphereName = self.uniqueName(name)
        self.pieCollNode = CollisionNode(self.pieCollSphereName)
        self.pieCollNode.setIntoCollideMask(ToontownGlobals.PieBitmask)
        self.pieCollNode.addSolid(self.pieCollSphere)
        self.pieCollNodePath = self.suit.attachNewNode(self.pieCollNode)
        #self.pieCollNodePath.show()

        # Add a hook looking for collisions with localToon
        #self.accept('enter' + self.pieCollSphereName,
        #            self.handleEnter)

    def shutdownCollisions(self):
        self.ignore(self.uniqueName('enter' + self.collSphereName))

        del self.collSphere
        self.collNodePath.removeNode()
        del self.collNodePath
        del self.collNode

    def updateGoal(self, timestamp, inResponseClientStamp, goalType, goalId,
                   pos):
        """Update our goal and position."""
        assert self.notify.debugStateCall(self)
        self.notify.debug('self.netTimeSentToStartByHit =%s' %
                          self.netTimeSentToStartByHit)
        if not self.game:
            self.notify.debug('updateGoal self.game is None, just returning')
            return
        if not self.suit:
            self.notify.debug('updateGoal self.suit is None, just returning')
            return
        if self.goal == CTGG.NoGoal:
            self.startWalkAnim()

        if goalType == CTGG.NoGoal:
            self.notify.debug('updateGoal setting position to %s' % pos)
            self.suit.setPos(pos)

        self.lastThinkTime = 0
        self.velocity = Vec3(0, 0, 0)
        self.oldVelocity = Vec3(0, 0, 0)
        self.acceleration = Vec3(0, 0, 0)

        if goalType == CTGG.RunAwayGoal:
            #import pdb; pdb.set_trace()
            pass

        if inResponseClientStamp < self.netTimeSentToStartByHit and \
           self.goal == CTGG.NoGoal and \
           goalType == CTGG.RunAwayGoal:
            #import pdb; pdb.set_trace()
            self.notify.warning(
                'ignoring newGoal %s as cog %d was recently hit responsetime=%s hitTime=%s'
                % (CTGG.GoalStr[goalType], self.cogIndex,
                   inResponseClientStamp, self.netTimeSentToStartByHit))
        else:
            self.lastLocalTimeStampFromAI = globalClockDelta.networkToLocalTime(
                timestamp, bits=32)
            self.goal = goalType
            self.goalId = goalId
            self.lastPosFromAI = pos
            self.doneAdjust = False
        self.signalledAtReturnPos = False
        # TODO move the suit to where we expect him to be given the time difference

    def startWalkAnim(self):
        if self.suit:
            self.suit.loop('walk')
            speed = self.cogSpeed  # float(MazeData.CELL_WIDTH) / self.cellWalkDuration
            self.defaultPlayRate = float(self.cogSpeed /
                                         self.DefaultSpeedWalkAnim)
            self.suit.setPlayRate(self.defaultPlayRate, 'walk')

    def think(self):
        """Calculate where we should go."""
        if self.goal == CTGG.ToonGoal:
            self.thinkAboutCatchingToon()
        elif self.goal == CTGG.BarrelGoal:
            self.thinkAboutGettingBarrel()
        elif self.goal == CTGG.RunAwayGoal:
            self.thinkAboutRunAway()

    def thinkAboutCatchingToon(self):
        if not self.game:
            return

        av = self.game.getAvatar(self.goalId)
        if av:
            if not self.lastThinkTime:
                self.lastThinkTime = globalClock.getFrameTime()
            diffTime = globalClock.getFrameTime() - self.lastThinkTime
            avPos = av.getPos()
            myPos = self.suit.getPos()

            if not self.doneAdjust:
                myPos = self.lastPosFromAI
                self.notify.debug(
                    'thinkAboutCatchingToon not doneAdjust setting pos %s' %
                    myPos)
                self.doneAdjust = True

            self.suit.setPos(myPos)

            if self.game.isToonPlayingHitTrack(self.goalId):
                # do nothing, just look at toon
                self.suit.headsUp(av)
                self.velocity = Vec3(0, 0, 0)
                self.oldVelocity = Vec3(0, 0, 0)
                self.acceleration = Vec3(0, 0, 0)
            else:
                self.commonMove()

            newPos = self.suit.getPos()
            self.adjustPlayRate(newPos, myPos, diffTime)

        self.lastThinkTime = globalClock.getFrameTime()

    def convertNetworkStampToGameTime(self, timestamp):
        """Convert a network timestamp to game time."""
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32)
        gameTime = self.game.local2GameTime(localStamp)
        return gameTime

    def respondToToonHit(self, timestamp):
        """The toon hit us, react appropriately."""
        assert self.notify.debugStateCall(self)
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32)
        # using 1.0 sec as fudge
        #if localStamp > self.lastLocalTimeStampFromAI:
        if self.netTimeSentToStartByHit < timestamp:
            self.clearGoal()
            self.showKaboom()
            # move him to his starting postion
            startPos = CTGG.CogStartingPositions[self.cogIndex]
            oldPos = self.suit.getPos()
            self.suit.setPos(startPos)
            if self.netTimeSentToStartByHit < timestamp:
                self.netTimeSentToStartByHit = timestamp
        else:
            self.notify.debug(
                'localStamp = %s, lastLocalTimeStampFromAI=%s, ignoring respondToToonHit'
                % (localStamp, self.lastLocalTimeStampFromAI))
        self.notify.debug(
            'respondToToonHit self.netTimeSentToStartByHit = %s' %
            self.netTimeSentToStartByHit)

    def clearGoal(self):
        """Clear goal and goal id."""
        self.goal = CTGG.NoGoal
        self.goalId = CTGG.InvalidGoalId

    def thinkAboutGettingBarrel(self):
        """Go for  a barrel."""
        if not self.game:
            return

        if not hasattr(self.game, 'barrels'):
            return
        if not self.goalId in xrange(len(self.game.barrels)):
            return

        if not self.lastThinkTime:
            self.lastThinkTime = globalClock.getFrameTime()
        diffTime = globalClock.getFrameTime() - self.lastThinkTime
        barrel = self.game.barrels[self.goalId]
        barrelPos = barrel.getPos()
        myPos = self.suit.getPos()
        if not self.doneAdjust:
            myPos = self.lastPosFromAI
            self.notify.debug(
                'thinkAboutGettingBarrel not doneAdjust setting position to %s'
                % myPos)
            self.suit.setPos(myPos)
            """
            diffTime = globalClock.getFrameTime()- self.lastLocalTimeStampFromAI
            self.notify.debug('doing adjust, diffTime = %s' % diffTime)
            if diffTime < 0:
                # it just looks really weird when it moves backwards
                diffTime = 0
                self.notify.debug('forcing diffTime to %s' % diffTime)
            """
            self.doneAdjust = True
        displacement = barrelPos - myPos
        distanceToToon = displacement.length()
        #self.notify.debug('diffTime = %s' % diffTime)
        self.suit.headsUp(barrel)
        lengthTravelled = diffTime * self.cogSpeed
        #self.notify.debug('lengthTravelled = %s' % lengthTravelled)
        # don't overshoot our target
        if lengthTravelled > distanceToToon:
            lengthTravelled = distanceToToon
            #self.notify.debug('overshooting lengthTravelled = %s' % lengthTravelled)
        displacement.normalize()
        dirVector = displacement
        dirVector *= lengthTravelled
        newPos = myPos + dirVector
        # always keep them grounded
        newPos.setZ(0)
        self.suit.setPos(newPos)
        self.adjustPlayRate(newPos, myPos, diffTime)

        self.lastThinkTime = globalClock.getFrameTime()

    def stopWalking(self, timestamp):
        """Stop the cog from walking."""
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32)
        if localStamp > self.lastLocalTimeStampFromAI:
            self.suit.loop('neutral')
            self.clearGoal()

    def thinkAboutRunAway(self):
        """Go for  a barrel."""
        if not self.game:
            return
        if not self.lastThinkTime:
            self.lastThinkTime = globalClock.getFrameTime()
        diffTime = globalClock.getFrameTime() - self.lastThinkTime

        returnPos = CTGG.CogReturnPositions[self.goalId]
        myPos = self.suit.getPos()
        if not self.doneAdjust:
            myPos = self.lastPosFromAI
            self.suit.setPos(myPos)
            """
            diffTime = globalClock.getFrameTime()- self.lastLocalTimeStampFromAI
            self.notify.debug('run away doing adjust, diffTime = %s' % diffTime)
            if diffTime < 0:
                # it just looks really weird when it moves backwards
                diffTime = 0
                self.notify.debug('forcing diffTime to %s' % diffTime)
            """
            self.doneAdjust = True
        displacement = returnPos - myPos
        distanceToToon = displacement.length()
        #self.notify.debug('diffTime = %s' % diffTime)
        tempNp = render.attachNewNode('tempRet')
        tempNp.setPos(returnPos)
        self.suit.headsUp(tempNp)
        tempNp.removeNode()
        lengthTravelled = diffTime * self.cogSpeed
        #self.notify.debug('lengthTravelled = %s' % lengthTravelled)
        # don't overshoot our target
        if lengthTravelled > distanceToToon:
            lengthTravelled = distanceToToon
            #self.notify.debug('overshooting lengthTravelled = %s' % lengthTravelled)
        displacement.normalize()
        dirVector = displacement
        dirVector *= lengthTravelled
        newPos = myPos + dirVector
        # always keep them grounded
        newPos.setZ(0)
        self.suit.setPos(newPos)
        self.adjustPlayRate(newPos, myPos, diffTime)

        if (self.suit.getPos() - returnPos).length() < 0.0001:
            if not self.signalledAtReturnPos and self.barrel >= 0:
                # tell the AI we're at return Pos
                self.game.sendCogAtReturnPos(self.cogIndex, self.barrel)
                self.signalledAtReturnPos = True

        self.lastThinkTime = globalClock.getFrameTime()

    def makeCogCarryBarrel(self, timestamp, inResponseClientStamp, barrelModel,
                           barrelIndex, cogPos):
        """Handle the AI telling us the barrel is attached to a cog."""
        #assert self.notify.debugStateCall(self)
        if not self.game:
            return
        localTimeStamp = globalClockDelta.networkToLocalTime(timestamp,
                                                             bits=32)
        # TODO validate time?
        self.lastLocalTimeStampFromAI = localTimeStamp
        inResponseGameTime = self.convertNetworkStampToGameTime(
            inResponseClientStamp)

        self.notify.debug('inResponseGameTime =%s timeSentToStart=%s' %
                          (inResponseGameTime, self.netTimeSentToStartByHit))
        if inResponseClientStamp  < self.netTimeSentToStartByHit and \
           self.goal == CTGG.NoGoal:
            self.notify.warning('ignoring makeCogCarrybarrel')
        else:
            barrelModel.setPos(0, -1.0, 1.5)
            barrelModel.reparentTo(self.suit)
            self.suit.setPos(cogPos)
            self.barrel = barrelIndex

    def makeCogDropBarrel(self, timestamp, inResponseClientStamp, barrelModel,
                          barrelIndex, barrelPos):
        """Handle the AI telling us the barrel is attached to a cog."""
        #assert self.notify.debugStateCall(self)
        localTimeStamp = globalClockDelta.networkToLocalTime(timestamp,
                                                             bits=32)
        # TODO validate time?
        self.lastLocalTimeStampFromAI = localTimeStamp

        barrelModel.reparentTo(render)
        barrelModel.setPos(barrelPos)

        self.barrel = CTGG.NoBarrelCarried

        #
        #self.suit.setPos(cogPos)

    def respondToPieHit(self, timestamp):
        """The toon hit us, react appropriately."""
        assert self.notify.debugStateCall(self)
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32)
        # argh using 1.0 sec as fudge
        #if localStamp  > self.lastLocalTimeStampFromAI:
        if self.netTimeSentToStartByHit < timestamp:
            self.clearGoal()
            self.showSplat()
            # move him to his starting postion
            startPos = CTGG.CogStartingPositions[self.cogIndex]
            oldPos = self.suit.getPos()
            self.suit.setPos(startPos)
            if self.netTimeSentToStartByHit < timestamp:
                self.netTimeSentToStartByHit = timestamp
        else:
            self.notify.debug(
                'localStamp = %s, lastLocalTimeStampFromAI=%s, ignoring respondToPieHit'
                % (localStamp, self.lastLocalTimeStampFromAI))
            self.notify.debug(
                'respondToPieHit self.netTimeSentToStartByHit = %s' %
                self.netTimeSentToStartByHit)

    def cleanup(self):
        """Do whatever is necessary to cleanup properly."""
        self.clearGoal()
        self.ignoreAll()
        self.suit.delete()
        if self.kaboomTrack and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        self.suit = None
        self.game = None

    def adjustPlayRate(self, newPos, oldPos, diffTime):
        """Adjust animation rate based on how far he's moved."""
        # lets slowdown playrate if they're not moving much
        lengthTravelled = (newPos - oldPos).length()
        if diffTime:
            speed = lengthTravelled / diffTime
        else:
            speed = self.cogSpeed
        rateMult = speed / self.cogSpeed
        newRate = rateMult * self.defaultPlayRate
        self.suit.setPlayRate(newRate, 'walk')

    def commonMove(self):
        """Move the cog thief. Common for all 3 behaviors """
        if not self.lastThinkTime:
            self.lastThinkTime = globalClock.getFrameTime()
        dt = globalClock.getFrameTime() - self.lastThinkTime

        # Step 1:  Update our position.
        # Update our position based on the velocity
        # vector we computed last time around.

        self.oldpos = self.suit.getPos()
        # save off our previous position

        pos = self.suit.getPos()
        pos += self.velocity * dt
        # apply velocities.
        self.suit.setPos(pos)

        # Step 2:  SeeFriends.
        # Determine if we can see any of our flockmates.

        self.seeFriends()

        acc = Vec3(0, 0, 0)

        # well first off we want to move to our target
        self.accumulate(acc, self.getTargetVector())

        # Step 3:  Flocking behavior.
        # Do we see any of our flockmates?  If yes, it's time to implement
        # the first Three Rules (they don't matter if we can't see anybody)

        if self.numFlockmatesSeen > 0:
            #if hasattr(base,'doDebug') and base.doDebug:
            #    import pdb; pdb.set_trace()
            keepDistanceVector = self.keepDistance()
            oldAcc = Vec3(acc)
            self.accumulate(acc, keepDistanceVector)
            if self.cogIndex == 0:
                #self.notify.debug('oldAcc=%s, keepDist=%s newAcc=%s' %
                #                  (oldAcc,keepDistanceVector, acc))
                pass

        # Step 8:  Constrain acceleration
        # If our acceleration change is more than we allow, constrain it

        if (acc.length() > self.maxAcceleration):
            # definitely too much...constrain to maximum change
            acc.normalize()
            acc *= self.maxAcceleration

        # Step 9:  Implementation.
        # Here's where we apply our newly computed acceleration vector
        # to create a new velocity vector to use next update cycle.

        self.oldVelocity = self.velocity
        # save off our previous velocity

        # now add in the acceleration

        self.velocity += acc

        # Step 10:  constraint Y velocity changes.
        # Attempt to restrict flight straight up/down by damping out Y axis velocity.
        # This isn't strictly necessary, but does lead to more realistic looking flight.

        # Step 11:  Constrain our speed.
        # If we're moving faster than we're allowed to move, constrain our velocity.
        if self.velocity.length() > self.maxVelocity:
            self.velocity.normalize()
            self.velocity *= self.maxVelocity

        # Step 12:  Compute roll/pitch/yaw.
        # Compute our orientation after all this speed adjustment nonsense.
        # bah no need, we turn on a dime towards our velocity
        forwardVec = Vec3(1, 0, 0)
        heading = rad2Deg(math.atan2(self.velocity[1], self.velocity[0]))
        heading -= 90
        self.suit.setH(heading)

    def getTargetVector(self):
        """Return a vector to my goal."""
        targetPos = Point3(0, 0, 0)
        if self.goal == CTGG.ToonGoal:
            av = self.game.getAvatar(self.goalId)
            if av:
                targetPos = av.getPos()
        elif self.goal == CTGG.BarrelGoal:
            barrel = self.game.barrels[self.goalId]
            targetPos = barrel.getPos()
        elif self.goal == CTGG.RunAwayGoal:
            targetPos = CTGG.CogReturnPositions[self.goalId]
        targetPos.setZ(0)
        myPos = self.suit.getPos()
        diff = targetPos - myPos
        if diff.length() > 1.0:
            diff.normalize()
            diff *= 1.0

        return diff

    def accumulate(self, accumulator, valueToAdd):
        """Return the magnitude of the accumulated vector."""

        accumulator += valueToAdd

        return accumulator.length()

    def seeFriends(self):
        """Determines which flockmates a given flock boid can see."""
        # clear the existing visibility list of any holdover from last round

        self.clearVisibleList()

        for cogIndex in self.game.cogInfo.keys():
            if cogIndex == self.cogIndex:
                continue

            if self.sameGoal(cogIndex):
                dist = self.canISee(cogIndex)
                if dist != self.Infinity:
                    self.addToVisibleList(cogIndex)
                    if dist < self.distToNearestFlockmate:
                        self.nearestFlockmate = cogIndex
                        self.distToNearestFlockmate = dist

        return self.numFlockmatesSeen

    def clearVisibleList(self):
        """Clears the visibility list and associated fields."""
        self.visibleFriendsList = []
        self.numFlockmatesSeen = 0
        self.nearestFlockmate = None
        self.distToNearestFlockmate = self.Infinity

    def addToVisibleList(self, cogIndex):
        """Add the cog to the visible list."""
        # test:  do we see enough buddies already?
        if self.numFlockmatesSeen < self.MaxFriendsVisible:
            #nope--we can add to this one to the list
            self.visibleFriendsList.append(cogIndex)
            self.numFlockmatesSeen += 1
            if self.cogIndex == 0:
                #self.notify.debug('self.numFlockmatesSeen = %s' % self.numFlockmatesSeen)
                pass

    def canISee(self, cogIndex):
        """Return distance if I can see the other cog, infinity otherwise"""

        if self.cogIndex == cogIndex:
            # well we should never see ourself
            return self.Infinity

        cogThief = self.game.getCogThief(cogIndex)
        distance = self.suit.getDistance(cogThief.suit)

        if distance < self.perceptionRange:
            #self.notify.debug('%s can see %s' % (self.cogIndex, cogIndex))
            return distance

        # fell through; can not see it
        return self.Infinity

    def sameGoal(self, cogIndex):
        """Return true if we have the same goal."""
        cogThief = self.game.getCogThief(cogIndex)
        result = (cogThief.goalId == self.goalId) and (cogThief.goal
                                                       == self.goal)
        return result

    def keepDistance(self):
        """Generates a vector for a flock boid to maintain his
        desired separation distance from the nearest flockmate he sees.
        """
        ratio = self.distToNearestFlockmate / self.SeparationDistance
        nearestThief = self.game.getCogThief(self.nearestFlockmate)
        change = nearestThief.suit.getPos() - self.suit.getPos()

        if ratio < self.MinUrgency:
            ratio = self.MinUrgency
        if ratio > self.MaxUrgency:
            ratio = self.MaxUrgency

        # test:  are we too close to our nearest flockmate?
        if self.distToNearestFlockmate < self.SeparationDistance:
            #self.notify.debug('%d is too close to %d' % (self.cogIndex, self.nearestFlockmate))

            # too close...move away from our neighbor
            change.normalize()
            change *= -(1 - ratio
                        )  # the close we are the more we are pushed away
        elif self.distToNearestFlockmate > self.SeparationDistance:
            # too far away move towards our neighbor
            change.normalize()
            change *= ratio
        else:
            # in the UNLIKELY event we're exactly the right distance away, do nothing
            change = Vec3(0, 0, 0)

        return change

    def showKaboom(self):
        """Show the kaboom graphic and sound."""
        if self.kaboomTrack and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        self.kaboom.reparentTo(render)
        self.kaboom.setPos(self.suit.getPos())
        self.kaboom.setZ(3)

        self.kaboomTrack = Parallel(
            SoundInterval(self.kaboomSound, volume=0.5),
            Sequence(
                Func(self.kaboom.showThrough),
                LerpScaleInterval(self.kaboom,
                                  duration=0.5,
                                  scale=Point3(10, 10, 10),
                                  startScale=Point3(1, 1, 1),
                                  blendType='easeOut'),
                Func(self.kaboom.hide),
            ))
        self.kaboomTrack.start()

    def showSplat(self):
        """Show the splat graphic and sound."""
        if self.kaboomTrack and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        self.splat.reparentTo(render)
        self.splat.setPos(self.suit.getPos())
        self.splat.setZ(3)

        self.kaboomTrack = Parallel(
            SoundInterval(self.pieHitSound, volume=1.0),
            Sequence(
                Func(self.splat.showThrough),
                LerpScaleInterval(self.splat,
                                  duration=0.5,
                                  scale=1.75,
                                  startScale=Point3(0.1, 0.1, 0.1),
                                  blendType='easeOut'),
                Func(self.splat.hide),
            ))
        self.kaboomTrack.start()
コード例 #13
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
コード例 #14
0
class LightDropGag(DropGag):

    rotate90 = False
    scale = 1

    def __init__(self):
        DropGag.__init__(self)
        DropGag.setShadowData(self, isCircle=True, shadowScale=0.5)
        self.stunTime = 1.5
        self.objTrack = None

    def startDrop(self, entity):
        if entity and self.dropLoc:
            x, y, z = self.dropLoc
            startPos = Point3(x, y, z + 20)
            entity.setPos(startPos)
            entity.node().setBounds(OmniBoundingVolume())
            entity.node().setFinal(1)
            entity.headsUp(self.avatar)
            entity.setPythonTag('EntityRoot', entity)
            if self.rotate90:
                entity.setH(entity.getH() - 90)
            self.buildCollisions(entity)
            objectTrack = Sequence()
            animProp = LerpPosInterval(entity,
                                       self.fallDuration,
                                       self.dropLoc,
                                       startPos=startPos)
            bounceProp = Effects.createZBounce(entity, 2, self.dropLoc, 0.5,
                                               1.5)
            objAnimShrink = Sequence(Wait(0.5), Func(entity.reparentTo,
                                                     render), animProp,
                                     bounceProp)
            objectTrack.append(objAnimShrink)
            dropShadow = CIGlobals.makeDropShadow(1.0)
            dropShadow.reparentTo(hidden)
            dropShadow.setPos(self.dropLoc)
            if self.name == GagGlobals.FlowerPot:
                dropShadow.setZ(dropShadow.getZ() - 3.5)
            dropShadow.setScale(0.01)
            shadowTrack = Sequence(
                Func(dropShadow.reparentTo, render),
                LerpScaleInterval(dropShadow,
                                  self.fallDuration + 0.1,
                                  self.getShadowScale(),
                                  startScale=Point3(0.01, 0.01, 0.01)),
                Wait(0.8), Func(dropShadow.removeNode))
            self.objTrack = Parallel(
                Sequence(Wait(self.fallDuration), Func(self.completeDrop)),
                objectTrack, shadowTrack)
            self.objTrack.start()
            self.dropLoc = None

    def onActivate(self, entity, suit):
        self.objTrack.finish()
        self.objTrack = None
        if not suit.isDead():
            suit.setAnimState('drop-react')
        suit.d_disableMovement(wantRay=True)

        if not entity or entity.isEmpty():
            entity = self.build()

        entity.setPos(suit.find('**/joint_head').getPos(render))
        dropMdl = entity.find('**/DropMdl')
        if self.name == GagGlobals.FlowerPot:
            entity.setZ(entity, 3.5)
        bounce = Effects.createScaleZBounce(dropMdl, 1,
                                            dropMdl.getScale(render), 0.3,
                                            0.75)
        dummyNode = suit.attachNewNode('fallOffNode')
        dummyNode.setX(2)
        dummyNode.setY(-2)
        flightIval = FlightProjectileInterval(entity,
                                              startPos=entity.getPos(render),
                                              endPos=dummyNode.getPos(render),
                                              duration=0.8,
                                              gravityMult=.35)
        Sequence(Parallel(bounce, flightIval), Wait(self.stunTime),
                 Func(suit.d_enableMovement)).start()

        dummyNode.removeNode()
        del dummyNode
コード例 #15
0
class DistributedBattleTrolley(DistributedObject):
    notify = directNotify.newCategory('DistributedBattleTrolley')
    STAND_POSITIONS = [Point3(-4.75, -5, 1.4),
     Point3(-4.75, -1.6, 1.4),
     Point3(-4.75, 1.6, 1.4),
     Point3(-4.75, 5, 1.4)]
    TROLLEY_NEUTRAL_POS = Point3(15.751, 14.1588, -0.984615)
    TROLLEY_GONE_POS = Point3(50, 14.1588, -0.984615)
    TROLLEY_ARRIVING_START_POS = Point3(-20, 14.1588, -0.984615)
    CAM_POS = Point3(-36.1269, 0.742999, 7.3503)
    CAM_HPR = Vec3(-90, -1.9966, 0)

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.fsm = ClassicFSM.ClassicFSM('DistributedBattleTrolley', [State.State('off', self.enterOff, self.exitOff),
         State.State('wait', self.enterWait, self.exitWait),
         State.State('waitCountdown', self.enterWaitCountdown, self.exitWaitCountdown),
         State.State('leaving', self.enterLeaving, self.exitLeaving),
         State.State('arriving', self.enterArriving, self.exitArriving)], 'off', 'off')
        self.fsm.enterInitialState()
        self.trolleyStation = None
        self.trolleyCar = None
        self.trolleyKey = None
        self.countdownText = None
        self.soundMoving = base.loadSfx('phase_4/audio/sfx/SZ_trolley_away.mp3')
        self.soundBell = base.loadSfx('phase_4/audio/sfx/SZ_trolley_bell.mp3')
        self.hoodIndex = 0
        self.localAvOnTrolley = False
        return

    def headOff(self, zoneId):
        hoodId = self.cr.playGame.hood.hoodId
        if hoodId == CIGlobals.ToontownCentral:
            hoodId = CIGlobals.BattleTTC
        requestStatus = {'zoneId': zoneId,
         'hoodId': hoodId,
         'where': 'playground',
         'avId': base.localAvatar.doId,
         'loader': 'safeZoneLoader',
         'shardId': None,
         'wantLaffMeter': 1,
         'how': 'teleportIn'}
        self.cr.playGame.getPlace().doneStatus = requestStatus
        messenger.send(self.cr.playGame.getPlace().doneEvent)
        base.localAvatar.reparentTo(render)
        base.localAvatar.setPos(0, 0, 0)
        base.localAvatar.setHpr(0, 0, 0)
        base.localAvatar.walkControls.setCollisionsActive(1)
        self.localAvOnTrolley = False
        return

    def setHoodIndex(self, zone):
        self.hoodIndex = zone

    def getToZone(self):
        return self.toZone

    def enterOff(self, ts = 0):
        pass

    def exitOff(self):
        pass

    def enterWait(self, ts = 0):
        self.trolleyCar.setPos(self.TROLLEY_NEUTRAL_POS)

    def exitWait(self):
        pass

    def enterWaitCountdown(self, ts = 0):
        self.trolleyCar.setPos(self.TROLLEY_NEUTRAL_POS)
        if self.countdownText:
            self.countdownTrack = Sequence()
            for i in range(10):
                self.countdownTrack.append(Func(self.countdownText.node().setText, str(10 - i)))
                self.countdownTrack.append(Wait(1.0))

            self.countdownTrack.start()

    def exitWaitCountdown(self):
        if hasattr(self, 'countdownTrack'):
            self.countdownTrack.finish()
            del self.countdownTrack
        if self.countdownText:
            self.countdownText.node().setText('')
        self.disableExitButton()

    def enterArriving(self, ts = 0):
        base.playSfx(self.soundMoving)
        self.moveTrack = LerpPosInterval(self.trolleyCar, duration=3.0, pos=self.TROLLEY_NEUTRAL_POS, startPos=self.TROLLEY_ARRIVING_START_POS, blendType='easeOut')
        self.moveTrack.start()

    def exitArriving(self):
        self.moveTrack.finish()
        self.acceptOnce('entertrolley_sphere', self.__handleTrolleyTrigger)
        del self.moveTrack

    def enterLeaving(self, ts = 0):
        base.playSfx(self.soundMoving)
        base.playSfx(self.soundBell)
        self.moveTrack = Parallel()
        self.moveTrack.append(LerpPosInterval(self.trolleyCar, duration=3.0, pos=self.TROLLEY_GONE_POS, startPos=self.TROLLEY_NEUTRAL_POS, blendType='easeIn'))
        if self.localAvOnTrolley == True:
            self.moveTrack.append(Sequence(Wait(2.0), Func(base.transitions.fadeOut)))
        self.moveTrack.start()
        self.ignore('entertrolley_sphere')

    def exitLeaving(self):
        self.moveTrack.finish()
        del self.moveTrack

    def setState(self, stateName, timestamp):
        ts = globalClockDelta.localElapsedTime(timestamp)
        self.fsm.request(stateName, [ts])

    def __handleTrolleyTrigger(self, entry):
        self.cr.playGame.getPlace().fsm.request('stop')
        base.localAvatar.disablePies()
        self.notify.info('Waiting for response from server to enter trolley')
        self.sendUpdate('requestBoard')
        base.localAvatar.walkControls.setCollisionsActive(0)

    def fillSlot(self, index, avId):
        toon = self.cr.doId2do.get(avId)
        toon.stopSmooth()
        if toon:
            toon.wrtReparentTo(self.trolleyCar)
            slotPos = self.STAND_POSITIONS[index]
            toon.headsUp(slotPos)
            track = Sequence(Func(toon.setAnimState, 'run'), LerpPosInterval(toon, duration=1.0, pos=slotPos, startPos=toon.getPos()), Func(toon.setAnimState, 'neutral'), Func(toon.setHpr, 90, 0, 0))
            track.start()
        if avId == base.localAvatar.doId:
            self.localAvOnTrolley = True
            base.localAvatar.stopSmartCamera()
            base.camera.wrtReparentTo(self.trolleyCar)
            camTrack = Sequence(Parallel(LerpPosInterval(base.camera, duration=0.5, pos=self.CAM_POS, startPos=base.camera.getPos(), blendType='easeOut'), LerpQuatInterval(base.camera, duration=0.5, hpr=self.CAM_HPR, startHpr=base.camera.getHpr(), blendType='easeOut')), Func(self.enableExitButton))
            camTrack.start()

    def enableExitButton(self):
        gui = loader.loadModel('phase_3.5/models/gui/inventory_gui.bam')
        up = gui.find('**/InventoryButtonUp')
        down = gui.find('**/InventoryButtonDown')
        rlvr = gui.find('**/InventoryButtonRollover')
        self.exitButton = DirectButton(image=(up, down, rlvr), relief=None, text='Exit', text_fg=(1, 1, 0.65, 1), text_pos=(0, -0.23), text_scale=0.8, image_scale=(11, 1, 11), pos=(0, 0, -0.8), scale=0.15, command=self.__handleExitButton, image_color=(1, 0, 0, 1))
        return

    def __handleExitButton(self):
        if self.fsm.getCurrentState().getName() == 'waitCountdown' and self.localAvOnTrolley == True:
            self.disableExitButton()
            self.sendUpdate('requestHopOff')

    def disableExitButton(self):
        if hasattr(self, 'exitButton'):
            self.exitButton.destroy()
            del self.exitButton

    def emptySlot(self, index, avId):
        toon = self.cr.doId2do.get(avId)
        toon.stopSmooth()
        currToonPos = toon.getPos(render)
        toon.wrtReparentTo(render)
        slotPos = self.STAND_POSITIONS[index]
        endPos = (-20, slotPos.getY(), 0.0)
        toon.setPos(self.trolleyCar, endPos)
        endPosWrtRender = toon.getPos(render)
        toon.setPos(currToonPos)
        toon.headsUp(self.trolleyCar, endPos)
        track = Sequence(Func(toon.setAnimState, 'run'), LerpPosInterval(toon, duration=1.0, pos=endPosWrtRender, startPos=currToonPos), Func(toon.setAnimState, 'neutral'), Func(toon.startSmooth))
        if avId == base.localAvatar.doId:
            self.localAvOnTrolley = False
            track.append(Func(self.__hoppedOffTrolley))
        track.start()

    def __hoppedOffTrolley(self):
        self.acceptOnce('entertrolley_sphere', self.__handleTrolleyTrigger)
        base.localAvatar.walkControls.setCollisionsActive(1)
        self.cr.playGame.getPlace().fsm.request('walk')

    def generate(self):
        DistributedObject.announceGenerate(self)
        self.trolleyStation = self.cr.playGame.hood.loader.geom.find('**/prop_trolley_station_DNARoot')
        self.trolleyCar = self.trolleyStation.find('**/trolley_car')
        self.trolleyKey = self.trolleyStation.find('**/key')
        tn = TextNode('trolleycountdowntext')
        tn.setFont(CIGlobals.getMickeyFont())
        tn.setTextColor(1, 0, 0, 1)
        self.countdownText = self.trolleyStation.attachNewNode(tn)
        self.countdownText.setScale(3.0)
        self.countdownText.setPos(14.58, 10.77, 11.17)
        self.acceptOnce('entertrolley_sphere', self.__handleTrolleyTrigger)

    def delete(self):
        self.trolleyStation = None
        self.trolleyKey = None
        self.soundMoving = None
        self.soundBell = None
        self.troleyCar = None
        self.ignore('entertrolley_sphere')
        DistributedObject.delete(self)
        return
コード例 #16
0
class DistributedTutorial(DistributedObject):
    notify = directNotify.newCategory('DistributedTutorial')
    GUIDE_NAME = 'Professor Prepostera'
    GUIDE_START_POS = (5, 10, -0.5)
    GUIDE_WATCH_POS = (12.4, 27.92, 0)
    GUIDE_WATCH_HPR = (41.63, 0, 0)
    GUIDE_INTRO_SPEECH = [
        'Hey, looks like you made it!', 'So, welcome to OToontown.',
        'OToontown is short for Old Toontown, or Toontown from the past.',
        'Not long ago, Toons used to live in present day Toontown.',
        'Unfortunately, the Cogs planned a mega-invasion that was sure to be a complete takeover of Toontown and make all Toons go sad for good.',
        "There was no way we could have let that happen, so we built a time machine, and sent every Toon back in time to OToontown, where Cogs didn't exist yet.",
        'The Cogs completely took over present day Toontown, and turned it into what they wanted it to be - a business metropolis.',
        'Toons happily live and play in OToontown now, but we want to learn about present day Toontown...',
        ' ...or as we now call it, CogTropolis.',
        "We've built time machines that send Toons back to CogTropolis to fight Cogs and to see what the Cogs have done.",
        "We know that the Cogs took over Toontown and turned it into a grey business city, but we don't know how they did it.",
        'Shopkeepers around OToontown will reward you for finding evidence that may help solve the mystery of how the Cogs turned Toontown into CogTropolis.',
        'Before you are able to head to CogTropolis, you need to be trained for battle.',
        'The Cogs have become much more skilled battlers and no longer wait for you to throw a gag before attacking you.',
        'This is much more difficult for Toons, and it may take some time to get used to.',
        "I'm going to give you 2 gags to start...",
        'A cupcake, and a squirting flower.',
        'Equip Gags in your loadout to use by pressing the corresponding key on your keyboard.',
        'You can use or throw the Gag that you have equipped by pressing the ALT key.',
        'Also, use the Arrow Keys on your keyboard to move, and press CTRL to jump.',
        "I'm going to summon one of our dummy bots for you to practice battling.",
        "Click your mouse when you're ready."
    ]
    GUIDE_PT2_INFO = [
        "Now it'll get a tad bit tougher.",
        'This next dummy bot will be walking around.',
        'This will test your aiming skills.',
        "Click your mouse when you're ready."
    ]
    GUIDE_PT3_INFO = [
        'This final dummy bot will walk around and try to attack you at times.',
        'Defeat this Cog to continue on to the next part of the tutorial.'
    ]
    GUIDE_DONE = [
        'Great!',
        'Did you know that Cog Invasion Online Alpha allows you to use any Gag that you want?',
        'Just use the Gags page in your Shticker Book to swap out the Gags that you want to be able to use!',
        'Also during Alpha testing, your Toon will start off with 5000 jellybeans and 100 Laff points.',
        "If you're looking to fight some Cogs, hop on the Trolley in the playgrounds to be teleported to CogTropolis!",
        'Each playground has a different difficulty of Cogs, so be careful!',
        "You can only fight Cogs in Toontown Central, Minnie's Melodyland, Donald's Dock, and Donald's Dreamland at the moment.",
        'You can also visit the Minigame Area using your Shticker Book to play some fun minigames!',
        'These games are best to play with other Toons!',
        'Remember, if you find any bugs or strange things during gameplay, you can go to the Contact Us page at coginvasion.com to report the issue.',
        'Have fun!'
    ]
    GUIDE_START_TRAINING = "Alright! Let's do this!"

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.fsm = ClassicFSM.ClassicFSM('TutorialFSM', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('newPlayerEmerge', self.enterPlayerEmerge,
                        self.exitPlayerEmerge, ['off', 'introSpeech']),
            State.State('introSpeech', self.enterGuideIntroSpeech,
                        self.exitGuideIntroSpeech,
                        ['off', 'introSpeech2Training']),
            State.State('introSpeech2Training', self.enterIntroSpeech2Training,
                        self.exitIntroSpeech2Training, ['off', 'training1']),
            State.State('training1', self.enterTrainingPT1,
                        self.exitTrainingPT1, ['off', 'training2info']),
            State.State('training2info', self.enterTraining2Info,
                        self.exitTraining2Info, ['off', 'training2']),
            State.State('training2', self.enterTrainingPT2,
                        self.exitTrainingPT2, ['off', 'training3info']),
            State.State('training3info', self.enterTraining3Info,
                        self.exitTraining3Info, ['off', 'training3']),
            State.State('training3', self.enterTrainingPT3,
                        self.exitTrainingPT3, ['off', 'trainingDone']),
            State.State('trainingDone', self.enterTrainingDone,
                        self.exitTrainingDone, ['off', 'leaveTutorial']),
            State.State('leaveTutorial', self.enterLeaveTutorial,
                        self.exitLeaveTutorial, ['off'])
        ], 'off', 'off')
        self.fsm.enterInitialState()
        self.dnaStore = DNAStorage()
        self.streetGeom = None
        self.sky = None
        self.skyUtil = SkyUtil()
        self.guide = None
        self.music = None
        self.battleMusic = None
        self.playerCamPos = None
        self.playerCamHpr = None
        return

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def introStuff(self):
        base.localAvatar.getGeomNode().hide()
        base.localAvatar.setPos(0, 0, -0.5)
        base.localAvatar.setHpr(0, 0, 0)
        self.guide.setPos(self.GUIDE_START_POS)
        self.guide.headsUp(base.localAvatar)
        base.localAvatar.attachCamera()

    def enterPlayerEmerge(self):
        self.introStuff()
        self.guide.loop('neutral')
        base.transitions.irisIn()
        base.taskMgr.doMethodLater(1.0, self.__playerEmerge,
                                   'playerEmergeTask')

    def __playerEmerge(self, task):
        base.localAvatar.setAnimState('teleportIn',
                                      callback=self.__playerEmergeFinished)
        return Task.done

    def __playerEmergeFinished(self):
        base.localAvatar.setAnimState('neutral')
        self.fsm.request('introSpeech')

    def exitPlayerEmerge(self):
        base.localAvatar.detachCamera()
        base.taskMgr.remove('playerEmergeTask')
        base.transitions.noTransitions()

    def enterGuideIntroSpeech(self):
        base.localAvatar.attachCamera()
        renderPos = base.camera.getPos(render)
        renderHpr = base.camera.getHpr(render)
        base.localAvatar.detachCamera()
        endPos = base.localAvatar.getPos(render) + (0, 0, 4)
        base.camera.setPos(endPos)
        base.camera.lookAt(self.guide, 0, 0, 3)
        endHpr = base.camera.getHpr(render)
        base.camera.setPos(renderPos)
        base.camera.setHpr(renderHpr)
        self.chatIndex = -1
        self.doNextIntroSpeech()
        self.camMoveTrack = Sequence(
            Parallel(
                LerpPosInterval(base.camera,
                                duration=3.0,
                                pos=endPos,
                                startPos=renderPos,
                                blendType='easeOut'),
                LerpQuatInterval(base.camera,
                                 duration=3.0,
                                 hpr=endHpr,
                                 startHpr=renderHpr,
                                 blendType='easeOut')),
            Func(base.localAvatar.getGeomNode().hide))
        self.camMoveTrack.start()

    def __finishedReadingGuideIntroSpeech(self):
        self.guide.autoClearChat = True
        self.guide.setChat(self.GUIDE_START_TRAINING)
        self.fsm.request('introSpeech2Training')

    def doNextIntroSpeech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_INTRO_SPEECH):
            self.__finishedReadingGuideIntroSpeech()
            return
        self.guide.setChat(self.GUIDE_INTRO_SPEECH[self.chatIndex])
        Sequence(Wait(0.1),
                 Func(self.acceptOnce, 'mouse1-up',
                      self.doNextIntroSpeech)).start()

    def exitGuideIntroSpeech(self):
        self.camMoveTrack.finish()
        base.localAvatar.getGeomNode().show()
        del self.camMoveTrack
        del self.chatIndex

    def enterIntroSpeech2Training(self):
        startCamPos = base.camera.getPos(render)
        startCamHpr = base.camera.getHpr(render)
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        base.localAvatar.attachCamera()
        endCamPos = base.camera.getPos(render)
        endCamHpr = base.camera.getHpr(render)
        base.localAvatar.detachCamera()
        startHpr = self.guide.getHpr(render)
        self.guide.headsUp(self.GUIDE_WATCH_POS)
        endHpr = self.guide.getHpr(render)
        self.guide.loop('run')
        self.camMoveIval = Parallel(
            LerpPosInterval(base.camera,
                            duration=2.0,
                            pos=endCamPos,
                            startPos=startCamPos,
                            blendType='easeOut'),
            LerpQuatInterval(base.camera,
                             duration=2.0,
                             hpr=endCamHpr,
                             startHpr=startCamHpr,
                             blendType='easeOut'),
            Sequence(
                LerpPosInterval(self.guide,
                                duration=2.0,
                                pos=self.GUIDE_WATCH_POS,
                                startPos=self.guide.getPos(render)),
                Func(self.guide.loop, 'walk'),
                LerpHprInterval(self.guide,
                                duration=1.0,
                                hpr=self.GUIDE_WATCH_HPR,
                                startHpr=endHpr),
                Func(self.guide.loop, 'neutral')),
            LerpHprInterval(self.guide,
                            duration=1.0,
                            hpr=endHpr,
                            startHpr=startHpr))
        self.camMoveIval.setDoneEvent('introSpeech2TrainingDone')
        self.acceptOnce('introSpeech2TrainingDone', self.__handleIS2TDone)
        self.camMoveIval.start()

    def __handleIS2TDone(self):
        self.fsm.request('training1')

    def exitIntroSpeech2Training(self):
        self.ignore('introSpeech2TrainingDone')
        self.camMoveIval.finish()
        del self.camMoveIval

    def makeWhisper(self, msg):
        whisper = WhisperPopup(msg, CIGlobals.getToonFont(),
                               ChatGlobals.WTSystem)
        whisper.manage(base.marginManager)

    def enterTrainingPT1(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [0])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enableGags(1)
        base.localAvatar.showGagButton()
        base.localAvatar.startTrackAnimToSpeed()
        self.makeWhisper(
            'This should be pretty simple. Just throw a gag at this dummy bot to defeat it.'
        )

    def suitNoHealth(self, index):
        if index == 0:
            self.makeWhisper(
                ('Good job, {0}!').format(base.localAvatar.getName()))
        else:
            if index == 1:
                self.makeWhisper("Wow, you're doing very well!")

    def suitExploded(self, index):
        if index == 0:
            self.makeWhisper(
                'Pick up the jellybean that he dropped. You can use them to buy more gags for your Toon.'
            )
        self.battleMusic.stop()
        base.playMusic(self.music, looping=1, volume=0.8)

    def pickedUpJellybean(self):
        if self.fsm.getCurrentState().getName() == 'training1':
            self.fsm.request('training2info')
        else:
            if self.fsm.getCurrentState().getName() == 'training2':
                self.fsm.request('training3info')
            else:
                if self.fsm.getCurrentState().getName() == 'training3':
                    self.fsm.request('trainingDone')

    def exitTrainingPT1(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disableGags()
        base.localAvatar.stopTrackAnimToSpeed()
        base.localAvatar.hideGagButton()
        return

    def enterTraining2Info(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTraining2Speech()

    def __finishedReadingGuideTraining2Speech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('training2')

    def doNextTraining2Speech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_PT2_INFO):
            self.__finishedReadingGuideTraining2Speech()
            return
        self.guide.setChat(self.GUIDE_PT2_INFO[self.chatIndex])
        Sequence(
            Wait(0.1),
            Func(self.acceptOnce, 'mouse1-up',
                 self.doNextTraining2Speech)).start()

    def exitTraining2Info(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterTrainingPT2(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [1])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enableGags(1)
        base.localAvatar.showGagButton()
        base.localAvatar.startTrackAnimToSpeed()

    def exitTrainingPT2(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disableGags()
        base.localAvatar.stopTrackAnimToSpeed()
        base.localAvatar.hideGagButton()
        return

    def enterTraining3Info(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTraining3Speech()

    def __finishedReadingGuideTraining3Speech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('training3')

    def doNextTraining3Speech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_PT3_INFO):
            self.__finishedReadingGuideTraining3Speech()
            return
        self.guide.setChat(self.GUIDE_PT3_INFO[self.chatIndex])
        Sequence(
            Wait(0.1),
            Func(self.acceptOnce, 'mouse1-up',
                 self.doNextTraining3Speech)).start()

    def exitTraining3Info(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterTrainingPT3(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [2])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enableGags(1)
        base.localAvatar.showGagButton()
        base.localAvatar.startTrackAnimToSpeed()

    def exitTrainingPT3(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disableGags()
        base.localAvatar.stopTrackAnimToSpeed()
        base.localAvatar.hideGagButton()
        return

    def enterTrainingDone(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTrainingDoneSpeech()

    def __finishedReadingGuideTrainingDoneSpeech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('leaveTutorial')

    def doNextTrainingDoneSpeech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_DONE):
            self.__finishedReadingGuideTrainingDoneSpeech()
            return
        self.guide.setChat(self.GUIDE_DONE[self.chatIndex])
        Sequence(
            Wait(0.1),
            Func(self.acceptOnce, 'mouse1-up',
                 self.doNextTrainingDoneSpeech)).start()

    def exitTrainingDone(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterLeaveTutorial(self):
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.b_setAnimState('teleportOut',
                                        callback=self.__teleOutDone)

    def __teleOutDone(self):
        zoneId = CIGlobals.ToontownCentralId
        hoodId = CIGlobals.ToontownCentral
        whereName = 'playground'
        avId = base.localAvatar.doId
        loaderName = 'safeZoneLoader'
        self.sendUpdate('finishedTutorial')
        self.cr.playGame.load()
        self.cr.playGame.enter(hoodId, zoneId, base.localAvatar.doId)

    def exitLeaveTutorial(self):
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()

    def announceGenerate(self):
        DistributedObject.announceGenerate(self)
        base.transitions.fadeScreen(0.0)
        self.guide = Toon(base.cr)
        self.guide.autoClearChat = False
        self.guide.parseDNAStrand(NPCGlobals.NPC_DNA[self.GUIDE_NAME])
        self.guide.setName(self.GUIDE_NAME)
        self.guide.generateToon()
        self.guide.nametag.setNametagColor(
            NametagGlobals.NametagColors[NametagGlobals.CCNPC])
        self.guide.nametag.setActive(0)
        self.guide.nametag.updateAll()
        self.guide.startBlink()
        self.guide.reparentTo(render)
        base.localAvatar.reparentTo(render)
        loader.loadDNAFile(self.dnaStore,
                           'phase_3.5/dna/storage_tutorial.pdna')
        node = loader.loadDNAFile(self.dnaStore,
                                  'phase_3.5/dna/tutorial_street.pdna')
        if node.getNumParents() == 1:
            self.streetGeom = NodePath(node.getParent(0))
            self.streetGeom.reparentTo(hidden)
        else:
            self.streetGeom = hidden.attachNewNode(node)
        self.streetGeom.flattenMedium()
        gsg = base.win.getGsg()
        if gsg:
            self.streetGeom.prepareScene(gsg)
        self.streetGeom.reparentTo(render)
        self.streetGeom.setPos(20.5, -20, 0)
        self.streetGeom.setH(90)
        self.sky = loader.loadModel('phase_3.5/models/props/TT_sky.bam')
        self.skyUtil.startSky(self.sky)
        self.sky.reparentTo(camera)
        ce = CompassEffect.make(NodePath(),
                                CompassEffect.PRot | CompassEffect.PZ)
        self.sky.node().setEffect(ce)
        self.music = base.loadMusic('phase_3.5/audio/bgm/TC_SZ.mid')
        base.playMusic(self.music, volume=0.8, looping=1)
        self.battleMusic = base.loadMusic(
            'phase_3.5/audio/bgm/encntr_general_bg.mid')
        self.fsm.request('newPlayerEmerge')
        base.localAvatar.inTutorial = True

    def disable(self):
        self.fsm.requestFinalState()
        del self.fsm
        if self.guide:
            self.guide.disable()
            self.guide.delete()
            self.guide = None
        if self.streetGeom:
            self.streetGeom.removeNode()
            self.streetGeom = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.music:
            self.music.stop()
            self.music = None
        if self.battleMusic:
            self.battleMusic.stop()
            self.battleMusic = None
        self.dnaStore.reset_nodes()
        self.dnaStore.reset_hood_nodes()
        self.dnaStore.reset_place_nodes()
        self.dnaStore.reset_hood()
        self.dnaStore.reset_fonts()
        self.dnaStore.reset_DNA_vis_groups()
        self.dnaStore.reset_textures()
        self.dnaStore.reset_block_numbers()
        self.dnaStore.reset_block_zones()
        self.dnaStore.reset_suit_points()
        self.dnaStore = None
        self.skyUtil = None
        base.localAvatar.inTutorial = False
        DistributedObject.disable(self)
        return
コード例 #17
0
class PairingGameCard(PlayingCardNodePath):
    DoIntervalDefault = True
    FlipTime = 0.25
    UseDifferentCardColors = True
    CardColors = [(0.933594, 0.265625, 0.28125, 1.0),
     (0.550781, 0.824219, 0.324219, 1.0),
     (0.347656, 0.820312, 0.953125, 1.0),
     (0.460938, 0.378906, 0.824219, 1.0),
     (0.710938, 0.234375, 0.4375, 1.0),
     (0.285156, 0.328125, 0.726562, 1.0),
     (0.242188, 0.742188, 0.515625, 1.0),
     (0.96875, 0.691406, 0.699219, 1.0),
     (0.996094, 0.957031, 0.597656, 1.0),
     (0.992188, 0.480469, 0.167969, 1.0)]

    def __init__(self, value):
        style = PlayingCardGlobals.Styles[0]
        PlayingCardNodePath.__init__(self, style, value)
        self.enterCallback = None
        self.exitCallback = None
        return

    def load(self):
        oneCard = loader.loadModel('phase_4/models/minigames/garden_sign_memory')
        prop = self.attachNewNode('prop')
        PlayingCardGlobals.getImage(self.style, self.suit, self.rank).copyTo(prop)
        prop.setScale(7)
        oneCard.find('**/glow').removeNode()
        cs = oneCard.find('**/collision')
        for solidIndex in xrange(cs.node().getNumSolids()):
            cs.node().modifySolid(solidIndex).setTangible(False)

        cs.node().setName('cardCollision-%d' % self.value)
        sign = oneCard.find('**/sign1')
        if self.UseDifferentCardColors:
            index = self.rank % len(self.CardColors)
            color = self.CardColors[index]
            sign.setColorScale(*color)
        prop.setPos(0.0, 0.0, 0.08)
        prop.setP(-90)
        prop.reparentTo(oneCard)
        oneCard.reparentTo(self)
        cardBack = oneCard.find('**/sign2')
        cardBack.setColorScale(0.12, 0.35, 0.5, 1.0)
        cardModel = loader.loadModel('phase_3.5/models/gui/playingCard')
        logo = cardModel.find('**/logo')
        logo.reparentTo(self)
        logo.setScale(0.45)
        logo.setP(90)
        logo.setZ(0.025)
        logo.setX(-0.05)
        logo.setH(180)
        cardModel.removeNode()
        self.setR(0)
        self.setScale(2.5)
        self.flipIval = None
        self.turnUpSound = base.loadSfx('phase_4/audio/sfx/MG_pairing_card_flip_face_up.ogg')
        self.turnDownSound = base.loadSfx('phase_4/audio/sfx/MG_pairing_card_flip_face_down.ogg')
        return

    def unload(self):
        self.clearFlipIval()
        self.removeNode()
        del self.turnUpSound
        del self.turnDownSound

    def turnUp(self, doInterval = DoIntervalDefault):
        self.faceUp = 1
        if doInterval:
            self.clearFlipIval()
            self.flipIval = Parallel(LerpHprInterval(self, self.FlipTime, Vec3(0, 0, 0)), SoundInterval(self.turnUpSound, node=self, listenerNode=base.localAvatar, cutOff=240))
            self.flipIval.start()
        else:
            self.setR(0)

    def clearFlipIval(self):
        if self.flipIval:
            self.flipIval.finish()
            self.flipIval = None
        return

    def turnDown(self, doInterval = DoIntervalDefault):
        self.faceUp = 0
        if doInterval:
            self.clearFlipIval()
            self.flipIval = Parallel(LerpHprInterval(self, self.FlipTime, Vec3(0, 0, 180)), SoundInterval(self.turnDownSound, node=self, listenerNode=base.localAvatar, cutOff=240))
            self.flipIval.start()
        else:
            self.setR(180)
コード例 #18
0
class PairingGameCard(PlayingCardNodePath):
    DoIntervalDefault = True
    FlipTime = 0.25
    UseDifferentCardColors = True
    CardColors = [(0.933594, 0.265625, 0.28125, 1.0),
     (0.550781, 0.824219, 0.324219, 1.0),
     (0.347656, 0.820312, 0.953125, 1.0),
     (0.460938, 0.378906, 0.824219, 1.0),
     (0.710938, 0.234375, 0.4375, 1.0),
     (0.285156, 0.328125, 0.726562, 1.0),
     (0.242188, 0.742188, 0.515625, 1.0),
     (0.96875, 0.691406, 0.699219, 1.0),
     (0.996094, 0.957031, 0.597656, 1.0),
     (0.992188, 0.480469, 0.167969, 1.0)]

    def __init__(self, value):
        style = PlayingCardGlobals.Styles[0]
        PlayingCardNodePath.__init__(self, style, value)
        self.enterCallback = None
        self.exitCallback = None
        return

    def load(self):
        oneCard = loader.loadModel('phase_4/models/minigames/garden_sign_memory')
        prop = self.attachNewNode('prop')
        PlayingCardGlobals.getImage(self.style, self.suit, self.rank).copyTo(prop)
        prop.setScale(7)
        oneCard.find('**/glow').removeNode()
        cs = oneCard.find('**/collision')
        for solidIndex in xrange(cs.node().getNumSolids()):
            cs.node().modifySolid(solidIndex).setTangible(False)

        cs.node().setName('cardCollision-%d' % self.value)
        sign = oneCard.find('**/sign1')
        if self.UseDifferentCardColors:
            index = self.rank % len(self.CardColors)
            color = self.CardColors[index]
            sign.setColorScale(*color)
        prop.setPos(0.0, 0.0, 0.08)
        prop.setP(-90)
        prop.reparentTo(oneCard)
        oneCard.reparentTo(self)
        cardBack = oneCard.find('**/sign2')
        cardBack.setColorScale(0.12, 0.35, 0.5, 1.0)
        cardModel = loader.loadModel('phase_3.5/models/gui/playingCard')
        logo = cardModel.find('**/logo')
        logo.reparentTo(self)
        logo.setScale(0.45)
        logo.setP(90)
        logo.setZ(0.025)
        logo.setX(-0.05)
        logo.setH(180)
        cardModel.removeNode()
        self.setR(0)
        self.setScale(2.5)
        self.flipIval = None
        self.turnUpSound = base.loader.loadSfx('phase_4/audio/sfx/MG_pairing_card_flip_face_up.ogg')
        self.turnDownSound = base.loader.loadSfx('phase_4/audio/sfx/MG_pairing_card_flip_face_down.ogg')
        return

    def unload(self):
        self.clearFlipIval()
        self.removeNode()
        del self.turnUpSound
        del self.turnDownSound

    def turnUp(self, doInterval = DoIntervalDefault):
        self.faceUp = 1
        if doInterval:
            self.clearFlipIval()
            self.flipIval = Parallel(LerpHprInterval(self, self.FlipTime, Vec3(0, 0, 0)), SoundInterval(self.turnUpSound, node=self, listenerNode=base.localAvatar, cutOff=240))
            self.flipIval.start()
        else:
            self.setR(0)

    def clearFlipIval(self):
        if self.flipIval:
            self.flipIval.finish()
            self.flipIval = None
        return

    def turnDown(self, doInterval = DoIntervalDefault):
        self.faceUp = 0
        if doInterval:
            self.clearFlipIval()
            self.flipIval = Parallel(LerpHprInterval(self, self.FlipTime, Vec3(0, 0, 180)), SoundInterval(self.turnDownSound, node=self, listenerNode=base.localAvatar, cutOff=240))
            self.flipIval.start()
        else:
            self.setR(180)
コード例 #19
0
class CogThief(DirectObject):
    notify = directNotify.newCategory('CogThief')
    DefaultSpeedWalkAnim = 4.0
    CollisionRadius = 1.25
    MaxFriendsVisible = 4
    Infinity = 100000.0
    SeparationDistance = 6.0
    MinUrgency = 0.5
    MaxUrgency = 0.75
    
    def __init__(self, cogIndex, suitType, game, cogSpeed):
        self.cogIndex = cogIndex
        self.suitType = suitType
        self.game = game
        self.cogSpeed = cogSpeed
        suit = Suit.Suit()
        d = SuitDNA.SuitDNA()
        d.newSuit(suitType)
        suit.setDNA(d)
        suit.pose('walk', 0)
        self.suit = suit
        self.goal = CTGG.NoGoal
        self.goalId = CTGG.InvalidGoalId
        self.lastLocalTimeStampFromAI = 0
        self.lastPosFromAI = Point3(0, 0, 0)
        self.lastThinkTime = 0
        self.doneAdjust = False
        self.barrel = CTGG.NoBarrelCarried
        self.signalledAtReturnPos = False
        self.defaultPlayRate = 1.0
        self.netTimeSentToStartByHit = 0
        self.velocity = Vec3(0, 0, 0)
        self.oldVelocity = Vec3(0, 0, 0)
        self.acceleration = Vec3(0, 0, 0)
        self.bodyLength = self.CollisionRadius * 2
        self.cruiseDistance = 2 * self.bodyLength
        self.maxVelocity = self.cogSpeed
        self.maxAcceleration = 5.0
        self.perceptionRange = 6
        self.notify.debug('cogSpeed=%s' % self.cogSpeed)
        self.kaboomSound = loader.loadSfx('phase_4/audio/sfx/MG_cannon_fire_alt.mp3')
        self.kaboom = loader.loadModel('phase_4/models/minigames/ice_game_kaboom')
        self.kaboom.setScale(2.0)
        self.kaboom.setBillboardPointEye()
        self.kaboom.hide()
        self.kaboomTrack = None
        splatName = 'splat-creampie'
        self.splat = globalPropPool.getProp(splatName)
        self.splat.setBillboardPointEye()
        self.splatType = globalPropPool.getPropType(splatName)
        self.pieHitSound = globalBattleSoundCache.getSound('AA_wholepie_only.mp3')

    
    def destroy(self):
        self.ignoreAll()
        self.suit.delete()
        self.game = None

    
    def uniqueName(self, baseStr):
        return baseStr + '-' + str(self.game.doId)

    
    def handleEnterSphere(self, collEntry):
        intoNp = collEntry.getIntoNodePath()
        self.notify.debug('handleEnterSphere suit %d hit %s' % (self.cogIndex, intoNp))
        if self.game:
            self.game.handleEnterSphere(collEntry)
        

    
    def gameStart(self, gameStartTime):
        self.gameStartTime = gameStartTime
        self.initCollisions()
        self.startWalkAnim()

    
    def gameEnd(self):
        self.moveIval.pause()
        del self.moveIval
        self.shutdownCollisions()
        self.suit.loop('neutral')

    
    def initCollisions(self):
        self.collSphere = CollisionSphere(0, 0, 0, 1.25)
        self.collSphere.setTangible(1)
        name = 'CogThiefSphere-%d' % self.cogIndex
        self.collSphereName = self.uniqueName(name)
        self.collNode = CollisionNode(self.collSphereName)
        self.collNode.setIntoCollideMask(CTGG.BarrelBitmask | ToontownGlobals.WallBitmask)
        self.collNode.addSolid(self.collSphere)
        self.collNodePath = self.suit.attachNewNode(self.collNode)
        self.accept('enter' + self.collSphereName, self.handleEnterSphere)
        self.pieCollSphere = CollisionTube(0, 0, 0, 0, 0, 4, self.CollisionRadius)
        self.pieCollSphere.setTangible(1)
        name = 'CogThiefPieSphere-%d' % self.cogIndex
        self.pieCollSphereName = self.uniqueName(name)
        self.pieCollNode = CollisionNode(self.pieCollSphereName)
        self.pieCollNode.setIntoCollideMask(ToontownGlobals.PieBitmask)
        self.pieCollNode.addSolid(self.pieCollSphere)
        self.pieCollNodePath = self.suit.attachNewNode(self.pieCollNode)

    
    def shutdownCollisions(self):
        self.ignore(self.uniqueName('enter' + self.collSphereName))
        del self.collSphere
        self.collNodePath.removeNode()
        del self.collNodePath
        del self.collNode

    
    def updateGoal(self, timestamp, inResponseClientStamp, goalType, goalId, pos):
        self.notify.debug('self.netTimeSentToStartByHit =%s' % self.netTimeSentToStartByHit)
        if not self.game:
            self.notify.debug('updateGoal self.game is None, just returning')
            return None
        
        if not self.suit:
            self.notify.debug('updateGoal self.suit is None, just returning')
            return None
        
        if self.goal == CTGG.NoGoal:
            self.startWalkAnim()
        
        if goalType == CTGG.NoGoal:
            self.notify.debug('updateGoal setting position to %s' % pos)
            self.suit.setPos(pos)
        
        self.lastThinkTime = 0
        self.velocity = Vec3(0, 0, 0)
        self.oldVelocity = Vec3(0, 0, 0)
        self.acceleration = Vec3(0, 0, 0)
        if goalType == CTGG.RunAwayGoal:
            pass
        1
        if inResponseClientStamp < self.netTimeSentToStartByHit and self.goal == CTGG.NoGoal and goalType == CTGG.RunAwayGoal:
            self.notify.warning('ignoring newGoal %s as cog %d was recently hit responsetime=%s hitTime=%s' % (CTGG.GoalStr[goalType], self.cogIndex, inResponseClientStamp, self.netTimeSentToStartByHit))
        else:
            self.lastLocalTimeStampFromAI = globalClockDelta.networkToLocalTime(timestamp, bits = 32)
            self.goal = goalType
            self.goalId = goalId
            self.lastPosFromAI = pos
            self.doneAdjust = False
        self.signalledAtReturnPos = False

    
    def startWalkAnim(self):
        if self.suit:
            self.suit.loop('walk')
            speed = self.cogSpeed
            self.defaultPlayRate = float(self.cogSpeed / self.DefaultSpeedWalkAnim)
            self.suit.setPlayRate(self.defaultPlayRate, 'walk')
        

    
    def think(self):
        if self.goal == CTGG.ToonGoal:
            self.thinkAboutCatchingToon()
        elif self.goal == CTGG.BarrelGoal:
            self.thinkAboutGettingBarrel()
        elif self.goal == CTGG.RunAwayGoal:
            self.thinkAboutRunAway()
        

    
    def thinkAboutCatchingToon(self):
        if not self.game:
            return None
        
        av = self.game.getAvatar(self.goalId)
        if av:
            if not self.lastThinkTime:
                self.lastThinkTime = globalClock.getFrameTime()
            
            diffTime = globalClock.getFrameTime() - self.lastThinkTime
            avPos = av.getPos()
            myPos = self.suit.getPos()
            if not self.doneAdjust:
                myPos = self.lastPosFromAI
                self.notify.debug('thinkAboutCatchingToon not doneAdjust setting pos %s' % myPos)
                self.doneAdjust = True
            
            self.suit.setPos(myPos)
            if self.game.isToonPlayingHitTrack(self.goalId):
                self.suit.headsUp(av)
                self.velocity = Vec3(0, 0, 0)
                self.oldVelocity = Vec3(0, 0, 0)
                self.acceleration = Vec3(0, 0, 0)
            else:
                self.commonMove()
            newPos = self.suit.getPos()
            self.adjustPlayRate(newPos, myPos, diffTime)
        
        self.lastThinkTime = globalClock.getFrameTime()

    
    def convertNetworkStampToGameTime(self, timestamp):
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits = 32)
        gameTime = self.game.local2GameTime(localStamp)
        return gameTime

    
    def respondToToonHit(self, timestamp):
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits = 32)
        if self.netTimeSentToStartByHit < timestamp:
            self.clearGoal()
            self.showKaboom()
            startPos = CTGG.CogStartingPositions[self.cogIndex]
            oldPos = self.suit.getPos()
            self.suit.setPos(startPos)
            if self.netTimeSentToStartByHit < timestamp:
                self.netTimeSentToStartByHit = timestamp
            
        else:
            self.notify.debug('localStamp = %s, lastLocalTimeStampFromAI=%s, ignoring respondToToonHit' % (localStamp, self.lastLocalTimeStampFromAI))
        self.notify.debug('respondToToonHit self.netTimeSentToStartByHit = %s' % self.netTimeSentToStartByHit)

    
    def clearGoal(self):
        self.goal = CTGG.NoGoal
        self.goalId = CTGG.InvalidGoalId

    
    def thinkAboutGettingBarrel(self):
        if not self.game:
            return None
        
        if not hasattr(self.game, 'barrels'):
            return None
        
        if self.goalId not in xrange(len(self.game.barrels)):
            return None
        
        if not self.lastThinkTime:
            self.lastThinkTime = globalClock.getFrameTime()
        
        diffTime = globalClock.getFrameTime() - self.lastThinkTime
        barrel = self.game.barrels[self.goalId]
        barrelPos = barrel.getPos()
        myPos = self.suit.getPos()
        if not self.doneAdjust:
            myPos = self.lastPosFromAI
            self.notify.debug('thinkAboutGettingBarrel not doneAdjust setting position to %s' % myPos)
            self.suit.setPos(myPos)
            self.doneAdjust = True
        
        displacement = barrelPos - myPos
        distanceToToon = displacement.length()
        self.suit.headsUp(barrel)
        lengthTravelled = diffTime * self.cogSpeed
        if lengthTravelled > distanceToToon:
            lengthTravelled = distanceToToon
        
        displacement.normalize()
        dirVector = displacement
        dirVector *= lengthTravelled
        newPos = myPos + dirVector
        newPos.setZ(0)
        self.suit.setPos(newPos)
        self.adjustPlayRate(newPos, myPos, diffTime)
        self.lastThinkTime = globalClock.getFrameTime()

    
    def stopWalking(self, timestamp):
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits = 32)
        if localStamp > self.lastLocalTimeStampFromAI:
            self.suit.loop('neutral')
            self.clearGoal()
        

    
    def thinkAboutRunAway(self):
        if not self.game:
            return None
        
        if not self.lastThinkTime:
            self.lastThinkTime = globalClock.getFrameTime()
        
        diffTime = globalClock.getFrameTime() - self.lastThinkTime
        returnPos = CTGG.CogReturnPositions[self.goalId]
        myPos = self.suit.getPos()
        if not self.doneAdjust:
            myPos = self.lastPosFromAI
            self.suit.setPos(myPos)
            self.doneAdjust = True
        
        displacement = returnPos - myPos
        distanceToToon = displacement.length()
        tempNp = render.attachNewNode('tempRet')
        tempNp.setPos(returnPos)
        self.suit.headsUp(tempNp)
        tempNp.removeNode()
        lengthTravelled = diffTime * self.cogSpeed
        if lengthTravelled > distanceToToon:
            lengthTravelled = distanceToToon
        
        displacement.normalize()
        dirVector = displacement
        dirVector *= lengthTravelled
        newPos = myPos + dirVector
        newPos.setZ(0)
        self.suit.setPos(newPos)
        self.adjustPlayRate(newPos, myPos, diffTime)
        if (self.suit.getPos() - returnPos).length() < 0.0001:
            if not (self.signalledAtReturnPos) and self.barrel >= 0:
                self.game.sendCogAtReturnPos(self.cogIndex, self.barrel)
                self.signalledAtReturnPos = True
            
        
        self.lastThinkTime = globalClock.getFrameTime()

    
    def makeCogCarryBarrel(self, timestamp, inResponseClientStamp, barrelModel, barrelIndex, cogPos):
        if not self.game:
            return None
        
        localTimeStamp = globalClockDelta.networkToLocalTime(timestamp, bits = 32)
        self.lastLocalTimeStampFromAI = localTimeStamp
        inResponseGameTime = self.convertNetworkStampToGameTime(inResponseClientStamp)
        self.notify.debug('inResponseGameTime =%s timeSentToStart=%s' % (inResponseGameTime, self.netTimeSentToStartByHit))
        if inResponseClientStamp < self.netTimeSentToStartByHit and self.goal == CTGG.NoGoal:
            self.notify.warning('ignoring makeCogCarrybarrel')
        else:
            barrelModel.setPos(0, -1.0, 1.5)
            barrelModel.reparentTo(self.suit)
            self.suit.setPos(cogPos)
            self.barrel = barrelIndex

    
    def makeCogDropBarrel(self, timestamp, inResponseClientStamp, barrelModel, barrelIndex, barrelPos):
        localTimeStamp = globalClockDelta.networkToLocalTime(timestamp, bits = 32)
        self.lastLocalTimeStampFromAI = localTimeStamp
        barrelModel.reparentTo(render)
        barrelModel.setPos(barrelPos)
        self.barrel = CTGG.NoBarrelCarried

    
    def respondToPieHit(self, timestamp):
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits = 32)
        if self.netTimeSentToStartByHit < timestamp:
            self.clearGoal()
            self.showSplat()
            startPos = CTGG.CogStartingPositions[self.cogIndex]
            oldPos = self.suit.getPos()
            self.suit.setPos(startPos)
            if self.netTimeSentToStartByHit < timestamp:
                self.netTimeSentToStartByHit = timestamp
            
        else:
            self.notify.debug('localStamp = %s, lastLocalTimeStampFromAI=%s, ignoring respondToPieHit' % (localStamp, self.lastLocalTimeStampFromAI))
            self.notify.debug('respondToPieHit self.netTimeSentToStartByHit = %s' % self.netTimeSentToStartByHit)

    
    def cleanup(self):
        self.clearGoal()
        self.ignoreAll()
        self.suit.delete()
        if self.kaboomTrack and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        
        self.suit = None
        self.game = None

    
    def adjustPlayRate(self, newPos, oldPos, diffTime):
        lengthTravelled = (newPos - oldPos).length()
        if diffTime:
            speed = lengthTravelled / diffTime
        else:
            speed = self.cogSpeed
        rateMult = speed / self.cogSpeed
        newRate = rateMult * self.defaultPlayRate
        self.suit.setPlayRate(newRate, 'walk')

    
    def commonMove(self):
        if not self.lastThinkTime:
            self.lastThinkTime = globalClock.getFrameTime()
        
        dt = globalClock.getFrameTime() - self.lastThinkTime
        self.oldpos = self.suit.getPos()
        pos = self.suit.getPos()
        pos += self.velocity * dt
        self.suit.setPos(pos)
        self.seeFriends()
        acc = Vec3(0, 0, 0)
        self.accumulate(acc, self.getTargetVector())
        if self.numFlockmatesSeen > 0:
            keepDistanceVector = self.keepDistance()
            oldAcc = Vec3(acc)
            self.accumulate(acc, keepDistanceVector)
            if self.cogIndex == 0:
                pass
            
        
        if acc.length() > self.maxAcceleration:
            acc.normalize()
            acc *= self.maxAcceleration
        
        self.oldVelocity = self.velocity
        self.velocity += acc
        if self.velocity.length() > self.maxVelocity:
            self.velocity.normalize()
            self.velocity *= self.maxVelocity
        
        forwardVec = Vec3(1, 0, 0)
        heading = rad2Deg(math.atan2(self.velocity[1], self.velocity[0]))
        heading -= 90
        self.suit.setH(heading)

    
    def getTargetVector(self):
        targetPos = Point3(0, 0, 0)
        if self.goal == CTGG.ToonGoal:
            av = self.game.getAvatar(self.goalId)
            if av:
                targetPos = av.getPos()
            
        elif self.goal == CTGG.BarrelGoal:
            barrel = self.game.barrels[self.goalId]
            targetPos = barrel.getPos()
        elif self.goal == CTGG.RunAwayGoal:
            targetPos = CTGG.CogReturnPositions[self.goalId]
        
        targetPos.setZ(0)
        myPos = self.suit.getPos()
        diff = targetPos - myPos
        if diff.length() > 1.0:
            diff.normalize()
            diff *= 1.0
        
        return diff

    
    def accumulate(self, accumulator, valueToAdd):
        accumulator += valueToAdd
        return accumulator.length()

    
    def seeFriends(self):
        self.clearVisibleList()
        for cogIndex in self.game.cogInfo.keys():
            if cogIndex == self.cogIndex:
                continue
            
            if self.sameGoal(cogIndex):
                dist = self.canISee(cogIndex)
                if dist != self.Infinity:
                    self.addToVisibleList(cogIndex)
                    if dist < self.distToNearestFlockmate:
                        self.nearestFlockmate = cogIndex
                        self.distToNearestFlockmate = dist
                    
                
            dist != self.Infinity
        
        return self.numFlockmatesSeen

    
    def clearVisibleList(self):
        self.visibleFriendsList = []
        self.numFlockmatesSeen = 0
        self.nearestFlockmate = None
        self.distToNearestFlockmate = self.Infinity

    
    def addToVisibleList(self, cogIndex):
        if self.numFlockmatesSeen < self.MaxFriendsVisible:
            self.visibleFriendsList.append(cogIndex)
            self.numFlockmatesSeen += 1
            if self.cogIndex == 0:
                pass
            
        

    
    def canISee(self, cogIndex):
        if self.cogIndex == cogIndex:
            return self.Infinity
        
        cogThief = self.game.getCogThief(cogIndex)
        distance = self.suit.getDistance(cogThief.suit)
        if distance < self.perceptionRange:
            return distance
        
        return self.Infinity

    
    def sameGoal(self, cogIndex):
        cogThief = self.game.getCogThief(cogIndex)
        if cogThief.goalId == self.goalId:
            pass
        result = cogThief.goal == self.goal
        return result

    
    def keepDistance(self):
        ratio = self.distToNearestFlockmate / self.SeparationDistance
        nearestThief = self.game.getCogThief(self.nearestFlockmate)
        change = nearestThief.suit.getPos() - self.suit.getPos()
        if ratio < self.MinUrgency:
            ratio = self.MinUrgency
        
        if ratio > self.MaxUrgency:
            ratio = self.MaxUrgency
        
        if self.distToNearestFlockmate < self.SeparationDistance:
            change.normalize()
            change *= -(1 - ratio)
        elif self.distToNearestFlockmate > self.SeparationDistance:
            change.normalize()
            change *= ratio
        else:
            change = Vec3(0, 0, 0)
        return change

    
    def showKaboom(self):
        if self.kaboomTrack and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        
        self.kaboom.reparentTo(render)
        self.kaboom.setPos(self.suit.getPos())
        self.kaboom.setZ(3)
        self.kaboomTrack = Parallel(SoundInterval(self.kaboomSound, volume = 0.5), Sequence(Func(self.kaboom.showThrough), LerpScaleInterval(self.kaboom, duration = 0.5, scale = Point3(10, 10, 10), startScale = Point3(1, 1, 1), blendType = 'easeOut'), Func(self.kaboom.hide)))
        self.kaboomTrack.start()

    
    def showSplat(self):
        if self.kaboomTrack and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        
        self.splat.reparentTo(render)
        self.splat.setPos(self.suit.getPos())
        self.splat.setZ(3)
        self.kaboomTrack = Parallel(SoundInterval(self.pieHitSound, volume = 1.0), Sequence(Func(self.splat.showThrough), LerpScaleInterval(self.splat, duration = 0.5, scale = 1.75, startScale = Point3(0.10000000000000001, 0.10000000000000001, 0.10000000000000001), blendType = 'easeOut'), Func(self.splat.hide)))
        self.kaboomTrack.start()
コード例 #20
0
class DistributedPartyGate(DistributedObject.DistributedObject):
    notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPartyGate")

    def __init__(self, cr):
        DistributedObject.DistributedObject.__init__(self, cr)
        self.publicPartyChooseGuiDoneEvent = "doneChoosingPublicParty"
        self.publicPartyGui = PublicPartyGui(self.publicPartyChooseGuiDoneEvent)
        self.publicPartyGui.stash()
        self.loadClockSounds()
        self.hourSoundInterval = Sequence()
        self.accept("stoppedAsleep", self.handleSleep)

    def loadClockSounds(self):
        self.clockSounds = []
        for i in range(1, 13):
            if i < 10:
                si = "0%d" % i
            else:
                si = "%d" % i
            self.clockSounds.append(base.loadSfx("phase_4/audio/sfx/clock%s.mp3" % si))

    def generate(self):
        DistributedObject.DistributedObject.generate(self)
        loader = self.cr.playGame.hood.loader
        partyGate = loader.geom.find("**/partyGate_grp")
        if partyGate.isEmpty():
            self.notify.warning("Could not find partyGate_grp in loader.geom")
            return None

        self.clockFlat = partyGate.find("**/clock_flat")
        collSphere = CollisionSphere(0, 0, 0, 6.9000000000000004)
        collSphere.setTangible(1)
        self.partyGateSphere = CollisionNode("PartyGateSphere")
        self.partyGateSphere.addSolid(collSphere)
        self.partyGateCollNodePath = partyGate.find("**/partyGate_stepsLocator").attachNewNode(self.partyGateSphere)
        self._DistributedPartyGate__enableCollisions()
        self.toontownTimeGui = ServerTimeGui(partyGate, hourCallback=self.hourChange)
        self.toontownTimeGui.setPos(
            partyGate.find("**/clockText_locator").getPos() + Point3(0.0, 0.0, -0.20000000000000001)
        )
        self.toontownTimeGui.setHpr(partyGate.find("**/clockText_locator").getHpr())
        self.toontownTimeGui.setScale(12.0, 1.0, 26.0)
        self.toontownTimeGui.amLabel.setPos(-0.035000000000000003, 0, -0.032000000000000001)
        self.toontownTimeGui.amLabel.setScale(0.5)
        self.toontownTimeGui.updateTime()
        self.setupSignText()

    def setupSignText(self):
        loader = self.cr.playGame.hood.loader
        partyGate = loader.geom.find("**/partyGateSignGroup")
        if partyGate.isEmpty():
            self.notify.warning("Could not find partyGate_grp in loader.geom")
            return None

        gateFont = ToontownGlobals.getMinnieFont()
        leftSign = partyGate.find("**/signTextL_locatorBack")
        signScale = 0.34999999999999998
        wordWrap = 8
        leftText = DirectLabel.DirectLabel(
            parent=leftSign,
            pos=(0, 0.0, 0.0),
            relief=None,
            text=TTLocalizer.PartyGateLeftSign,
            text_align=TextNode.ACenter,
            text_font=gateFont,
            text_wordwrap=wordWrap,
            text_fg=Vec4(0.69999999999999996, 0.29999999999999999, 0.29999999999999999, 1.0),
            scale=signScale,
        )
        rightSign = partyGate.find("**/signTextR_locatorFront")
        rightText = DirectLabel.DirectLabel(
            parent=rightSign,
            pos=(0, 0.0, 0.0),
            relief=None,
            text=TTLocalizer.PartyGateRightSign,
            text_align=TextNode.ACenter,
            text_font=gateFont,
            text_wordwrap=wordWrap,
            text_fg=Vec4(0.69999999999999996, 0.29999999999999999, 0.29999999999999999, 1.0),
            scale=signScale,
        )

    def announceGenerate(self):
        DistributedObject.DistributedObject.announceGenerate(self)
        if ToontownGlobals.dnaMap.has_key(self.zoneId):
            playground = ToontownGlobals.dnaMap[self.zoneId]
        else:
            playground = ToontownGlobals.dnaMap[2000]
        self.toontownTimeGui.hourLabel["text_fg"] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.colonLabel["text_fg"] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.minutesLabel["text_fg"] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.amLabel["text_fg"] = PartyGlobals.PlayGroundToPartyClockColors[playground]

    def disable(self):
        DistributedObject.DistributedObject.disable(self)
        self._DistributedPartyGate__disableCollisions()
        self.toontownTimeGui.ival.finish()
        self.hourSoundInterval.finish()
        if self.publicPartyGui:
            self.publicPartyGui.stash()
            self.publicPartyGui.destroy()
            self.publicPartyGui = None

    def delete(self):
        DistributedObject.DistributedObject.delete(self)
        self.toontownTimeGui.destroy()
        del self.toontownTimeGui
        self.hourSoundInterval.finish()
        del self.hourSoundInterval
        del self.clockFlat
        if self.publicPartyGui:
            self.publicPartyGui.destroy()
            del self.publicPartyGui

        self.partyGateCollNodePath.removeNode()
        del self.partyGateCollNodePath
        self.ignoreAll()

    def showMessage(self, message):
        self.messageDoneEvent = self.uniqueName("messageDoneEvent")
        self.acceptOnce(self.messageDoneEvent, self._DistributedPartyGate__handleMessageDone)
        self.messageGui = TTDialog.TTGlobalDialog(
            doneEvent=self.messageDoneEvent, message=message, style=TTDialog.Acknowledge
        )

    def _DistributedPartyGate__handleMessageDone(self):
        self.ignore(self.messageDoneEvent)
        self.freeAvatar()
        self.messageGui.cleanup()
        self.messageGui = None

    def _DistributedPartyGate__handleAskDone(self):
        DistributedPartyGate.notify.debug("__handleAskDone")
        self.ignore(self.publicPartyChooseGuiDoneEvent)
        doneStatus = self.publicPartyGui.doneStatus
        self.publicPartyGui.stash()
        if doneStatus is None:
            self.freeAvatar()
            return None

        self.sendUpdate("partyChoiceRequest", [base.localAvatar.doId, doneStatus[0], doneStatus[1]])

    def partyRequestDenied(self, reason):
        DistributedPartyGate.notify.debug(
            "partyRequestDenied( reason=%s )" % PartyGlobals.PartyGateDenialReasons.getString(reason)
        )
        if reason == PartyGlobals.PartyGateDenialReasons.Unavailable:
            self.showMessage(TTLocalizer.PartyGatePartyUnavailable)
        elif reason == PartyGlobals.PartyGateDenialReasons.Full:
            self.showMessage(TTLocalizer.PartyGatePartyFull)

    def setParty(self, partyInfoTuple):
        DistributedPartyGate.notify.debug("setParty")
        self.freeAvatar()
        if partyInfoTuple[0] == 0:
            DistributedPartyGate.notify.debug("Public Party closed before toon could get to it.")
            return None

        (shardId, zoneId, numberOfGuests, hostName, activityIds, lane) = partyInfoTuple
        if base.localAvatar.defaultShard == shardId:
            shardId = None

        base.cr.playGame.getPlace().requestLeave(
            {
                "loader": "safeZoneLoader",
                "where": "party",
                "how": "teleportIn",
                "hoodId": ToontownGlobals.PartyHood,
                "zoneId": zoneId,
                "shardId": shardId,
                "avId": -1,
            }
        )

    def freeAvatar(self):
        base.localAvatar.posCamera(0, 0)
        base.cr.playGame.getPlace().setState("walk")

    def hourChange(self, currentHour):
        currentHour = currentHour % 12
        if currentHour == 0:
            currentHour = 12

        self.hourSoundInterval = Parallel()
        seq1 = Sequence()
        for i in range(currentHour):
            seq1.append(SoundInterval(self.clockSounds[i]))
            seq1.append(Wait(0.20000000000000001))

        timeForEachDeformation = seq1.getDuration() / currentHour
        seq2 = Sequence()
        for i in range(currentHour):
            seq2.append(
                self.clockFlat.scaleInterval(
                    timeForEachDeformation / 2.0, Vec3(0.90000000000000002, 1.0, 1.2), blendType="easeInOut"
                )
            )
            seq2.append(
                self.clockFlat.scaleInterval(
                    timeForEachDeformation / 2.0, Vec3(1.2, 1.0, 0.90000000000000002), blendType="easeInOut"
                )
            )

        seq2.append(
            self.clockFlat.scaleInterval(timeForEachDeformation / 2.0, Vec3(1.0, 1.0, 1.0), blendType="easeInOut")
        )
        self.hourSoundInterval.append(seq1)
        self.hourSoundInterval.append(seq2)
        self.hourSoundInterval.start()

    def handleEnterGateSphere(self, collEntry):
        self.notify.debug("Entering steps Sphere....")
        base.cr.playGame.getPlace().fsm.request("stopped")
        self.sendUpdate("getPartyList", [base.localAvatar.doId])

    def listAllPublicParties(self, publicPartyInfo):
        self.notify.debug("listAllPublicParties : publicPartyInfo = %s" % publicPartyInfo)
        self.acceptOnce(self.publicPartyChooseGuiDoneEvent, self._DistributedPartyGate__handleAskDone)
        self.publicPartyGui.refresh(publicPartyInfo)
        self.publicPartyGui.unstash()

    def _DistributedPartyGate__enableCollisions(self):
        self.accept("enterPartyGateSphere", self.handleEnterGateSphere)
        self.partyGateSphere.setCollideMask(OTPGlobals.WallBitmask)

    def _DistributedPartyGate__disableCollisions(self):
        self.ignore("enterPartyGateSphere")
        self.partyGateSphere.setCollideMask(BitMask32(0))

    def handleSleep(self):
        if hasattr(self, "messageGui") and self.messageGui:
            self._DistributedPartyGate__handleMessageDone()
コード例 #21
0
class DodgeballFirstPerson(FirstPerson):
    """The first person controls for the local player in Winter Dodgeball"""

    notify = directNotify.newCategory("DodgeballFirstPerson")

    MaxPickupDistance = 5.0

    def __init__(self, mg):
        self.mg = mg
        self.crosshair = None
        self.soundCatch = None
        self.vModelRoot = None
        self.vModel = None
        self.ival = None
        self.soundPickup = base.loadSfx(
            'phase_4/audio/sfx/MG_snowball_pickup.wav')
        self.fakeSnowball = loader.loadModel(
            "phase_5/models/props/snowball.bam")
        self.hasSnowball = False
        self.mySnowball = None
        self.fsm = ClassicFSM.ClassicFSM("DodgeballFirstPerson", [
            State.State("off", self.enterOff, self.exitOff),
            State.State("hold", self.enterHold, self.exitHold),
            State.State("catch", self.enterCatch, self.exitCatch),
            State.State("throw", self.enterThrow, self.exitThrow)
        ], "off", "off")
        self.fsm.enterInitialState()

        FirstPerson.__init__(self)

    def enterOff(self):
        if self.vModel:
            self.vModel.hide()

    def exitOff(self):
        if self.vModel:
            self.vModel.show()

    def enterHold(self):
        self.ival = Sequence(ActorInterval(self.vModel, "hold-start"),
                             Func(self.vModel.loop, "hold"))
        self.ival.start()

    def exitHold(self):
        if self.ival:
            self.ival.finish()
            self.ival = None
        self.vModel.stop()

    def enterThrow(self):
        self.ival = Parallel(
            Sequence(Wait(0.4), Func(self.mySnowball.b_throw)),
            Sequence(ActorInterval(self.vModel, "throw"),
                     Func(self.fsm.request, 'off')))
        self.ival.start()

    def exitThrow(self):
        if self.ival:
            self.ival.pause()
            self.ival = None
        self.vModel.stop()

    def enterCatch(self):
        self.ival = Parallel(
            Sequence(Wait(0.2), Func(self.__tryToCatchOrGrab)),
            Sequence(ActorInterval(self.vModel, "catch"),
                     Func(self.__maybeHold)))
        self.ival.start()

    def __maybeHold(self):
        if self.hasSnowball:
            self.fsm.request('hold')
        else:
            self.fsm.request('off')

    def __tryToCatchOrGrab(self):
        snowballs = list(self.mg.snowballs)
        snowballs.sort(
            key=lambda snowball: snowball.getDistance(base.localAvatar))
        for i in xrange(len(snowballs)):
            snowball = snowballs[i]
            if (not snowball.hasOwner() and not snowball.isAirborne
                    and snowball.getDistance(base.localAvatar) <=
                    DodgeballFirstPerson.MaxPickupDistance):
                snowball.b_pickup()
                self.mySnowball = snowball
                self.fakeSnowball.setPosHpr(0, 0.73, 0, 0, 0, 0)
                self.fakeSnowball.reparentTo(
                    self.vModel.exposeJoint(None, "modelRoot", "Bone.011"))
                base.playSfx(self.soundPickup)
                self.hasSnowball = True
                break

    def exitCatch(self):
        self.vModel.stop()
        if self.ival:
            self.ival.pause()
            self.ival = None

    def start(self):
        # Black crosshair because basically the entire arena is white.
        self.crosshair = getCrosshair(color=(0, 0, 0, 1), hidden=False)

        self.soundCatch = base.loadSfx(
            "phase_4/audio/sfx/MG_sfx_vine_game_catch.ogg")

        self.vModelRoot = camera.attachNewNode('vModelRoot')
        self.vModelRoot.setPos(-0.09, 1.38, -2.48)

        self.vModel = Actor(
            "phase_4/models/minigames/v_dgm.egg", {
                "hold": "phase_4/models/minigames/v_dgm-ball-hold.egg",
                "hold-start":
                "phase_4/models/minigames/v_dgm-ball-hold-start.egg",
                "throw": "phase_4/models/minigames/v_dgm-ball-throw.egg",
                "catch": "phase_4/models/minigames/v_dgm-ball-catch.egg"
            })
        self.vModel.setBlend(frameBlend=True)
        self.vModel.reparentTo(self.vModelRoot)
        self.vModel.setBin("fixed", 40)
        self.vModel.setDepthTest(False)
        self.vModel.setDepthWrite(False)
        self.vModel.hide()

        base.localAvatar.walkControls.setWalkSpeed(ToonForwardSpeed,
                                                   ToonJumpForce,
                                                   ToonReverseSpeed,
                                                   ToonRotateSpeed)

        FirstPerson.start(self)

    def reallyStart(self):
        FirstPerson.reallyStart(self)
        base.localAvatar.startTrackAnimToSpeed()

        self.accept('mouse3', self.__handleCatchOrGrabButton)
        self.accept('mouse1', self.__handleThrowButton)

    def __handleThrowButton(self):
        if self.hasSnowball and self.mySnowball and self.fsm.getCurrentState(
        ).getName() == 'hold':
            self.fakeSnowball.reparentTo(hidden)
            self.fsm.request('throw')

    def __handleCatchOrGrabButton(self):
        if not self.hasSnowball and not self.mySnowball and self.fsm.getCurrentState(
        ).getName() == 'off':
            self.fsm.request('catch')

    def reallyEnd(self):
        base.localAvatar.setWalkSpeedNormal()
        FirstPerson.reallyEnd(self)
class DistributedDodgeballGame(DistributedToonFPSGame, TeamMinigame):
    """The winter dodgeball minigame (client side)"""

    notify = directNotify.newCategory("DistributedDodgeballGame")

    TreeData = [['prop_snow_tree_small_ur', Point3(23.23, 66.52, 7.46)],
	            ['prop_snow_tree_small_ul', Point3(-34.03, 88.02, 24.17)],
	            ['prop_snow_tree_small_ur', Point3(-54.80, 0, 4.19)],
	            ['prop_snow_tree_small_ul', Point3(54.80, -5, 4.19)],
	            ['prop_snow_tree_small_ur', Point3(62.71, 62.66, 16.80)],
	            ['prop_snow_tree_small_ul', Point3(-23.23, -66.52, 6)],
	            ['prop_snow_tree_small_ur', Point3(34.03, -88.02, 23)],
	            ['prop_snow_tree_small_ul', Point3(-62.71, -62.66, 16)]]

    SnowballData = [Point3(30, 0, 0.75),
                    Point3(22.5, 0, 0.75),
                    Point3(15, 0, 0.75),
                    Point3(7.5, 0, 0.75),
                    Point3(0, 0, 0.75),
                    Point3(-7.5, 0, 0.75),
                    Point3(-15, 0, 0.75),
                    Point3(-22.5, 0, 0.75),
                    Point3(-30, 0, 0.75)]

    GameSong = "phase_4/audio/bgm/MG_Dodgeball.ogg"
    GameDesc = ("Welcome to the north! You have been invited to play dodgeball with the penguins!\n\n"
                "How To Play\nWASD to Move and use the mouse to aim.\nLeft click to Throw!\nRight click"
                " to Catch!\n\nObjective\nThe first team to get everyone out wins!")

    InitCamTrans = [Point3(25, 45, 19.5317), Vec3(154.001, -15, 0)]

    SnowBallDmg = 25

    GetSnowBalls = "Pick up a snowball from the center!"

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

        DistributedToonFPSGame.__init__(self, cr)

        TeamMinigame.__init__(self, "BlueSnow", ('phase_4/maps/db_blue_neutral.png',
                                               'phase_4/maps/db_blue_hover.png',
                                               'phase_4/maps/db_blue_hover.png'),
                                    "RedIce", ('phase_4/maps/db_red_neutral.png',
                                               'phase_4/maps/db_red_hover.png',
                                               'phase_4/maps/db_red_hover.png'))

        self.fsm.addState(State('chooseTeam', self.enterChooseTeam, self.exitChooseTeam, ['waitForOthers']))
        self.fsm.addState(State('scrollBy', self.enterScrollBy, self.exitScrollBy, ['countdown']))
        self.fsm.addState(State('countdown', self.enterCountdown, self.exitCountdown, ['play']))
        self.fsm.getStateNamed('waitForOthers').addTransition('chooseTeam')
        self.fsm.getStateNamed('waitForOthers').addTransition('scrollBy')

        self.firstPerson = DodgeballFirstPerson(self)

        self.scrollBySeq = None
        self.infoText = None

        self.infoText = getAlertText()

        self.spawnPointsByTeam = {
            BLUE: [
                [Point3(5, 15, 0), Vec3(180, 0, 0)],
                [Point3(15, 15, 0), Vec3(180, 0, 0)],
                [Point3(-5, 15, 0), Vec3(180, 0, 0)],
                [Point3(-15, 15, 0), Vec3(180, 0, 0)]],
            RED: [
                [Point3(5, -15, 0), Vec3(0, 0, 0)],
                [Point3(15, -15, 0), Vec3(0, 0, 0)],
                [Point3(-5, -15, 0), Vec3(0, 0, 0)],
                [Point3(-15, -15, 0), Vec3(0, 0, 0)]]}

        # Environment vars
        self.sky = None
        self.arena = None
        self.fog = None
        self.snow = None
        self.snowRender = None
        self.trees = []
        self.snowballs = []

    def snowballHitWall(self, snowballIndex):
        snowball = self.snowballs[snowballIndex]
        snowball.handleHitWallOrPlayer()

    def snowballHitPlayer(self, damagedPlayer, snowballIndex):
        av = self.getRemoteAvatar(damagedPlayer)
        if av:
            print "setting health"
            av.setHealth(av.health - DistributedDodgeballGame.SnowBallDmg)
        if damagedPlayer == base.localAvatar.doId:
            self.showAlert("You were hit by a snowball!")
        snowball = self.snowballs[snowballIndex]
        snowball.handleHitWallOrPlayer()

    def playerCaughtSnowball(self, snowballIndex, catcherId):
        av = self.getRemoteAvatar(catcherId)
        if av:
            snowball = self.snowballs[snowballIndex]
            snowball.pauseThrowIval()
            snowball.pickup(av)

    def setupRemoteAvatar(self, avId):
        av = RemoteDodgeballAvatar(self, self.cr, avId)
        if avId == self.cr.localAvId:
            self.myRemoteAvatar = av
        print "setup remove avatar {0}".format(avId)
        self.remoteAvatars.append(av)

    def __getSnowTree(self, path):
        trees = loader.loadModel('phase_8/models/props/snow_trees.bam')
        tree = trees.find('**/' + path)
        tree.find('**/*shadow*').removeNode()
        return tree

    def load(self):
        self.setMinigameMusic(DistributedDodgeballGame.GameSong)
        self.setDescription(DistributedDodgeballGame.GameDesc)
        self.createWorld()

        trans = DistributedDodgeballGame.InitCamTrans
        camera.setPos(trans[0])
        camera.setHpr(trans[1])

        DistributedToonFPSGame.load(self)

    def createWorld(self):
        self.deleteWorld()

        self.sky = loader.loadModel("phase_3.5/models/props/BR_sky.bam")
        self.sky.reparentTo(render)
        self.sky.setZ(-40)
        self.sky.setFogOff()

        self.arena = loader.loadModel("phase_4/models/minigames/dodgeball_arena.egg")
        self.arena.reparentTo(render)
        self.arena.setScale(0.75)
        self.arena.find('**/team_divider').setBin('ground', 18)
        self.arena.find('**/floor').setBin('ground', 18)
        self.arena.find('**/team_divider_coll').setCollideMask(CIGlobals.FloorBitmask)

        for data in DistributedDodgeballGame.TreeData:
            code = data[0]
            pos = data[1]
            tree = self.__getSnowTree(code)
            tree.reparentTo(self.arena)
            tree.setPos(pos)
            self.trees.append(tree)

        for i in xrange(len(DistributedDodgeballGame.SnowballData)):
            snowdata = DistributedDodgeballGame.SnowballData[i]
            snowball = Snowball(self, i)
            snowball.load()
            snowball.reparentTo(render)
            snowball.setPos(snowdata)
            self.snowballs.append(snowball)

        self.snow = ParticleLoader.loadParticleEffect('phase_8/etc/snowdisk.ptf')
        self.snow.setPos(0, 0, 5)
        self.snowRender = self.arena.attachNewNode('snowRender')
        self.snowRender.setDepthWrite(0)
        self.snowRender.setBin('fixed', 1)
        self.snow.start(camera, self.snowRender)

        self.fog = Fog('snowFog')
        self.fog.setColor(0.486, 0.784, 1)
        self.fog.setExpDensity(0.003)
        render.setFog(self.fog)

    def throw(self, snowballIndex, p):
        snowball = self.snowballs[snowballIndex]
        snowball.throw(p)

    def snowballPickup(self, snowballIndex, pickerUpperAvId):
        remoteAv = self.getRemoteAvatar(pickerUpperAvId)
        if remoteAv:
            snowball = self.snowballs[snowballIndex]
            snowball.pickup(remoteAv)

    def deleteWorld(self):
        for snowball in self.snowballs:
            snowball.removeNode()
        self.snowballs = []
        for tree in self.trees:
            tree.removeNode()
        self.trees = []
        if self.snow:
            self.snow.cleanup()
            self.snow = None
        if self.snowRender:
            self.snowRender.removeNode()
            self.snowRender = None
        self.fog = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.arena:
            self.arena.removeNode()
            self.arena = None
        render.clearFog()

    def enterPlay(self):
        self.firstPerson.reallyStart()

    def exitPlay(self):
        self.firstPerson.end()

    def enterCountdown(self):
        self.firstPerson.start()
        self.firstPerson.disableMouse()

        self.infoText.setText(DistributedDodgeballGame.GetSnowBalls)

        self.countdownText = getGameText()
        self.countdownIval = Parallel(
            Sequence(
                Func(self.countdownText.setText, "5"),
                getCountdownIval(self.countdownText),
                Func(self.countdownText.setText, "4"),
                getCountdownIval(self.countdownText),
                Func(self.countdownText.setText, "3"),
                getCountdownIval(self.countdownText),
                Func(self.countdownText.setText, "2"),
                getCountdownIval(self.countdownText),
                Func(self.countdownText.setText, "1"),
                getCountdownIval(self.countdownText)),
            getAlertPulse(self.infoText),
            name = "COUNTDOWNIVAL")
        self.countdownIval.setDoneEvent(self.countdownIval.getName())
        self.acceptOnce(self.countdownIval.getDoneEvent(), self.__handleCountdownDone)
        self.countdownIval.start()

    def __handleCountdownDone(self):
        self.fsm.request('play')

    def exitCountdown(self):
        if hasattr(self, 'countdownText'):
            self.countdownText.destroy()
            del self.countdownText
        if hasattr(self, 'countdownIval'):
            self.ignore(self.countdownIval.getDoneEvent())
            self.countdownIval.finish()
            del self.countdownIval

    def enterScrollBy(self):
        BLUE_START_POS = Point3(-20, 0, 4)
        BLUE_END_POS = Point3(20, 0, 4)
        BLUE_HPR = Vec3(0, 0, 0)

        RED_START_POS = Point3(20, 0, 4)
        RED_END_POS = Point3(-20, 0, 4)
        RED_HPR = Vec3(180, 0, 0)

        self.playMinigameMusic()

        self.scrollBySeq = Sequence(
            Func(camera.setHpr, BLUE_HPR),
            LerpPosInterval(
                camera, duration = 5.0, pos = BLUE_END_POS, startPos = BLUE_START_POS, blendType = 'easeOut'),
            Func(base.transitions.fadeOut, 0.4),
            Wait(0.5),
            Func(base.transitions.fadeIn, 0.4),
            Func(camera.setHpr, RED_HPR),
            LerpPosInterval(
                camera, duration = 5.0, pos = RED_END_POS, startPos = RED_START_POS, blendType = 'easeOut'),
            name = "SCROLLBYSEQ")
        self.scrollBySeq.setDoneEvent(self.scrollBySeq.getName())
        self.acceptOnce(self.scrollBySeq.getDoneEvent(), self.__handleScrollByDone)
        self.scrollBySeq.start()

    def __handleScrollByDone(self):
        self.fsm.request('countdown')

    def exitScrollBy(self):
        if self.scrollBySeq:
            self.ignore(self.scrollBySeq.getDoneEvent())
            self.scrollBySeq.finish()
            self.scrollBySeq = None

    def allPlayersReady(self):
        self.fsm.request('scrollBy')

    def chooseUrTeam(self):
        # The AI has told us it's time to choose our team.
        self.fsm.request('chooseTeam')

    def enterChooseTeam(self):
        self.makeSelectionGUI()

    def acceptedIntoTeam(self, spawnPoint):
        TeamMinigame.acceptedIntoTeam(self)

        self.sendUpdate('readyToStart')
        self.fsm.request('waitForOthers')

        pos, hpr = self.spawnPointsByTeam[self.team][spawnPoint]
        base.localAvatar.setPos(pos)
        base.localAvatar.setHpr(hpr)

    def exitChooseTeam(self):
        self.destroySelectionGUI()

    def announceGenerate(self):
        DistributedToonFPSGame.announceGenerate(self)
        base.camLens.setMinFov(CIGlobals.GunGameFOV / (4./3.))
        self.load()

    def disable(self):
        self.deleteWorld()
        self.trees = None
        self.snowballs = None
        self.spawnPointsByTeam = None
        if self.firstPerson:
            self.firstPerson.cleanup()
            self.firstPerson = None
        DistributedToonFPSGame.disable(self)
コード例 #23
0
ファイル: gamescene.py プロジェクト: othelarian/arcns
class gameScene(FSM,DirectObject):
    """ ****************************
    Méthodes pour l'initialisation
    **************************** """
    def __init__(self,app):
        self.app = app; FSM.__init__(self,"gameScene")
        self.defaultTransitions = {"Init":["Base"],"Base":["Cinematic","Explore"],"Cinematic":["Base","Explore"],"Explore":["Base","Cinematic"]}
        if self.app.main_config["lang_chx"] == 0: self.app.speak = lang.fr.fr_lang
        elif self.app.main_config["lang_chx"] == 1: self.app.speak = lang.en.en_lang
        self.giroscope = render.attachNewNode("giroscope"); self.giroscope.setPos(0,0,0); self.giroscope.setHpr(0,0,0)
        self.giroHpr = [0,0,0]; self.giroPos = [0,0,0]; camera.reparentTo(self.giroscope); camera.setPos(0,-34,25); camera.lookAt(0,0,0)
        #
        self.camMove = {"strapCam":[0,0,0],"rotCam":[0,0,0]}
        #
        #
        # DEBUG : test du passage de la scène et du display
        self.accept("a",self.returnMainMenu)
        self.accept("escape",sys.exit,[0])
        ###
        #
        self.dic_gui = {"wait_visual":{},"main_visual":{},"tuto_visual":{},"base_visual":{},"explore_visual":{}}
        self.loadGUI(); self.dic_gui["wait_visual"]["frame"].show()
        self.act_place = self.app.transit["place"]; self.actscene = scenebuilder.gamescene_builder[self.act_place]
        self.type_place = 0 #0 : base; 1 : explore; 2 : cinematic
        self.dic_statics, self.dic_dynamics, self.dic_lights = self.app.arcstools.parse_scene(self.actscene,self)
        self.loadmodels(); self.dic_anims = {}; self.activeAnim()
        self.dic_sounds = {}; self.loadSfx(); self.dic_musics = {}; self.loadMusics()
        #
        # TODO : voir pour une tâche en "again" pour la gestion de la souris
        #
    # DEBUG : retour au menu principal (méthode de test)
    def returnMainMenu(self):
        taskMgr.add(self.app.main_screen,"return to main menu")
    ###
    def loadSfx(self):
        #
        # TODO : chargement des sons
        #
        pass
    def loadMusics(self):
        #
        # TODO : chargement des musiques
        #
        pass
    def loadGUI(self):
        #frame de chargement
        tmp_frame = DirectFrame(); self.dic_gui["wait_visual"]["frame"] = tmp_frame; tmp_frame.hide()
        tmp_gui = self.app.arcLabel(self.app.speak["wait_visual"]["titre"],(0,0,0.4),0.15,TextNode.ACenter)
        tmp_gui.reparentTo(tmp_frame); self.dic_gui["wait_visual"]["titre"] = tmp_gui
        tmp_gui = self.app.arcLabel(self.app.speak["wait_visual"]["waiting_text"],(0,0,0),0.1,TextNode.ACenter)
        tmp_gui.reparentTo(tmp_frame); self.dic_gui["wait_visual"]["waiting_text"] = tmp_gui
        #frame principale
        #
        # TODO : frame principale, présente tout le temps
        #
        tmp_frame = DirectFrame(); self.dic_gui["main_visual"]["frame"] = tmp_frame; tmp_frame.hide()
        #
        # TODO : barre de boutons pour quitter, les options, l'aide, etc
        #
        tmp_gui = self.app.arcButton(self.app.speak["main_visual"]["quit"],(-0.75,0,0.95),None,0.06,TextNode.ACenter)
        tmp_gui.reparentTo(tmp_frame); tmp_gui["state"] = DGG.DISABLED; self.dic_gui["main_visual"]["quit"] = tmp_gui
        #
        #
        #tmp_gui = self.app.arcButton(self.app.speak["main_visual"][""],(-0.4,0,0.95),None,0.06,TextNode.ACenter)
        #tmp_gui.reparentTo(tmp_frame); tmp_gui["state"] = DGG.DISABLED; self.dic_gui["main_visual"][""] = tmp_gui
        #
        #
        tmp_gui = self.app.arcButton(self.app.speak["main_visual"]["option"],(0.4,0,0.95),None,0.06,TextNode.ACenter)
        tmp_gui.reparentTo(tmp_frame); tmp_gui["state"] = DGG.DISABLED; self.dic_gui["main_visual"]["option"] = tmp_gui
        #
        #
        tmp_gui = self.app.arcButton(self.app.speak["main_visual"]["help"],(0.75,0,0.95),None,0.06,TextNode.ACenter)
        tmp_gui.reparentTo(tmp_frame); tmp_gui["state"] = DGG.DISABLED; self.dic_gui["main_visual"]["help"] = tmp_gui
        #
        #
        #frame "tutoriel"
        #
        # TODO : frame s'affichant uniquement lors de la création d'une partie
        #
        tmp_frame = DirectFrame(); self.dic_gui["tuto_visual"]["frame"] = tmp_frame; tmp_frame.hide()
        #
        #
        #frame "base"
        #
        # TODO : frame lorsque l'unité est dans une base
        #
        tmp_frame = DirectFrame(); self.dic_gui["base_visual"]["frame"] = tmp_frame; tmp_frame.hide()
        #
        #
        #frame "explore"
        #
        # TODO : frame lorsque l'unité est sortie
        #
        tmp_frame = DirectFrame(); self.dic_gui["explore_visual"]["frame"] = tmp_frame; tmp_frame.hide()
        #
        #
    def loadmodels(self):
        tmp_mod = Actor("mainscene/models/dynamics/main_gates.bam"); tmp_mod.reparentTo(camera)
        tmp_mod.setPos(0,14,0); tmp_mod.setHpr(0,90,0); self.gates = tmp_mod
        #
        # TODO : chargement des models additionnels
        #
        #
    def activeAnim(self):
        self.cam_anim_enter = Parallel(name="cam gates enter")
        self.cam_anim_enter.append(camera.posInterval(1,Point3(0,-29,25)))
        self.cam_anim_enter.append(self.gates.posInterval(1,Point3(0,9,0)))
        self.cam_anim_exit = Parallel(name="cam gates exit")
        self.cam_anim_exit.append(camera.posInterval(1,Point3(0,-34,25)))
        self.cam_anim_exit.append(self.gates.posInterval(1,Point3(0,14,0)))
        #
        # TODO : chargement des animations
        #
        #
    def mouseTask(self,task):
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            #
            # TODO : capture de la souris
            #
            #
        return task.cont
    """ ****************************
    méthodes pour contrôler la caméra
    **************************** """
    def activeCamControl(self):
        self.accept("arrow_left",self.captureCamControl,["strap","left","down"])
        self.accept("arrow_left-up",self.captureCamControl,["strap","left","up"])
        self.accept("arrow_right",self.captureCamControl,["strap","right","down"])
        self.accept("arrow_right-up",self.captureCamControl,["strap","right","up"])
        self.accept("shift",self.captureCamControl,["rot","down"]); self.accept("shift-up",self.captureCamControl,["rot","up"])
        #
        # TODO : activation des contrôles de la caméra
        #
        #
        #
        pass
    def captureCamControl(self,cmd1,cmd2=None,cmd3=None):
        #
        # TODO : capture des contrôles de la caméra
        #
        print cmd1
        print cmd2
        print cmd3
        #
        pass
    def moveCam(self,task):
        #
        # TODO : gestion des contrôles de la caméra
        #
        #
        return task.cont
    """ ****************************
    méthodes pour l'état "Init"
    **************************** """
    def enterInit(self):
    	self.gates.play("open_gates"); taskMgr.doMethodLater(7,self.initTasks,"entering cam")
    	taskMgr.doMethodLater(9,self.initTasks,"change state"); self.task_chx = 0
    	self.dic_gui["wait_visual"]["frame"].hide()
    def exitInit(self):
    	pass
    def initTasks(self,task):
        if self.task_chx == 0:
            self.cam_anim_enter.start(); self.task_chx = 1
        elif self.task_chx == 1: self.request("Base")
        return task.done
    """ ****************************
    méthodes pour l'état "Base"
    **************************** """
    def enterBase(self):
    	self.app.change_cursor("main"); self.dic_gui["main_visual"]["frame"].show()
    	#
    	# TODO : etat pour afficher une base (enterBase)
    	#
    	self.activeCamControl()
    	#
    	#
    def exitBase(self):
    	#
    	# TODO : méthode de sortie de l'état "Base"
    	#
    	pass
    """ ****************************
    méthodes pour l'état "Cinematic"
    **************************** """
    def enterCinematic(self):
    	#
    	# TODO : méthode d'entrée dans l'état "Cinematic"
    	#
    	print "Cinematic state entering"
    	#
    def exitCinematic(self):
    	#
    	# TODO : moéthde de sortie de l'état "Cinematic"
    	#
    	print "Cinematic state exiting"
    	#
    """ ****************************
    méthodes pour l'état "Explore"
    **************************** """
    def enterExplore(self):
    	#
    	# TODO : méthode d'entrée dans l'état "Explore"
    	#
    	print "Explore state entering"
    	#
    def exitExplore(self):
    	#
    	# TODO : méthode de sortie de l'état "Explore"
    	#
    	print "Explore state exiting"
    	#
    """ ****************************
    méthodes pour la sortie de la scène de jeu
    **************************** """
    def delete_actscene(self):
        for key in self.dic_anims:
            try: self.dic_anims[key].finish()
            except: pass
            self.dic_anims[key] = None
        for key in self.dic_lights:
        	render.clearLight(self.dic_lights[key]); self.dic_lights[key].removeNode()
        for key in self.dic_statics: self.dic_statics[key].removeNode()
        for key in self.dic_dynamics: self.dic_dynamics[key].delete()
        self.dic_statics = None; self.dic_dynamics = None; self.dic_anims = None
    def close(self):
        self.ignoreAll();
        #
        #taskMgr.remove(self.mouse_task); self.mouse_task = None
        #
        for key in self.dic_sounds:
            self.dic_sounds[key].stop(); self.dic_sounds[key] = None
        for key in self.dic_musics:
            self.dic_musics[key].stop(); self.dic_musics[key] = None
        for key1 in self.dic_gui:
            for key2 in self.dic_gui[key1]:
                for t in self.dic_gui[key1][key2].options():
                    if t[0] == "command":
                        self.dic_gui[key1][key2]["command"] = None; break
                self.dic_gui[key1][key2].removeNode()
        self.dic_sounds = None; self.dic_musics = None
        #
        # TODO : suppression des éléments non classés
        #
        self.giroscope.removeNode(); self.gates.delete()
        try:
            self.cam_anim_enter.finish(); self.cam_anim_exit.finish()
        except: pass
        del self.cam_anim_exit; del self.cam_anim_enter
        #
    # DEBUG : cette méthode n'aura plus d'utilité une fois le code de ce fichier terminé
    def __del__(self):
    	print "delete gamescene"
コード例 #24
0
class DistributedCityCart(DistributedNode):
    notify = directNotify.newCategory('DistributedCityCart')

    def __init__(self, cr):
        DistributedNode.__init__(self, cr)
        self.fsm = ClassicFSM('DistributedCityCart', [State('off', self.enterOff, self.exitOff),
         State('pathFollow', self.enterPathFollow, self.exitPathFollow),
         State('collision', self.enterCollision, self.exitCollision)], 'off', 'off')
        self.fsm.enterInitialState()
        self.suitInCar = None
        self.cart = None
        self.honkSfxPath = 'phase_14/audio/sfx/cogtropolis_citycar_driveby_horn.ogg'
        self.cartModelPath = 'phase_12/models/bossbotHQ/Coggolf_cart3.bam'
        self.moPaths = ['phase_14/models/paths/ct-citycar-drivepath-1.egg',
            'phase_14/models/paths/ct-citycar-drivepath-2.egg',
            'phase_14/models/paths/ct-citycar-drivepath-3.egg',
            'phase_14/models/paths/ct-citycar-drivepath-4.egg',
            'phase_14/models/paths/ct-citycar-drivepath-5.egg',
            'phase_14/models/paths/ct-citycar-drivepath-6.egg']
        self.moPath = None
        self.soundEngineLoop = None
        self.soundDriveByHorn = None
        self.ivalTDisplace = None
        self.pathIndex = None
        self.wheelSpinTrack = None
        self.collNodePath = None
        self.soundDriveBy = None

    def setIvalTDisplace(self, displace):
        self.ivalTDisplace = displace

    def setPathIndex(self, index):
        self.pathIndex = index

    def setState(self, state, timestamp):
        ts = ClockDelta.globalClockDelta.localElapsedTime(timestamp)
        self.fsm.request(state, [ts])

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterPathFollow(self, ts):
        duration = CityCartGlobals.index2Duration[self.pathIndex]
        self.moPath = NURBSMopath.NURBSMopath(self.moPaths[self.pathIndex], name = self.uniqueName('DCityCart_moPath'))
        startT = 0.0
        if ts > 0.0:
            startT = (ts % duration) * (1.0 / duration)
        self.moPath.play(self, loop = True, duration = duration, startT = startT)
        base.taskMgr.add(self.__drive, self.uniqueName('DCityCart.drive'))
        self.wheelSpinTrack = Parallel()
        for name in ['leftFrontWheel', 'rightBackWheel', 'rightFrontWheel', 'leftBackWheel']:
            wheel = self.find('**/' + name)
            self.wheelSpinTrack.append(LerpHprInterval(wheel, duration = 0.1, hpr = (0, 360, 0), startHpr = (0, 0, 0)))
        self.wheelSpinTrack.loop()
        self.accept('enter' + self.collNodePath.node().getName(), self.__handleRanOver)

    def __handleRanOver(self, entry):
        self.suitInCar.setChat(CityCartGlobals.SuitRanOverTaunt)
        self.sendUpdate('hitByCar')
        self.cr.playGame.getPlace().fsm.request('stop')
        base.localAvatar.b_setAnimState('squish', callback = self.cr.playGame.getPlace().fsm.request, extraArgs = ['walk'])

    def __drive(self, task):
        if base.localAvatar.getDistance(self) < 10.0:
            if self.soundDriveByHorn.status() == self.soundDriveByHorn.READY:
                wantsToHonk = random.randint(0, 3)
                if wantsToHonk == 3:
                    base.playSfx(self.soundDriveByHorn)
                return task.cont
        elif base.localAvatar.getDistance(self) < 20.0:
            if self.soundDriveBy.status() == self.soundDriveBy.READY:
                base.playSfx(self.soundDriveBy)
                return task.cont
        return task.cont

    def exitPathFollow(self):
        self.ignore('enter' + self.collNodePath.node().getName())
        base.taskMgr.remove(self.uniqueName('DCityCart.drive'))
        if self.wheelSpinTrack:
            self.wheelSpinTrack.finish()
            self.wheelSpinTrack = None
        if self.moPath:
            self.moPath.stop()
            self.moPath = None

    def enterCollision(self, ts):
        pass

    def exitCollision(self):
        pass

    def generate(self):
        DistributedNode.generate(self)
        self.cart = loader.loadModel(self.cartModelPath)
        self.cart.reparentTo(self)
        self.cart.setH(180)
        plans = []
        for plan in SuitBank.getSuits():
            if plan.getSuitType() != SuitType.B:
                plans.append(plan)
        plan = random.choice(plans)
        self.suitInCar = Suit()
        self.suitInCar.level = 0
        self.suitInCar.generate(plan, Variant.NORMAL)
        self.suitInCar.loop('sit')
        self.suitInCar.disableRay()
        self.suitInCar.setScale(0.7)
        self.suitInCar.setH(180)
        self.suitInCar.setPos(0, -1, -1.5)
        self.suitInCar.reparentTo(self.cart.find('**/seat1'))
        self.suitInCar.show()
        self.soundEngineLoop = base.audio3d.loadSfx('phase_6/audio/sfx/KART_Engine_loop_0.ogg')
        base.audio3d.attachSoundToObject(self.soundEngineLoop, self)
        base.playSfx(self.soundEngineLoop, looping = 1)
        self.soundDriveByHorn = base.audio3d.loadSfx(self.honkSfxPath)
        base.audio3d.attachSoundToObject(self.soundDriveByHorn, self)
        self.soundDriveBy = base.audio3d.loadSfx('phase_14/audio/sfx/cogtropolis_citycar_driveby.ogg')
        base.audio3d.attachSoundToObject(self.soundDriveBy, self)
        sphere = CollisionSphere(0, 0, 0, 2.5)
        sphere.setTangible(0)
        node = CollisionNode(self.uniqueName('cartSphere'))
        node.setCollideMask(CIGlobals.WallBitmask)
        node.addSolid(sphere)
        self.collNodePath = self.attachNewNode(node)
        self.collNodePath.setZ(1.5)
        self.collNodePath.setSy(2.0)
        self.collNodePath.setSx(1.75)

    def disable(self):
        self.fsm.requestFinalState()
        if self.moPath:
            self.moPath.stop()
            self.moPath = None
        self.moPaths = None
        self.honkSfxPath = None
        self.cartModelPath = None
        self.soundEngineLoop = None
        self.soundDriveBy = None
        if self.suitInCar:
            self.suitInCar.disable()
            self.suitInCar.delete()
            self.suitInCar = None
        if self.cart:
            self.cart.removeNode()
            self.cart = None
        del self.fsm
        DistributedNode.disable(self)
コード例 #25
0
class Suit(Avatar):
    notify = directNotify.newCategory('Suit')

    def __init__(self):
        Avatar.__init__(self)
        self.dept = None
        self.suit = None
        self.head = None
        self.headModel = None
        self.variant = None
        self.handColor = None
        self.voice = None
        self.chat = None
        self.chatDial = None
        self.shadow = None
        self.deathSound = None
        self.propeller = None
        self.smallExp = None
        self.largeExp = None
        self.explosion = None
        self.hasSpawned = False
        self.suitTrack = None
        self.timestampAnimTrack = None
        self.propellerSounds = {}
        self.healthBar = None
        self.healthBarGlow = None
        self.condition = 0
        self.avatarType = CIGlobals.Suit
        self.suitPlan = None
        self.footstepSound = None
        self.showNametagInMargins = False
        self.surfaceProp = "metal"

        self.activities = {
            ACT_WAKE_ANGRY: WakeAngry(self),
            ACT_SMALL_FLINCH: Flinch(self),
            ACT_DIE: Die(self),
            ACT_VICTORY_DANCE: VictoryDance(self),
            ACT_COG_FLY_DOWN: FlyDown(self),
            ACT_SIT: Sit(self),
            ACT_STUN: Stun(self)
        }

        self.standWalkRunReverse = [('neutral', 'walk', 0.0, 5.0, 1.0, 1.0)]

        self.gruntSound = base.audio3d.loadSfx(
            "phase_14/audio/sfx/cog_grunt.ogg")
        base.audio3d.attachSoundToObject(self.gruntSound, self)

        self.animFSM = ClassicFSM('Suit', [
            State('off', self.enterOff, self.exitOff),
            State('neutral', self.enterNeutral, self.exitNeutral),
            State('walk', self.enterWalk, self.exitWalk),
            State('die', self.enterDie, self.exitDie),
            State('win', self.enterWin, self.exitWin),
            State('flail', self.enterFlail, self.exitFlail),
            State('flyDown', self.enterFlyDown, self.exitFlyDown),
            State('flyAway', self.enterFlyAway, self.exitFlyAway),
            State('flyNeutral', self.enterFlyNeutral, self.exitFlyNeutral),
            State('trayWalk', self.enterTrayWalk, self.exitTrayWalk),
            State('trayNeutral', self.enterTrayNeutral, self.exitTrayNeutral),
            State('stunned', self.enterStunned, self.exitStunned),
            State('pie', self.enterPie, self.exitPie),
            State('drop', self.enterDrop, self.exitDrop),
            State('drop-react', self.enterDropReact, self.exitDropReact),
            State('soak', self.enterSoak, self.exitSoak),
            State('squirt-small', self.enterSquirtSmall, self.exitSquirtSmall)
        ], 'off', 'off')
        self.animFSM.enterInitialState()

    def getRightHandNode(self):
        return self.find("**/joint_Rhold")

    def getLeftHandNode(self):
        return self.find("**/joint_Lhold")

    def getHeadNode(self):
        return self.headModel

    def getUpperBodySubpart(self):
        return [None]

    def getLowerBodySubpart(self):
        return [None]

    def getMoveAction(self, forward, rotate, strafe):
        return 0

    def enterPie(self, ts=0):
        self.play('pie')

    def exitPie(self):
        self.stop()

    def enterDrop(self, ts=0):
        self.play("drop")

    def exitDrop(self):
        self.stop()

    def enterDropReact(self, ts=0):
        self.play('drop-react')

    def exitDropReact(self):
        self.stop()

    def enterSoak(self, ts=0):
        self.play('soak')

    def exitSoak(self):
        self.stop()

    def enterSquirtSmall(self, ts=0):
        self.play('squirt-small')

    def exitSquirtSmall(self):
        self.stop()

    def enterStunned(self, animB4Stun, ts=0):
        self.show()

        if isinstance(animB4Stun, int):
            animB4Stun = SuitGlobals.getAnimById(animB4Stun).getName()

        self.stunnedSound = base.loadSfxOnNode(
            "phase_4/audio/sfx/SZ_TC_bird1.ogg", self)
        self.stunnedSound.setLoop(True)
        self.stunnedSound.play()

        self.stunnedIval = Parallel(
            Sequence(ActorInterval(self, animB4Stun),
                     Func(self.loop, 'stunned')),
            SuitGlobals.createStunInterval(self, 0, 100))
        self.stunnedIval.start()

    def clearStunnedIval(self):
        if hasattr(self, 'stunnedSound'):
            self.stunnedSound.stop()
            del self.stunnedSound
        if hasattr(self, 'stunnedIval'):
            self.stunnedIval.finish()
            del self.stunnedIval

    def exitStunned(self):
        self.clearStunnedIval()
        self.stop()

    def getLeftHand(self):
        return self.find("**/joint_Lhold")

    def getRightHand(self):
        return self.find("**/joint_Rhold")

    def getNametagJoints(self):
        return []

    # BEGIN STATES

    def enterOff(self, ts=0):
        pass

    def exitOff(self):
        pass

    def exitGeneral(self):
        pass

    def enterTrayWalk(self, ts=0):
        self.show()
        self.loop('tray-walk')

    def exitTrayWalk(self):
        self.exitGeneral()

    def enterTrayNeutral(self, ts=0):
        self.loop('tray-neutral')

    def exitTrayNeutral(self):
        self.stop()

    def enterNeutral(self, ts=0):
        self.show()
        self.loop("neutral")

    def exitNeutral(self):
        self.exitTimestampAnimTrack()
        self.exitGeneral()

    def enterWalk(self, ts=0):
        self.show()
        self.loop("walk")
        self.enableRay()
        self.disableShadowRay()
        self.startFootsteps()

    def exitWalk(self):
        self.stopFootsteps()
        self.exitTimestampAnimTrack()
        self.exitGeneral()
        self.enableShadowRay()

    def enterFlail(self, ts=0):
        self.pingpong('flail', fromFrame=30, toFrame=35)

    def exitFlail(self):
        self.stop()

    def exitTimestampAnimTrack(self):
        if self.timestampAnimTrack:
            self.timestampAnimTrack.pause()
            self.timestampAnimTrack = None

    def enterFlyNeutral(self, ts=0):
        self.disableRay()
        self.enableShadowRay()
        if not self.propeller:
            self.generatePropeller()
        sfx = self.propellerSounds['neutral']
        base.playSfx(sfx, node=self, looping=1)
        self.propeller.loop('chan', fromFrame=0, toFrame=3)
        self.setPlayRate(0.8, 'land')
        self.pingpong('land', fromFrame=0, toFrame=10)

    def exitFlyNeutral(self):
        self.cleanupPropeller()

    def enterFlyDown(self, ts=0):
        self.disableRay()
        self.enableShadowRay()
        if not self.propeller:
            self.generatePropeller()
        sfx = self.propellerSounds['in']
        base.playSfx(sfx, node=self)
        groundF = 28
        dur = self.getDuration('land')
        fr = self.getFrameRate('land')
        if fr:
            animTimeInAir = groundF / fr
        else:
            animTimeInAir = groundF
        impactLength = dur - animTimeInAir
        timeTillLanding = 6.5 - impactLength
        waitTime = timeTillLanding - animTimeInAir
        lastSpinFrame = 8
        propDur = self.propeller.getDuration('chan')
        fr = self.propeller.getFrameRate('chan')
        spinTime = lastSpinFrame / fr
        openTime = (lastSpinFrame + 1) / fr
        if hasattr(self, 'uniqueName'):
            name = self.uniqueName('enterFlyDown')
        else:
            name = 'enterFlyDown'
        animTrack = Sequence(Func(self.pose, 'land', 0), Wait(waitTime),
                             ActorInterval(self, 'land', duration=dur))
        propTrack = Parallel(
            SoundInterval(sfx, duration=waitTime + dur, node=self),
            Sequence(
                ActorInterval(self.propeller,
                              'chan',
                              constrainedLoop=1,
                              duration=waitTime + spinTime,
                              startTime=0.0,
                              endTime=spinTime),
                ActorInterval(self.propeller,
                              'chan',
                              duration=propDur - openTime,
                              startTime=openTime)))
        self.suitTrack = Parallel(animTrack,
                                  propTrack,
                                  name=self.taskName('flyDown'))
        if not self.hasSpawned:
            self.show()
            fadeInTrack = Sequence(
                Func(self.setTransparency, 1),
                self.colorScaleInterval(1,
                                        colorScale=VBase4(1, 1, 1, 1),
                                        startColorScale=VBase4(1, 1, 1, 0)),
                Func(self.clearColorScale), Func(self.clearTransparency))
            self.hasSpawned = True
            self.suitTrack.append(fadeInTrack)
        self.suitTrack.setDoneEvent(self.suitTrack.getName())
        self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyDown)
        self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name)
        self.suitTrack.start(ts)

    def exitFlyDown(self):
        self.cleanupPropeller()
        self.enableRay()
        if self.suitTrack != None:
            self.ignore(self.suitTrack.getDoneEvent())
            self.suitTrack.finish()
            DelayDelete.cleanupDelayDeletes(self.suitTrack)
            self.suitTrack = None
        self.exitGeneral()

    def enterFlyAway(self, ts=0, doFadeOut=0):
        self.show()
        if not self.propeller:
            self.generatePropeller()
        sfx = self.propellerSounds['out']
        if hasattr(self, 'uniqueName'):
            name = self.uniqueName('enterFlyAway')
        else:
            name = 'enterFlyAway'
        dur = self.getDuration('land')
        actInt = ActorInterval(self,
                               'land',
                               loop=0,
                               startTime=dur,
                               endTime=0.0)
        lastSpinFrame = 8
        propDur = self.propeller.getDuration('chan')
        fr = self.propeller.getFrameRate('chan')
        spinTime = lastSpinFrame / fr
        openTime = (lastSpinFrame + 1) / fr
        propTrack = Parallel(
            SoundInterval(sfx, node=self),
            Sequence(
                Func(self.propeller.show),
                ActorInterval(self.propeller,
                              'chan',
                              endTime=openTime,
                              startTime=propDur),
                ActorInterval(self.propeller,
                              'chan',
                              constrainedLoop=1,
                              duration=propDur - openTime,
                              startTime=spinTime,
                              endTime=0.0)))
        self.suitTrack = Parallel(actInt,
                                  propTrack,
                                  name=self.taskName('trackName'))
        if doFadeOut:
            fadeOut = Sequence(
                Wait(4.0), Func(self.setTransparency, 1),
                self.colorScaleInterval(1,
                                        colorScale=VBase4(1, 1, 1, 0),
                                        startColorScale=VBase4(1, 1, 1, 1)),
                Func(self.clearColorScale), Func(self.clearTransparency),
                Func(self.reparentTo, hidden))
            self.suitTrack.append(fadeOut)
        self.suitTrack.setDoneEvent(self.suitTrack.getName())
        self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyAway)
        self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name)
        self.suitTrack.start(ts)
        self.disableRay()
        self.enableShadowRay()

    def exitFlyAway(self):
        self.cleanupPropeller()
        if self.suitTrack:
            self.ignore(self.suitTrack.getDoneEvent())
            self.suitTrack.finish()
            DelayDelete.cleanupDelayDeletes(self.suitTrack)
            self.suitTrack = None
        self.exitGeneral()

    def enterDie(self, ts=0):
        self.show()
        self.clearStunnedIval()
        self.generateCog(isLose=1)
        self.nametag.clearChatText()
        self.deleteNameTag()
        self.deathSound = base.audio3d.loadSfx(
            "phase_3.5/audio/sfx/Cog_Death_Full.ogg")
        base.audio3d.attachSoundToObject(self.deathSound, self)
        trackName = self.uniqueName('enterDie')

        smallGears = ParticleLoader.loadParticleEffect(
            'phase_3.5/etc/gearExplosionSmall.ptf')
        #smallGears.getParticlesNamed('particles-1').setPoolSize(30)

        singleGear = ParticleLoader.loadParticleEffect(
            'phase_3.5/etc/gearExplosion.ptf')
        singleGear.getParticlesNamed('particles-1').setPoolSize(1)

        smallGearExplosion = ParticleLoader.loadParticleEffect(
            'phase_3.5/etc/gearExplosion.ptf')
        smallGearExplosion.getParticlesNamed('particles-1').setPoolSize(10)

        bigGearExplosion = ParticleLoader.loadParticleEffect(
            'phase_3.5/etc/gearExplosionBig.ptf')
        bigGearExplosion.getParticlesNamed('particles-1').setPoolSize(30)

        smallGears.setDepthWrite(False)
        singleGear.setDepthWrite(False)
        smallGearExplosion.setDepthWrite(False)
        bigGearExplosion.setDepthWrite(False)

        gearPoint = self.getPos(render) + (0, 0, self.getHeight() - 0.2)

        self.smallGears = smallGears
        self.smallGears.setPos(gearPoint)
        self.singleGear = singleGear
        self.singleGear.setPos(gearPoint)
        self.smallGearExp = smallGearExplosion
        self.smallGearExp.setPos(gearPoint)
        self.bigGearExp = bigGearExplosion
        self.bigGearExp.setPos(gearPoint)

        gearTrack = Sequence(Wait(0.7), Func(self.doSingleGear), Wait(1.5),
                             Func(self.doSmallGears), Wait(3.0),
                             Func(self.doBigExp))
        self.suitTrack = Parallel(
            Sequence(Wait(0.8), SoundInterval(self.deathSound, duration=4.28)),
            Sequence(Wait(0.7), Func(self.doSingleGear), Wait(4.5),
                     Func(self.suitExplode), Wait(1.0),
                     Func(self.disableBodyCollisions)),
            gearTrack,
            Sequence(ActorInterval(self, 'lose', duration=6),
                     Func(self.getGeomNode().hide)),
            name=trackName)
        self.suitTrack.setDoneEvent(self.suitTrack.getName())
        self.acceptOnce(self.suitTrack.getName(), self.exitDie)
        if self.isDistributed():
            self.suitTrack.delayDelete = DelayDelete.DelayDelete(
                self, trackName)
        self.suitTrack.start(ts)

    def doSingleGear(self):
        self.singleGear.start(CIGlobals.getParticleRender())

    def doSmallGears(self):
        self.smallGears.start(CIGlobals.getParticleRender())

    def doSmallExp(self):
        self.smallGearExp.start(CIGlobals.getParticleRender())

    def doBigExp(self):
        self.bigGearExp.start(CIGlobals.getParticleRender())

    def suitExplode(self):
        pos = self.getPart('body').find('**/joint_head').getPos(render) + (
            0, 0, 2)

        # Force the loser suit to use UnlitGeneric shader, workaround for the has_mat() assertion
        BSPUtility.applyUnlitOverride(self)

        CIGlobals.makeExplosion(pos, 0.5, soundVol=0.32, smoke=False)

    def exitDie(self):
        if self.suitTrack != None:
            self.ignore(self.suitTrack.getName())
            self.suitTrack.finish()
            if self.isDistributed():
                DelayDelete.cleanupDelayDeletes(self.suitTrack)
            self.suitTrack = None
        if hasattr(self, 'singleGear'):
            self.singleGear.softStop()
            del self.singleGear
        if hasattr(self, 'smallGears'):
            self.smallGears.softStop()
            del self.smallGears
        if hasattr(self, 'smallGearExp'):
            self.smallGearExp.softStop()
            del self.smallGearExp
        if hasattr(self, 'bigGearExp'):
            self.bigGearExp.softStop()
            del self.bigGearExp
        if self.deathSound:
            self.deathSound.stop()
        self.deathSound = None

    def enterWin(self, ts=0):
        self.play('win')

    def exitWin(self):
        self.exitGeneral()

    # END STATES

    def generateSuit(self, suitPlan, variant, voice=None, hideFirst=False):
        startTime = globalClock.getRealTime()

        self.suitPlan = suitPlan
        self.suit = suitPlan.getSuitType()
        self.head = suitPlan.getHead()
        self.dept = suitPlan.getDept()
        self.handColor = suitPlan.getHandColor()
        self.variant = variant
        self.setVoice(voice)
        self.generateCog()

        mat = CIGlobals.getCharacterMaterial(shininess=50.0,
                                             specular=(0.4, 0.4, 0.4, 1))
        self.setMaterial(mat)

        #ts = TextureStage('shiny')
        #ts.setMode(TextureStage.MAdd)
        #ts.setRgbScale(2)
        #tex = loader.loadCubeMap('phase_14/maps/cubemap/defaultcubemap_#.png')
        #tex = loader.loadTexture('phase_14/maps/envmap001a_cog.png')
        #self.setTexGen(ts, TexGenAttrib.MEyeSphereMap)
        #self.setTexture(ts, tex)

        self.initializeBodyCollisions()

        if hideFirst:
            self.hide()
        else:
            self.show()

        endTime = globalClock.getRealTime()
        print("generateSuit took {0} ms".format((endTime - startTime) * 1000))

    def __blinkRed(self, task):
        self.healthBar.setColor(SuitGlobals.healthColors[3], 1)
        #self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[3], 1)
        if self.condition == 5:
            self.healthBar.setScale(1.17)
        return task.done

    def __blinkGray(self, task):
        if not self.healthBar:
            return
        self.healthBar.setColor(SuitGlobals.healthColors[4], 1)
        #self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[4], 1)
        if self.condition == 5:
            self.healthBar.setScale(1.0)
        return task.done

    def generateHealthBar(self):
        self.removeHealthBar()
        button = loader.loadModel('phase_3.5/models/gui/matching_game_gui.bam'
                                  ).find('**/minnieCircle')
        button.setScale(3.0)
        button.setH(180)
        button.setColor(SuitGlobals.healthColors[0])
        chestNull = self.find('**/def_joint_attachMeter')
        if chestNull.isEmpty():
            chestNull = self.find('**/joint_attachMeter')
        button.reparentTo(chestNull)
        self.healthBar = button
        #self.healthBarGlow = loader.loadModel('phase_3.5/models/props/glow.bam')
        #self.healthBarGlow.reparentTo(self.healthBar)
        #self.healthBarGlow.setScale(0.28)
        #self.healthBarGlow.setPos(-0.005, 0.01, 0.015)
        #self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[0])
        button.flattenLight()
        button.setLightOff()
        self.condition = 0
        if hasattr(self, 'getHealth'):
            self.updateHealthBar(self.getHealth())

    def updateHealthBar(self, hp):
        if not self.healthBar:
            return
        if hp > self.health:
            self.health = hp
        health = 0.0
        try:
            health = float(hp) / float(self.maxHealth)
        except:
            pass
        if health > 0.95:
            condition = 0
        elif health > 0.7:
            condition = 1
        elif health > 0.3:
            condition = 2
        elif health > 0.05:
            condition = 3
        elif health > 0.0:
            condition = 4
        else:
            condition = 5
        if self.condition != condition:
            taskMgr.remove(self.taskName('blink-task'))
            if condition == 4:
                blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75),
                                      Task(self.__blinkGray), Task.pause(0.1))
                taskMgr.add(blinkTask, self.taskName('blink-task'))
            elif condition == 5:
                blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25),
                                      Task(self.__blinkGray), Task.pause(0.1))
                taskMgr.add(blinkTask, self.taskName('blink-task'))
            else:
                self.healthBar.setColor(SuitGlobals.healthColors[condition], 1)
                #self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[condition], 1)
            self.condition = condition

    def removeHealthBar(self):
        if self.healthBar:
            self.healthBar.removeNode()
            self.healthBar = None
        if self.condition == 4 or self.condition == 5:
            taskMgr.remove(self.taskName('blink-task'))
        self.healthCondition = 0
        return

    def initializeBodyCollisions(self):
        self.notify.info('Initializing Body Collisions!')
        self.setupPhysics(2, self.getHeight())
        self.enableRay()

    def hideSuit(self):
        self.hide()

    def showSuit(self):
        self.show()
        fadeIn = Sequence(
            Func(self.setTransparency, 1),
            self.colorScaleInterval(0.6,
                                    colorScale=Vec4(1, 1, 1, 1),
                                    startColorScale=Vec4(1, 1, 1, 0)),
            Func(self.clearColorScale), Func(self.clearTransparency),
            Func(self.reparentTo, render))
        fadeIn.start()

    def doStunEffect(self):
        self.clearStunnedIval()
        self.stunnedIval = SuitGlobals.createStunInterval(self, 0, 2)
        self.stunnedIval.start()

    def doGagEffect(self, flags):
        GagEffects.doGagEffect(self, flags)

    def generateCog(self, isLose=0, nameTag=True):
        #startTime = globalClock.getRealTime()

        generateCollector.start()

        cleanupCollector.start()
        self.cleanup()
        cleanupCollector.stop()

        if not isLose:

            if self.suitPlan in SuitBank.suitSetups:
                setup = SuitBank.suitSetups[self.suitPlan]
            else:
                setup = SuitBank.SuitSetup()
                SuitBank.suitSetups[self.suitPlan] = setup

            if not self.variant in setup.actor:
                setupActor = Actor()
                if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE:
                    setupActor.loadModel(
                        'phase_5/models/char/cog%s_robot-zero.bam' %
                        (str(self.suit)), 'body')
                else:
                    setupActor.loadModel(
                        'phase_3.5/models/char/suit%s-mod.bam' %
                        (str(self.suit)), 'body')
                animations = SuitGlobals.animations
                anims = {}
                for anim in animations:
                    if not self.suit in anim.getSuitTypes():
                        continue
                    path = 'phase_%s/models/char/suit%s-%s.bam' % (
                        anim.getPhase(), self.suit, anim.getFile())
                    anims[anim.getName()] = path
                setupActor.loadAnims(anims, 'body')
                setup.actor[self.variant] = setupActor

            actorCollector.start()
            self.copyActor(setup.actor[self.variant])
            actorCollector.stop()

            healthBarCollector.start()
            self.generateHealthBar()
            healthBarCollector.stop()

            footstepCollector.start()
            if self.suitPlan.suitType == SuitType.A:
                self.footstepSound = base.audio3d.loadSfx(
                    "phase_5/audio/sfx/ENC_cogafssm.ogg")
            elif self.suitPlan.suitType == SuitType.B:
                self.footstepSound = base.audio3d.loadSfx(
                    "phase_5/audio/sfx/ENC_cogbfssm.ogg")
            elif self.suitPlan.suitType == SuitType.C:
                self.footstepSound = base.audio3d.loadSfx(
                    "phase_5/audio/sfx/ENC_cogcfssm.ogg")
            if self.footstepSound:
                base.audio3d.attachSoundToObject(self.footstepSound, self)
                self.footstepSound.setVolume(0.0)
                self.footstepSound.setLoop(True)
                self.footstepSound.play()
            footstepCollector.stop()

        else:
            if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE:
                self.loadModel(
                    'phase_5/models/char/cog%s_robot-lose-mod.bam' %
                    (str(self.suit)), 'body')
            else:
                self.loadModel(
                    'phase_4/models/char/suit%s-lose-mod.bam' %
                    (str(self.suit)), 'body')
            self.loadAnims(
                {
                    'lose':
                    'phase_4/models/char/suit%s-lose.bam' % (str(self.suit))
                }, 'body')

        genHeadCollector.start()
        if self.variant != Variant.SKELETON:
            self.headModel = self.head.generate()
            self.headModel.reparentTo(self.find("**/joint_head"))
        if self.suitPlan.getName() == SuitGlobals.VicePresident:
            self.headModel.setScale(0.35)
            self.headModel.setHpr(270, 0, 270)
            self.headModel.setZ(-0.10)
            self.headModel.loop('neutral')
        if self.variant == Variant.SKELETON:
            self.headModel = self.find("**/joint_head")
        #antenna = loader.loadModel("models/police_antenna.bam")
        ##antenna.reparentTo(self.find("**/joint_head"))
        #antenna.setPos(0.5, -0.5, 0)
        #antenna.setScale(1.25)
        #antenna.clearModelNodes()
        #antenna.flattenStrong()
        genHeadCollector.stop()

        self.setClothes()

        classScale = 1.0  #self.suitPlan.getCogClassAttrs().scaleMod
        self.setAvatarScale(
            (self.suitPlan.getScale() / SuitGlobals.scaleFactors[self.suit]) *
            classScale)
        self.setHeight(self.suitPlan.getHeight())

        nametagCollector.start()
        if nameTag:
            self.setupNameTag()
        nametagCollector.stop()

        Avatar.initShadow(self)

        if self.variant != Variant.SKELETON:
            # We've already done all manipulating to the cog, we can just flatten it.
            self.getPart('body').flattenStrong()
            self.postFlatten()
            self.headModel.flattenStrong()
            if isinstance(self.headModel, Actor):
                self.headModel.postFlatten()

        #endTime = globalClock.getRealTime()
        #print("GenerateCog took {0} seconds".format(endTime - startTime))

        generateCollector.stop()

    def cleanup(self):
        if self.footstepSound:
            self.footstepSound.stop()
        self.footstepSound = None
        self.cleanupPropeller()
        self.clearChatbox()
        if self.shadow:
            self.deleteShadow()
        if self.headModel:
            self.headModel.removeNode()
        self.headModel = None
        if self.getPart('body'):
            self.removePart('body')
        self.timestampAnimTrack = None

    def generatePropeller(self):
        self.cleanupPropeller()

        self.propeller = Actor(
            'phase_4/models/props/propeller-mod.bam',
            {'chan': 'phase_4/models/props/propeller-chan.bam'})
        self.propeller.reparentTo(self.find("**/joint_head"))
        self.propellerSounds['in'] = base.audio3d.loadSfx(
            SuitGlobals.propellerInSfx)
        self.propellerSounds['out'] = base.audio3d.loadSfx(
            SuitGlobals.propellerOutSfx)
        self.propellerSounds['neutral'] = base.audio3d.loadSfx(
            SuitGlobals.propellerNeutSfx)
        for sound in self.propellerSounds.values():
            base.audio3d.attachSoundToObject(sound, self.propeller)

    def cleanupPropeller(self):
        for sound in self.propellerSounds.values():
            base.audio3d.detachSound(sound)
            sound.stop()
        self.propellerSounds = {}
        if self.propeller and not self.propeller.isEmpty():
            self.propeller.cleanup()
        self.propeller = None

    def setVoice(self, voice):
        if not voice:
            if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE:
                self.voice = Voice.SKELETON
            else:
                self.voice = Voice.NORMAL
        else:
            self.voice = voice

        if self.variant == Variant.SKELETON:
            head = self
        else:
            head = self.headModel

        self.addSound("statement",
                      self.voice.getSoundFile('statement'),
                      node=head)
        self.addSound("grunt", self.voice.getSoundFile('grunt'), node=head)
        self.addSound("question",
                      self.voice.getSoundFile('question'),
                      node=head)
        if self.voice == Voice.NORMAL:
            self.addSound("question2",
                          self.voice.getSoundFile('question_2'),
                          node=head)

        self.chatSoundTable[CHAT_SHORT] = "statement"
        self.chatSoundTable[CHAT_MEDIUM] = "statement"
        self.chatSoundTable[CHAT_LONG] = "statement"
        self.chatSoundTable[CHAT_EXCLAIM] = "grunt"
        self.chatSoundTable[CHAT_HOWL] = "statement"
        if self.voice == Voice.NORMAL:
            self.chatSoundTable[CHAT_QUESTION] = ["question", "question2"]
        else:
            self.chatSoundTable[CHAT_QUESTION] = "question"

    def setClothes(self):
        setClothesCollector.start()

        if self.variant == Variant.SKELETON:
            parts = self.findAllMatches('**/pPlane*')
            for partNum in range(0, parts.getNumPaths()):
                bb = parts.getPath(partNum)
                bb.setTwoSided(1)
            tie = 'phase_5/maps/cog_robot_tie_%s.mat' % self.dept.getTie()
            #tie.setMinfilter(Texture.FTLinearMipmapLinear)
            #tie.setMagfilter(Texture.FTLinear)
            self.find('**/tie').setBSPMaterial(tie, 1)
        else:
            texture = 'phase_3.5/maps/tt_t_ene_' + self.dept.getName().lower(
            ) + '.mat'
            #texture = 'materials/models/suit/tt_t_ene_police.mat'
            #if self.variant == Variant.WAITER:
            #    prefix = 'phase_3.5/maps/waiter_m_%s.mat'
            #elif self.variant == Variant.CORRODED:
            #    prefix = 'phase_3.5/maps/' + self.dept.getClothingPrefix() + '_rust_%s.mat'

            #legTex = prefix % 'leg'
            #armTex = prefix % 'sleeve'
            #blazTex = prefix % 'blazer'

            #texs = [legTex, armTex, blazTex]

            #for texture in texs:
            #    texture.setMinfilter(Texture.FTLinearMipmapLinear)
            #    texture.setMagfilter(Texture.FTLinear)

            #self.find('**/legs').setBSPMaterial(legTex, 1)
            #self.find('**/arms').setBSPMaterial(armTex, 1)
            #self.find('**/torso').setBSPMaterial(blazTex, 1)

            #self.find('**/hands').setBSPMaterial("phase_3.5/maps/tt_t_ene_sellbotRental_hand.mat", 1)

            body = self.getPart('body')
            for child in body.getChildren():
                if isinstance(child.node(), GeomNode):
                    child.setBSPMaterial(texture, 1)

            if not self.variant == Variant.CORRODED:
                self.find('**/hands').setColor(self.handColor)
            else:
                self.find('**/hands').setColor(Variant.CORRODED_HAND_COLOR)

        setClothesCollector.stop()

    def startFootsteps(self):
        classAttrs = self.suitPlan.getCogClassAttrs()

        if not self.footstepSound or not classAttrs.footsteps:
            return

        self.footstepSound.setPlayRate(classAttrs.walkMod)
        self.footstepSound.setLoop(True)
        self.footstepSound.play()

    def stopFootsteps(self):
        if not self.footstepSound:
            return

        self.footstepSound.stop()

    def setSpeed(self, forwardSpeed, rotateSpeed, strafeSpeed=0.0):
        Avatar.setSpeed(self, forwardSpeed, rotateSpeed, strafeSpeed)

        currSpeed = self.currentSpeed
        if self.doingActivity:
            currSpeed = 0

        if self.footstepSound and self.standWalkRunReverse is not None:
            action = self.getMoveAction(forwardSpeed, rotateSpeed, strafeSpeed)
            minSpeed = self.standWalkRunReverse[action][2]
            maxSpeed = self.standWalkRunReverse[action][3]
            self.footstepSound.setVolume(
                CIGlobals.clamp(
                    CIGlobals.remapVal(currSpeed, minSpeed, maxSpeed, 0, 1), 0,
                    1))
            self.footstepSound.setPlayRate(max(1, currSpeed / maxSpeed))

    def setName(self, nameString, charName):
        Avatar.setName(self, nameString, charName=charName, createNow=1)

    def setupNameTag(self, tempName=None):
        Avatar.setupNameTag(self, tempName=tempName)
        if self.nametag:
            if self.level > 0:
                self.nametag.setText(self.nametag.getText() +
                                     '\n%s\nLevel %s %s' %
                                     (self.dept.getName(), self.level,
                                      self.suitPlan.getCogClassName()))
            else:
                self.nametag.setText(self.nametag.getText() + '\n%s' %
                                     (self.dept.getName()))

    def clearChatbox(self):
        self.clearChat()
        self.chat = None
        if self.chatDial:
            base.audio3d.detachSound(self.chatDial)
            self.chatDial.stop()
            self.chatDial = None

    def getDept(self):
        return self.dept

    def getVariant(self):
        return self.variant

    def disable(self):
        if self.suitTrack:
            self.suitTrack.finish()
            DelayDelete.cleanupDelayDeletes(self.suitTrack)
            self.suitTrack = None
        self.animFSM.requestFinalState()
        self.cleanup()
        Avatar.disable(self)

    def delete(self):
        Avatar.delete(self)
        self.cleanup()
コード例 #26
0
ファイル: BambooCane.py プロジェクト: coginvasion/src
class BambooCane(ToonUpGag):

    def __init__(self):
        ToonUpGag.__init__(self, CIGlobals.BambooCane, 'phase_5/models/props/cane.bam', 40, 45, 100, GagGlobals.BAMBOO_CANE_SFX, 1)
        self.setImage('phase_3.5/maps/bamboo-cane.png')
        self.hatPath = 'phase_5/models/props/hat.bam'
        self.hat = None
        self.track = None
        self.scaleDuration = 0.5
        self.scaleUp = None
        self.scaleDown = None
        self.soundInterval = None
        return

    def buildHat(self):
        self.cleanupHat()
        self.hat = loader.loadModel(self.hatPath)

    def cleanupHat(self):
        if self.hat:
            self.hat.removeNode()

    def buildScaleTracks(self):
        props = []
        props.append(self.hat)
        props.append(self.gag)
        self.scaleUp = self.getScaleTrack(props, self.scaleDuration, self.PNTNEARZERO, self.PNTNORMAL)
        self.scaleDown = self.getScaleTrack(props, self.scaleDuration, self.PNTNORMAL, self.PNTNEARZERO)

    def start(self):
        super(BambooCane, self).start()
        if not self.hat:
            self.buildHat()
        if not self.gag:
            self.build()
        self.setupHandJoints()
        if not self.scaleUp:
            self.buildScaleTracks()
        self.placeProp(self.handJoint, self.hat, Point3(0.23, 0.09, 0.69), Point3(180, 0, 0))
        self.placeProp(self.lHandJoint, self.gag, Point3(-0.28, 0.0, 0.14), Point3(0.0, 0.0, -150.0))
        self.soundInterval = self.getSoundTrack(0.2, self.gag, 6.4)
        propInterval = Sequence()
        propInterval.append(self.scaleUp)
        propInterval.append(Wait(base.localAvatar.getDuration('happy-dance') - 2))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(self.setHealAmount))
            propInterval.append(Func(self.healNearbyAvatars, 25))
        propInterval.append(self.scaleDown)
        propInterval.append(Func(self.cleanupGag))
        propInterval.append(Func(self.reset))
        self.track = Parallel(propInterval, ActorInterval(self.avatar, 'happy-dance'), Func(self.soundInterval.start))
        self.track.start()

    def equip(self):
        super(BambooCane, self).equip()
        self.build()
        self.buildHat()
        self.buildScaleTracks()

    def unEquip(self):
        if self.track:
            self.soundInterval.finish()
            self.track.finish()
            self.track = None
        self.reset()
        if self.scaleDown:
            Sequence(self.scaleDown, Func(self.cleanupGag)).start()
        return

    def cleanupGag(self):
        if self.gag:
            self.gag.removeNode()
        self.cleanupHat()
コード例 #27
0
class DistributedBattleTrolley(DistributedObject):
    notify = directNotify.newCategory('DistributedBattleTrolley')

    STAND_POSITIONS = [
        Point3(-4.75, -5, 1.4),
        Point3(-4.75, -1.6, 1.4),
        Point3(-4.75, 1.6, 1.4),
        Point3(-4.75, 5, 1.4),
        Point3(-4.75, -5, 1.4),
        Point3(-4.75, -1.6, 1.4),
        Point3(-4.75, 1.6, 1.4),
        Point3(-4.75, 5, 1.4)
    ]
    TROLLEY_NEUTRAL_POS = Point3(15, 14, -1)
    TROLLEY_GONE_POS = Point3(50, 14.1588, -0.984615)
    TROLLEY_ARRIVING_START_POS = Point3(-20, 14.1588, -0.984615)
    CAM_POS = Point3(-35, 0, 8)
    CAM_HPR = Vec3(-90, 0, 0)

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.fsm = ClassicFSM.ClassicFSM('DistributedBattleTrolley', [State.State('off', self.enterOff, self.exitOff),
         State.State('wait', self.enterWait, self.exitWait),
         State.State('waitCountdown', self.enterWaitCountdown, self.exitWaitCountdown),
         State.State('leaving', self.enterLeaving, self.exitLeaving),
         State.State('arriving', self.enterArriving, self.exitArriving)], 'off', 'off')
        self.fsm.enterInitialState()
        self.trolleyStation = None
        self.trolleyCar = None
        self.trolleyKey = None
        self.countdownText = None
        self.trolleyAwaySfx = base.audio3d.loadSfx('phase_4/audio/sfx/SZ_trolley_away.ogg')

        if self.cr.holidayManager.getHoliday() == HolidayType.CHRISTMAS:
            self.trolleyAwaySfx = base.audio3d.loadSfx('winter/audio/sfx/SZ_trolley_away.mp3')

        self.trolleyBellSfx = base.audio3d.loadSfx('phase_4/audio/sfx/SZ_trolley_bell.ogg')
        self.toZone = 0
        self.localAvOnTrolley = False
        self.trolleyEnterTrack = None
        self.trolleyExitTrack = None
        self.hoodAbbr = ""
        self.index = 0
        self.mySlot = -1
        
    def setIndex(self, index):
        self.index = index
        
        hood = self.cr.playGame.hood
        hoodAbbr = None
        
        if self.index == 0:
            hoodAbbr = hood.abbr
        elif self.index == 1:
            hoodAbbr = 'TT' #ZoneUtil.ZoneId2HoodAbbr[self.toZone]
        self.hoodAbbr = hoodAbbr
        
        findStr = '**/prop_trolley_station_' + hoodAbbr + '_DNARoot'
        
        self.trolleyStation = hood.loader.geom.find(findStr)
        self.trolleyStation.flattenStrong()
        self.trolleyCar = self.trolleyStation.find('**/trolley_car')
        self.trolleyKey = self.trolleyStation.find('**/key')

        base.audio3d.attachSoundToObject(self.trolleyAwaySfx, self.trolleyCar)
        base.audio3d.attachSoundToObject(self.trolleyBellSfx, self.trolleyCar)

        exitFog = Fog('TrolleyExitFog')
        exitFog.setColor(0.0, 0.0, 0.0)
        exitFog.setLinearOnsetPoint(30.0, 14.0, 0.0)
        exitFog.setLinearOpaquePoint(37.0, 14.0, 0.0)
        exitFog.setLinearFallback(70.0, 999.0, 1000.0)
        self.trolleyExitFog = self.trolleyStation.attachNewNode(exitFog)
        self.trolleyExitFogNode = exitFog
        enterFog = Fog('TrolleyEnterFog')
        enterFog.setColor(0.0, 0.0, 0.0)
        enterFog.setLinearOnsetPoint(0.0, 14.0, 0.0)
        enterFog.setLinearOpaquePoint(-7.0, 14.0, 0.0)
        enterFog.setLinearFallback(70.0, 999.0, 1000.0)
        self.trolleyEnterFog = self.trolleyStation.attachNewNode(enterFog)
        self.trolleyEnterFogNode = enterFog
        self.trolleyCar.setFogOff()

        tn = TextNode('trolleycountdowntext')
        tn.setFont(CIGlobals.getMickeyFont())
        tn.setTextColor(1, 0, 0, 1)
        tn.setAlign(TextNode.ACenter)

        self.keys = self.trolleyCar.findAllMatches('**/key')
        self.numKeys = self.keys.getNumPaths()
        self.keyInit = []
        self.keyRef = []
        for i in range(self.numKeys):
            key = self.keys[i]
            key.setTwoSided(1)
            ref = self.trolleyCar.attachNewNode('key' + `i` + 'ref')
            ref.setPosHpr(key, 0, 0, 0, 0, 0, 0)
            self.keyRef.append(ref)
            self.keyInit.append(key.getTransform())

        self.frontWheels = self.trolleyCar.findAllMatches('**/front_wheels')
        self.numFrontWheels = self.frontWheels.getNumPaths()
        self.frontWheelInit = []
        self.frontWheelRef = []
        for i in range(self.numFrontWheels):
            wheel = self.frontWheels[i]
            ref = self.trolleyCar.attachNewNode('frontWheel' + `i` + 'ref')
            ref.setPosHpr(wheel, 0, 0, 0, 0, 0, 0)
            self.frontWheelRef.append(ref)
            self.frontWheelInit.append(wheel.getTransform())

        self.backWheels = self.trolleyCar.findAllMatches('**/back_wheels')
        self.numBackWheels = self.backWheels.getNumPaths()
        self.backWheelInit = []
        self.backWheelRef = []
        for i in range(self.numBackWheels):
            wheel = self.backWheels[i]
            ref = self.trolleyCar.attachNewNode('backWheel' + `i` + 'ref')
            ref.setPosHpr(wheel, 0, 0, 0, 0, 0, 0)
            self.backWheelRef.append(ref)
            self.backWheelInit.append(wheel.getTransform())

        trolleyAnimationReset = Func(self.resetAnimation)
        trolleyEnterStartPos = Point3(-20, 14, -1)
        trolleyEnterEndPos = Point3(15, 14, -1)
        trolleyEnterPos = Sequence(name='TrolleyEnterPos')
        trolleyEnterPos.append(Func(self.trolleyCar.setFog, self.trolleyEnterFogNode))
        trolleyEnterPos.append(self.trolleyCar.posInterval(TROLLEY_ENTER_TIME, trolleyEnterEndPos, startPos=trolleyEnterStartPos, blendType='easeOut'))
        trolleyEnterPos.append(Func(self.trolleyCar.setFogOff))
        trolleyEnterTrack = Sequence(trolleyAnimationReset, trolleyEnterPos, name='trolleyEnter')
        keyAngle = round(TROLLEY_ENTER_TIME) * 360
        dist = Vec3(trolleyEnterEndPos - trolleyEnterStartPos).length()
        wheelAngle = dist / (2.0 * math.pi * 0.95) * 360
        trolleyEnterAnimateInterval = LerpFunctionInterval(self.animateTrolley, duration=TROLLEY_ENTER_TIME, blendType='easeOut', extraArgs=[keyAngle, wheelAngle], name='TrolleyAnimate')
        trolleyEnterSoundTrack = SoundInterval(self.trolleyAwaySfx, node=self.trolleyCar)
        self.trolleyEnterTrack = Parallel(trolleyEnterTrack, trolleyEnterAnimateInterval, trolleyEnterSoundTrack)
        trolleyExitStartPos = Point3(15, 14, -1)
        trolleyExitEndPos = Point3(50, 14, -1)
        trolleyExitPos = Sequence(name='TrolleyExitPos')
        trolleyExitPos.append(Func(self.trolleyCar.setFog, self.trolleyExitFogNode))
        trolleyExitPos.append(self.trolleyCar.posInterval(TROLLEY_EXIT_TIME, trolleyExitEndPos, startPos=trolleyExitStartPos, blendType='easeIn'))
        trolleyExitPos.append(Func(self.trolleyCar.setFogOff))
        trolleyExitStartPos = Point3(15, 14, -1)
        trolleyExitEndPos = Point3(50, 14, -1)
        trolleyExitBellInterval = SoundInterval(self.trolleyBellSfx, node=self.trolleyCar)
        trolleyExitAwayInterval = SoundInterval(self.trolleyAwaySfx, node=self.trolleyCar)
        keyAngle = round(TROLLEY_EXIT_TIME) * 360
        dist = Vec3(trolleyExitEndPos - trolleyExitStartPos).length()
        wheelAngle = dist / (2.0 * math.pi * 0.95) * 360
        trolleyExitAnimateInterval = LerpFunctionInterval(self.animateTrolley, duration=TROLLEY_EXIT_TIME, blendType='easeIn', extraArgs=[keyAngle, wheelAngle], name='TrolleyAnimate')
        self.trolleyExitTrack = Parallel(trolleyExitPos, trolleyExitBellInterval, trolleyExitAwayInterval, trolleyExitAnimateInterval, name=self.uniqueName('trolleyExit'))

        self.countdownText = self.trolleyStation.attachNewNode(tn)
        self.countdownText.setScale(3.0)
        self.countdownText.setPos(14.58, 10.77, 11.17)
        
        try:
            self.trolleySphere = self.trolleyStation.find('**/trolley_sphere')
            self.trolleySphere.setName('trolley{0}_sphere'.format(hoodAbbr))
        except:
            pass
        
    def getIndex(self):
        return self.index
        
    def putAvatarInTrolley(self, avId, slot):
        av = self.cr.doId2do.get(avId)
        if av:
            print "putAvatarInTrolley:", av.node().getName()
            av.stopSmooth()
            av.wrtReparentTo(self.trolleyCar)
            av.setAnimState('off')
            slotPos = self.STAND_POSITIONS[slot]
            av.setPos(slotPos)
            if slot <= 3:
                av.loop('sit')
            else:
                av.loop('neutral')
            av.setHpr(90, 0, 0)

    def headOff(self):
        if self.index == 1:
            zoneId = base.localAvatar.getLastHood()
            hoodId = ZoneUtil.getHoodId(zoneId)
        else:
            zoneId = self.toZone
            hoodId = ZoneUtil.getHoodId(self.toZone)

        requestStatus = {'zoneId': zoneId,
                    'hoodId': hoodId,
                    'where': 'playground',
                    'avId': base.localAvatar.doId,
                    'loader': 'safeZoneLoader',
                    'shardId': None,
                    'wantLaffMeter': 1,
                    'how': 'teleportIn',
                    'prevZoneId': base.localAvatar.zoneId,
                    'slot': self.mySlot}
        self.cr.playGame.getPlace().doneStatus = requestStatus
        messenger.send(self.cr.playGame.getPlace().doneEvent)
        base.localAvatar.reparentTo(render)
        base.localAvatar.setPos(0, 0, 0)
        base.localAvatar.setHpr(0, 0, 0)
        base.localAvatar.walkControls.setCollisionsActive(1)
        self.localAvOnTrolley = False

    def setToZone(self, zone):
        self.toZone = zone

    def getToZone(self):
        return self.toZone

    def enterOff(self, ts = 0):
        pass

    def exitOff(self):
        pass
        
    def __maybeAcceptCollisions(self):
        if self.fsm.getCurrentState().getName() in ['wait', 'waitCountdown'] and not self.localAvOnTrolley:
            self.acceptOnce('entertrolley{0}_sphere'.format(self.hoodAbbr), self.__handleTrolleyTrigger)
            
    def __ignoreCollisions(self):
        self.ignore('entertrolley{0}_sphere'.format(self.hoodAbbr))

    def enterWait(self, ts = 0):
        self.trolleyCar.setPos(self.TROLLEY_NEUTRAL_POS)
        self.__maybeAcceptCollisions()

    def exitWait(self):
        self.__ignoreCollisions()

    def enterWaitCountdown(self, ts = 0):
        self.trolleyCar.setPos(self.TROLLEY_NEUTRAL_POS)
        self.__maybeAcceptCollisions()
        if self.countdownText:
            self.countdownTrack = Sequence()
            for i in range(10):
                self.countdownTrack.append(Func(self.countdownText.node().setText, str(10 - i)))
                self.countdownTrack.append(Wait(1.0))
            self.countdownTrack.start()

    def exitWaitCountdown(self):
        self.__ignoreCollisions()
        if hasattr(self, 'countdownTrack'):
            self.countdownTrack.finish()
            del self.countdownTrack
        if self.countdownText:
            self.countdownText.node().setText('')
        self.disableExitButton()

    def enterArriving(self, ts = 0):
        if self.localAvOnTrolley == True:
            CIGlobals.hideWaitForOthers()
            camera.wrtReparentTo(self.trolleyCar)
            camera.setPos(0, -18.55, 3.75)
            camera.setHpr(0, 0, 0)
            Sequence(Wait(2.0), camera.posHprInterval(3, self.CAM_POS, self.CAM_HPR, startPos = (0, -18.55, 3.75), startHpr = (0, 0, 0), blendType='easeInOut')).start()
        self.trolleyEnterTrack.start(ts)

    def exitArriving(self):
        if self.trolleyEnterTrack:
            self.trolleyEnterTrack.finish()

    def enterLeaving(self, ts = 0):
        base.playSfx(self.trolleyBellSfx, node = self.trolleyCar)
        if self.localAvOnTrolley == True:
            camera.posHprInterval(3, (0, 18.55, 3.75), (-180, 0, 0), blendType='easeInOut').start()
            self.trolleyExitTrack.append(Sequence(Wait(4.0), Func(base.transitions.fadeOut), Wait(1.0), Func(self.headOff)))
        self.trolleyExitTrack.start(ts)
        self.__ignoreCollisions()

    def exitLeaving(self):
        if self.trolleyExitTrack:
            self.trolleyExitTrack.finish()

    def setState(self, stateName, timestamp):
        ts = globalClockDelta.localElapsedTime(timestamp)
        self.fsm.request(stateName, [ts])

    def __handleTrolleyTrigger(self, collNp):
        # workaround for a bug that i don't understand why it happens
        if not hasattr(self, 'cr') or not self.cr:
            self.cr = base.cr
            
        self.cr.playGame.getPlace().fsm.request('stop')
        base.localAvatar.disableGags()
        self.notify.info('Waiting for response from server to enter trolley')
        self.sendUpdate('requestBoard')
        base.localAvatar.walkControls.setCollisionsActive(0)

    def rejectBoard(self):
        base.localAvatar.walkControls.setCollisionsActive(1)
        self.cr.playGame.getPlace().fsm.request('walk')
        self.__maybeAcceptCollisions()

    def fillSlot(self, index, avId):
        if avId == base.localAvatar.doId:
            self.localAvOnTrolley = True
            base.localAvatar.stopSmartCamera()
            base.camera.wrtReparentTo(self.trolleyCar)
            camTrack = Sequence(Parallel(
             LerpPosInterval(
              base.camera,
              duration = 1.5,
              pos = self.CAM_POS,
              startPos = base.camera.getPos(),
              blendType = 'easeOut'
             ),
             LerpQuatInterval(
              base.camera,
              duration = 1.5,
              hpr = self.CAM_HPR,
              startHpr = base.camera.getHpr(),
              blendType = 'easeOut'
             )
            ), Func(self.enableExitButton))
            camTrack.start()
            self.mySlot = index

        toon = self.cr.doId2do.get(avId)
        toon.stopSmooth()
        if toon:
            toon.wrtReparentTo(self.trolleyCar)
            slotPos = self.STAND_POSITIONS[index]
            toon.headsUp(slotPos)
            track = Sequence(
                Func(toon.setAnimState, 'run'),
                LerpPosInterval(toon, 0.75, slotPos),
                LerpHprInterval(toon, 0.25, Point3(90, 0, 0)))
            if index <= 3:
                sitStartDuration = toon.getDuration('start-sit')
                track.append(Parallel(ActorInterval(toon, 'start-sit'),
                                      Sequence(Wait(sitStartDuration * 0.25),
                                               LerpPosInterval(toon, sitStartDuration * 0.25, Point3(-3.9, -4.5 + index * 3, 3.0)))))
                track.append(Func(toon.loop, 'sit'))
            else:
                track.append(Func(toon.loop, 'neutral'))
            track.start()
        

    def enableExitButton(self):
        if self.fsm.getCurrentState().getName() != 'leaving':
            self.exitButton = CIGlobals.getExitButton(cmd = self.__handleExitButton, pos = (0, 0, -0.8))

    def __handleExitButton(self):
        if self.fsm.getCurrentState().getName() == 'waitCountdown' and self.localAvOnTrolley == True:
            self.disableExitButton()
            self.sendUpdate('requestHopOff')

    def disableExitButton(self):
        if hasattr(self, 'exitButton'):
            self.exitButton.destroy()
            del self.exitButton

    def emptySlot(self, index, avId):
        toon = self.cr.doId2do.get(avId)
        toon.stopSmooth()
        currToonPos = toon.getPos(render)
        toon.wrtReparentTo(render)
        slotPos = self.STAND_POSITIONS[index]
        endPos = (-20, slotPos.getY(), 1.4)
        toon.setPos(self.trolleyCar, endPos)
        endPosWrtRender = toon.getPos(render)
        toon.setPos(currToonPos)
        toon.headsUp(self.trolleyCar, endPos)
        if index <= 3:
            track = Sequence(Parallel(
                ActorInterval(toon, 'start-sit', startTime=1, endTime=0.0),
                Sequence(Wait(0.5),
                    LerpPosInterval(toon, 0.25,
                    Point3(-5, -4.5 + index * 3, 1.4), other=self.trolleyCar))),
                    Func(toon.setAnimState, 'run'),
                    LerpPosInterval(toon, 1, Point3(21 - index * 3, -5, 0.02), other=self.trolleyStation),
                    Func(toon.setAnimState, 'neutral'),
                    Func(toon.startSmooth),
                name=toon.uniqueName('emptyTrolley'), autoPause=1)
        else:
            track = Sequence(
             Func(toon.setAnimState, 'run'),
             LerpPosInterval(
              toon,
              duration = 1.0,
              pos = endPosWrtRender,
              startPos = currToonPos
             ),
             Func(toon.setAnimState, 'neutral'),
             Func(toon.startSmooth)
            )
        if avId == base.localAvatar.doId:
            self.localAvOnTrolley = False
            track.append(Func(self.__hoppedOffTrolley))
        track.start()

    def __hoppedOffTrolley(self):
        #self.acceptOnce('entertrolley_sphere', self.__handleTrolleyTrigger)
        base.localAvatar.walkControls.setCollisionsActive(1)
        self.cr.playGame.getPlace().fsm.request('walk')

    def resetAnimation(self):
        if self.keys:
            for i in range(self.numKeys):
                self.keys[i].setTransform(self.keyInit[i])

            for i in range(self.numFrontWheels):
                self.frontWheels[i].setTransform(self.frontWheelInit[i])

            for i in range(self.numBackWheels):
                self.backWheels[i].setTransform(self.backWheelInit[i])

    def animateTrolley(self, t, keyAngle, wheelAngle):
        if self.keys:
            for i in range(self.numKeys):
                key = self.keys[i]
                ref = self.keyRef[i]
                key.setH(ref, t * keyAngle)

            for i in range(self.numFrontWheels):
                frontWheel = self.frontWheels[i]
                ref = self.frontWheelRef[i]
                frontWheel.setH(ref, t * wheelAngle)

            for i in range(self.numBackWheels):
                backWheel = self.backWheels[i]
                ref = self.backWheelRef[i]
                backWheel.setH(ref, t * wheelAngle)

    def delete(self):
        self.__ignoreCollisions()
    
        self.trolleyStation = None
        self.trolleyKey = None
        self.soundMoving = None
        self.soundBell = None
        self.troleyCar = None
        self.backWheelInit = None
        self.backWheelRef = None
        self.backWheels = None
        self.frontWheelInit = None
        self.frontWheelRef = None
        self.frontWheels = None
        self.keyInit = None
        self.keyRef = None
        self.keys = None
        self.trolleyEnterTrack = None
        self.trolleyExitTrack = None
        self.trolleyExitFog = None
        self.trolleyExitFogNode = None
        self.trolleyEnterFogNode = None
        self.trolleyEnterFog = None
        
        if self.countdownText:
            self.countdownText.removeNode()
            self.countdownText = None

        DistributedObject.delete(self)
コード例 #28
0
class DistributedCityCart(DistributedNode):
    notify = directNotify.newCategory('DistributedCityCart')

    def __init__(self, cr):
        DistributedNode.__init__(self, cr)
        self.fsm = ClassicFSM('DistributedCityCart', [State('off', self.enterOff, self.exitOff), State('pathFollow', self.enterPathFollow, self.exitPathFollow), State('collision', self.enterCollision, self.exitCollision)], 'off', 'off')
        self.fsm.enterInitialState()
        self.suitInCar = None
        self.cart = None
        self.honkSfxPath = 'phase_14/audio/sfx/cogtropolis_citycar_driveby_horn.mp3'
        self.cartModelPath = 'phase_12/models/bossbotHQ/Coggolf_cart3.bam'
        self.moPaths = ['phase_14/models/paths/ct-citycar-drivepath-1.egg',
         'phase_14/models/paths/ct-citycar-drivepath-2.egg',
         'phase_14/models/paths/ct-citycar-drivepath-3.egg',
         'phase_14/models/paths/ct-citycar-drivepath-4.egg',
         'phase_14/models/paths/ct-citycar-drivepath-5.egg',
         'phase_14/models/paths/ct-citycar-drivepath-6.egg']
        self.moPath = None
        self.soundEngineLoop = None
        self.soundDriveByHorn = None
        self.ivalTDisplace = None
        self.pathIndex = None
        self.wheelSpinTrack = None
        self.collNodePath = None
        self.soundDriveBy = None
        return

    def setIvalTDisplace(self, displace):
        self.ivalTDisplace = displace

    def setPathIndex(self, index):
        self.pathIndex = index

    def setState(self, state, timestamp):
        ts = ClockDelta.globalClockDelta.localElapsedTime(timestamp)
        self.fsm.request(state, [ts])

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterPathFollow(self, ts):
        duration = CityCartGlobals.index2Duration[self.pathIndex]
        self.moPath = NURBSMopath.NURBSMopath(self.moPaths[self.pathIndex], name=self.uniqueName('DCityCart_moPath'))
        startT = 0.0
        if ts > 0.0:
            startT = ts % duration * (1.0 / duration)
        self.moPath.play(self, loop=True, duration=duration, startT=startT)
        base.taskMgr.add(self.__drive, self.uniqueName('DCityCart.drive'))
        self.wheelSpinTrack = Parallel()
        for name in ['leftFrontWheel',
         'rightBackWheel',
         'rightFrontWheel',
         'leftBackWheel']:
            wheel = self.find('**/' + name)
            self.wheelSpinTrack.append(LerpHprInterval(wheel, duration=0.1, hpr=(0, 360, 0), startHpr=(0, 0, 0)))

        self.wheelSpinTrack.loop()
        self.accept('enter' + self.collNodePath.node().getName(), self.__handleRanOver)

    def __handleRanOver(self, entry):
        self.suitInCar.setChat(CityCartGlobals.SuitRanOverTaunt)
        self.sendUpdate('hitByCar')
        self.cr.playGame.getPlace().fsm.request('stop')
        base.localAvatar.b_setAnimState('squish', callback=self.cr.playGame.getPlace().fsm.request, extraArgs=['walk'])

    def __drive(self, task):
        if base.localAvatar.getDistance(self) < 10.0:
            if self.soundDriveByHorn.status() == self.soundDriveByHorn.READY:
                wantsToHonk = random.randint(0, 3)
                if wantsToHonk == 3:
                    base.playSfx(self.soundDriveByHorn)
                return task.cont
        elif base.localAvatar.getDistance(self) < 20.0:
            if self.soundDriveBy.status() == self.soundDriveBy.READY:
                base.playSfx(self.soundDriveBy)
                return task.cont
        return task.cont

    def exitPathFollow(self):
        self.ignore('enter' + self.collNodePath.node().getName())
        if self.wheelSpinTrack:
            self.wheelSpinTrack.finish()
            self.wheelSpinTrack = None
        if self.moPath:
            self.moPath.stop()
            self.moPath = None
        return

    def enterCollision(self, ts):
        pass

    def exitCollision(self):
        pass

    def generate(self):
        DistributedNode.generate(self)
        self.cart = loader.loadModel(self.cartModelPath)
        self.cart.reparentTo(self)
        self.cart.setH(180)
        heads = []
        for head in CIGlobals.SuitBodyData.keys():
            if CIGlobals.SuitBodyData[head][0] != 'B':
                heads.append(head)

        head = random.choice(heads)
        suitType = CIGlobals.SuitBodyData[head][0]
        suitDept = CIGlobals.SuitBodyData[head][1]
        self.suitInCar = Suit()
        self.suitInCar.generateSuit(suitType, head, suitDept, 137, 0, False)
        self.suitInCar.loop('sit')
        self.suitInCar.disableRay()
        self.suitInCar.setScale(0.7)
        self.suitInCar.setH(180)
        self.suitInCar.setPos(0, -1, -1.5)
        self.suitInCar.reparentTo(self.cart.find('**/seat1'))
        self.soundEngineLoop = base.audio3d.loadSfx('phase_6/audio/sfx/KART_Engine_loop_0.wav')
        base.audio3d.attachSoundToObject(self.soundEngineLoop, self)
        base.playSfx(self.soundEngineLoop, looping=1)
        self.soundDriveByHorn = base.audio3d.loadSfx(self.honkSfxPath)
        base.audio3d.attachSoundToObject(self.soundDriveByHorn, self)
        self.soundDriveBy = base.audio3d.loadSfx('phase_14/audio/sfx/cogtropolis_citycar_driveby.mp3')
        base.audio3d.attachSoundToObject(self.soundDriveBy, self)
        sphere = CollisionSphere(0, 0, 0, 2.5)
        sphere.setTangible(0)
        node = CollisionNode(self.uniqueName('cartSphere'))
        node.setCollideMask(CIGlobals.WallBitmask)
        node.addSolid(sphere)
        self.collNodePath = self.attachNewNode(node)
        self.collNodePath.setZ(1.5)
        self.collNodePath.setSy(2.0)
        self.collNodePath.setSx(1.75)

    def disable(self):
        self.fsm.requestFinalState()
        if self.moPath:
            self.moPath.stop()
            self.moPath = None
        self.moPaths = None
        self.honkSfxPath = None
        self.cartModelPath = None
        self.soundEngineLoop = None
        self.soundDriveBy = None
        if self.suitInCar:
            self.suitInCar.disable()
            self.suitInCar.delete()
            self.suitInCar = None
        if self.cart:
            self.cart.removeNode()
            self.cart = None
        del self.fsm
        DistributedNode.disable(self)
        return
コード例 #29
0
ファイル: CogThief.py プロジェクト: colenoreika/rtask
class CogThief(DirectObject):
    notify = directNotify.newCategory('CogThief')
    DefaultSpeedWalkAnim = 4.0
    CollisionRadius = 1.25
    MaxFriendsVisible = 4
    Infinity = 100000.0
    SeparationDistance = 6.0
    MinUrgency = 0.5
    MaxUrgency = 0.75

    def __init__(self, cogIndex, suitType, game, cogSpeed):
        self.cogIndex = cogIndex
        self.suitType = suitType
        self.game = game
        self.cogSpeed = cogSpeed
        suit = Suit.Suit()
        d = SuitDNA.SuitDNA()
        d.newSuit(suitType)
        suit.setDNA(d)
        suit.pose('walk', 0)
        self.suit = suit
        self.goal = CTGG.NoGoal
        self.goalId = CTGG.InvalidGoalId
        self.lastLocalTimeStampFromAI = 0
        self.lastPosFromAI = Point3(0, 0, 0)
        self.lastThinkTime = 0
        self.doneAdjust = False
        self.barrel = CTGG.NoBarrelCarried
        self.signalledAtReturnPos = False
        self.defaultPlayRate = 1.0
        self.netTimeSentToStartByHit = 0
        self.velocity = Vec3(0, 0, 0)
        self.oldVelocity = Vec3(0, 0, 0)
        self.acceleration = Vec3(0, 0, 0)
        self.bodyLength = self.CollisionRadius * 2
        self.cruiseDistance = 2 * self.bodyLength
        self.maxVelocity = self.cogSpeed
        self.maxAcceleration = 5.0
        self.perceptionRange = 6
        self.notify.debug('cogSpeed=%s' % self.cogSpeed)
        self.kaboomSound = loader.loadSfx(
            'phase_4/audio/sfx/MG_cannon_fire_alt.mp3')
        self.kaboom = loader.loadModel(
            'phase_4/models/minigames/ice_game_kaboom')
        self.kaboom.setScale(2.0)
        self.kaboom.setBillboardPointEye()
        self.kaboom.hide()
        self.kaboomTrack = None
        splatName = 'splat-creampie'
        self.splat = globalPropPool.getProp(splatName)
        self.splat.setBillboardPointEye()
        self.splatType = globalPropPool.getPropType(splatName)
        self.pieHitSound = globalBattleSoundCache.getSound(
            'AA_wholepie_only.mp3')

    def destroy(self):
        self.ignoreAll()
        self.suit.delete()
        self.game = None

    def uniqueName(self, baseStr):
        return baseStr + '-' + str(self.game.doId)

    def handleEnterSphere(self, collEntry):
        intoNp = collEntry.getIntoNodePath()
        self.notify.debug('handleEnterSphere suit %d hit %s' %
                          (self.cogIndex, intoNp))
        if self.game:
            self.game.handleEnterSphere(collEntry)

    def gameStart(self, gameStartTime):
        self.gameStartTime = gameStartTime
        self.initCollisions()
        self.startWalkAnim()

    def gameEnd(self):
        self.moveIval.pause()
        del self.moveIval
        self.shutdownCollisions()
        self.suit.loop('neutral')

    def initCollisions(self):
        self.collSphere = CollisionSphere(0, 0, 0, 1.25)
        self.collSphere.setTangible(1)
        name = 'CogThiefSphere-%d' % self.cogIndex
        self.collSphereName = self.uniqueName(name)
        self.collNode = CollisionNode(self.collSphereName)
        self.collNode.setIntoCollideMask(CTGG.BarrelBitmask
                                         | ToontownGlobals.WallBitmask)
        self.collNode.addSolid(self.collSphere)
        self.collNodePath = self.suit.attachNewNode(self.collNode)
        self.accept('enter' + self.collSphereName, self.handleEnterSphere)
        self.pieCollSphere = CollisionTube(0, 0, 0, 0, 0, 4,
                                           self.CollisionRadius)
        self.pieCollSphere.setTangible(1)
        name = 'CogThiefPieSphere-%d' % self.cogIndex
        self.pieCollSphereName = self.uniqueName(name)
        self.pieCollNode = CollisionNode(self.pieCollSphereName)
        self.pieCollNode.setIntoCollideMask(ToontownGlobals.PieBitmask)
        self.pieCollNode.addSolid(self.pieCollSphere)
        self.pieCollNodePath = self.suit.attachNewNode(self.pieCollNode)

    def shutdownCollisions(self):
        self.ignore(self.uniqueName('enter' + self.collSphereName))
        del self.collSphere
        self.collNodePath.removeNode()
        del self.collNodePath
        del self.collNode

    def updateGoal(self, timestamp, inResponseClientStamp, goalType, goalId,
                   pos):
        self.notify.debug('self.netTimeSentToStartByHit =%s' %
                          self.netTimeSentToStartByHit)
        if not self.game:
            self.notify.debug('updateGoal self.game is None, just returning')
            return None

        if not self.suit:
            self.notify.debug('updateGoal self.suit is None, just returning')
            return None

        if self.goal == CTGG.NoGoal:
            self.startWalkAnim()

        if goalType == CTGG.NoGoal:
            self.notify.debug('updateGoal setting position to %s' % pos)
            self.suit.setPos(pos)

        self.lastThinkTime = 0
        self.velocity = Vec3(0, 0, 0)
        self.oldVelocity = Vec3(0, 0, 0)
        self.acceleration = Vec3(0, 0, 0)
        if goalType == CTGG.RunAwayGoal:
            pass
        1
        if inResponseClientStamp < self.netTimeSentToStartByHit and self.goal == CTGG.NoGoal and goalType == CTGG.RunAwayGoal:
            self.notify.warning(
                'ignoring newGoal %s as cog %d was recently hit responsetime=%s hitTime=%s'
                % (CTGG.GoalStr[goalType], self.cogIndex,
                   inResponseClientStamp, self.netTimeSentToStartByHit))
        else:
            self.lastLocalTimeStampFromAI = globalClockDelta.networkToLocalTime(
                timestamp, bits=32)
            self.goal = goalType
            self.goalId = goalId
            self.lastPosFromAI = pos
            self.doneAdjust = False
        self.signalledAtReturnPos = False

    def startWalkAnim(self):
        if self.suit:
            self.suit.loop('walk')
            speed = self.cogSpeed
            self.defaultPlayRate = float(self.cogSpeed /
                                         self.DefaultSpeedWalkAnim)
            self.suit.setPlayRate(self.defaultPlayRate, 'walk')

    def think(self):
        if self.goal == CTGG.ToonGoal:
            self.thinkAboutCatchingToon()
        elif self.goal == CTGG.BarrelGoal:
            self.thinkAboutGettingBarrel()
        elif self.goal == CTGG.RunAwayGoal:
            self.thinkAboutRunAway()

    def thinkAboutCatchingToon(self):
        if not self.game:
            return None

        av = self.game.getAvatar(self.goalId)
        if av:
            if not self.lastThinkTime:
                self.lastThinkTime = globalClock.getFrameTime()

            diffTime = globalClock.getFrameTime() - self.lastThinkTime
            avPos = av.getPos()
            myPos = self.suit.getPos()
            if not self.doneAdjust:
                myPos = self.lastPosFromAI
                self.notify.debug(
                    'thinkAboutCatchingToon not doneAdjust setting pos %s' %
                    myPos)
                self.doneAdjust = True

            self.suit.setPos(myPos)
            if self.game.isToonPlayingHitTrack(self.goalId):
                self.suit.headsUp(av)
                self.velocity = Vec3(0, 0, 0)
                self.oldVelocity = Vec3(0, 0, 0)
                self.acceleration = Vec3(0, 0, 0)
            else:
                self.commonMove()
            newPos = self.suit.getPos()
            self.adjustPlayRate(newPos, myPos, diffTime)

        self.lastThinkTime = globalClock.getFrameTime()

    def convertNetworkStampToGameTime(self, timestamp):
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32)
        gameTime = self.game.local2GameTime(localStamp)
        return gameTime

    def respondToToonHit(self, timestamp):
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32)
        if self.netTimeSentToStartByHit < timestamp:
            self.clearGoal()
            self.showKaboom()
            startPos = CTGG.CogStartingPositions[self.cogIndex]
            oldPos = self.suit.getPos()
            self.suit.setPos(startPos)
            if self.netTimeSentToStartByHit < timestamp:
                self.netTimeSentToStartByHit = timestamp

        else:
            self.notify.debug(
                'localStamp = %s, lastLocalTimeStampFromAI=%s, ignoring respondToToonHit'
                % (localStamp, self.lastLocalTimeStampFromAI))
        self.notify.debug(
            'respondToToonHit self.netTimeSentToStartByHit = %s' %
            self.netTimeSentToStartByHit)

    def clearGoal(self):
        self.goal = CTGG.NoGoal
        self.goalId = CTGG.InvalidGoalId

    def thinkAboutGettingBarrel(self):
        if not self.game:
            return None

        if not hasattr(self.game, 'barrels'):
            return None

        if self.goalId not in xrange(len(self.game.barrels)):
            return None

        if not self.lastThinkTime:
            self.lastThinkTime = globalClock.getFrameTime()

        diffTime = globalClock.getFrameTime() - self.lastThinkTime
        barrel = self.game.barrels[self.goalId]
        barrelPos = barrel.getPos()
        myPos = self.suit.getPos()
        if not self.doneAdjust:
            myPos = self.lastPosFromAI
            self.notify.debug(
                'thinkAboutGettingBarrel not doneAdjust setting position to %s'
                % myPos)
            self.suit.setPos(myPos)
            self.doneAdjust = True

        displacement = barrelPos - myPos
        distanceToToon = displacement.length()
        self.suit.headsUp(barrel)
        lengthTravelled = diffTime * self.cogSpeed
        if lengthTravelled > distanceToToon:
            lengthTravelled = distanceToToon

        displacement.normalize()
        dirVector = displacement
        dirVector *= lengthTravelled
        newPos = myPos + dirVector
        newPos.setZ(0)
        self.suit.setPos(newPos)
        self.adjustPlayRate(newPos, myPos, diffTime)
        self.lastThinkTime = globalClock.getFrameTime()

    def stopWalking(self, timestamp):
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32)
        if localStamp > self.lastLocalTimeStampFromAI:
            self.suit.loop('neutral')
            self.clearGoal()

    def thinkAboutRunAway(self):
        if not self.game:
            return None

        if not self.lastThinkTime:
            self.lastThinkTime = globalClock.getFrameTime()

        diffTime = globalClock.getFrameTime() - self.lastThinkTime
        returnPos = CTGG.CogReturnPositions[self.goalId]
        myPos = self.suit.getPos()
        if not self.doneAdjust:
            myPos = self.lastPosFromAI
            self.suit.setPos(myPos)
            self.doneAdjust = True

        displacement = returnPos - myPos
        distanceToToon = displacement.length()
        tempNp = render.attachNewNode('tempRet')
        tempNp.setPos(returnPos)
        self.suit.headsUp(tempNp)
        tempNp.removeNode()
        lengthTravelled = diffTime * self.cogSpeed
        if lengthTravelled > distanceToToon:
            lengthTravelled = distanceToToon

        displacement.normalize()
        dirVector = displacement
        dirVector *= lengthTravelled
        newPos = myPos + dirVector
        newPos.setZ(0)
        self.suit.setPos(newPos)
        self.adjustPlayRate(newPos, myPos, diffTime)
        if (self.suit.getPos() - returnPos).length() < 0.0001:
            if not (self.signalledAtReturnPos) and self.barrel >= 0:
                self.game.sendCogAtReturnPos(self.cogIndex, self.barrel)
                self.signalledAtReturnPos = True

        self.lastThinkTime = globalClock.getFrameTime()

    def makeCogCarryBarrel(self, timestamp, inResponseClientStamp, barrelModel,
                           barrelIndex, cogPos):
        if not self.game:
            return None

        localTimeStamp = globalClockDelta.networkToLocalTime(timestamp,
                                                             bits=32)
        self.lastLocalTimeStampFromAI = localTimeStamp
        inResponseGameTime = self.convertNetworkStampToGameTime(
            inResponseClientStamp)
        self.notify.debug('inResponseGameTime =%s timeSentToStart=%s' %
                          (inResponseGameTime, self.netTimeSentToStartByHit))
        if inResponseClientStamp < self.netTimeSentToStartByHit and self.goal == CTGG.NoGoal:
            self.notify.warning('ignoring makeCogCarrybarrel')
        else:
            barrelModel.setPos(0, -1.0, 1.5)
            barrelModel.reparentTo(self.suit)
            self.suit.setPos(cogPos)
            self.barrel = barrelIndex

    def makeCogDropBarrel(self, timestamp, inResponseClientStamp, barrelModel,
                          barrelIndex, barrelPos):
        localTimeStamp = globalClockDelta.networkToLocalTime(timestamp,
                                                             bits=32)
        self.lastLocalTimeStampFromAI = localTimeStamp
        barrelModel.reparentTo(render)
        barrelModel.setPos(barrelPos)
        self.barrel = CTGG.NoBarrelCarried

    def respondToPieHit(self, timestamp):
        localStamp = globalClockDelta.networkToLocalTime(timestamp, bits=32)
        if self.netTimeSentToStartByHit < timestamp:
            self.clearGoal()
            self.showSplat()
            startPos = CTGG.CogStartingPositions[self.cogIndex]
            oldPos = self.suit.getPos()
            self.suit.setPos(startPos)
            if self.netTimeSentToStartByHit < timestamp:
                self.netTimeSentToStartByHit = timestamp

        else:
            self.notify.debug(
                'localStamp = %s, lastLocalTimeStampFromAI=%s, ignoring respondToPieHit'
                % (localStamp, self.lastLocalTimeStampFromAI))
            self.notify.debug(
                'respondToPieHit self.netTimeSentToStartByHit = %s' %
                self.netTimeSentToStartByHit)

    def cleanup(self):
        self.clearGoal()
        self.ignoreAll()
        self.suit.delete()
        if self.kaboomTrack and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()

        self.suit = None
        self.game = None

    def adjustPlayRate(self, newPos, oldPos, diffTime):
        lengthTravelled = (newPos - oldPos).length()
        if diffTime:
            speed = lengthTravelled / diffTime
        else:
            speed = self.cogSpeed
        rateMult = speed / self.cogSpeed
        newRate = rateMult * self.defaultPlayRate
        self.suit.setPlayRate(newRate, 'walk')

    def commonMove(self):
        if not self.lastThinkTime:
            self.lastThinkTime = globalClock.getFrameTime()

        dt = globalClock.getFrameTime() - self.lastThinkTime
        self.oldpos = self.suit.getPos()
        pos = self.suit.getPos()
        pos += self.velocity * dt
        self.suit.setPos(pos)
        self.seeFriends()
        acc = Vec3(0, 0, 0)
        self.accumulate(acc, self.getTargetVector())
        if self.numFlockmatesSeen > 0:
            keepDistanceVector = self.keepDistance()
            oldAcc = Vec3(acc)
            self.accumulate(acc, keepDistanceVector)
            if self.cogIndex == 0:
                pass

        if acc.length() > self.maxAcceleration:
            acc.normalize()
            acc *= self.maxAcceleration

        self.oldVelocity = self.velocity
        self.velocity += acc
        if self.velocity.length() > self.maxVelocity:
            self.velocity.normalize()
            self.velocity *= self.maxVelocity

        forwardVec = Vec3(1, 0, 0)
        heading = rad2Deg(math.atan2(self.velocity[1], self.velocity[0]))
        heading -= 90
        self.suit.setH(heading)

    def getTargetVector(self):
        targetPos = Point3(0, 0, 0)
        if self.goal == CTGG.ToonGoal:
            av = self.game.getAvatar(self.goalId)
            if av:
                targetPos = av.getPos()

        elif self.goal == CTGG.BarrelGoal:
            barrel = self.game.barrels[self.goalId]
            targetPos = barrel.getPos()
        elif self.goal == CTGG.RunAwayGoal:
            targetPos = CTGG.CogReturnPositions[self.goalId]

        targetPos.setZ(0)
        myPos = self.suit.getPos()
        diff = targetPos - myPos
        if diff.length() > 1.0:
            diff.normalize()
            diff *= 1.0

        return diff

    def accumulate(self, accumulator, valueToAdd):
        accumulator += valueToAdd
        return accumulator.length()

    def seeFriends(self):
        self.clearVisibleList()
        for cogIndex in self.game.cogInfo.keys():
            if cogIndex == self.cogIndex:
                continue

            if self.sameGoal(cogIndex):
                dist = self.canISee(cogIndex)
                if dist != self.Infinity:
                    self.addToVisibleList(cogIndex)
                    if dist < self.distToNearestFlockmate:
                        self.nearestFlockmate = cogIndex
                        self.distToNearestFlockmate = dist

            dist != self.Infinity

        return self.numFlockmatesSeen

    def clearVisibleList(self):
        self.visibleFriendsList = []
        self.numFlockmatesSeen = 0
        self.nearestFlockmate = None
        self.distToNearestFlockmate = self.Infinity

    def addToVisibleList(self, cogIndex):
        if self.numFlockmatesSeen < self.MaxFriendsVisible:
            self.visibleFriendsList.append(cogIndex)
            self.numFlockmatesSeen += 1
            if self.cogIndex == 0:
                pass

    def canISee(self, cogIndex):
        if self.cogIndex == cogIndex:
            return self.Infinity

        cogThief = self.game.getCogThief(cogIndex)
        distance = self.suit.getDistance(cogThief.suit)
        if distance < self.perceptionRange:
            return distance

        return self.Infinity

    def sameGoal(self, cogIndex):
        cogThief = self.game.getCogThief(cogIndex)
        if cogThief.goalId == self.goalId:
            pass
        result = cogThief.goal == self.goal
        return result

    def keepDistance(self):
        ratio = self.distToNearestFlockmate / self.SeparationDistance
        nearestThief = self.game.getCogThief(self.nearestFlockmate)
        change = nearestThief.suit.getPos() - self.suit.getPos()
        if ratio < self.MinUrgency:
            ratio = self.MinUrgency

        if ratio > self.MaxUrgency:
            ratio = self.MaxUrgency

        if self.distToNearestFlockmate < self.SeparationDistance:
            change.normalize()
            change *= -(1 - ratio)
        elif self.distToNearestFlockmate > self.SeparationDistance:
            change.normalize()
            change *= ratio
        else:
            change = Vec3(0, 0, 0)
        return change

    def showKaboom(self):
        if self.kaboomTrack and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()

        self.kaboom.reparentTo(render)
        self.kaboom.setPos(self.suit.getPos())
        self.kaboom.setZ(3)
        self.kaboomTrack = Parallel(
            SoundInterval(self.kaboomSound, volume=0.5),
            Sequence(
                Func(self.kaboom.showThrough),
                LerpScaleInterval(self.kaboom,
                                  duration=0.5,
                                  scale=Point3(10, 10, 10),
                                  startScale=Point3(1, 1, 1),
                                  blendType='easeOut'),
                Func(self.kaboom.hide)))
        self.kaboomTrack.start()

    def showSplat(self):
        if self.kaboomTrack and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()

        self.splat.reparentTo(render)
        self.splat.setPos(self.suit.getPos())
        self.splat.setZ(3)
        self.kaboomTrack = Parallel(
            SoundInterval(self.pieHitSound, volume=1.0),
            Sequence(
                Func(self.splat.showThrough),
                LerpScaleInterval(self.splat,
                                  duration=0.5,
                                  scale=1.75,
                                  startScale=Point3(0.10000000000000001,
                                                    0.10000000000000001,
                                                    0.10000000000000001),
                                  blendType='easeOut'), Func(self.splat.hide)))
        self.kaboomTrack.start()
コード例 #30
0
class LightDropGag(DropGag):
    def __init__(self,
                 name,
                 model,
                 anim,
                 damage,
                 hitSfx,
                 missSfx,
                 rotate90=False,
                 sphereSize=2,
                 sphereZ=0):
        DropGag.__init__(self,
                         name,
                         model,
                         anim,
                         damage,
                         hitSfx,
                         missSfx,
                         scale=1,
                         playRate=1)
        DropGag.setShadowData(self, isCircle=True, shadowScale=0.5)
        self.stunTime = 1.5
        self.objTrack = None
        self.rotate90 = rotate90
        self.sphereSize = sphereSize
        self.sphereZ = sphereZ

    def startDrop(self):
        if self.gag and self.dropLoc:
            x, y, z = self.dropLoc
            startPos = Point3(x, y, z + 20)
            self.gag.setPos(x, y + 2, z)
            self.gag.node().setBounds(OmniBoundingVolume())
            self.gag.node().setFinal(1)
            self.gag.headsUp(self.avatar)
            if self.rotate90:
                self.gag.setH(self.gag.getH() - 90)
            self.buildCollisions()
            objectTrack = Sequence()
            animProp = LerpPosInterval(self.gag,
                                       self.fallDuration,
                                       self.dropLoc,
                                       startPos=startPos)
            bounceProp = Effects.createZBounce(self.gag, 2, self.dropLoc, 0.5,
                                               1.5)
            objAnimShrink = Sequence(Wait(0.5),
                                     Func(self.gag.reparentTo, render),
                                     animProp, bounceProp)
            objectTrack.append(objAnimShrink)
            dropShadow = loader.loadModel(
                'phase_3/models/props/drop_shadow.bam')
            dropShadow.reparentTo(render)
            dropShadow.setPos(self.dropLoc)
            dropShadow.setScale(self.getShadowScale())
            shadowTrack = Sequence(
                LerpScaleInterval(dropShadow,
                                  self.fallDuration + 0.1,
                                  dropShadow.getScale(),
                                  startScale=Point3(0.01, 0.01, 0.01)),
                Wait(0.3), Func(dropShadow.removeNode))
            self.objTrack = Parallel(
                Sequence(Wait(self.fallDuration), Func(self.completeDrop)),
                objectTrack, shadowTrack)
            self.objTrack.start()
            self.dropLoc = None

    def onActivate(self, ignore, suit):
        self.objTrack.finish()
        self.objTrack = None
        if not suit.isDead():
            suit.setAnimState('drop-react')
        suit.d_disableMovement(wantRay=True)

        if not self.gag or self.gag.isEmpty():
            self.build()

        self.gag.setPos(suit.find('**/joint_head').getPos(render))
        if self.name == CIGlobals.FlowerPot:
            self.gag.setZ(self.gag, 3)
        bounce = Effects.createScaleZBounce(self.gag, 1,
                                            self.gag.getScale(render), 0.3,
                                            0.75)
        dummyNode = suit.attachNewNode('fallOffNode')
        dummyNode.setX(2)
        dummyNode.setY(-2)
        flightIval = FlightProjectileInterval(self.gag,
                                              startPos=self.gag.getPos(render),
                                              endPos=dummyNode.getPos(render),
                                              duration=0.8,
                                              gravityMult=.35)
        Sequence(Parallel(bounce, flightIval), Wait(self.stunTime),
                 Func(suit.d_enableMovement)).start()

        dummyNode.removeNode()
        del dummyNode

    def buildCollisions(self):
        gagSph = CollisionSphere(0, 0, self.sphereZ, self.sphereSize)
        gagSensor = CollisionNode('gagSensor')
        gagSensor.addSolid(gagSph)
        sensorNP = self.gag.attachNewNode(gagSensor)
        sensorNP.setCollideMask(BitMask32(0))
        sensorNP.node().setFromCollideMask(CIGlobals.WallBitmask
                                           | CIGlobals.FloorBitmask)
        event = CollisionHandlerEvent()
        event.set_in_pattern("%fn-into")
        event.set_out_pattern("%fn-out")
        base.cTrav.addCollider(sensorNP, event)
        self.avatar.acceptOnce('gagSensor-into', self.onCollision)
コード例 #31
0
class DistributedBoat(DistributedObject):
    notify = directNotify.newCategory("DistributedBoat")

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.fsm = ClassicFSM('DistributedBoat', [
            State('off', self.enterOff, self.exitOff),
            State('eastToWest', self.enterEastToWest, self.exitEastToWest),
            State('westToEast', self.enterWestToEast, self.exitWestToEast)
        ], 'off', 'off')
        self.boat = None
        self.eastPier = None
        self.eastPierPath = 'east_pier'
        self.westPier = None
        self.westPierPath = 'west_pier'
        self.pierUpP = 0.0
        self.pierDownP = -45.0
        self.fogHorn = 'phase_5/audio/sfx/SZ_DD_foghorn.ogg'
        self.shipBell = 'phase_6/audio/sfx/SZ_DD_shipbell.ogg'
        self.waterLap = 'phase_6/audio/sfx/SZ_DD_waterlap.ogg'
        self.dockCreak = 'phase_6/audio/sfx/SZ_DD_dockcreak.ogg'
        self.eastWest = 'phase_6/paths/dd-e-w.bam'
        self.westEast = 'phase_6/paths/dd-w-e.bam'
        self.track = None
        self.state = None
        self.animBoat1Track = None
        self.animBoatTrack = None

        # Variables that handle the winter collision node.
        self.crashColl = None
        self.crashCollNP = None

    def __handleOnBoat(self, entry):
        base.localAvatar.b_setParent(CIGlobals.SPDonaldsBoat)

    def __handleOffBoat(self, entry):
        base.localAvatar.b_setParent(CIGlobals.SPRender)
        base.localAvatar.setR(0)
        base.localAvatar.setP(0)

    def generate(self):
        DistributedObject.generate(self)
        self.soundFogHorn = base.audio3d.loadSfx(self.fogHorn)
        self.soundShipBell = base.audio3d.loadSfx(self.shipBell)
        self.soundWaterLap = base.audio3d.loadSfx(self.waterLap)
        self.soundDockCreak = base.audio3d.loadSfx(self.dockCreak)

        geom = self.cr.playGame.hood.loader.geom
        self.boatMdl = geom.find('**/*donalds_boat*')
        self.boat = geom.find("**/ddBoatRoot")
        self.boatMdl1 = geom.find("**/ddBoatMdl1")

        base.audio3d.attachSoundToObject(self.soundFogHorn, self.boat)
        base.audio3d.attachSoundToObject(self.soundShipBell, self.boat)
        base.audio3d.attachSoundToObject(self.soundWaterLap, self.boat)
        base.audio3d.attachSoundToObject(self.soundDockCreak, self.boat)

        self.soundWaterLap.setLoop(True)
        self.soundWaterLap.play()

        self.generated()

    def generated(self):
        self.eastPier = self.cr.playGame.hood.loader.geom.find(
            '**/' + self.eastPierPath)
        self.westPier = self.cr.playGame.hood.loader.geom.find(
            '**/' + self.westPierPath)
        base.cr.parentMgr.registerParent(CIGlobals.SPDonaldsBoat, self.boatMdl)
        self.accept('enterdonalds_boat_floor', self.__handleOnBoat)
        self.accept('exitdonalds_boat_floor', self.__handleOffBoat)
        self.d_requestCurrentStateAndTimestamp()
        self.fsm.enterInitialState()

        speedFactor = 2

        self.animBoatTrack = Sequence(
            LerpHprInterval(self.boatMdl,
                            duration=1 * speedFactor,
                            hpr=(0, 0, -1),
                            startHpr=(0, 0, 1),
                            blendType='easeInOut'),
            LerpHprInterval(self.boatMdl,
                            duration=1 * speedFactor,
                            hpr=(0, 0, 1),
                            startHpr=(0, 0, -1),
                            blendType='easeInOut'))

        import math

        self.animBoat1Track = Sequence(
            LerpHprInterval(self.boatMdl1,
                            duration=math.pi * speedFactor,
                            hpr=(0, 1, 0),
                            startHpr=(0, -1, 0),
                            blendType='easeInOut'),
            LerpHprInterval(self.boatMdl1,
                            duration=math.pi * speedFactor,
                            hpr=(0, -1, 0),
                            startHpr=(0, 1, 0),
                            blendType='easeInOut'))
        self.animBoat1Track.loop()
        self.animBoatTrack.loop()

        if base.cr.holidayManager.getHoliday() == HolidayType.CHRISTMAS:
            self.boat.setPosHpr(12.73, -1.6, -4.7, 341.57, 350.0, 26.5)
            self.fsm.request('off')

            self.crashColl = CollisionSphere(0, 0, 0, 15)
            self.crashCollNP = self.boat.attachNewNode(
                CollisionNode('crashed_boat_collision'))
            self.crashCollNP.node().addSolid(self.crashColl)
            self.crashCollNP.node().setCollideMask(CIGlobals.WallBitmask)
            self.crashCollNP.setSz(2)
            self.crashCollNP.setSx(0.75)
            self.crashCollNP.setSy(1.25)
            self.crashCollNP.setPosHpr(2.05, 3.21, 1.66, 8.44, 6.93, 332.61)

    def disable(self):
        base.taskMgr.remove(self.uniqueName('__pollBoat'))
        base.cr.parentMgr.unregisterParent(CIGlobals.SPDonaldsBoat)
        self.ignore('enterdonalds_boat_floor')
        self.ignore('exitdonalds_boat_floor')
        self.fsm.requestFinalState()

        if self.animBoat1Track:
            self.animBoat1Track.finish()
            self.animBoat1Track = None
        if self.animBoatTrack:
            self.animBoatTrack.finish()
            self.animBoatTrack = None

        if self.crashCollNP:
            self.crashCollNP.removeNode()
            del self.crashCollNP
            del self.crashColl

        del self.fsm
        del self.soundFogHorn
        del self.soundShipBell
        self.soundWaterLap.stop()
        del self.soundWaterLap
        del self.soundDockCreak
        self.fogHorn = None
        self.shipBell = None
        self.waterLap = None
        self.dockCreak = None
        self.boat = None
        self.boatMdl = None
        self.boatMdl1 = None
        self.track = None
        self.pierDownP = None
        self.pierUpP = None
        self.eastPier = None
        self.eastPierPath = None
        self.westPier = None
        self.westPierPath = None
        self.boatPath = None
        self.westEast = None
        self.eastWest = None
        DistributedObject.disable(self)

    def currentStateAndTimestamp(self, state, timestamp):
        self.setState(state, timestamp)

    def d_requestCurrentStateAndTimestamp(self):
        self.sendUpdate('requestCurrentStateAndTimestamp', [])

    def setState(self, state, timestamp=None):
        if timestamp is None:
            ts = 0.0
        else:
            ts = globalClockDelta.localElapsedTime(timestamp)
        self.state = state
        if self.boat and base.cr.holidayManager.getHoliday(
        ) != HolidayType.CHRISTMAS:
            self.fsm.request(state, [ts])

    def enterEastToWest(self, ts=0):
        moPath = Mopath.Mopath()
        moPath.loadFile(self.eastWest)
        moIval = MopathInterval(moPath, self.boat, blendType='easeInOut')

        self.track = Parallel(
            SoundInterval(self.soundShipBell, node=self.boat),
            SoundInterval(self.soundDockCreak, node=self.eastPier), moIval,
            LerpQuatInterval(self.eastPier,
                             duration=5.0,
                             quat=(90, self.pierDownP, 0),
                             startHpr=(90, self.pierUpP, 0),
                             blendType='easeInOut'),
            Sequence(
                Wait(15.0),
                Parallel(
                    LerpQuatInterval(self.westPier,
                                     duration=5.0,
                                     quat=(-90, self.pierUpP, 0),
                                     startHpr=(-90, self.pierDownP, 0),
                                     blendType='easeInOut'),
                    Sequence(
                        Wait(2.0),
                        SoundInterval(self.soundDockCreak,
                                      node=self.westPier))),
                SoundInterval(self.soundFogHorn, node=self.boat)))
        self.track.start(ts)

    def exitEastToWest(self):
        if self.track:
            self.track.finish()
            self.track = None

    def enterWestToEast(self, ts=0):
        moPath = Mopath.Mopath()
        moPath.loadFile(self.westEast)
        moIval = MopathInterval(moPath, self.boat, blendType='easeInOut')

        self.track = Parallel(
            SoundInterval(self.soundShipBell, node=self.boat),
            SoundInterval(self.soundDockCreak, node=self.westPier), moIval,
            LerpQuatInterval(self.westPier,
                             duration=5.0,
                             quat=(-90, self.pierDownP, 0),
                             startHpr=(-90, self.pierUpP, 0),
                             blendType='easeInOut'),
            Sequence(
                Wait(15.0),
                Parallel(
                    LerpQuatInterval(self.eastPier,
                                     duration=5.0,
                                     quat=(90, self.pierUpP, 0),
                                     startHpr=(90, self.pierDownP, 0),
                                     blendType='easeInOut'),
                    Sequence(
                        Wait(2.0),
                        SoundInterval(self.soundDockCreak,
                                      node=self.eastPier))),
                SoundInterval(self.soundFogHorn, node=self.boat)))
        self.track.start(ts)

    def exitWestToEast(self):
        if self.track:
            self.track.finish()
            self.track = None

    def enterOff(self):
        pass

    def exitOff(self):
        pass
コード例 #32
0
ファイル: Place.py プロジェクト: coginvasion/src
class Place(StateData):
    notify = directNotify.newCategory('Place')

    def __init__(self, loader, doneEvent):
        StateData.__init__(self, doneEvent)
        self.loader = loader
        self.zoneId = None
        self.track = None
        return

    def maybeUpdateAdminPage(self):
        if self.fsm:
            if self.fsm.getCurrentState():
                if self.fsm.getCurrentState().getName() == 'shtickerBook':
                    if hasattr(self, 'shtickerBookStateData'):
                        if self.shtickerBookStateData.fsm.getCurrentState().getName() == 'adminPage':
                            if base.cr.playGame.suitManager:
                                text2Change2 = 'Turn Suit Spawner '
                                if base.cr.playGame.suitManager.getSpawner():
                                    text2Change2 += 'Off'
                                else:
                                    text2Change2 += 'On'
                                self.shtickerBookStateData.adminPageStateData.suitSpawnerBtn['text'] = text2Change2

    def enterStart(self):
        pass

    def exitStart(self):
        pass

    def enterFinal(self):
        pass

    def exitFinal(self):
        pass

    def enter(self):
        StateData.enter(self)
        base.localAvatar.createChatInput()

    def exit(self):
        base.localAvatar.disableChatInput()
        StateData.exit(self)

    def enterDoorIn(self, distDoor):
        base.localAvatar.attachCamera()
        requestStatus = {}
        requestStatus['zoneId'] = distDoor.getToZone()
        requestStatus['hoodId'] = base.cr.playGame.hood.id
        requestStatus['how'] = 'doorOut'
        requestStatus['shardId'] = None
        requestStatus['doorIndex'] = distDoor.getDoorIndex()
        foundBlock = False
        for interior in base.cr.doFindAll('DistributedToonInterior'):
            if interior.zoneId == base.localAvatar.zoneId:
                foundBlock = True
                requestStatus['block'] = interior.getBlock()
                break

        if not foundBlock:
            requestStatus['block'] = distDoor.getBlock()
        requestStatus['where'] = ZoneUtil.getWhereName(requestStatus['zoneId'])
        requestStatus['loader'] = base.cr.playGame.hood.fsm.getCurrentState().getName()
        requestStatus['avId'] = base.localAvatar.doId
        self.acceptOnce('DistributedDoor_localAvatarWentInDoor', self.handleDoorInDone, [requestStatus])
        self.acceptOnce('DistributedDoor_localAvatarGoingInDoor', base.transitions.irisOut)
        return

    def exitDoorIn(self):
        base.localAvatar.detachCamera()
        self.ignore('DistributedDoor_localAvatarWentInDoor')
        self.ignore('DistributedDoor_localAvatarGoingInDoor')

    def handleDoorInDone(self, requestStatus):
        self.doneStatus = requestStatus
        messenger.send(self.doneEvent)

    def __waitOnDoor(self, door, task):
        if door.ready:
            self.__doorReady(door)
            return task.done
        return task.cont

    def enterDoorOut(self, requestStatus):
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.d_clearSmoothing()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.walkControls.setCollisionsActive(0)
        block = requestStatus['block']
        zoneId = requestStatus['zoneId']
        doorIndex = requestStatus['doorIndex']
        doorToExitFrom = None
        for door in base.cr.doFindAll('DistributedDoor'):
            if door.zoneId == zoneId:
                if door.getBlock() == block:
                    if door.getDoorIndex() == doorIndex:
                        doorToExitFrom = door
                        break

        if not doorToExitFrom:
            self.notify.error('Could not find a DistributedDoor to exit from!')
        elif not doorToExitFrom.ready:
            base.taskMgr.add(self.__waitOnDoor, 'Place.waitOnDoor', extraArgs=[doorToExitFrom], appendTask=True)
            return
        self.__doorReady(doorToExitFrom)
        return

    def __doorReady(self, door):
        door.sendUpdate('requestExit', [])
        self.nextState = 'walk'
        self.acceptOnce('DistributedDoor_localAvatarCameOutOfDoor', self.handleDoorOutDone)

    def exitDoorOut(self):
        base.taskMgr.remove('Place.waitOnDoor')
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()
        self.ignore('DistributedDoor_localAvatarCameOutOfDoor')

    def handleDoorOutDone(self):
        base.transitions.irisIn()
        base.localAvatar.walkControls.setCollisionsActive(1)
        self.fsm.request(self.nextState)

    def enterShtickerBook(self):
        base.localAvatar.attachCamera()
        base.localAvatar.createLaffMeter()
        base.localAvatar.startSmartCamera()
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.b_setAnimState('openBook', self.enterShtickerBookGui)

    def enterShtickerBookGui(self):
        doneEvent = 'shtickerBookDone'
        self.shtickerBookStateData = ShtickerBook(self.fsm, doneEvent)
        self.acceptOnce(doneEvent, self.__shtickerBookDone)
        self.shtickerBookStateData.load()
        self.shtickerBookStateData.enter()
        base.localAvatar.showBookButton(1)
        base.localAvatar.b_setAnimState('readBook')

    def __shtickerBookDone(self):
        doneStatus = self.shtickerBookStateData.getDoneStatus()
        base.localAvatar.hideBookButton()
        self.shtickerBookStateData.exit()
        if doneStatus['mode'] == 'exit':
            base.localAvatar.b_setAnimState('closeBook', self.__handleBookCloseExit)
        elif doneStatus['mode'] == 'teleport':
            base.localAvatar.b_setAnimState('closeBook', self.__handleBookCloseTeleport, [doneStatus])
        elif doneStatus['mode'] == 'resume':
            base.localAvatar.b_setAnimState('closeBook', self.__handleBookCloseResume)
        elif doneStatus['mode'] == 'switchShard':
            base.localAvatar.b_setAnimState('closeBook', self.__handleBookCloseSwitchShard, [doneStatus])

    def __handleBookCloseSwitchShard(self, requestStatus):
        base.localAvatar.b_setAnimState('teleportOut', self.__handleBookSwitchShard, [requestStatus])

    def __handleBookSwitchShard(self, requestStatus):
        params = []
        params.append(requestStatus['shardId'])
        params.append(base.cr.playGame.hood.id)
        params.append(ZoneUtil.getZoneId(base.cr.playGame.hood.id))
        params.append(base.localAvatar.doId)
        base.cr.gameFSM.request('switchShards', params)

    def __handleBookCloseResume(self):
        self.fsm.request('walk')

    def __handleBookCloseTeleport(self, requestStatus):
        self.fsm.request('teleportOut', [requestStatus])

    def __teleportOutDone(self, requestStatus):
        self.doneStatus = requestStatus
        messenger.send(self.doneEvent)

    def __handleBookCloseExit(self):
        base.localAvatar.b_setAnimState('teleportOut', self.__handleBookExitTeleport)

    def __handleBookExitTeleport(self):
        base.transitions.fadeOut(0.0)
        base.cr.gameFSM.request('closeShard')

    def exitShtickerBook(self):
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.disableLaffMeter()
        self.ignore(self.shtickerBookStateData.doneEvent)
        self.shtickerBookStateData.exit()
        self.shtickerBookStateData.unload()
        del self.shtickerBookStateData
        base.localAvatar.hideBookButton()

    def enterStop(self, doNeutral = 1):
        if doNeutral:
            base.localAvatar.b_setAnimState('neutral')
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.createLaffMeter()
        base.localAvatar.createMoney()
        base.localAvatar.enablePies(0)

    def exitStop(self):
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()
        base.localAvatar.disableLaffMeter()
        base.localAvatar.disableMoney()
        base.localAvatar.disablePies()

    def load(self):
        StateData.load(self)
        self.walkDoneEvent = 'walkDone'
        self.walkStateData = PublicWalk(self.fsm, self.walkDoneEvent)
        self.walkStateData.load()

    def unload(self):
        StateData.unload(self)
        del self.walkDoneEvent
        self.walkStateData.unload()
        del self.walkStateData
        del self.loader

    def enterTeleportIn(self, requestStatus):
        if requestStatus['avId'] != base.localAvatar.doId:
            av = base.cr.doId2do.get(requestStatus['avId'])
            if av:
                base.localAvatar.gotoNode(av)
                base.localAvatar.b_setChat('Hi, %s.' % av.getName())
        base.transitions.irisIn()
        self.nextState = requestStatus.get('nextState', 'walk')
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.startPosHprBroadcast()
        globalClock.tick()
        base.localAvatar.b_setAnimState('teleportIn', callback=self.teleportInDone)
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.b_setParent(CIGlobals.SPRender)

    def exitTeleportIn(self):
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()
        base.localAvatar.stopPosHprBroadcast()

    def teleportInDone(self):
        if hasattr(self, 'fsm'):
            self.fsm.request(self.nextState, [1])

    def enterAcknowledgeDeath(self, foo = 0):
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        message = 'You were defeated by the Cogs! Collect treasures in the Playground to refill your Laff meter.'
        self.dialog = GlobalDialog(message=message, style=3, doneEvent='ackDeathDone')
        self.dialog.show()
        self.acceptOnce('ackDeathDone', self.handleAckDeathDone)

    def handleAckDeathDone(self):
        self.fsm.request('walk', [1])

    def exitAcknowledgeDeath(self):
        self.ignore('ackDeathDone')
        self.dialog.cleanup()
        del self.dialog
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()

    def enterDied(self, requestStatus, callback = None):
        if callback == None:
            callback = self.__diedDone
        base.localAvatar.createLaffMeter()
        base.localAvatar.attachCamera()
        base.localAvatar.b_setAnimState('died', callback, [requestStatus])
        return

    def __diedDone(self, requestStatus):
        self.doneStatus = requestStatus
        messenger.send(self.doneEvent)

    def exitDied(self):
        base.localAvatar.disableLaffMeter()
        base.localAvatar.detachCamera()

    def enterWalk(self, teleportIn = 0):
        self.walkStateData.enter()
        if teleportIn == 0:
            self.walkStateData.fsm.request('walking')
        self.acceptOnce(self.walkDoneEvent, self.handleWalkDone)
        self.walkStateData.fsm.request('walking')
        self.watchTunnelSeq = Sequence(Wait(1.0), Func(LinkTunnel.globalAcceptCollisions))
        self.watchTunnelSeq.start()
        base.localAvatar.setBusy(0)
        base.localAvatar.enablePicking()
        base.localAvatar.showFriendButton()

    def exitWalk(self):
        self.walkStateData.exit()
        self.ignore(self.walkDoneEvent)
        if base.cr.playGame.hood.titleText != None:
            base.cr.playGame.hood.hideTitleText()
        self.watchTunnelSeq.pause()
        del self.watchTunnelSeq
        base.localAvatar.setBusy(1)
        base.localAvatar.disablePicking()
        base.localAvatar.hideFriendButton()
        base.localAvatar.friendsList.fsm.requestFinalState()
        base.localAvatar.panel.fsm.requestFinalState()
        return

    def handleWalkDone(self, doneStatus):
        pass

    def enterTeleportOut(self, requestStatus, callback = None):
        if not callback:
            callback = self.__teleportOutDone
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.b_setAnimState('teleportOut', callback, [requestStatus])

    def exitTeleportOut(self):
        base.localAvatar.disableLaffMeter()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()
        base.localAvatar.stopPosHprBroadcast()

    def enterTunnelIn(self, linkTunnel):
        base.localAvatar.attachCamera()
        base.localAvatar.playMovementSfx('run')
        pivotPoint = linkTunnel.inPivotPoint
        self.pivotPointNode = linkTunnel.tunnel.attachNewNode('tunnelPivotPoint')
        self.pivotPointNode.setPos(pivotPoint)
        currCamPos = camera.getPos(linkTunnel.tunnel)
        currCamHpr = camera.getHpr(linkTunnel.tunnel)
        currPos = base.localAvatar.getPos(self.pivotPointNode)
        currHpr = base.localAvatar.getHpr(self.pivotPointNode)
        if linkTunnel.__class__.__name__ == 'SafeZoneLinkTunnel':
            base.localAvatar.setHpr(180, 0, 0)
        else:
            base.localAvatar.setHpr(0, 0, 0)
        base.localAvatar.setPos(currPos)
        base.localAvatar.reparentTo(self.pivotPointNode)
        base.localAvatar.walkControls.setCollisionsActive(0)
        base.localAvatar.detachCamera()
        camera.reparentTo(linkTunnel.tunnel)
        tunnelCamPos = linkTunnel.camPos
        tunnelCamHpr = linkTunnel.camHpr
        self.track = Parallel(LerpPosInterval(camera, duration=0.7, pos=tunnelCamPos, startPos=currCamPos, blendType='easeOut'), LerpQuatInterval(camera, duration=0.7, quat=tunnelCamHpr, startHpr=currCamHpr, blendType='easeOut'), Sequence(Func(base.localAvatar.b_setAnimState, 'run'), Wait(2.0), Func(base.transitions.irisOut)), Sequence(LerpHprInterval(self.pivotPointNode, duration=2.0, hpr=linkTunnel.inPivotEndHpr, startHpr=linkTunnel.inPivotStartHpr), LerpPosInterval(self.pivotPointNode, duration=1.0, pos=(linkTunnel.inPivotEndX, self.pivotPointNode.getY(), self.pivotPointNode.getZ()), startPos=(linkTunnel.inPivotStartX, self.pivotPointNode.getY(), self.pivotPointNode.getZ()))), name='Place.enterTunnelIn')
        requestStatus = {}
        requestStatus['zoneId'] = linkTunnel.data['zoneId']
        if linkTunnel.__class__.__name__ == 'SafeZoneLinkTunnel':
            requestStatus['where'] = 'street'
            requestStatus['loader'] = 'townLoader'
            requestStatus['hoodId'] = base.cr.playGame.hood.id
            requestStatus['shardId'] = None
            requestStatus['avId'] = base.localAvatar.doId
            requestStatus['how'] = 'tunnelOut'
            requestStatus['fromZone'] = base.localAvatar.zoneId
        elif linkTunnel.__class__.__name__ == 'StreetLinkTunnel':
            requestStatus['where'] = 'playground'
            requestStatus['loader'] = 'safeZoneLoader'
            requestStatus['hoodId'] = base.cr.playGame.hood.id
            requestStatus['shardId'] = None
            requestStatus['avId'] = base.localAvatar.doId
            requestStatus['how'] = 'tunnelOut'
            requestStatus['fromZone'] = base.localAvatar.zoneId
        elif linkTunnel.__class__.__name__ == 'NeighborhoodLinkTunnel':
            requestStatus['where'] = 'street'
            requestStatus['loader'] = 'townLoader'
            hoodId = ZoneUtil.getHoodId(linkTunnel.data['zoneId'], 1)
            requestStatus['hoodId'] = hoodId
            requestStatus['shardId'] = None
            requestStatus['avId'] = base.localAvatar.doId
            requestStatus['how'] = 'tunnelOut'
            requestStatus['fromZone'] = base.localAvatar.zoneId
        self.track.setDoneEvent(self.track.getName())
        self.acceptOnce(self.track.getDoneEvent(), self.__handleTunnelInDone, [requestStatus])
        self.track.start()
        return

    def __handleTunnelInDone(self, requestStatus):
        self.doneStatus = requestStatus
        messenger.send(self.doneEvent)

    def exitTunnelIn(self):
        base.localAvatar.playMovementSfx(None)
        if self.track:
            self.ignore(self.track.getDoneEvent())
            self.track.finish()
            self.track = None
        base.localAvatar.reparentTo(render)
        self.pivotPointNode.removeNode()
        del self.pivotPointNode
        base.localAvatar.detachCamera()
        base.localAvatar.walkControls.setCollisionsActive(1)
        return

    def enterTunnelOut(self, requestStatus):
        base.localAvatar.playMovementSfx('run')
        base.transitions.irisIn()
        self.nextState = requestStatus.get('nextState', 'walk')
        linkTunnel = LinkTunnel.getTunnelThatGoesToZone(requestStatus['fromZone'])
        pivotPoint = linkTunnel.outPivotPoint
        self.pivotPointNode = linkTunnel.tunnel.attachNewNode('tunnelPivotPoint')
        self.pivotPointNode.setPos(pivotPoint)
        self.pivotPointNode.setHpr(linkTunnel.outPivotStartHpr)
        base.localAvatar.walkControls.setCollisionsActive(0)
        base.localAvatar.reparentTo(self.pivotPointNode)
        base.localAvatar.setHpr(linkTunnel.toonOutHpr)
        base.localAvatar.setPos(linkTunnel.toonOutPos)
        base.localAvatar.detachCamera()
        camera.reparentTo(linkTunnel.tunnel)
        tunnelCamPos = linkTunnel.camPos
        tunnelCamHpr = linkTunnel.camHpr
        camera.setPos(tunnelCamPos)
        camera.setHpr(tunnelCamHpr)
        self.track = Parallel(Sequence(Func(base.localAvatar.b_setAnimState, 'run'), LerpPosInterval(self.pivotPointNode, duration=1.0, pos=(linkTunnel.outPivotEndX, self.pivotPointNode.getY(), self.pivotPointNode.getZ()), startPos=(linkTunnel.outPivotStartX, self.pivotPointNode.getY(), self.pivotPointNode.getZ())), LerpHprInterval(self.pivotPointNode, duration=2.0, hpr=linkTunnel.outPivotEndHpr, startHpr=linkTunnel.outPivotStartHpr)), name='Place.enterTunnelOut')
        self.track.setDoneEvent(self.track.getName())
        self.acceptOnce(self.track.getDoneEvent(), self.__handleTunnelOutDone)
        self.track.start()

    def __handleTunnelOutDone(self):
        base.localAvatar.walkControls.setCollisionsActive(1)
        self.fsm.request(self.nextState)

    def exitTunnelOut(self):
        base.localAvatar.playMovementSfx(None)
        base.localAvatar.walkControls.setCollisionsActive(1)
        if self.track:
            self.ignore(self.track.getDoneEvent())
            self.track.finish()
            self.track = None
        base.localAvatar.setPos(base.localAvatar.getPos(render))
        base.localAvatar.setHpr(base.localAvatar.getHpr(render))
        base.localAvatar.reparentTo(render)
        self.pivotPointNode.removeNode()
        del self.pivotPointNode
        base.localAvatar.detachCamera()
        del self.nextState
        return
コード例 #33
0
class DistributedPartyGate(DistributedObject.DistributedObject):
    notify = DirectNotifyGlobal.directNotify.newCategory('DistributedPartyGate')

    def __init__(self, cr):
        DistributedObject.DistributedObject.__init__(self, cr)
        self.publicPartyChooseGuiDoneEvent = 'doneChoosingPublicParty'
        self.publicPartyGui = PublicPartyGui(self.publicPartyChooseGuiDoneEvent)
        self.publicPartyGui.stash()
        self.loadClockSounds()
        self.hourSoundInterval = Sequence()
        self.accept('stoppedAsleep', self.handleSleep)

    def loadClockSounds(self):
        self.clockSounds = []
        for i in range(1, 13):
            if i < 10:
                si = '0%d' % i
            else:
                si = '%d' % i
            self.clockSounds.append(base.loadSfx('phase_4/audio/sfx/clock%s.ogg' % si))

    def generate(self):
        DistributedObject.DistributedObject.generate(self)
        loader = self.cr.playGame.hood.loader
        partyGate = loader.geom.find('**/partyGate_grp')
        if partyGate.isEmpty():
            self.notify.warning('Could not find partyGate_grp in loader.geom')
            return
        self.clockFlat = partyGate.find('**/clock_flat')
        collSphere = CollisionSphere(0, 0, 0, 6.9)
        collSphere.setTangible(1)
        self.partyGateSphere = CollisionNode('PartyGateSphere')
        self.partyGateSphere.addSolid(collSphere)
        self.partyGateCollNodePath = partyGate.find('**/partyGate_stepsLocator').attachNewNode(self.partyGateSphere)
        self.__enableCollisions()
        self.toontownTimeGui = ServerTimeGui(partyGate, hourCallback=self.hourChange)
        self.toontownTimeGui.setPos(partyGate.find('**/clockText_locator').getPos() + Point3(0.0, 0.0, -0.2))
        self.toontownTimeGui.setHpr(partyGate.find('**/clockText_locator').getHpr())
        self.toontownTimeGui.setScale(12.0, 1.0, 26.0)
        self.toontownTimeGui.amLabel.setPos(-0.035, 0, -0.032)
        self.toontownTimeGui.amLabel.setScale(0.5)
        self.toontownTimeGui.updateTime()
        self.setupSignText()

    def setupSignText(self):
        loader = self.cr.playGame.hood.loader
        partyGate = loader.geom.find('**/partyGateSignGroup')
        if partyGate.isEmpty():
            self.notify.warning('Could not find partyGate_grp in loader.geom')
            return
        gateFont = ToontownGlobals.getMinnieFont()
        leftSign = partyGate.find('**/signTextL_locatorBack')
        signScale = 0.35
        wordWrap = 8
        leftText = DirectLabel.DirectLabel(parent=leftSign, pos=(0, 0.0, 0.0), relief=None, text=TTLocalizer.PartyGateLeftSign, text_align=TextNode.ACenter, text_font=gateFont, text_wordwrap=wordWrap, text_fg=Vec4(0.7, 0.3, 0.3, 1.0), scale=signScale)
        rightSign = partyGate.find('**/signTextR_locatorFront')
        rightText = DirectLabel.DirectLabel(parent=rightSign, pos=(0, 0.0, 0.0), relief=None, text=TTLocalizer.PartyGateRightSign, text_align=TextNode.ACenter, text_font=gateFont, text_wordwrap=wordWrap, text_fg=Vec4(0.7, 0.3, 0.3, 1.0), scale=signScale)
        return

    def announceGenerate(self):
        DistributedObject.DistributedObject.announceGenerate(self)
        if ToontownGlobals.dnaMap.has_key(self.zoneId):
            playground = ToontownGlobals.dnaMap[self.zoneId]
        else:
            playground = ToontownGlobals.dnaMap[2000]
        self.toontownTimeGui.hourLabel['text_fg'] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.colonLabel['text_fg'] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.minutesLabel['text_fg'] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.amLabel['text_fg'] = PartyGlobals.PlayGroundToPartyClockColors[playground]

    def disable(self):
        DistributedObject.DistributedObject.disable(self)
        self.__disableCollisions()
        self.toontownTimeGui.ival.finish()
        self.hourSoundInterval.finish()
        if self.publicPartyGui:
            self.publicPartyGui.stash()
            self.publicPartyGui.destroy()
            self.publicPartyGui = None
        return

    def delete(self):
        DistributedObject.DistributedObject.delete(self)
        self.toontownTimeGui.destroy()
        del self.toontownTimeGui
        self.hourSoundInterval.finish()
        del self.hourSoundInterval
        del self.clockFlat
        if self.publicPartyGui:
            self.publicPartyGui.destroy()
            del self.publicPartyGui
        self.partyGateCollNodePath.removeNode()
        del self.partyGateCollNodePath
        self.ignoreAll()

    def showMessage(self, message):
        self.messageDoneEvent = self.uniqueName('messageDoneEvent')
        self.acceptOnce(self.messageDoneEvent, self.__handleMessageDone)
        self.messageGui = TTDialog.TTGlobalDialog(doneEvent=self.messageDoneEvent, message=message, style=TTDialog.Acknowledge)

    def __handleMessageDone(self):
        self.ignore(self.messageDoneEvent)
        self.freeAvatar()
        self.messageGui.cleanup()
        self.messageGui = None
        return

    def __handleAskDone(self):
        DistributedPartyGate.notify.debug('__handleAskDone')
        self.ignore(self.publicPartyChooseGuiDoneEvent)
        doneStatus = self.publicPartyGui.doneStatus
        self.publicPartyGui.stash()
        if doneStatus is None:
            self.freeAvatar()
            return
        self.sendUpdate('partyChoiceRequest', [base.localAvatar.doId, doneStatus[0], doneStatus[1]])
        return

    def partyRequestDenied(self, reason):
        DistributedPartyGate.notify.debug('partyRequestDenied( reason=%s )' % PartyGlobals.PartyGateDenialReasons.getString(reason))
        if reason == PartyGlobals.PartyGateDenialReasons.Unavailable:
            self.showMessage(TTLocalizer.PartyGatePartyUnavailable)
        elif reason == PartyGlobals.PartyGateDenialReasons.Full:
            self.showMessage(TTLocalizer.PartyGatePartyFull)

    def setParty(self, partyInfoTuple, hostId):
        DistributedPartyGate.notify.debug('setParty')
        self.freeAvatar()
        if partyInfoTuple[0] == 0:
            DistributedPartyGate.notify.debug('Public Party closed before toon could get to it.')
            return
        shardId, zoneId, numberOfGuests, hostName, activityIds, lane = partyInfoTuple
        #For some reason, the party gate is attempting to teleport to the host of a party rather than a random spot in the party.
        #This temporarily fixes a hang on the loading screen
        if base.localAvatar.defaultShard != shardId:
            shardId = None
        base.cr.playGame.getPlace().requestLeave({'loader': 'safeZoneLoader',
         'where': 'party',
         'how': 'teleportIn',
         'hoodId': ToontownGlobals.PartyHood,
         'zoneId': zoneId,
         'shardId': None,
         'avId': hostId})
        return

    def freeAvatar(self):
        base.localAvatar.posCamera(0, 0)
        base.cr.playGame.getPlace().setState('walk')

    def hourChange(self, currentHour):
        currentHour %= 12
        if currentHour == 0:
            currentHour = 12
        self.hourSoundInterval = Parallel()
        seq1 = Sequence()
        for i in range(currentHour):
            seq1.append(SoundInterval(self.clockSounds[i]))
            seq1.append(Wait(0.2))

        timeForEachDeformation = seq1.getDuration() / currentHour
        seq2 = Sequence()
        for i in range(currentHour):
            seq2.append(self.clockFlat.scaleInterval(timeForEachDeformation / 2.0, Vec3(0.9, 1.0, 1.2), blendType='easeInOut'))
            seq2.append(self.clockFlat.scaleInterval(timeForEachDeformation / 2.0, Vec3(1.2, 1.0, 0.9), blendType='easeInOut'))

        seq2.append(self.clockFlat.scaleInterval(timeForEachDeformation / 2.0, Vec3(1.0, 1.0, 1.0), blendType='easeInOut'))
        self.hourSoundInterval.append(seq1)
        self.hourSoundInterval.append(seq2)
        self.hourSoundInterval.start()

    def handleEnterGateSphere(self, collEntry):
        self.notify.debug('Entering steps Sphere....')
        base.cr.playGame.getPlace().fsm.request('stopped')
        self.sendUpdate('getPartyList', [base.localAvatar.doId])

    def listAllPublicParties(self, publicPartyInfo):
        self.notify.debug('listAllPublicParties : publicPartyInfo = %s' % publicPartyInfo)
        self.acceptOnce(self.publicPartyChooseGuiDoneEvent, self.__handleAskDone)
        self.publicPartyGui.refresh(publicPartyInfo)
        self.publicPartyGui.unstash()

    def __enableCollisions(self):
        self.accept('enterPartyGateSphere', self.handleEnterGateSphere)
        self.partyGateSphere.setCollideMask(OTPGlobals.WallBitmask)

    def __disableCollisions(self):
        self.ignore('enterPartyGateSphere')
        self.partyGateSphere.setCollideMask(BitMask32(0))

    def handleSleep(self):
        if hasattr(self, 'messageGui') and self.messageGui:
            self.__handleMessageDone()
コード例 #34
0
ファイル: DistributedBoat.py プロジェクト: coginvasion/src
class DistributedBoat(DistributedObject):
    notify = directNotify.newCategory('DistributedBoat')

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.fsm = ClassicFSM('DistributedBoat', [State('off', self.enterOff, self.exitOff), State('eastToWest', self.enterEastToWest, self.exitEastToWest), State('westToEast', self.enterWestToEast, self.exitWestToEast)], 'off', 'off')
        self.boat = None
        self.eastPier = None
        self.eastPierPath = 'east_pier'
        self.westPier = None
        self.westPierPath = 'west_pier'
        self.pierUpP = 0.0
        self.pierDownP = -45.0
        self.fogHorn = 'phase_5/audio/sfx/SZ_DD_foghorn.mp3'
        self.shipBell = 'phase_6/audio/sfx/SZ_DD_shipbell.mp3'
        self.waterLap = 'phase_6/audio/sfx/SZ_DD_waterlap.mp3'
        self.dockCreak = 'phase_6/audio/sfx/SZ_DD_dockcreak.mp3'
        self.eastWest = 'phase_6/paths/dd-e-w.bam'
        self.westEast = 'phase_6/paths/dd-w-e.bam'
        self.boatPath = '*donalds_boat*'
        self.track = None
        self.state = None
        return

    def __handleOnBoat(self, entry):
        base.localAvatar.b_setParent(CIGlobals.SPDonaldsBoat)
        base.playSfx(self.soundWaterLap, looping=1)

    def __handleOffBoat(self, entry):
        base.localAvatar.b_setParent(CIGlobals.SPRender)
        self.soundWaterLap.stop()

    def __pollBoat(self, task):
        try:
            self.boat = self.cr.playGame.hood.loader.geom.find('**/' + self.boatPath)
        except:
            return task.cont

        self.generated()
        return task.done

    def generate(self):
        DistributedObject.generate(self)
        self.soundFogHorn = base.loadSfx(self.fogHorn)
        self.soundShipBell = base.loadSfx(self.shipBell)
        self.soundWaterLap = base.loadSfx(self.waterLap)
        self.soundDockCreak = base.loadSfx(self.dockCreak)
        self.boat = self.cr.playGame.hood.loader.geom.find('**/' + self.boatPath)
        self.generated()

    def generated(self):
        self.eastPier = self.cr.playGame.hood.loader.geom.find('**/' + self.eastPierPath)
        self.westPier = self.cr.playGame.hood.loader.geom.find('**/' + self.westPierPath)
        base.cr.parentMgr.registerParent(CIGlobals.SPDonaldsBoat, self.boat)
        self.accept('enterdonalds_boat_floor', self.__handleOnBoat)
        self.accept('exitdonalds_boat_floor', self.__handleOffBoat)
        self.d_requestCurrentStateAndTimestamp()
        self.fsm.enterInitialState()

    def disable(self):
        base.taskMgr.remove(self.uniqueName('__pollBoat'))
        base.cr.parentMgr.unregisterParent(CIGlobals.SPDonaldsBoat)
        self.ignore('enterdonalds_boat_floor')
        self.ignore('exitdonalds_boat_floor')
        self.fsm.requestFinalState()
        del self.fsm
        del self.soundFogHorn
        del self.soundShipBell
        del self.soundWaterLap
        del self.soundDockCreak
        self.fogHorn = None
        self.shipBell = None
        self.waterLap = None
        self.dockCreak = None
        self.boat = None
        self.track = None
        self.pierDownP = None
        self.pierUpP = None
        self.eastPier = None
        self.eastPierPath = None
        self.westPier = None
        self.westPierPath = None
        self.boatPath = None
        self.westEast = None
        self.eastWest = None
        DistributedObject.disable(self)
        return

    def currentStateAndTimestamp(self, state, timestamp):
        self.setState(state, timestamp)

    def d_requestCurrentStateAndTimestamp(self):
        self.sendUpdate('requestCurrentStateAndTimestamp', [])

    def setState(self, state, timestamp = None):
        if timestamp == None:
            ts = 0.0
        else:
            ts = globalClockDelta.localElapsedTime(timestamp)
        self.state = state
        if self.boat:
            self.fsm.request(state, [ts])
        return

    def enterEastToWest(self, ts = 0):
        moPath = Mopath.Mopath()
        moPath.loadFile(self.eastWest)
        moIval = MopathInterval(moPath, self.boat)
        self.track = Parallel(SoundInterval(self.soundShipBell, node=self.boat), SoundInterval(self.soundDockCreak, node=self.eastPier), moIval, LerpQuatInterval(self.eastPier, duration=5.0, quat=(90, self.pierDownP, 0), startHpr=(90, self.pierUpP, 0)), Sequence(Wait(15.0), Parallel(LerpQuatInterval(self.westPier, duration=5.0, quat=(-90, self.pierUpP, 0), startHpr=(-90, self.pierDownP, 0)), Sequence(Wait(2.0), SoundInterval(self.soundDockCreak, node=self.westPier))), SoundInterval(self.soundFogHorn, node=self.boat)))
        self.track.start(ts)

    def exitEastToWest(self):
        if self.track:
            self.track.finish()
            self.track = None
        return

    def enterWestToEast(self, ts = 0):
        moPath = Mopath.Mopath()
        moPath.loadFile(self.westEast)
        moIval = MopathInterval(moPath, self.boat)
        self.track = Parallel(SoundInterval(self.soundShipBell, node=self.boat), SoundInterval(self.soundDockCreak, node=self.westPier), moIval, LerpQuatInterval(self.westPier, duration=5.0, quat=(-90, self.pierDownP, 0), startHpr=(-90, self.pierUpP, 0)), Sequence(Wait(15.0), Parallel(LerpQuatInterval(self.eastPier, duration=5.0, quat=(90, self.pierUpP, 0), startHpr=(90, self.pierDownP, 0)), Sequence(Wait(2.0), SoundInterval(self.soundDockCreak, node=self.eastPier))), SoundInterval(self.soundFogHorn, node=self.boat)))
        self.track.start(ts)

    def exitWestToEast(self):
        if self.track:
            self.track.finish()
            self.track = None
        return

    def enterOff(self):
        pass

    def exitOff(self):
        pass
コード例 #35
0
class BambooCane(ToonUpGag):
    def __init__(self):
        ToonUpGag.__init__(self, CIGlobals.BambooCane,
                           'phase_5/models/props/cane.bam', 40, 45, 100,
                           GagGlobals.BAMBOO_CANE_SFX, 1)
        self.setImage('phase_3.5/maps/bamboo-cane.png')
        self.hatPath = 'phase_5/models/props/hat.bam'
        self.hat = None
        self.track = None
        self.scaleDuration = 0.5
        self.scaleUp = None
        self.scaleDown = None
        self.soundInterval = None
        self.timeout = 5.0

    def buildHat(self):
        self.cleanupHat()
        self.hat = loader.loadModel(self.hatPath)

    def cleanupHat(self):
        if self.hat:
            self.hat.removeNode()

    def buildScaleTracks(self):
        props = []
        props.append(self.hat)
        props.append(self.gag)
        self.scaleUp = self.getScaleTrack(props, self.scaleDuration,
                                          self.PNTNEARZERO, self.PNTNORMAL)
        self.scaleDown = self.getScaleTrack(props, self.scaleDuration,
                                            self.PNTNORMAL, self.PNTNEARZERO)

    def start(self):
        super(BambooCane, self).start()
        if not self.hat:
            self.buildHat()
        if not self.gag:
            self.build()
        self.setupHandJoints()
        if not self.scaleUp:
            self.buildScaleTracks()
        self.placeProp(self.handJoint, self.hat, Point3(0.23, 0.09, 0.69),
                       Point3(180, 0, 0))
        self.placeProp(self.lHandJoint, self.gag, Point3(-0.28, 0.0, 0.14),
                       Point3(0.0, 0.0, -150.0))
        self.soundInterval = self.getSoundTrack(0.2, self.gag, 6.4)
        propInterval = Sequence()
        propInterval.append(self.scaleUp)
        propInterval.append(
            Wait(base.localAvatar.getDuration('happy-dance') - 2))
        if self.avatar == base.localAvatar:
            propInterval.append(Func(self.setHealAmount))
            propInterval.append(Func(self.healNearbyAvatars, 25))
        propInterval.append(self.scaleDown)
        propInterval.append(Func(self.cleanupGag))
        propInterval.append(Func(self.reset))
        self.track = Parallel(propInterval,
                              ActorInterval(self.avatar, 'happy-dance'),
                              Func(self.soundInterval.start))
        self.track.start()

    def equip(self):
        # self.gag returns the cane object.
        super(BambooCane, self).equip()
        self.build()
        self.buildHat()
        self.buildScaleTracks()

    def unEquip(self):
        if self.track:
            self.soundInterval.finish()
            self.track.finish()
            self.track = None
        self.reset()
        if self.scaleDown:
            Sequence(self.scaleDown, Func(self.cleanupGag)).start()

    def cleanupGag(self):
        if self.gag:
            self.gag.removeNode()
        self.cleanupHat()
コード例 #36
0
class DistributedPlayerToon(DistributedToon, DistributedPlayerToonShared):
    notify = directNotify.newCategory('DistributedPlayerToon')

    def __init__(self, cr):
        try:
            self.DistributedPlayerToon_initialized
            return
        except:
            self.DistributedPlayerToon_initialized = 1
        DistributedToon.__init__(self, cr)
        DistributedPlayerToonShared.__init__(self)
        self.role = None
        self.ghost = 0
        self.puInventory = []
        self.equippedPU = -1
        self.backpack = Backpack(self)
        self.battleMeter = None
        self.headMeter = None
        self.firstTimeChangingHP = True

        # Quest-related variables.
        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.tunnelTrack = None
        self.trackExperience = dict(GagGlobals.DefaultTrackExperiences)

        self.takeDmgSfx = base.audio3d.loadSfx(
            'phase_5/audio/sfx/tt_s_ara_cfg_toonHit.ogg')
        base.audio3d.attachSoundToObject(self.takeDmgSfx, self)
        return

    def getHealth(self):
        return DistributedPlayerToonShared.getHealth(self)

    def getMaxHealth(self):
        return DistributedPlayerToonShared.getMaxHealth(self)

    def stopSmooth(self):
        DistributedToon.stopSmooth(self)
        localAvatarReachable = (hasattr(base, 'localAvatar')
                                and base.localAvatar)
        if localAvatarReachable and self.doId != base.localAvatar.doId:
            self.resetTorsoRotation()

    def handleHealthChange(self, hp, oldHp):
        if hp < oldHp and not self.firstTimeChangingHP:
            # We took damage, make oof sound.
            self.takeDmgSfx.play()

    def setHealth(self, health):
        self.handleHealthChange(health, self.getHealth())
        DistributedToon.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.firstTimeChangingHP = False

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

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

    def goThroughTunnel(self, toZone, inOrOut, requestStatus=None):
        # inOrOut: 0 = in; 1 = out

        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:
            # Going in a tunnel!
            pivotPoint = linkTunnel.inPivotPoint
            pivotPointNode = linkTunnel.tunnel.attachNewNode(
                'tunnelPivotPoint')
            pivotPointNode.setPos(pivotPoint)
            pivotPointNode.setHpr(linkTunnel.inPivotStartHpr)

            x, y, z = self.getPos(render)
            surfZ = PhysicsUtils.getNearestGroundSurfaceZ(
                self,
                self.getHeight() + self.getHeight() / 2.0)

            if not surfZ == -1:
                # Let's use the ray-tested surface z-point instead so we don't come out of the tunnel hovering.
                # This is just in case the user jumped into the tunnel, which in that case would mean that they are
                # airborne and we can't depend on their current Z value.
                z = surfZ

            if base.localAvatar.doId == self.doId:
                doneMethod = self._handleWentInTunnel
                extraArgs = [requestStatus]
                base.localAvatar.walkControls.setCollisionsActive(
                    0, andPlaceOnGround=1)
                self.resetHeadHpr(override=True)
                camera.wrtReparentTo(linkTunnel.tunnel)
                currCamPos = camera.getPos()
                currCamHpr = camera.getHpr()
                tunnelCamPos = linkTunnel.camPos
                tunnelCamHpr = linkTunnel.camHpr
                camera.setPos(tunnelCamPos)
                camera.setHpr(tunnelCamHpr)
                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'))

            self.wrtReparentTo(pivotPointNode)
            self.setPos(x, y, z)
            self.resetTorsoRotation()
            self.stopLookAround()

            if linkTunnel.__class__.__name__ == "SafeZoneLinkTunnel":
                self.setHpr(180, 0, 0)
            else:
                self.setHpr(0, 0, 0)

            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())),
                    Func(self.reparentTo, hidden)))
        elif inOrOut == 1:

            # Going out!
            pivotPoint = linkTunnel.outPivotPoint
            pivotPointNode = linkTunnel.tunnel.attachNewNode(
                'tunnelPivotPoint')
            pivotPointNode.setPos(pivotPoint)
            pivotPointNode.setHpr(linkTunnel.outPivotStartHpr)

            exitSeq = Sequence()

            if base.localAvatar.doId == self.doId:
                base.localAvatar.walkControls.setCollisionsActive(
                    0, andPlaceOnGround=1)
                base.localAvatar.detachCamera()
                camera.reparentTo(linkTunnel.tunnel)
                tunnelCamPos = linkTunnel.camPos
                tunnelCamHpr = linkTunnel.camHpr
                camera.setPos(tunnelCamPos)
                camera.setHpr(tunnelCamHpr)
                doneMethod = self._handleCameOutTunnel
                extraArgs = []

                exitSeq.append(Func(base.transitions.irisIn))
            else:
                self.stopSmooth()

            self.reparentTo(pivotPointNode)
            self.setHpr(linkTunnel.toonOutHpr)
            self.setPos(linkTunnel.toonOutPos)

            seq = 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,
                ))
            if base.localAvatar.doId != self.doId:
                seq.append(Func(self.startSmooth))
            seq.append(Func(self.wrtReparentTo, render))
            exitSeq.append(seq)
            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()

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

    def getDefaultShard(self):
        return self.defaultShard

    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 getQuestHistory(self):
        return self.questHistory

    def setQuests(self, dataStr):
        self.quests = dataStr

    def getQuests(self):
        return self.quests

    def maybeMakeHeadMeter(self):
        if base.localAvatar.doId != self.doId:
            if self.getHealth() < 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

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

    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

    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
        self.handleGhost(value)

    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 getBackpack(self):
        return self.backpack

    def setEquippedAttack(self, attackID):
        try:
            self.backpack.setCurrentGag(attackID)
        except:
            # If we couldn't do this, it means that the avatar was most likely disabled.
            pass
        DistributedToon.setEquippedAttack(self, attackID)

    def getCurrentGag(self):
        return self.getEquippedAttack()

    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, netString):
        if len(self.attackIds) != 0 or len(self.attacks) != 0:
            self.cleanupAttacks()
            self.clearAttackIds()
        return self.backpack.updateSuppliesFromNetString(netString)

    def getBackpackAmmo(self):
        if self.backpack:
            return self.backpack.netString
        return GagGlobals.getDefaultBackpack().toNetString()

    def setTrackExperience(self, netString):
        self.trackExperience = GagGlobals.getTrackExperienceFromNetString(
            netString)
        if GagGlobals.processTrackData(
                self.trackExperience,
                self.backpack) and self == base.localAvatar:
            if base.localAvatar.invGui:
                base.localAvatar.reloadInvGui()

    def getTrackExperience(self):
        return GagGlobals.trackExperienceToNetString(self.trackExperience)

    def updateAttackAmmo(self, gagId, ammo, maxAmmo, ammo2, maxAmmo2, clip,
                         maxClip):
        if self.useBackpack():
            self.backpack.setSupply(gagId, ammo)
        else:
            DistributedToon.updateAttackAmmo(self, gagId, ammo, maxAmmo, ammo2,
                                             maxAmmo2, clip, maxClip)

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

    def getMoney(self):
        return self.money

    def setAccessLevel(self, value):
        prevLevel = self.getAccessLevel()
        self.role = AdminCommands.Roles.get(value, None)

        if prevLevel != AdminCommands.NoAccess:
            # Let's remove any tokens that already are showing up.
            DistributedToon.removeAdminToken(self)

        if self.role:
            # Let's put a new token above our head.
            DistributedToon.setAdminToken(self, self.role.token)

    def getAccessLevel(self):
        return AdminCommands.NoAccess if not self.role else self.role.accessLevel

    def disable(self):
        base.audio3d.detachSound(self.takeDmgSfx)
        self.takeDmgSfx = None
        if self.tunnelTrack:
            self.ignore(self.tunnelTrack.getDoneEvent())
            self.tunnelTrack.finish()
            self.tunnelTrack = None
        self.role = None
        self.ghost = None
        self.puInventory = None
        self.equippedPU = None
        if self.backpack:
            self.backpack.cleanup()
            self.backpack = None
        self.firstTimeChangingHP = None
        self.quests = None
        self.tier = None
        self.questHistory = None
        self.busy = None
        self.friends = None
        self.tutDone = None
        self.hoodsDiscovered = None
        self.teleportAccess = None
        self.lastHood = None
        self.defaultShard = None
        self.trackExperience = None
        self.__removeHeadMeter()
        self.destroyBattleMeter()
        DistributedToon.disable(self)

    def delete(self):
        try:
            self.DistributedPlayerToon_deleted
        except:
            self.DistributedPlayerToon_deleted = 1
            DistributedPlayerToonShared.delete(self)
            del self.takeDmgSfx
            del self.tunnelTrack
            del self.role
            del self.ghost
            del self.puInventory
            del self.equippedPU
            del self.backpack
            del self.firstTimeChangingHP
            del self.quests
            del self.tier
            del self.questHistory
            del self.busy
            del self.friends
            del self.tutDone
            del self.hoodsDiscovered
            del self.teleportAccess
            del self.lastHood
            del self.defaultShard
            del self.trackExperience
            del self.battleMeter
            del self.headMeter
            DistributedToon.delete(self)
        return
コード例 #37
0
class DistributedNPCToon(DistributedToon):
    notify = directNotify.newCategory('DistributedNPCToon')

    def __init__(self, cr):
        DistributedToon.__init__(self, cr)
        self.collisionNodePath = None
        self.cameraTrack = None
        self.originIndex = None
        self.npcId = None
        self.currentChatIndex = 0
        self.chatArray = None
        return

    def setLoadout(self, foo):
        pass

    def lookAtAvatar(self, avId):
        av = self.cr.doId2do.get(avId)
        if av:
            self.headsUp(av)

    def setNpcId(self, id):
        self.npcId = id

    def getNpcId(self):
        return self.npcId

    def setOriginIndex(self, index):
        self.originIndex = index

    def getOriginIndex(self):
        return self.originIndex

    def __setupCollisions(self):
        sphere = CollisionSphere(0, 0, 0, 4)
        sphere.setTangible(0)
        collisionNode = CollisionNode(self.uniqueName('NPCToonSphere'))
        collisionNode.addSolid(sphere)
        collisionNode.setCollideMask(CIGlobals.WallBitmask)
        self.collisionNodePath = self.attachNewNode(collisionNode)
        self.collisionNodePath.setY(1.5)

    def __removeCollisions(self):
        if self.collisionNodePath:
            self.collisionNodePath.removeNode()
            self.collisionNodePath = None
        return

    def handleEnterCollision(self, entry):
        self.cr.playGame.getPlace().fsm.request('stop')
        base.localAvatar.stopSmartCamera()
        self.sendUpdate('requestEnter', [])

    def doCameraNPCInteraction(self):
        currCamPos = camera.getPos()
        currCamHpr = camera.getHpr()
        camera.setX(camera.getX() + 5)
        camera.setY(camera.getY() + 5)
        camera.headsUp(self)
        newCamPos = camera.getPos()
        newCamHpr = camera.getHpr()
        camera.setPos(currCamPos)
        camera.setHpr(currCamHpr)
        self.cameraTrack = Parallel(
            LerpPosInterval(camera,
                            duration=1.0,
                            pos=newCamPos,
                            startPos=currCamPos,
                            blendType='easeOut'),
            LerpQuatInterval(camera,
                             duration=1.0,
                             quat=newCamHpr,
                             startHpr=currCamHpr,
                             blendType='easeOut'))
        self.cameraTrack.start()

    def stopCameraTrack(self):
        if self.cameraTrack:
            self.cameraTrack.finish()
            self.cameraTrack = None
        return

    def oneChatThenExit(self):
        self.acceptOnce('mouse1-up', self.d_requestExit)

    def enterAccepted(self):
        self.doCameraNPCInteraction()
        questData = base.localAvatar.questManager.getQuestAndIdWhereCurrentObjectiveIsToVisit(
            self.npcId)
        if questData:
            quest = questData[1]
            self.currentQuestObjective = quest.currentObjectiveIndex
            self.currentQuestId = questData[0]
            self.currentChatIndex = 0
            if CIGlobals.NPCToonDict[self.npcId][3] == CIGlobals.NPC_HQ:
                if not quest.isComplete():
                    self.doNPCChat(array=Quests.QuestHQOfficerDialogue)
            if CIGlobals.NPCToonDict[self.npcId][3] == CIGlobals.NPC_REGULAR:
                self.doNPCChat(array=Quests.QuestNPCDialogue)

    def doNPCChat(self, array=Quests.QuestNPCDialogue, chat=None):
        if array and not chat:
            self.chatArray = array
            self.b_setChat(array[self.currentQuestId][
                self.currentQuestObjective][self.currentChatIndex])
            self.currentChatIndex += 1
            Sequence(Wait(0.1),
                     Func(self.acceptOnce, 'mouse1-up',
                          self.doNextNPCChat)).start()
        else:
            if chat and not array:
                self.b_setChat(chat)
                Sequence(
                    Wait(0.1),
                    Func(self.acceptOnce, 'mouse1-up',
                         self.d_requestExit)).start()

    def d_requestExit(self):
        self.sendUpdate('requestExit', [])

    def doNextNPCChat(self):
        if self.currentChatIndex >= len(self.chatArray[self.currentQuestId][
                self.currentQuestObjective]):
            self.chatArray = None
            self.d_requestExit()
        else:
            self.doNPCChat(self.chatArray)
        return

    def rejectEnter(self):
        self.exitAccepted()

    def exitAccepted(self):
        self.stopCameraTrack()
        self.cr.playGame.getPlace().fsm.request('walk')
        self.acceptCollisions()

    def acceptCollisions(self):
        self.acceptOnce('enter' + self.uniqueName('NPCToonSphere'),
                        self.handleEnterCollision)

    def ignoreCollisions(self):
        self.ignore('enter' + self.uniqueName('NPCToonSphere'))

    def __npcOriginPoll(self, task):
        if task.time > 4.0:
            self.notify.warning(
                'Giving up waiting for npc origin after %d seconds. Will parent to render.'
                % task.time)
            self.reparentTo(render)
            return task.done
        npcOrigin = render.find('**/npc_origin_' + str(self.originIndex))
        if not npcOrigin.isEmpty():
            self.reparentTo(npcOrigin)
            return task.done
        return task.cont

    def startNPCOriginPoll(self):
        base.taskMgr.add(self.__npcOriginPoll,
                         self.uniqueName('NPCOriginPoll'))

    def stopNPCOriginPoll(self):
        base.taskMgr.remove(self.uniqueName('NPCOriginPoll'))

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

    def announceGenerate(self):
        DistributedToon.announceGenerate(self)
        self.startLookAround()
        self.__setupCollisions()
        npcOrigin = render.find('**/npc_origin_' + str(self.originIndex))
        if not npcOrigin.isEmpty():
            self.reparentTo(npcOrigin)
        else:
            self.startNPCOriginPoll()
        self.acceptCollisions()

    def disable(self):
        self.ignore('mouse1-up')
        self.stopLookAround()
        self.stopNPCOriginPoll()
        self.chatArray = None
        self.originIndex = None
        self.npcId = None
        self.stopCameraTrack()
        self.ignoreCollisions()
        self.__removeCollisions()
        DistributedToon.disable(self)
        return
コード例 #38
0
ファイル: CharSelection.py プロジェクト: NoraTheGamer/cio-src
class CharSelection(DirectObject):
    notify = directNotify.newCategory('CharSelection')

    NO_TOON = "Empty Slot"
    PLAY = "Play"
    CREATE = "Create"
    TITLE = "Pick  A  Toon  To  Play"

    def __init__(self, avChooser):
        self.avChooser = avChooser
        self.choice = None
        self.charList = None
        self.charNameLabel = None
        self.charButtons = []
        self.playOrCreateButton = None
        self.deleteButton = None
        self.quitButton = None
        self.title = None
        self.stageToon = None
        self.stageToonRoot = None
        self.deleteConf = None
        self.frame = None
        self.stageFSM = ClassicFSM.ClassicFSM('StageFSM', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('loadSZ', self.enterLoadSZ, self.exitLoadSZ),
            State.State('onStage', self.enterOnStage, self.exitOnStage)
        ], 'off', 'off')
        self.stageFSM.enterInitialState()
        self.selectionFSM = ClassicFSM.ClassicFSM('CharSelection', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('character', self.enterCharSelected,
                        self.exitCharSelected),
            State.State('empty', self.enterEmptySelected,
                        self.exitEmptySelected)
        ], 'off', 'off')
        self.selectionFSM.enterInitialState()

        self.szGeom = None
        self.olc = None
        self.asyncSZLoadStatus = False
        self.isNewToon = False
        self.newToonSlot = None
        self.camIval = None
        self.stAnimSeq = None
        self.newToonAnnounceSfx = base.loadSfx(
            "phase_4/audio/sfx/King_Crab.ogg")
        self.newToonDrumrollSfx = base.loadSfx(
            "phase_5/audio/sfx/SZ_MM_drumroll.ogg")
        self.newToonRevealSfx = base.loadSfx(
            "phase_5/audio/sfx/SZ_MM_fanfare.ogg")

        self.dnaStore = DNAStorage()
        loader.loadDNAFile(self.dnaStore,
                           'phase_4/dna/pickatoon/storage_pickatoon.pdna')

    def __setupStageToon(self):
        self.stageToonRoot = render.attachNewNode('stageToonRoot')
        self.stageToon = Toon(base.cr)
        self.stageToon.setPosHpr(0, 0, 0, 0, 0, 0)
        self.stageToon.reparentTo(self.stageToonRoot)

    def cleanupStageToon(self):
        if self.stageToon != None:
            self.stageToon.disable()
            self.stageToon.delete()
            self.stageToon = None
        if self.stageToonRoot != None:
            self.stageToonRoot.removeNode()
            self.stageToonRoot = None

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def __async_loadSZTask(self, task=None):
        dnas = HOOD_ID_2_DNA[self.choice.lastHood]
        for i in xrange(len(dnas)):
            dnaFile = dnas[i]
            if i == len(dnas) - 1:
                node = loader.loadDNAFile(self.dnaStore, dnaFile)
                if node.getNumParents() == 1:
                    self.szGeom = NodePath(node.getParent(0))
                    self.szGeom.reparentTo(render)
                else:
                    self.szGeom = render.attachNewNode(node)

                # The 2D trees should not be flattened, to do that, we're going to traverse
                # the scene graph for all trees, use #wrtReparentTo(render) on them, flatten
                # the scene with #flattenStrong(), and finally #wrtReparentTo(self.szGeom)
                # the trees back to the main scene node so they get cleaned up properly.
                trees = self.szGeom.findAllMatches('**/*tree*')
                #self.szGeom.find("**/shadow").removeNode()

                #from panda3d.core import CullBinAttrib
                #self.szGeom.find("**/shadow_crack").setAttrib(CullBinAttrib.make("foreground", 10), 10)
                #shs = self.szGeom.findAllMatches("**/*shadow*")
                #for sh in shs:
                #    sh.removeNode()

                # self.szGeom.ls()

                for tree in trees:
                    tree.wrtReparentTo(render)

                self.szGeom.flattenStrong()

                for tree in trees:
                    tree.wrtReparentTo(self.szGeom)

            else:
                loader.loadDNAFile(self.dnaStore, dnaFile)

        self.olc = ZoneUtil.getOutdoorLightingConfig(self.choice.lastHood)
        self.olc.setup()
        self.olc.apply()

        CIGlobals.preRenderScene(render)

        self.asyncSZLoadStatus = True

        #base.accept('l', render.ls)

        if task:
            return task.done

    def enterLoadSZ(self):
        self.loadingDlg = Dialog.GlobalDialog("Loading...")
        self.loadingDlg.show()

        base.cr.renderFrame()
        base.cr.renderFrame()

        self.notify.info("Polling for SZ to load")
        self.asyncSZLoadStatus = False
        self.__async_loadSZTask()

        base.doNextFrame(self.stageFSM.request, ['onStage'])

    def exitLoadSZ(self):
        if hasattr(self, 'loadingDlg'):
            self.loadingDlg.cleanup()
            del self.loadingDlg

    def __changeCamFOV(self, val):
        base.camLens.setMinFov(val / (4. / 3.))

    def enterOnStage(self):
        dna = self.choice.dna
        name = self.choice.name
        self.stageToon.setName(name)
        self.stageToon.setDNAStrand(dna)
        self.stageToon.nametag.setNametagColor(
            NametagGlobals.NametagColors[NametagGlobals.CCLocal])
        self.stageToon.nametag.setActive(0)
        self.stageToon.nametag.nametag3d.request('Rollover')
        self.stageToon.nametag.unmanage(base.marginManager)
        self.stageToon.nametag.updateAll()
        self.stageToon.animFSM.request('neutral')
        self.stageToon.setPosHpr(0, 0, 0, 10, 0, 0)
        self.stageToon.show()

        dat = HOOD_STAGE_DATA[self.choice.lastHood]

        self.stageToonRoot.setPos(dat[2])
        self.stageToonRoot.setHpr(dat[3])

        camera.reparentTo(self.stageToonRoot)

        camera.setPos(dat[0])
        camera.lookAt(self.stageToonRoot, 0, 0, 3)
        startHpr = camera.getHpr()
        camera.setPos(dat[1])
        camera.lookAt(self.stageToonRoot, 0, 0, 3)
        endHpr = camera.getHpr()

        self.camIval = Parallel(
            LerpPosInterval(camera,
                            5.0,
                            dat[1] - (1.6, 0, 0),
                            dat[0] - (1.6, 0, 0),
                            blendType='easeInOut'),
            LerpQuatInterval(camera,
                             5.0,
                             hpr=endHpr,
                             startHpr=startHpr,
                             blendType='easeInOut'),
            LerpFunc(self.__changeCamFOV,
                     duration=5.0,
                     fromData=80.0,
                     toData=CIGlobals.DefaultCameraFov,
                     blendType='easeInOut'))
        if self.isNewToon:
            self.camIval.append(
                Sequence(
                    Func(self.stageToon.hide), Func(base.stopMusic),
                    SoundInterval(self.newToonAnnounceSfx,
                                  startTime=1.674,
                                  duration=4.047),
                    SoundInterval(self.newToonDrumrollSfx),
                    Func(self.stageToon.pose, 'tele',
                         self.stageToon.getNumFrames('tele')),
                    Func(self.newToonAppear), Func(self.stageToon.show),
                    SoundInterval(self.newToonRevealSfx),
                    Func(base.cr.playTheme)))
        else:
            self.camIval.append(
                Sequence(Func(self.showActionButtons),
                         Func(self.enableAllCharButtons), Wait(5.0),
                         Func(self.beginRandomAnims)))

        self.camIval.start()

    def hideActionButtons(self):
        self.playOrCreateButton.hide()
        self.deleteButton.hide()

    def showActionButtons(self):
        self.playOrCreateButton.show()
        self.deleteButton.show()

    def newToonAppear(self):
        self.stopSTAnimSeq()

        self.stAnimSeq = Sequence(
            Func(self.stageToon.animFSM.request, 'teleportIn'), Wait(2.0),
            ActorInterval(self.stageToon, 'wave'),
            Func(self.stageToon.loop, 'neutral'), Func(self.beginRandomAnims),
            Func(self.enableAllCharButtons), Func(self.showActionButtons))
        self.stAnimSeq.start()

    def stopSTAnimSeq(self):
        if self.stAnimSeq:
            self.stAnimSeq.finish()
            self.stAnimSeq = None

    def unloadSZGeom(self):
        if self.szGeom:
            self.szGeom.removeNode()
            self.szGeom = None
        if self.olc:
            self.olc.cleanup()
            self.olc = None

    def beginRandomAnims(self):
        self.stageToon.startLookAround()
        taskMgr.doMethodLater(random.uniform(*ST_ANIM_IVAL),
                              self.__doRandomSTAnim, "doRandomSTAnim")

    def __doRandomSTAnim(self, task):
        anim = random.choice(ST_RANDOM_ANIMS)

        self.stopSTAnimSeq()

        self.stageToon.stopLookAround()

        head = self.stageToon.getPart('head')

        if anim == 'read':
            self.stAnimSeq = Sequence(
                Func(self.stageToon.lerpLookAt, head, (0, -15, 0)),
                Func(self.stageToon.animFSM.request, 'openBook'), Wait(0.5),
                Func(self.stageToon.animFSM.request, 'readBook'), Wait(2.0),
                Func(self.stageToon.lerpLookAt, head, (0, 0, 0)),
                Func(self.stageToon.animFSM.request, 'closeBook'), Wait(1.75),
                Func(self.stageToon.loop, 'neutral'),
                Func(self.stageToon.startLookAround))
        else:
            self.stageToon.lerpLookAt(head, (0, 0, 0))
            self.stAnimSeq = Sequence(ActorInterval(self.stageToon, anim),
                                      Func(self.stageToon.loop, 'neutral'),
                                      Func(self.stageToon.startLookAround))

        self.stAnimSeq.start()

        task.delayTime = random.uniform(*ST_ANIM_IVAL)
        return task.again

    def endRandomAnims(self):
        taskMgr.remove("doRandomSTAnim")
        self.stopSTAnimSeq()

    def exitOnStage(self):
        self.isNewToon = False
        if self.camIval:
            self.camIval.finish()
            self.camIval = None
        self.endRandomAnims()
        self.stopSTAnimSeq()
        camera.reparentTo(render)
        camera.setPosHpr(0, 0, 0, 0, 0, 0)
        #base.transitions.fadeScreen(1.0)
        self.unloadSZGeom()
        self.stageToon.hide()

    def enterCharSelected(self):
        self.playOrCreateButton['text'] = self.PLAY
        self.playOrCreateButton['extraArgs'] = ['play']
        #aspect2d.hide()

    def exitCharSelected(self):
        self.playOrCreateButton.hide()
        self.deleteButton.hide()

    def enterEmptySelected(self):
        self.charNameLabel.setText(self.NO_TOON)
        self.playOrCreateButton['text'] = self.CREATE
        self.playOrCreateButton['extraArgs'] = ['create']
        self.playOrCreateButton.show()

    def exitEmptySelected(self):
        self.playOrCreateButton.hide()

    def __action(self, action):
        for btn in self.charButtons:
            if btn['state'] == DGG.DISABLED:
                self.slot = btn.getPythonTag('slot')
                break
        func = None
        arg = None
        doFade = True
        if action == 'delete':
            func = self.deleteToon
            arg = self.choice.avId
            doFade = False
        elif action == 'play':
            func = self.playGame
            arg = self.choice.slot
        elif action == 'create':
            func = self.enterMAT
        elif action == 'quit':
            func = sys.exit
            doFade = False
        if doFade:
            base.transitions.fadeOut(0.3)
            if arg != None:
                Sequence(Wait(0.31), Func(func, arg)).start()
            else:
                Sequence(Wait(0.31), Func(func)).start()
        else:
            if arg != None:
                func(arg)
            else:
                func()

    def playGame(self, slot):
        messenger.send("avChooseDone",
                       [self.avChooser.getAvChoiceBySlot(slot)])

    def enterMAT(self):
        messenger.send("enterMakeAToon", [self.slot])

    def deleteToon(self, avId):
        # Show a confirmation message
        self.deleteConf = Dialog.GlobalDialog(
            message='This will delete {0} forever.\n\nAre you sure?'.format(
                self.avChooser.getNameFromAvId(avId)),
            style=Dialog.YesNo,
            doneEvent='deleteConfResponse',
            extraArgs=[avId])
        self.acceptOnce('deleteConfResponse', self.__handleDeleteConfResponse)
        self.deleteConf.show()

    def __handleDeleteConfResponse(self, avId):
        doneStatus = self.deleteConf.getValue()
        if doneStatus:
            # Alright, they pressed yes. No complaining to us.
            self.avChooser.avChooseFSM.request("waitForToonDelResponse",
                                               [avId])
        else:
            self.deleteConf.cleanup()
            self.deleteConf = None

    def __handleCharButton(self, slot):
        for btn in self.charButtons:
            if btn.getPythonTag('slot') == slot:
                btn['state'] = DGG.DISABLED
            else:
                btn['state'] = DGG.NORMAL
        if self.avChooser.hasToonInSlot(slot):
            self.choice = self.avChooser.getAvChoiceBySlot(slot)
            self.selectionFSM.request('character')
            self.stageFSM.request('loadSZ')
        else:
            self.selectionFSM.request('empty')
            self.stageFSM.request('off')

    def disableAllCharButtons(self):
        for btn in self.charButtons:
            btn['state'] = DGG.DISABLED

    def enableAllCharButtons(self):
        for btn in self.charButtons:
            if not self.choice or btn.getPythonTag('slot') != self.choice.slot:
                btn['state'] = DGG.NORMAL

    def load(self, newToonSlot=None):
        self.isNewToon = newToonSlot is not None
        self.newToonSlot = newToonSlot

        base.transitions.noTransitions()

        base.cr.renderFrame()
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4. / 3.))

        self.__setupStageToon()

        self.title = DirectLabel(text=self.TITLE,
                                 text_font=CIGlobals.getMickeyFont(),
                                 text_fg=(1, 0.9, 0.1, 1),
                                 relief=None,
                                 text_scale=0.13,
                                 pos=(0, 0, 0.82))
        self.charNameLabel = OnscreenText(text="",
                                          font=CIGlobals.getMickeyFont(),
                                          pos=(-0.25, 0.5, 0),
                                          fg=(1, 0.9, 0.1, 1.0))
        self.charNameLabel.hide()
        self.frame = DirectFrame()
        self.frame['image'] = DGG.getDefaultDialogGeom()
        self.frame['image_color'] = CIGlobals.DialogColor
        self.frame['image_scale'] = (-0.9, -0.9, 0.8)
        self.frame['image_pos'] = (0.82, 0, -0.125)
        self.playOrCreateButton = DirectButton(
            text="",
            pos=(0.8125, 0, -0.35),
            command=self.__action,
            geom=CIGlobals.getDefaultBtnGeom(),
            text_scale=0.06,
            relief=None,
            text_pos=(0, -0.01))
        self.playOrCreateButton.hide()
        self.deleteButton = DirectButton(text="Delete",
                                         pos=(0.8125, 0, -0.45),
                                         command=self.__action,
                                         extraArgs=['delete'],
                                         geom=CIGlobals.getDefaultBtnGeom(),
                                         text_scale=0.06,
                                         relief=None,
                                         text_pos=(0, -0.01))
        self.deleteButton.hide()
        self.quitButton = DirectButton(text="Quit",
                                       pos=(-1.10, 0, -0.925),
                                       command=self.__action,
                                       extraArgs=['quit'],
                                       text_scale=0.06,
                                       geom=CIGlobals.getDefaultBtnGeom(),
                                       relief=None,
                                       text_pos=(0, -0.01))

        for slot in range(6):
            if self.avChooser.hasToonInSlot(slot):
                choice = self.avChooser.getAvChoiceBySlot(slot)
                text = choice.name
            else:
                text = self.NO_TOON
            btn = CIGlobals.makeDefaultScrolledListBtn(
                text=text,
                text_scale=0.06,
                command=self.__handleCharButton,
                extraArgs=[slot])
            btn.setPythonTag('slot', slot)
            self.charButtons.append(btn)
            btn['state'] = DGG.NORMAL

        self.charList = CIGlobals.makeDefaultScrolledList(
            pos=(0.75, 0, -0.225),
            listZorigin=-0.43,
            listFrameSizeZ=0.51,
            arrowButtonScale=0.0,
            items=self.charButtons,
            parent=self.frame)

        if self.isNewToon:
            self.__handleCharButton(self.newToonSlot)
            self.disableAllCharButtons()

    def unload(self):
        self.selectionFSM.requestFinalState()
        self.stageFSM.requestFinalState()
        self.cleanupStageToon()
        self.choice = None
        if self.frame:
            self.frame.destroy()
            self.frame = None
        if self.charButtons:
            for btn in self.charButtons:
                btn.destroy()
            self.charButtons = None
        if self.deleteConf:
            self.deleteConf.cleanup()
            self.deleteConf = None
        if self.charList:
            self.charList.destroy()
            self.charList = None
        if self.charNameLabel:
            self.charNameLabel.destroy()
            self.charNameLabel = None
        if self.playOrCreateButton:
            self.playOrCreateButton.destroy()
            self.playOrCreateButton = None
        if self.deleteButton:
            self.deleteButton.destroy()
            self.deleteButton = None
        if self.quitButton:
            self.quitButton.destroy()
            self.quitButton = None
        if self.title:
            self.title.destroy()
            self.title = None
        base.camera.setPos(0, 0, 0)
        base.camera.setHpr(0, 0, 0)
        base.transitions.noTransitions()
        del self.selectionFSM
コード例 #39
0
class DistributedPartyGate(DistributedObject.DistributedObject):

    notify = DirectNotifyGlobal.directNotify.newCategory(
        "DistributedPartyGate")

    def __init__(self, cr):
        """__init__(cr)
        """
        DistributedObject.DistributedObject.__init__(self, cr)
        self.publicPartyChooseGuiDoneEvent = "doneChoosingPublicParty"
        self.publicPartyGui = PublicPartyGui(
            self.publicPartyChooseGuiDoneEvent)
        self.publicPartyGui.stash()
        self.loadClockSounds()
        self.hourSoundInterval = Sequence()
        self.accept('stoppedAsleep', self.handleSleep)

    def loadClockSounds(self):
        self.clockSounds = []
        for i in range(1, 13):
            if i < 10:
                si = "0%d" % i
            else:
                si = "%d" % i
            self.clockSounds.append(
                base.loader.loadSfx("phase_4/audio/sfx/clock%s.mp3" % si))

    def generate(self):
        """generate(self)
        This method is called when the DistributedObject is reintroduced
        to the world, either for the first time or from the cache.
        """
        DistributedObject.DistributedObject.generate(self)

        loader = self.cr.playGame.hood.loader
        partyGate = loader.geom.find('**/partyGate_grp')
        if partyGate.isEmpty():
            self.notify.warning('Could not find partyGate_grp in loader.geom')
            return
        self.clockFlat = partyGate.find("**/clock_flat")
        collSphere = CollisionSphere(0, 0, 0, 6.9)
        collSphere.setTangible(1)
        self.partyGateSphere = CollisionNode("PartyGateSphere")
        self.partyGateSphere.addSolid(collSphere)
        self.partyGateCollNodePath = partyGate.find(
            "**/partyGate_stepsLocator").attachNewNode(self.partyGateSphere)
        self.__enableCollisions()
        #        self.tunnelOrigin = NodePath("PartyGateTunnelOrigin")
        #        self.tunnelOrigin.reparentTo(partyGate)
        #        self.tunnelOrigin.setPos(partyGate.find("**/clockText_locator").getPos() + Point3(0.0, 0.0, -12.0))

        self.toontownTimeGui = ServerTimeGui(partyGate,
                                             hourCallback=self.hourChange)
        self.toontownTimeGui.setPos(
            partyGate.find("**/clockText_locator").getPos() +
            Point3(0.0, 0.0, -0.2))
        self.toontownTimeGui.setHpr(
            partyGate.find("**/clockText_locator").getHpr())
        self.toontownTimeGui.setScale(12.0, 1.0, 26.0)
        self.toontownTimeGui.amLabel.setPos(-0.035, 0, -0.032)
        self.toontownTimeGui.amLabel.setScale(0.5)
        self.toontownTimeGui.updateTime()
        self.setupSignText()

    def setupSignText(self):
        """Attach text to the left and right signs"""
        loader = self.cr.playGame.hood.loader
        partyGate = loader.geom.find('**/partyGateSignGroup')
        if partyGate.isEmpty():
            self.notify.warning('Could not find partyGate_grp in loader.geom')
            return
        gateFont = ToontownGlobals.getMinnieFont()
        leftSign = partyGate.find("**/signTextL_locatorBack")
        signScale = 0.35
        wordWrap = 8
        leftText = DirectLabel.DirectLabel(
            parent=leftSign,
            pos=(0, 0.0, 0.0),
            relief=None,
            text=TTLocalizer.PartyGateLeftSign,
            text_align=TextNode.ACenter,
            text_font=gateFont,
            text_wordwrap=wordWrap,
            text_fg=Vec4(0.7, 0.3, 0.3, 1.0),
            scale=signScale,
        )
        rightSign = partyGate.find("**/signTextR_locatorFront")
        rightText = DirectLabel.DirectLabel(
            parent=rightSign,
            pos=(0, 0.0, 0.0),
            relief=None,
            text=TTLocalizer.PartyGateRightSign,
            text_align=TextNode.ACenter,
            text_font=gateFont,
            text_wordwrap=wordWrap,
            text_fg=Vec4(0.7, 0.3, 0.3, 1.0),
            scale=signScale,
        )

    def announceGenerate(self):
        DistributedObject.DistributedObject.announceGenerate(self)
        if self.zoneId in ToontownGlobals.dnaMap:
            playground = ToontownGlobals.dnaMap[self.zoneId]
        else:
            playground = ToontownGlobals.dnaMap[2000]
        self.toontownTimeGui.hourLabel[
            "text_fg"] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.colonLabel[
            "text_fg"] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.minutesLabel[
            "text_fg"] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.amLabel[
            "text_fg"] = PartyGlobals.PlayGroundToPartyClockColors[playground]

    def disable(self):
        DistributedObject.DistributedObject.disable(self)
        self.__disableCollisions()
        self.toontownTimeGui.ival.finish()
        self.hourSoundInterval.finish()
        if self.publicPartyGui:
            self.publicPartyGui.stash()
            self.publicPartyGui.destroy()
            self.publicPartyGui = None

    def delete(self):
        DistributedObject.DistributedObject.delete(self)
        self.toontownTimeGui.destroy()
        del self.toontownTimeGui
        self.hourSoundInterval.finish()
        del self.hourSoundInterval
        del self.clockFlat
        if self.publicPartyGui:
            self.publicPartyGui.destroy()
            del self.publicPartyGui
        self.partyGateCollNodePath.removeNode()
        del self.partyGateCollNodePath
        self.ignoreAll()

    def showMessage(self, message):
        self.messageDoneEvent = self.uniqueName("messageDoneEvent")
        self.acceptOnce(self.messageDoneEvent, self.__handleMessageDone)
        self.messageGui = TTDialog.TTGlobalDialog(
            doneEvent=self.messageDoneEvent,
            message=message,
            style=TTDialog.Acknowledge,
        )

    def __handleMessageDone(self):
        self.ignore(self.messageDoneEvent)
        self.freeAvatar()
        self.messageGui.cleanup()
        self.messageGui = None

    def __handleAskDone(self):
        DistributedPartyGate.notify.debug("__handleAskDone")
        self.ignore(self.publicPartyChooseGuiDoneEvent)
        doneStatus = self.publicPartyGui.doneStatus
        self.publicPartyGui.stash()
        if doneStatus is None:
            # They don't want to party... just let them walk away from the hat
            self.freeAvatar()
            return
        self.sendUpdate("partyChoiceRequest",
                        [base.localAvatar.doId, doneStatus[0], doneStatus[1]])

    def partyRequestDenied(self, reason):
        """
        Called by the AI when the player's request to join a public party was denied.
        """
        DistributedPartyGate.notify.debug(
            "partyRequestDenied( reason=%s )" %
            PartyGlobals.PartyGateDenialReasons.getString(reason))
        # let the local toon know that they were denied
        # TODO-parties: tell player through gui
        if reason == PartyGlobals.PartyGateDenialReasons.Unavailable:
            self.showMessage(TTLocalizer.PartyGatePartyUnavailable)
        elif reason == PartyGlobals.PartyGateDenialReasons.Full:
            self.showMessage(TTLocalizer.PartyGatePartyFull)

    def setParty(self, partyInfoTuple):
        """
        Gets called by the AI server with the approved partyId.
        """
        DistributedPartyGate.notify.debug("setParty")

        self.freeAvatar()
        if partyInfoTuple[0] == 0:
            DistributedPartyGate.notify.debug(
                "Public Party closed before toon could get to it.")
            return

        # We now need to enter the party with the given partyId, that is, move
        # our toon toward the hat entrance and do the appropriate state transition
        shardId, zoneId, numberOfGuests, hostName, activityIds, lane = partyInfoTuple
        if base.localAvatar.defaultShard == shardId:
            shardId = None
        base.cr.playGame.getPlace().requestLeave({
            "loader": "safeZoneLoader",
            "where": "party",
            "how": "teleportIn",
            "hoodId": ToontownGlobals.PartyHood,
            "zoneId": zoneId,
            "shardId": shardId,
            "avId": -1,
            #            "partyHat" : True,
            #            "tunnelOrigin" : self.tunnelOrigin,
        })

    def freeAvatar(self):
        base.localAvatar.posCamera(0, 0)
        base.cr.playGame.getPlace().setState("walk")

    def hourChange(self, currentHour):
        currentHour = currentHour % 12
        if currentHour == 0:
            currentHour = 12
        self.hourSoundInterval = Parallel()
        # Make a sequence with all the clock sounds
        seq1 = Sequence()
        for i in range(currentHour):
            seq1.append(SoundInterval(self.clockSounds[i]))
            seq1.append(Wait(0.2))
        # Now make a sequence that will deform the clock face
        timeForEachDeformation = seq1.getDuration() / currentHour
        seq2 = Sequence()
        for i in range(currentHour):
            seq2.append(
                self.clockFlat.scaleInterval(timeForEachDeformation / 2.0,
                                             Vec3(0.9, 1.0, 1.2),
                                             blendType='easeInOut'))
            seq2.append(
                self.clockFlat.scaleInterval(timeForEachDeformation / 2.0,
                                             Vec3(1.2, 1.0, 0.9),
                                             blendType='easeInOut'))
        seq2.append(
            self.clockFlat.scaleInterval(timeForEachDeformation / 2.0,
                                         Vec3(1.0, 1.0, 1.0),
                                         blendType='easeInOut'))
        # Now parallel the two together
        self.hourSoundInterval.append(seq1)
        self.hourSoundInterval.append(seq2)
        self.hourSoundInterval.start()

    def handleEnterGateSphere(self, collEntry):
        self.notify.debug("Entering steps Sphere....")
        # Freeze the toon, don't let him walk away...
        base.cr.playGame.getPlace().fsm.request('stopped')
        self.sendUpdate("getPartyList", [base.localAvatar.doId])

    def listAllPublicParties(self, publicPartyInfo):
        """
        Called from DistributedPartyGateAI with a tuple of all the public party
        information as told to it by the DistributedPartyManagerAI in order of
        newest party to oldest party.
        ( shardId, zoneId, numberOfGuests, hostName, activityIds, minLeft )
        """
        self.notify.debug("listAllPublicParties : publicPartyInfo = %s" %
                          publicPartyInfo)
        self.acceptOnce(self.publicPartyChooseGuiDoneEvent,
                        self.__handleAskDone)
        self.publicPartyGui.refresh(publicPartyInfo)
        self.publicPartyGui.unstash()

    def __enableCollisions(self):
        # start listening for toons to enter.
        self.accept('enterPartyGateSphere', self.handleEnterGateSphere)
        self.partyGateSphere.setCollideMask(OTPGlobals.WallBitmask)

    def __disableCollisions(self):
        # stop listening for toons.
        self.ignore('enterPartyGateSphere')
        self.partyGateSphere.setCollideMask(BitMask32(0))

    def handleSleep(self):
        if hasattr(self, 'messageGui'):
            self.__handleMessageDone()
class DistributedPieTurret(DistributedAvatar, DistributedSmoothNode):
	notify = directNotify.newCategory("DistributedPieTurret")

	def __init__(self, cr):
		DistributedAvatar.__init__(self, cr)
		DistributedSmoothNode.__init__(self, cr)
		self.fsm = ClassicFSM(
			'DistributedPieTurret',
			[
				State('off', self.enterOff, self.exitOff),
				State('scan', self.enterScan, self.exitScan),
				#State('lockOn', self.enterLockOn, self.exitLockOn),
				State('shoot', self.enterShoot, self.exitShoot)
			],
			'off', 'off'
		)
		self.fsm.enterInitialState()
		self.cannon = None
		self.track = None
		self.avatar = None
		self.readyPie = None
		self.explosion = None
		self.wallCollNode = None
		self.eventCollNode = None
		self.event = None
		self.piesInFlight = []

	def setHealth(self, hp):
		DistributedAvatar.setHealth(self, hp)
		if self.getAvatar() == base.localAvatar.doId:
			base.localAvatar.getMyBattle().getTurretManager().updateTurretGui()

	def die(self):
		self.fsm.requestFinalState()
		turretPos = self.cannon.getPos(render)
		self.removeTurret()
		self.explosion = loader.loadModel("phase_3.5/models/props/explosion.bam")
		self.explosion.setScale(0.5)
		self.explosion.reparentTo(render)
		self.explosion.setBillboardPointEye()
		self.explosion.setPos(turretPos + (0, 0, 1))
		sfx = base.localAvatar.audio3d.loadSfx("phase_3.5/audio/sfx/ENC_cogfall_apart.mp3")
		base.localAvatar.audio3d.attachSoundToObject(sfx, self)
		base.playSfx(sfx)

	def showAndMoveHealthLabel(self):
		self.unstashHpLabel()
		self.stopMovingHealthLabel()
		moveTrack = LerpPosInterval(self.healthLabel,
								duration = 0.5,
								pos = Point3(0, 0, 5),
								startPos = Point3(0, 0, 0),
								blendType = 'easeOut')
		self.healthLabelTrack = Sequence(moveTrack, Wait(1.0), Func(self.stashHpLabel))
		self.healthLabelTrack.start()

	def enterOff(self):
		pass

	def exitOff(self):
		pass

	def makeSplat(self, pos):
		splat = Actor("phase_3.5/models/props/splat-mod.bam",
			{"chan": "phase_3.5/models/props/splat-chan.bam"})
		splat.setScale(0.5)
		splat.reparentTo(render)
		splat.setBillboardPointEye()
		splat.setColor(VBase4(1, 1, 0, 1))
		x, y, z = pos
		splat.setPos(x, y, z)
		sfx = base.localAvatar.audio3d.loadSfx("phase_4/audio/sfx/AA_wholepie_only.mp3")
		base.localAvatar.audio3d.attachSoundToObject(sfx, splat)
		base.playSfx(sfx)
		track = Sequence(
			ActorInterval(splat, "chan"),
			Func(splat.cleanup),
			Func(splat.removeNode)
		)
		track.start()

	def d_makeSplat(self, pos):
		self.sendUpdate("makeSplat", [pos])

	def b_makeSplat(self, pos):
		self.d_makeSplat(pos)
		self.makeSplat(pos)

	def shoot(self, suitId):
		self.fsm.request('shoot', [suitId])

	def enterShoot(self, suitId):
		if self.cannon:
			smoke = loader.loadModel("phase_4/models/props/test_clouds.bam")
			smoke.setBillboardPointEye()
			smoke.reparentTo(self.cannon.find('**/cannon'))
			smoke.setPos(0, 6, -3)
			smoke.setScale(0.5)
			smoke.wrtReparentTo(render)
			self.suit = self.cr.doId2do.get(suitId)
			self.cannon.find('**/cannon').lookAt(self.suit.find('**/joint_head'))
			self.cannon.find('**/square_drop_shadow').headsUp(self.suit.find('**/joint_head'))
			self.eventId = random.uniform(0, 100000000)
			track = Sequence(Parallel(LerpScaleInterval(smoke, 0.5, 3), LerpColorScaleInterval(smoke, 0.5, Vec4(2, 2, 2, 0))), Func(smoke.removeNode))
			track.start()
			self.createAndShootPie()

	def loadPieInTurret(self):
		if self.cannon:
			if self.readyPie:
				self.readyPie.removeNode()
				self.readyPie = None
			pie = loader.loadModel("phase_3.5/models/props/tart.bam")
			pie.reparentTo(self.cannon.find('**/cannon'))
			pie.setY(5.2)
			pie.setHpr(90, -90, 90)
			self.readyPie = pie

	def removePieInTurret(self):
		if self.readyPie:
			self.readyPie.removeNode()
			self.readyPie = None

	def createAndShootPie(self):
		if not self.readyPie:
			self.loadPieInTurret()
		local = 0
		if base.localAvatar.doId == self.getAvatar():
			local = 1
		proj = ProjectilePie(self.uniqueName('pieTurretCollision') + str(self.eventId), self.cannon.find('**/cannon'), self.readyPie, Point3(0, 200, -90), 0.9, 2.5, local, self)
		self.readyPie = None
		self.piesInFlight.append(proj)
		if local:
			self.acceptOnce(self.uniqueName('pieTurretCollision') + str(self.eventId), self.handlePieCollision)
		Sequence(Wait(0.25), Func(self.loadPieInTurret)).start()

	def handlePieCollision(self, entry, proj):
		x, y, z = proj.pie.getPos(render)
		self.b_makeSplat([x, y, z])
		proj.cleanup()
		if base.localAvatar.doId == self.getAvatar():
			intoNP = entry.getIntoNodePath()
			avNP = intoNP.getParent()
			for key in self.cr.doId2do.keys():
				obj = self.cr.doId2do[key]
				if obj.__class__.__name__ == "DistributedSuit":
					if obj.getKey() == avNP.getKey():
						if obj.getHealth() > 0:
							base.localAvatar.sendUpdate('suitHitByPie', [obj.doId, GagGlobals.getIDByName(CIGlobals.WholeCreamPie)])

	def exitShoot(self):
		del self.suit
		del self.eventId

	def scan(self, timestamp = None, afterShooting = 0):
		if timestamp == None:
			ts = 0.0
		else:
			ts = globalClockDelta.localElapsedTime(timestamp)

		self.fsm.request('scan', [ts, afterShooting])

	def enterScan(self, ts = 0, afterShooting = 0):
		if afterShooting:
			self.track = Parallel(
				LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0),
					startHpr = self.cannon.find('**/cannon').getHpr(), blendType = 'easeInOut'),
				LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0),
					startHpr = self.cannon.find('**/square_drop_shadow').getHpr(), blendType = 'easeInOut'),
				name = "afterShootTrack" + str(id(self))
			)
			self.track.setDoneEvent(self.track.getName())
			self.acceptOnce(self.track.getDoneEvent(), self._afterShootTrackDone)
			self.track.start(ts)
		else:
			self.track = Parallel(
				Sequence(
					LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (60, 0, 0),
						startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'),
					LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0),
						startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'),
				),
				Sequence(
					LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (60, 0, 0),
						startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'),
					LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0),
						startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'),
				)
			)
			self.track.loop(ts)

	def _afterShootTrackDone(self):
		self.track = None
		self.track = Parallel(
			Sequence(
				LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (60, 0, 0),
					startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'),
				LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0),
					startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'),
			),
			Sequence(
				LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (60, 0, 0),
					startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'),
				LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0),
					startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'),
			)
		)
		self.track.loop()

	def exitScan(self):
		if self.track:
			self.ignore(self.track.getDoneEvent())
			self.track.finish()
			self.track = None

	def setAvatar(self, avId):
		self.avatar = avId

	def getAvatar(self):
		return self.avatar

	def makeTurret(self):
		self.cannon = loader.loadModel("phase_4/models/minigames/toon_cannon.bam")
		self.cannon.reparentTo(self)
		self.loadPieInTurret()
		self.setupWallSphere()
		if self.getAvatar() == base.localAvatar.doId:
			self.setupEventSphere()

	def setupWallSphere(self):
		sphere = CollisionSphere(0.0, 0.0, 0.0, 3.0)
		node = CollisionNode('DistributedPieTurret.WallSphere')
		node.addSolid(sphere)
		node.setCollideMask(CIGlobals.WallBitmask)
		self.wallCollNode = self.cannon.attachNewNode(node)
		self.wallCollNode.setZ(2)
		self.wallCollNode.setY(1.0)

	def removeWallSphere(self):
		if self.wallCollNode:
			self.wallCollNode.removeNode()
			self.wallCollNode = None

	def removeTurret(self):
		self.removeWallSphere()
		self.removePieInTurret()
		if self.cannon:
			self.cannon.removeNode()
			self.cannon = None

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

	def announceGenerate(self):
		DistributedAvatar.announceGenerate(self)
		DistributedSmoothNode.announceGenerate(self)
		self.healthLabel.setScale(1.1)
		self.makeTurret()

	def disable(self):
		self.fsm.requestFinalState()
		del self.fsm
		for projs in self.piesInFlight:
			projs.cleanup()
		self.piesInFlight = None
		if self.explosion:
			self.explosion.removeNode()
			self.explosion = None
		self.removeTurret()
		DistributedSmoothNode.disable(self)
		DistributedAvatar.disable(self)
コード例 #41
0
ファイル: DistributedNPCToon.py プロジェクト: coginvasion/src
class DistributedNPCToon(DistributedToon):
    notify = directNotify.newCategory('DistributedNPCToon')

    def __init__(self, cr):
        DistributedToon.__init__(self, cr)
        self.collisionNodePath = None
        self.cameraTrack = None
        self.originIndex = None
        self.npcId = None
        self.currentChatIndex = 0
        self.chatArray = None
        return

    def setLoadout(self, foo):
        pass

    def lookAtAvatar(self, avId):
        av = self.cr.doId2do.get(avId)
        if av:
            self.headsUp(av)

    def setNpcId(self, id):
        self.npcId = id

    def getNpcId(self):
        return self.npcId

    def setOriginIndex(self, index):
        self.originIndex = index

    def getOriginIndex(self):
        return self.originIndex

    def __setupCollisions(self):
        sphere = CollisionSphere(0, 0, 0, 4)
        sphere.setTangible(0)
        collisionNode = CollisionNode(self.uniqueName('NPCToonSphere'))
        collisionNode.addSolid(sphere)
        collisionNode.setCollideMask(CIGlobals.WallBitmask)
        self.collisionNodePath = self.attachNewNode(collisionNode)
        self.collisionNodePath.setY(1.5)

    def __removeCollisions(self):
        if self.collisionNodePath:
            self.collisionNodePath.removeNode()
            self.collisionNodePath = None
        return

    def handleEnterCollision(self, entry):
        self.cr.playGame.getPlace().fsm.request('stop')
        base.localAvatar.stopSmartCamera()
        self.sendUpdate('requestEnter', [])

    def doCameraNPCInteraction(self):
        currCamPos = camera.getPos()
        currCamHpr = camera.getHpr()
        camera.setX(camera.getX() + 5)
        camera.setY(camera.getY() + 5)
        camera.headsUp(self)
        newCamPos = camera.getPos()
        newCamHpr = camera.getHpr()
        camera.setPos(currCamPos)
        camera.setHpr(currCamHpr)
        self.cameraTrack = Parallel(LerpPosInterval(camera, duration=1.0, pos=newCamPos, startPos=currCamPos, blendType='easeOut'), LerpQuatInterval(camera, duration=1.0, quat=newCamHpr, startHpr=currCamHpr, blendType='easeOut'))
        self.cameraTrack.start()

    def stopCameraTrack(self):
        if self.cameraTrack:
            self.cameraTrack.finish()
            self.cameraTrack = None
        return

    def oneChatThenExit(self):
        self.acceptOnce('mouse1-up', self.d_requestExit)

    def enterAccepted(self):
        self.doCameraNPCInteraction()
        questData = base.localAvatar.questManager.getQuestAndIdWhereCurrentObjectiveIsToVisit(self.npcId)
        if questData:
            quest = questData[1]
            self.currentQuestObjective = quest.currentObjectiveIndex
            self.currentQuestId = questData[0]
            self.currentChatIndex = 0
            if CIGlobals.NPCToonDict[self.npcId][3] == CIGlobals.NPC_REGULAR:
                self.doNPCChat(array=Quests.QuestNPCDialogue)

    def doNPCChat(self, array = Quests.QuestNPCDialogue, chat = None):
        if array and not chat:
            self.chatArray = array
            self.b_setChat(array[self.currentQuestId][self.currentQuestObjective][self.currentChatIndex])
            self.currentChatIndex += 1
            Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextNPCChat)).start()
        elif chat and not array:
            self.b_setChat(chat)
            Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.d_requestExit)).start()

    def d_requestExit(self):
        self.sendUpdate('requestExit', [])

    def doNextNPCChat(self):
        if self.currentChatIndex >= len(self.chatArray[self.currentQuestId][self.currentQuestObjective]):
            self.chatArray = None
            self.d_requestExit()
        else:
            self.doNPCChat(self.chatArray)
        return

    def rejectEnter(self):
        self.exitAccepted()

    def exitAccepted(self):
        self.stopCameraTrack()
        self.cr.playGame.getPlace().fsm.request('walk')
        self.acceptCollisions()

    def acceptCollisions(self):
        self.acceptOnce('enter' + self.uniqueName('NPCToonSphere'), self.handleEnterCollision)

    def ignoreCollisions(self):
        self.ignore('enter' + self.uniqueName('NPCToonSphere'))

    def __npcOriginPoll(self, task):
        if task.time > 4.0:
            self.notify.warning('Giving up waiting for npc origin after %d seconds. Will parent to render.' % task.time)
            self.reparentTo(render)
            return task.done
        npcOrigin = render.find('**/npc_origin_' + str(self.originIndex))
        if not npcOrigin.isEmpty():
            self.reparentTo(npcOrigin)
            return task.done
        return task.cont

    def startNPCOriginPoll(self):
        base.taskMgr.add(self.__npcOriginPoll, self.uniqueName('NPCOriginPoll'))

    def stopNPCOriginPoll(self):
        base.taskMgr.remove(self.uniqueName('NPCOriginPoll'))

    def announceGenerate(self):
        DistributedToon.announceGenerate(self)
        self.startLookAround()
        self.__setupCollisions()
        npcOrigin = render.find('**/npc_origin_' + str(self.originIndex))
        if not npcOrigin.isEmpty():
            self.reparentTo(npcOrigin)
        else:
            self.startNPCOriginPoll()
        self.acceptCollisions()
        self.nameTag.setClickable(0)

    def disable(self):
        self.ignore('mouse1-up')
        self.stopLookAround()
        self.stopNPCOriginPoll()
        self.chatArray = None
        self.originIndex = None
        self.npcId = None
        self.stopCameraTrack()
        self.ignoreCollisions()
        self.__removeCollisions()
        DistributedToon.disable(self)
        return
コード例 #42
0
class DodgeballFirstPerson(FirstPerson):
    """The first person controls for the local player in Winter Dodgeball"""

    notify = directNotify.newCategory("DodgeballFirstPerson")

    MaxPickupDistance = 5.0

    def __init__(self, mg):
        self.mg = mg
        self.crosshair = None
        self.soundCatch = None
        self.vModelRoot = None
        self.vModel = None
        self.ival = None
        self.soundPickup = base.loadSfx(
            'phase_4/audio/sfx/MG_snowball_pickup.ogg')
        self.fakeSnowball = loader.loadModel(
            "phase_5/models/props/snowball.bam")
        self.hasSnowball = False
        self.mySnowball = None
        self.waitingOnPickupResp = False
        self.camPivotNode = base.localAvatar.attachNewNode('cameraPivotNode')
        self.camFSM = ClassicFSM.ClassicFSM("DFPCamera", [
            State.State('off', self.enterCamOff, self.exitCamOff),
            State.State('frozen', self.enterFrozen, self.exitFrozen),
            State.State('unfrozen', self.enterUnFrozen, self.exitUnFrozen)
        ], 'off', 'off')
        self.camFSM.enterInitialState()
        self.fsm = ClassicFSM.ClassicFSM("DodgeballFirstPerson", [
            State.State("off", self.enterOff, self.exitOff),
            State.State("hold", self.enterHold, self.exitHold),
            State.State("catch", self.enterCatch, self.exitCatch),
            State.State("throw", self.enterThrow, self.exitThrow)
        ], "off", "off")
        self.fsm.enterInitialState()

        FirstPerson.__init__(self)

    def enterCamOff(self):
        self.releaseSnowball()

    def exitCamOff(self):
        pass

    def releaseSnowball(self):
        if self.hasSnowball:
            if self.mySnowball and not self.mySnowball.isAirborne:
                self.hasSnowball = False
                self.mySnowball.resetSnowball()
                self.mySnowball = None
                self.fsm.request('off')

    def enterFrozen(self):
        self.releaseSnowball()

        self.vModel.hide()
        base.localAvatar.getGeomNode().show()
        camera.wrtReparentTo(self.camPivotNode)
        camHeight = max(base.localAvatar.getHeight(), 3.0)
        nrCamHeight = base.localAvatar.getHeight()
        heightScaleFactor = camHeight * 0.3333333333
        defLookAt = Point3(0.0, 1.5, camHeight)
        idealData = (Point3(0.0, -12.0 * heightScaleFactor,
                            camHeight), defLookAt)
        self.camTrack = Parallel(
            LerpPosInterval(camera,
                            duration=1.0,
                            pos=idealData[0],
                            startPos=camera.getPos(),
                            blendType='easeOut'),
            LerpQuatInterval(camera,
                             duration=1.0,
                             hpr=idealData[1],
                             startHpr=camera.getHpr(),
                             blendType='easeOut'))
        self.camTrack.start()
        self.max_camerap = 0.0
        self.disableMouse()

    def cameraMovement(self, task):
        if not self.camFSM:
            return task.done

        if self.camFSM.getCurrentState().getName() == 'frozen':
            if hasattr(self, 'min_camerap') and hasattr(self, 'max_camerap'):
                md = base.win.getPointer(0)
                x = md.getX()
                y = md.getY()
                if base.win.movePointer(0,
                                        base.win.getXSize() / 2,
                                        base.win.getYSize() / 2):
                    self.camPivotNode.setP(self.camPivotNode.getP() -
                                           (y - base.win.getYSize() / 2) * 0.1)
                    self.camPivotNode.setH(self.camPivotNode.getH() -
                                           (x - base.win.getXSize() / 2) * 0.1)
                    if self.camPivotNode.getP() < self.min_camerap:
                        self.camPivotNode.setP(self.min_camerap)
                    elif self.camPivotNode.getP() > self.max_camerap:
                        self.camPivotNode.setP(self.max_camerap)
                return task.cont
            else:
                return task.done

        return FirstPerson.cameraMovement(self, task)

    def exitFrozen(self):
        self.camTrack.finish()
        del self.camTrack
        self.max_camerap = 90.0
        self.vModel.show()
        self.enableMouse()
        base.localAvatar.stopSmartCamera()

    def enterUnFrozen(self):
        base.localAvatar.getGeomNode().hide()
        self.reallyStart()
        camera.setPosHpr(0, 0, 0, 0, 0, 0)
        camera.reparentTo(self.player_node)
        camera.setZ(base.localAvatar.getHeight())

    def exitUnFrozen(self):
        self.end()
        self.enableMouse()

    def enterOff(self):
        if self.vModel:
            self.vModel.hide()
        if self.waitingOnPickupResp:
            taskMgr.add(self.__waitForPickupRespTask, "waitForPickupRespTask")

    def __waitForPickupRespTask(self, task):
        if not self.waitingOnPickupResp:
            if self.hasSnowball:
                self.fsm.request('hold')
            return task.done
        return task.cont

    def exitOff(self):
        if self.vModel:
            self.vModel.show()
        taskMgr.remove("waitForPickupRespTask")

    def enterHold(self):
        self.ival = Sequence(ActorInterval(self.vModel, "hold-start"),
                             Func(self.vModel.loop, "hold"))
        self.ival.start()

    def exitHold(self):
        if self.ival:
            self.ival.finish()
            self.ival = None
        self.vModel.stop()

    def enterThrow(self):
        self.ival = Parallel(
            Sequence(Wait(0.4), Func(self.mySnowball.b_throw)),
            Sequence(ActorInterval(self.vModel, "throw"),
                     Func(self.fsm.request, 'off')))
        self.ival.start()

    def exitThrow(self):
        if self.ival:
            self.ival.pause()
            self.ival = None
        self.vModel.stop()

    def enterCatch(self):
        self.ival = Parallel(
            Sequence(Wait(0.2), Func(self.__tryToCatchOrGrab)),
            Sequence(ActorInterval(self.vModel, "catch"),
                     Func(self.__maybeHold)))
        self.ival.start()

    def __maybeHold(self):
        if self.hasSnowball:
            self.fsm.request('hold')
        else:
            self.fsm.request('off')

    def __tryToCatchOrGrab(self):
        snowballs = list(self.mg.snowballs)
        snowballs.sort(
            key=lambda snowball: snowball.getDistance(base.localAvatar))
        for i in xrange(len(snowballs)):
            snowball = snowballs[i]
            if (not snowball.hasOwner() and not snowball.isAirborne
                    and snowball.getDistance(base.localAvatar) <=
                    DodgeballFirstPerson.MaxPickupDistance):
                self.waitingOnPickupResp = True
                self.mg.sendUpdate('reqPickupSnowball', [snowball.index])
                break

    def snowballPickupResp(self, flag, idx):
        if flag:
            snowball = self.mg.snowballs[idx]
            snowball.b_pickup()
            self.mySnowball = snowball
            self.fakeSnowball.setPosHpr(0, 0.73, 0, 0, 0, 0)
            self.fakeSnowball.reparentTo(
                self.vModel.exposeJoint(None, "modelRoot", "Bone.011"))
            base.playSfx(self.soundPickup)
            self.hasSnowball = True
        self.waitingOnPickupResp = False

    def exitCatch(self):
        self.vModel.stop()
        if self.ival:
            self.ival.pause()
            self.ival = None

    def start(self):
        # Black crosshair because basically the entire arena is white.
        self.crosshair = getCrosshair(color=(0, 0, 0, 1), hidden=False)

        self.soundCatch = base.loadSfx(
            "phase_4/audio/sfx/MG_sfx_vine_game_catch.ogg")

        self.vModelRoot = camera.attachNewNode('vModelRoot')
        self.vModelRoot.setPos(-0.09, 1.38, -2.48)

        self.vModel = Actor(
            "phase_4/models/minigames/v_dgm.egg", {
                "hold": "phase_4/models/minigames/v_dgm-ball-hold.egg",
                "hold-start":
                "phase_4/models/minigames/v_dgm-ball-hold-start.egg",
                "throw": "phase_4/models/minigames/v_dgm-ball-throw.egg",
                "catch": "phase_4/models/minigames/v_dgm-ball-catch.egg"
            })
        self.vModel.setBlend(frameBlend=True)
        self.vModel.reparentTo(self.vModelRoot)
        self.vModel.setBin("fixed", 40)
        self.vModel.setDepthTest(False)
        self.vModel.setDepthWrite(False)
        self.vModel.hide()

        base.localAvatar.walkControls.setWalkSpeed(ToonForwardSpeed,
                                                   ToonJumpForce,
                                                   ToonReverseSpeed,
                                                   ToonRotateSpeed)

        FirstPerson.start(self)

    def reallyStart(self):
        FirstPerson.reallyStart(self)
        base.localAvatar.startTrackAnimToSpeed()

        self.accept('mouse3', self.__handleCatchOrGrabButton)
        self.accept('mouse1', self.__handleThrowButton)

    def end(self):
        base.localAvatar.stopTrackAnimToSpeed()
        self.ignore('mouse3')
        self.ignore('mouse1')
        FirstPerson.end(self)

    def __handleThrowButton(self):
        if self.hasSnowball and self.mySnowball and self.fsm.getCurrentState(
        ).getName() == 'hold':
            self.fakeSnowball.reparentTo(hidden)
            self.fsm.request('throw')

    def __handleCatchOrGrabButton(self):
        if not self.hasSnowball and not self.mySnowball and self.fsm.getCurrentState(
        ).getName() == 'off':
            self.fsm.request('catch')

    def reallyEnd(self):
        base.localAvatar.setWalkSpeedNormal()
        if self.camFSM:
            self.camFSM.requestFinalState()
            self.camFSM = None
        if self.fsm:
            self.fsm.requestFinalState()
            self.fsm = None
        if self.crosshair:
            self.crosshair.destroy()
            self.crosshair = None
        if self.vModel:
            self.vModel.removeNode()
            self.vModel = None
        if self.vModelRoot:
            self.vModelRoot.removeNode()
            self.vModelRoot = None
        self.soundCatch = None
        FirstPerson.reallyEnd(self)
コード例 #43
0
class DistributedPartyGate(DistributedObject.DistributedObject):
    notify = DirectNotifyGlobal.directNotify.newCategory(
        'DistributedPartyGate')

    def __init__(self, cr):
        DistributedObject.DistributedObject.__init__(self, cr)
        self.publicPartyChooseGuiDoneEvent = 'doneChoosingPublicParty'
        self.publicPartyGui = PublicPartyGui(
            self.publicPartyChooseGuiDoneEvent)
        self.publicPartyGui.stash()
        self.loadClockSounds()
        self.hourSoundInterval = Sequence()
        self.accept('stoppedAsleep', self.handleSleep)

    def loadClockSounds(self):
        self.clockSounds = []
        for i in range(1, 13):
            if i < 10:
                si = '0%d' % i
            else:
                si = '%d' % i
            self.clockSounds.append(
                base.loadSfx('phase_4/audio/sfx/clock%s.mp3' % si))

    def generate(self):
        DistributedObject.DistributedObject.generate(self)
        loader = self.cr.playGame.hood.loader
        partyGate = loader.geom.find('**/partyGate_grp')
        if partyGate.isEmpty():
            self.notify.warning('Could not find partyGate_grp in loader.geom')
            return
        self.clockFlat = partyGate.find('**/clock_flat')
        collSphere = CollisionSphere(0, 0, 0, 6.9)
        collSphere.setTangible(1)
        self.partyGateSphere = CollisionNode('PartyGateSphere')
        self.partyGateSphere.addSolid(collSphere)
        self.partyGateCollNodePath = partyGate.find(
            '**/partyGate_stepsLocator').attachNewNode(self.partyGateSphere)
        self.__enableCollisions()
        self.toontownTimeGui = ServerTimeGui(partyGate,
                                             hourCallback=self.hourChange)
        self.toontownTimeGui.setPos(
            partyGate.find('**/clockText_locator').getPos() +
            Point3(0.0, 0.0, -0.2))
        self.toontownTimeGui.setHpr(
            partyGate.find('**/clockText_locator').getHpr())
        self.toontownTimeGui.setScale(12.0, 1.0, 26.0)
        self.toontownTimeGui.amLabel.setPos(-0.035, 0, -0.032)
        self.toontownTimeGui.amLabel.setScale(0.5)
        self.toontownTimeGui.updateTime()
        self.setupSignText()

    def setupSignText(self):
        loader = self.cr.playGame.hood.loader
        partyGate = loader.geom.find('**/partyGateSignGroup')
        if partyGate.isEmpty():
            self.notify.warning('Could not find partyGate_grp in loader.geom')
            return
        gateFont = ToontownGlobals.getMinnieFont()
        leftSign = partyGate.find('**/signTextL_locatorBack')
        signScale = 0.35
        wordWrap = 8
        leftText = DirectLabel.DirectLabel(parent=leftSign,
                                           pos=(0, 0.0, 0.0),
                                           relief=None,
                                           text=TTLocalizer.PartyGateLeftSign,
                                           text_align=TextNode.ACenter,
                                           text_font=gateFont,
                                           text_wordwrap=wordWrap,
                                           text_fg=Vec4(0.7, 0.3, 0.3, 1.0),
                                           scale=signScale)
        rightSign = partyGate.find('**/signTextR_locatorFront')
        rightText = DirectLabel.DirectLabel(
            parent=rightSign,
            pos=(0, 0.0, 0.0),
            relief=None,
            text=TTLocalizer.PartyGateRightSign,
            text_align=TextNode.ACenter,
            text_font=gateFont,
            text_wordwrap=wordWrap,
            text_fg=Vec4(0.7, 0.3, 0.3, 1.0),
            scale=signScale)
        return

    def announceGenerate(self):
        DistributedObject.DistributedObject.announceGenerate(self)
        if ToontownGlobals.dnaMap.has_key(self.zoneId):
            playground = ToontownGlobals.dnaMap[self.zoneId]
        else:
            playground = ToontownGlobals.dnaMap[2000]
        self.toontownTimeGui.hourLabel[
            'text_fg'] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.colonLabel[
            'text_fg'] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.minutesLabel[
            'text_fg'] = PartyGlobals.PlayGroundToPartyClockColors[playground]
        self.toontownTimeGui.amLabel[
            'text_fg'] = PartyGlobals.PlayGroundToPartyClockColors[playground]

    def disable(self):
        DistributedObject.DistributedObject.disable(self)
        self.__disableCollisions()
        self.toontownTimeGui.ival.finish()
        self.hourSoundInterval.finish()
        if self.publicPartyGui:
            self.publicPartyGui.stash()
            self.publicPartyGui.destroy()
            self.publicPartyGui = None
        return

    def delete(self):
        DistributedObject.DistributedObject.delete(self)
        self.toontownTimeGui.destroy()
        del self.toontownTimeGui
        self.hourSoundInterval.finish()
        del self.hourSoundInterval
        del self.clockFlat
        if self.publicPartyGui:
            self.publicPartyGui.destroy()
            del self.publicPartyGui
        self.partyGateCollNodePath.removeNode()
        del self.partyGateCollNodePath
        self.ignoreAll()

    def showMessage(self, message):
        self.messageDoneEvent = self.uniqueName('messageDoneEvent')
        self.acceptOnce(self.messageDoneEvent, self.__handleMessageDone)
        self.messageGui = TTDialog.TTGlobalDialog(
            doneEvent=self.messageDoneEvent,
            message=message,
            style=TTDialog.Acknowledge)

    def __handleMessageDone(self):
        self.ignore(self.messageDoneEvent)
        self.freeAvatar()
        self.messageGui.cleanup()
        self.messageGui = None
        return

    def __handleAskDone(self):
        DistributedPartyGate.notify.debug('__handleAskDone')
        self.ignore(self.publicPartyChooseGuiDoneEvent)
        doneStatus = self.publicPartyGui.doneStatus
        self.publicPartyGui.stash()
        if doneStatus is None:
            self.freeAvatar()
            return
        self.sendUpdate('partyChoiceRequest',
                        [base.localAvatar.doId, doneStatus[0], doneStatus[1]])
        return

    def partyRequestDenied(self, reason):
        DistributedPartyGate.notify.debug(
            'partyRequestDenied( reason=%s )' %
            PartyGlobals.PartyGateDenialReasons.getString(reason))
        if reason == PartyGlobals.PartyGateDenialReasons.Unavailable:
            self.showMessage(TTLocalizer.PartyGatePartyUnavailable)
        elif reason == PartyGlobals.PartyGateDenialReasons.Full:
            self.showMessage(TTLocalizer.PartyGatePartyFull)

    def setParty(self, partyInfoTuple):
        DistributedPartyGate.notify.debug('setParty')
        self.freeAvatar()
        if partyInfoTuple[0] == 0:
            DistributedPartyGate.notify.debug(
                'Public Party closed before toon could get to it.')
            return
        shardId, zoneId, numberOfGuests, hostName, activityIds, lane = partyInfoTuple
        if base.localAvatar.defaultShard == shardId:
            shardId = None
        base.cr.playGame.getPlace().requestLeave({
            'loader': 'safeZoneLoader',
            'where': 'party',
            'how': 'teleportIn',
            'hoodId': ToontownGlobals.PartyHood,
            'zoneId': zoneId,
            'shardId': shardId,
            'avId': -1
        })
        return

    def freeAvatar(self):
        base.localAvatar.posCamera(0, 0)
        base.cr.playGame.getPlace().setState('walk')

    def hourChange(self, currentHour):
        currentHour = currentHour % 12
        if currentHour == 0:
            currentHour = 12
        self.hourSoundInterval = Parallel()
        seq1 = Sequence()
        for i in range(currentHour):
            seq1.append(SoundInterval(self.clockSounds[i]))
            seq1.append(Wait(0.2))

        timeForEachDeformation = seq1.getDuration() / currentHour
        seq2 = Sequence()
        for i in range(currentHour):
            seq2.append(
                self.clockFlat.scaleInterval(timeForEachDeformation / 2.0,
                                             Vec3(0.9, 1.0, 1.2),
                                             blendType='easeInOut'))
            seq2.append(
                self.clockFlat.scaleInterval(timeForEachDeformation / 2.0,
                                             Vec3(1.2, 1.0, 0.9),
                                             blendType='easeInOut'))

        seq2.append(
            self.clockFlat.scaleInterval(timeForEachDeformation / 2.0,
                                         Vec3(1.0, 1.0, 1.0),
                                         blendType='easeInOut'))
        self.hourSoundInterval.append(seq1)
        self.hourSoundInterval.append(seq2)
        self.hourSoundInterval.start()

    def handleEnterGateSphere(self, collEntry):
        self.notify.debug('Entering steps Sphere....')
        base.cr.playGame.getPlace().fsm.request('stopped')
        self.sendUpdate('getPartyList', [base.localAvatar.doId])

    def listAllPublicParties(self, publicPartyInfo):
        self.notify.debug('listAllPublicParties : publicPartyInfo = %s' %
                          publicPartyInfo)
        self.acceptOnce(self.publicPartyChooseGuiDoneEvent,
                        self.__handleAskDone)
        self.publicPartyGui.refresh(publicPartyInfo)
        self.publicPartyGui.unstash()

    def __enableCollisions(self):
        self.accept('enterPartyGateSphere', self.handleEnterGateSphere)
        self.partyGateSphere.setCollideMask(OTPGlobals.WallBitmask)

    def __disableCollisions(self):
        self.ignore('enterPartyGateSphere')
        self.partyGateSphere.setCollideMask(BitMask32(0))

    def handleSleep(self):
        if hasattr(self, 'messageGui') and self.messageGui:
            self.__handleMessageDone()
コード例 #44
0
ファイル: golem.py プロジェクト: grimfang/owp_ajaw
class Golem(FSM, DirectObject):
    def __init__(self):
        FSM.__init__(self, "FSM-Golem")
        random.seed()
        self.golem = loader.loadModel("Golem")
        self.golem = Actor("Golem", {
            "Idle":"Golem-Idle",
            "Walk":"Golem-Walk",
            "Attack":"Golem-Attack",
            "Destroyed":"Golem-Destroyed"})
        self.golem.setBlend(frameBlend = True)
        golemViewSphere = CollisionSphere(0, 0, 0.5, 6)
        golemViewSphere.setTangible(False)
        golemViewColNP = self.golem.attachNewNode(CollisionNode('golemViewField'))
        golemViewColNP.node().addSolid(golemViewSphere)
        golemHitSphere = CollisionSphere(0, 0, 0.5, 1)
        golemHitColNP = self.golem.attachNewNode(CollisionNode('golemHitField'))
        golemHitColNP.node().addSolid(golemHitSphere)

        # a collision segment to check attacks
        self.attackCheckSegment = CollisionSegment(0, 0, 1, 0, -1.3, 1)
        self.golemAttackRay = self.golem.attachNewNode(CollisionNode("golemAttackCollision"))
        self.golemAttackRay.node().addSolid(self.attackCheckSegment)
        self.golemAttackRay.node().setIntoCollideMask(0)
        self.attackqueue = CollisionHandlerQueue()
        base.cTrav.addCollider(self.golemAttackRay, self.attackqueue)

        attackAnim = self.golem.actorInterval("Attack", playRate = 2)
        self.AttackSeq = Parallel(
            attackAnim,
            Sequence(
                Wait(0.5),
                Func(self.ceckAttack)
            ))

        self.lookatFloater = NodePath(PandaNode("golemTracker"))
        self.lookatFloater.setPos(self.golem, 0, 0, 3.4)
        self.lookatFloater.hide()
        self.lookatFloater.reparentTo(render)
        self.trackerObject = loader.loadModel("misc/Pointlight")
        self.trackerObject.setColor(0, 1, 0)
        self.trackerObject.setScale(0.25)
        self.trackerObject.reparentTo(self.lookatFloater)

    def start(self, startPos):
        self.golem.setPos(startPos.getPos())
        self.golem.setHpr(startPos.getHpr())
        self.golem.reparentTo(render)
        self.trackedEnemy = None
        self.health = 5
        self.accept("playerCollision-in-golemViewField",
                    lambda extraArgs: base.messenger.send("golemSeesPlayer", [self.golem]))

    def stop(self):
        self.trackedEnemy = None
        taskMgr.remove("GolemAI_task")
        self.golem.hide()
        self.ignoreAll()

    def cleanup(self):
        self.stop()
        self.lookatFloater.removeNode()
        self.golem.cleanup()
        self.golem.removeNode()

    def activate(self, trackedEnemy):
        self.trackedEnemy = trackedEnemy
        taskMgr.add(self.aiTask, "GolemAI_task")
        self.lookatFloater.show()

    def aiTask(self, task):
        dt = globalClock.getDt()
        if self.AttackSeq.isPlaying(): return task.cont

        self.lookatFloater.setPos(self.golem, 0, 0, 3.4)
        self.lookatFloater.lookAt(self.trackedEnemy)
        self.lookatFloater.setH(self.lookatFloater.getH() + 180)
        self.lookatFloater.setP(0)
        self.lookatFloater.setR(0)

        self.golem.lookAt(self.trackedEnemy)
        self.golem.setH(self.golem.getH() + 180)

        distanceVec = self.golem.getPos() - self.trackedEnemy.getPos()
        enemyDist = distanceVec.length()

        if enemyDist < 2.0:
            # close enough for combat
            action = random.choice(["Attack", "Idle"])
            if action == "Attack":
                self.request("Attack")
            else:
                if self.state != "Idle":
                    self.request("Idle")
        else:
            self.golem.setY(self.golem, -0.5 * dt)
            if self.state != "Walk":
                self.request("Walk")

        return task.cont

    def hit(self):
        hitInterval = Sequence(
            Func(self.golem.setColorScale, 1, 0, 0, 0.75),
            Wait(0.15),
            Func(self.golem.clearColorScale),
            Wait(0.15),
            Func(self.golem.setColorScale, 1, 0, 0, 0.75),
            Wait(0.15),
            Func(self.golem.clearColorScale),
            Wait(0.15),
            Func(self.golem.setColorScale, 1, 0, 0, 0.75),
            Wait(0.15),
            Func(self.golem.clearColorScale),
            Wait(0.15),
            Func(self.golem.setColorScale, 1, 0, 0, 0.75),
            Wait(0.15),
            Func(self.golem.clearColorScale),
            Wait(0.15))
        self.health -= 1
        if self.health == 4:
            self.trackerObject.setColor(0, 1, 0)
            hitInterval.start()
        elif self.health == 3:
            self.trackerObject.setColor(0.25, 0.75, 0)
            hitInterval.start()
        elif self.health == 2:
            self.trackerObject.setColor(0.5, .5, 0)
            hitInterval.start()
        elif self.health == 1:
            self.trackerObject.setColor(0.75, 0.25, 0)
            hitInterval.start()
        elif self.health == 0:
            self.trackerObject.setColor(0, 0, 0)
            self.request("Destroyed")

    def ceckAttack(self):
        for i in range(self.attackqueue.getNumEntries()):
            entry = self.attackqueue.getEntry(i)
            into = entry.getIntoNode()
            if "playerCollision" in into.getName():
                if random.random() > .5:
                    base.messenger.send("HitPlayer")

    def enterIdle(self):
        self.golem.loop("Idle")

    def enterWalk(self):
        self.golem.setPlayRate(2, "Walk")
        self.golem.loop("Walk")

    def enterAttack(self):
        self.AttackSeq.start()

    def enterDestroyed(self):
        self.ignoreAll()
        taskMgr.remove("GolemAI_task")
        self.AttackSeq.finish()
        self.golem.play("Destroyed")
        self.lookatFloater.hide()
        base.messenger.send("GolemDestroyed")
class DistributedDodgeballGame(DistributedToonFPSGame, TeamMinigame):
    """The winter dodgeball minigame (client side)"""

    notify = directNotify.newCategory("DistributedDodgeballGame")

    TreeData = [['prop_snow_tree_small_ur',
                 Point3(23.23, 66.52, 7.46)],
                ['prop_snow_tree_small_ul',
                 Point3(-34.03, 88.02, 24.17)],
                ['prop_snow_tree_small_ur',
                 Point3(-54.80, 0, 4.19)],
                ['prop_snow_tree_small_ul',
                 Point3(54.80, -5, 4.19)],
                ['prop_snow_tree_small_ur',
                 Point3(62.71, 62.66, 16.80)],
                ['prop_snow_tree_small_ul',
                 Point3(-23.23, -66.52, 6)],
                ['prop_snow_tree_small_ur',
                 Point3(34.03, -88.02, 23)],
                ['prop_snow_tree_small_ul',
                 Point3(-62.71, -62.66, 16)]]

    SnowballData = [
        Point3(30, 0, 0.75),
        Point3(22.5, 0, 0.75),
        Point3(15, 0, 0.75),
        Point3(7.5, 0, 0.75),
        Point3(0, 0, 0.75),
        Point3(-7.5, 0, 0.75),
        Point3(-15, 0, 0.75),
        Point3(-22.5, 0, 0.75),
        Point3(-30, 0, 0.75)
    ]

    GameSong = "phase_4/audio/bgm/MG_Dodgeball.ogg"
    GameDesc = (
        "Welcome to the north! You have been invited to play dodgeball with the penguins!\n\n"
        "How To Play\nWASD to Move and use the mouse to aim.\nLeft click to Throw!\nThrow a "
        "snowball at a teammate to unfreeze them!\n\nThe team with the most points after {0} rounds wins!"
        .format(MaxRounds))

    InitCamTrans = [Point3(25, 45, 19.5317), Vec3(154.001, -15, 0)]

    SnowBallDmg = 25

    GetSnowBalls = "Pick up a snowball from the center!"

    Team2OtherBarrier = {BLUE: "red_barrier_coll", RED: "blue_barrier_coll"}

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

        DistributedToonFPSGame.__init__(self, cr)

        TeamMinigame.__init__(
            self, "BlueSnow", ('phase_4/maps/db_blue_neutral.png',
                               'phase_4/maps/db_blue_hover.png',
                               'phase_4/maps/db_blue_hover.png'), "RedIce",
            ('phase_4/maps/db_red_neutral.png',
             'phase_4/maps/db_red_hover.png', 'phase_4/maps/db_red_hover.png'))

        self.fsm.addState(
            State('chooseTeam', self.enterChooseTeam, self.exitChooseTeam,
                  ['waitForOthers']))
        self.fsm.addState(
            State('scrollBy', self.enterScrollBy, self.exitScrollBy,
                  ['countdown']))
        self.fsm.addState(
            State('countdown', self.enterCountdown, self.exitCountdown,
                  ['play']))
        self.fsm.addState(
            State('announceGameOver', self.enterAnnGameOver,
                  self.exitAnnGameOver, ['displayWinners', 'countdown']))
        self.fsm.addState(
            State('displayWinners', self.enterDisplayWinners,
                  self.exitDisplayWinners, ['gameOver']))
        self.fsm.getStateNamed('waitForOthers').addTransition('chooseTeam')
        self.fsm.getStateNamed('waitForOthers').addTransition('scrollBy')
        self.fsm.getStateNamed('play').addTransition('announceGameOver')

        self.firstPerson = DodgeballFirstPerson(self)

        self.scrollBySeq = None
        self.infoText = None

        self.redScoreLbl = None
        self.blueScoreLbl = None

        self.barrierIsStashed = False

        self.mySpawnPoint = 0

        self.infoText = getAlertText()

        self.spawnPointsByTeam = {
            BLUE: [[Point3(5, 15, 0), Vec3(180, 0, 0)],
                   [Point3(15, 15, 0), Vec3(180, 0, 0)],
                   [Point3(-5, 15, 0), Vec3(180, 0, 0)],
                   [Point3(-15, 15, 0), Vec3(180, 0, 0)]],
            RED: [[Point3(5, -15, 0), Vec3(0, 0, 0)],
                  [Point3(15, -15, 0), Vec3(0, 0, 0)],
                  [Point3(-5, -15, 0), Vec3(0, 0, 0)],
                  [Point3(-15, -15, 0), Vec3(0, 0, 0)]]
        }

        self.winnerMusic = base.loadMusic(
            'phase_9/audio/bgm/encntr_hall_of_fame.ogg')
        self.loserMusic = base.loadMusic(
            'phase_9/audio/bgm/encntr_sting_announce.ogg')
        self.danceSound = base.loadSfx('phase_3.5/audio/sfx/ENC_Win.ogg')

        # Environment vars
        self.arena = None
        self.olc = None
        self.trees = []
        self.snowballs = []

    def snowballPickupResp(self, flag, idx):
        self.firstPerson.snowballPickupResp(flag, idx)

    def roundOver(self, time=0):
        teams = [BLUE, RED]
        teams.sort(key=lambda team: self.scoreByTeam[team], reverse=True)
        self.winnerTeam = teams[0]
        base.localAvatar.disableAvatarControls()
        self.firstPerson.end()
        self.deleteTimer()
        self.fsm.request('announceGameOver', [time])

    def getTeamDNAColor(self, team):
        if team == TEAM1:
            return ToonDNA.colorDNA2color['18']
        elif team == TEAM2:
            return ToonDNA.colorDNA2color['02']

    def enterDisplayWinners(self):
        base.localAvatar.stopLookAround()
        base.localAvatar.resetHeadHpr()
        base.localAvatar.getGeomNode().show()
        camera.reparentTo(render)
        camera.setPos((-2.5, 12, 3.5))
        camera.setHpr((-175.074, -5.47218, 0))

        base.transitions.fadeIn()

        base.playSfx(self.danceSound, looping=1)

        if self.winnerTeam == self.team:
            base.playMusic(self.winnerMusic)
        else:
            base.playMusic(self.loserMusic)

        winnerPositions = [(-2, 0, 0), (2, 0, 0), (6, 0, 0), (-6, 0, 0)]
        loserPositions = [(-3.5, -10, 0), (-1.5, -15, 0), (3.0, -8, 0),
                          (5.5, -12, 0)]
        for team in [RED, BLUE]:
            for avId in self.playerListByTeam[team]:
                av = self.cr.doId2do.get(avId)
                if av:
                    av.stopSmooth()
                    av.setHpr(0, 0, 0)
                    if team == self.winnerTeam:
                        posList = winnerPositions
                        av.setAnimState("off")
                        av.stop()
                        if not self.getRemoteAvatar(avId).isFrozen:
                            av.loop("win")
                    else:
                        posList = loserPositions
                        av.setAnimState('off')
                        av.stop()
                        if not self.getRemoteAvatar(avId).isFrozen:
                            av.loop("pout")
                    pos = random.choice(posList)
                    posList.remove(pos)
                    av.setPos(pos)

        if self.winnerTeam == self.team:
            text = "YOU WIN!"
        else:
            text = "YOU LOSE!"
        self.gameOverLbl.setText(text)

        self.track = Sequence(Wait(2.0), Func(self.gameOverLbl.setScale, 0.01),
                              Func(self.gameOverLbl.show),
                              getAlertPulse(self.gameOverLbl, 0.27, 0.25))
        self.track.start()

        base.localAvatar.collisionsOff()

    def exitDisplayWinners(self):
        base.localAvatar.collisionsOn()
        base.transitions.noTransitions()
        self.danceSound.stop()
        if hasattr(self, 'track'):
            self.track.finish()
            self.track = None
        self.gameOverLbl.hide()

    def __prepareForNextRound(self):
        for av in self.remoteAvatars:
            av.unFreeze()
        pos, hpr = self.spawnPointsByTeam[self.team][self.mySpawnPoint]
        base.localAvatar.setPos(pos)
        base.localAvatar.setHpr(hpr)
        self.playMinigameMusic()
        self.fsm.request('countdown')

    def enterAnnGameOver(self, timeRanOut=0):
        self.firstPerson.vModel.hide()

        text = getGameText()
        text.setBin('gui-popup', 60)

        ival = Sequence()

        if timeRanOut:
            ival.append(Func(text.setText, "Time's Up!"))
            ival.append(getRoundIval(text))

        ival.append(
            Func(text.setText, "Round {0} Over!".format(self.getRound())))
        ival.append(getRoundIval(text))

        team = "Red"
        if self.winnerTeam == BLUE:
            team = "Blue"

        if self.round != MaxRounds:
            if self.scoreByTeam[RED] == self.scoreByTeam[BLUE]:
                ival.append(Func(text.setText, "The scores are tied!"))
            else:
                ival.append(
                    Func(text.setText, "{0} is in the lead!".format(team)))
        else:
            ival.append(Func(text.setText, "{0} wins!".format(team)))

        ival.append(getRoundIval(text))
        ival.setDoneEvent(self.uniqueName('annGameOverDone'))
        self.acceptOnce(ival.getDoneEvent(), self.__annGameOverTask)
        self.ival = ival
        self.ival.start()
        self.text = text

        base.transitions.fadeScreen()

    def __annGameOverTask(self):
        if self.round == MaxRounds:
            nextState = Func(self.fsm.request, "displayWinners")
        else:
            nextState = Func(self.__prepareForNextRound)

        self.ival = Sequence(base.transitions.getFadeOutIval(), nextState)
        self.ival.start()

    def exitAnnGameOver(self):
        if hasattr(self, 'ival'):
            self.ignore(self.ival.getDoneEvent())
            self.ival.finish()
            del self.ival
        if hasattr(self, 'text'):
            self.text.destroy()
            del self.text

    def teamWon(self, team, time=0):
        TeamMinigame.teamWon(self, team, time)
        base.localAvatar.disableAvatarControls()
        self.firstPerson.end()
        self.deleteTimer()
        self.fsm.request('announceGameOver', [time])

    def incrementTeamScore(self, team):
        TeamMinigame.incrementTeamScore(self, team)
        if team == BLUE:
            self.blueScoreLbl.setText("BLUE: " + str(self.scoreByTeam[team]))
            ToontownIntervals.start(
                ToontownIntervals.getPulseLargerIval(self.blueScoreLbl,
                                                     'blueScorePulse'))
        elif team == RED:
            self.redScoreLbl.setText("RED: " + str(self.scoreByTeam[team]))
            ToontownIntervals.start(
                ToontownIntervals.getPulseLargerIval(self.redScoreLbl,
                                                     'redScorePulse'))

    def getWinterDodgeballScoreText(self, color):
        text = OnscreenText(fg=color,
                            font=CIGlobals.getMinnieFont(),
                            scale=0.15,
                            shadow=(0, 0, 0, 1))
        return text

    def snowballHitWall(self, snowballIndex):
        snowball = self.snowballs[snowballIndex]
        snowball.handleHitWallOrPlayer()
        base.playSfx(snowball.impactSound, node=snowball, volume=1.5)

    def snowballHitGround(self, snowballIndex):
        snowball = self.snowballs[snowballIndex]
        snowball.handleHitGround()
        base.playSfx(snowball.impactSound, node=snowball, volume=1.5)

    def snowballHitPlayer(self, damagedPlayer, throwerTeam, snowballIndex):
        av = self.getRemoteAvatar(damagedPlayer)
        if av:
            if throwerTeam == av.team:
                # Someone on my team hit me. Unfreeze me if I am frozen.
                if av.unFreeze():
                    if damagedPlayer == base.localAvatar.doId:
                        self.showAlert("A team member has unfroze you!")
                        self.firstPerson.camFSM.request('unfrozen')
                        self.sendUpdate('teamMateUnfrozeMe', [self.team])
            else:
                # An enemy hit me. Become frozen if I am not already.
                if av.freeze():
                    if damagedPlayer == base.localAvatar.doId:
                        self.showAlert("You've been frozen by an enemy!")
                        self.firstPerson.camFSM.request('frozen')
                        self.sendUpdate('enemyFrozeMe',
                                        [self.team, throwerTeam])

        snowball = self.snowballs[snowballIndex]
        snowball.handleHitWallOrPlayer()
        base.playSfx(snowball.impactSound, node=snowball, volume=1.5)

    def playerCaughtSnowball(self, snowballIndex, catcherId):
        av = self.getRemoteAvatar(catcherId)
        if av:
            snowball = self.snowballs[snowballIndex]
            snowball.pauseThrowIval()
            snowball.pickup(av)

    def setupRemoteAvatar(self, avId):
        av = RemoteDodgeballAvatar(self, self.cr, avId)
        if avId == self.cr.localAvId:
            self.myRemoteAvatar = av
        self.remoteAvatars.append(av)

    def __getSnowTree(self, path):
        trees = loader.loadModel('phase_8/models/props/snow_trees.bam')
        tree = trees.find('**/' + path)
        tree.find('**/*shadow*').removeNode()
        return tree

    def load(self):
        self.setMinigameMusic(DistributedDodgeballGame.GameSong)
        self.setDescription(DistributedDodgeballGame.GameDesc)
        self.setWinnerPrize(200)
        self.setLoserPrize(0)
        self.createWorld()

        self.blueScoreLbl = self.getWinterDodgeballScoreText(VBase4(
            0, 0, 1, 1))
        self.blueScoreLbl.reparentTo(base.a2dTopLeft)
        self.blueScoreLbl['align'] = TextNode.ALeft
        self.blueScoreLbl.setText('Blue: 0')
        self.blueScoreLbl.setZ(-0.17)
        self.blueScoreLbl.setX(0.05)
        self.blueScoreLbl.hide()

        self.redScoreLbl = self.getWinterDodgeballScoreText(VBase4(1, 0, 0, 1))
        self.redScoreLbl.reparentTo(base.a2dTopLeft)
        self.redScoreLbl['align'] = TextNode.ALeft
        self.redScoreLbl.setText('Red: 0')
        self.redScoreLbl.setZ(-0.35)
        self.redScoreLbl.setX(0.05)
        self.redScoreLbl.hide()

        trans = DistributedDodgeballGame.InitCamTrans
        camera.setPos(trans[0])
        camera.setHpr(trans[1])

        DistributedToonFPSGame.load(self)

    def createWorld(self):
        self.deleteWorld()

        self.arena = loader.loadModel(
            "phase_4/models/minigames/dodgeball_arena.egg")
        self.arena.reparentTo(render)
        self.arena.setScale(0.75)
        self.arena.find('**/team_divider').setBin('ground', 18)
        self.arena.find('**/floor').setBin('ground', 18)
        self.arena.find('**/team_divider_coll').setCollideMask(
            CIGlobals.FloorBitmask)

        for data in DistributedDodgeballGame.TreeData:
            code = data[0]
            pos = data[1]
            tree = self.__getSnowTree(code)
            tree.reparentTo(self.arena)
            tree.setPos(pos)
            self.trees.append(tree)

        for i in xrange(len(DistributedDodgeballGame.SnowballData)):
            snowdata = DistributedDodgeballGame.SnowballData[i]
            snowball = Snowball(self, i)
            snowball.load()
            snowball.reparentTo(render)
            snowball.setPos(snowdata)
            self.snowballs.append(snowball)

        self.olc = ZoneUtil.getOutdoorLightingConfig(ZoneUtil.TheBrrrgh)
        self.olc.setupAndApply()

    def throw(self, snowballIndex, p):
        snowball = self.snowballs[snowballIndex]
        snowball.throw(p)

    def snowballPickup(self, snowballIndex, pickerUpperAvId):
        remoteAv = self.getRemoteAvatar(pickerUpperAvId)
        if remoteAv:
            snowball = self.snowballs[snowballIndex]
            snowball.pickup(remoteAv)

    def deleteWorld(self):
        if self.redScoreLbl:
            self.redScoreLbl.destroy()
            self.redScoreLbl = None
        if self.blueScoreLbl:
            self.blueScoreLbl.destroy()
            self.blueScoreLbl = None
        for snowball in self.snowballs:
            snowball.removeNode()
        self.snowballs = []
        for tree in self.trees:
            tree.removeNode()
        self.trees = []
        if self.olc:
            self.olc.cleanup()
            self.olc = None
        if self.arena:
            self.arena.removeNode()
            self.arena = None
        render.clearFog()

    def enterPlay(self):
        self.createTimer()
        self.redScoreLbl.show()
        self.blueScoreLbl.show()
        self.firstPerson.camFSM.request('unfrozen')

        # Stash the other team's barrier.
        if not self.barrierIsStashed:
            self.arena.find('**/' + self.Team2OtherBarrier[self.team]).stash()
            self.barrierIsStashed = True

    def exitPlay(self):
        self.firstPerson.crosshair.destroy()
        self.firstPerson.crosshair = None
        self.firstPerson.camFSM.request('off')
        DistributedToonFPSGame.exitPlay(self)

    def enterCountdown(self):
        base.transitions.noTransitions()
        self.firstPerson.start()
        self.firstPerson.disableMouse()

        self.setRound(self.getRound() + 1)

        self.infoText.setText(DistributedDodgeballGame.GetSnowBalls)

        self.countdownText = getGameText()
        self.countdownIval = Parallel(Sequence(
            Func(self.countdownText.setText,
                 "Round {0}".format(self.getRound())),
            getRoundIval(self.countdownText),
            Func(self.countdownText.setText, "5"),
            getCountdownIval(self.countdownText),
            Func(self.countdownText.setText, "4"),
            getCountdownIval(self.countdownText),
            Func(self.countdownText.setText, "3"),
            getCountdownIval(self.countdownText),
            Func(self.countdownText.setText, "2"),
            getCountdownIval(self.countdownText),
            Func(self.countdownText.setText, "1"),
            getCountdownIval(self.countdownText)),
                                      getAlertPulse(self.infoText),
                                      name="COUNTDOWNIVAL")
        self.countdownIval.setDoneEvent(self.countdownIval.getName())
        self.acceptOnce(self.countdownIval.getDoneEvent(),
                        self.__handleCountdownDone)
        self.countdownIval.start()

    def __handleCountdownDone(self):
        self.fsm.request('play')

    def exitCountdown(self):
        if hasattr(self, 'countdownIval'):
            self.ignore(self.countdownIval.getDoneEvent())
            self.countdownIval.finish()
            del self.countdownIval
        if hasattr(self, 'countdownText'):
            self.countdownText.destroy()
            del self.countdownText

    def enterScrollBy(self):
        BLUE_START_POS = Point3(-20, 0, 4)
        BLUE_END_POS = Point3(20, 0, 4)
        BLUE_HPR = Vec3(0, 0, 0)

        RED_START_POS = Point3(20, 0, 4)
        RED_END_POS = Point3(-20, 0, 4)
        RED_HPR = Vec3(180, 0, 0)

        self.playMinigameMusic()

        self.scrollBySeq = Sequence(Func(camera.setHpr, BLUE_HPR),
                                    LerpPosInterval(camera,
                                                    duration=5.0,
                                                    pos=BLUE_END_POS,
                                                    startPos=BLUE_START_POS,
                                                    blendType='easeOut'),
                                    Func(base.transitions.fadeOut, 0.4),
                                    Wait(0.5),
                                    Func(base.transitions.fadeIn, 0.4),
                                    Func(camera.setHpr, RED_HPR),
                                    LerpPosInterval(camera,
                                                    duration=5.0,
                                                    pos=RED_END_POS,
                                                    startPos=RED_START_POS,
                                                    blendType='easeOut'),
                                    name="SCROLLBYSEQ")
        self.scrollBySeq.setDoneEvent(self.scrollBySeq.getName())
        self.acceptOnce(self.scrollBySeq.getDoneEvent(),
                        self.__handleScrollByDone)
        self.scrollBySeq.start()

    def __handleScrollByDone(self):
        self.fsm.request('countdown')

    def exitScrollBy(self):
        if self.scrollBySeq:
            self.ignore(self.scrollBySeq.getDoneEvent())
            self.scrollBySeq.finish()
            self.scrollBySeq = None

    def allPlayersReady(self):
        self.fsm.request('scrollBy')

    def chooseUrTeam(self):
        # The AI has told us it's time to choose our team.
        self.fsm.request('chooseTeam')

    def enterChooseTeam(self):
        self.makeSelectionGUI()

    def acceptedIntoTeam(self, spawnPoint):
        TeamMinigame.acceptedIntoTeam(self)

        self.sendUpdate('readyToStart')
        self.fsm.request('waitForOthers')

        self.mySpawnPoint = spawnPoint

        pos, hpr = self.spawnPointsByTeam[self.team][spawnPoint]
        base.localAvatar.setPos(pos)
        base.localAvatar.setHpr(hpr)

    def exitChooseTeam(self):
        self.destroySelectionGUI()

    def announceGenerate(self):
        DistributedToonFPSGame.announceGenerate(self)
        base.camLens.setMinFov(CIGlobals.GunGameFOV / (4. / 3.))
        self.load()

    def disable(self):
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4. / 3.))
        self.fsm.requestFinalState()
        self.deleteWorld()
        self.trees = None
        self.snowballs = None
        self.spawnPointsByTeam = None
        if self.firstPerson:
            self.firstPerson.reallyEnd()
            self.firstPerson.cleanup()
            self.firstPerson = None
        self.scrollBySeq = None
        self.winnerMusic = None
        self.loserMusic = None
        self.danceSound = None
        self.infoText = None
        base.localAvatar.setWalkSpeedNormal()
        DistributedToonFPSGame.disable(self)
コード例 #46
0
ファイル: LightDropGag.py プロジェクト: coginvasion/src
class LightDropGag(DropGag):
    def __init__(self, name, model, anim, damage, hitSfx, missSfx, rotate90=False, sphereSize=2, sphereZ=0):
        DropGag.__init__(self, name, model, anim, damage, hitSfx, missSfx, scale=1, playRate=1)
        DropGag.setShadowData(self, isCircle=True, shadowScale=0.5)
        self.stunTime = 1.5
        self.objTrack = None
        self.rotate90 = rotate90
        self.sphereSize = sphereSize
        self.sphereZ = sphereZ
        return

    def startDrop(self):
        if self.gag and self.dropLoc:
            x, y, z = self.dropLoc
            startPos = Point3(x, y, z + 20)
            self.gag.setPos(x, y + 2, z)
            self.gag.node().setBounds(OmniBoundingVolume())
            self.gag.node().setFinal(1)
            self.gag.headsUp(self.avatar)
            if self.rotate90:
                self.gag.setH(self.gag.getH() - 90)
            self.buildCollisions()
            objectTrack = Sequence()
            animProp = LerpPosInterval(self.gag, self.fallDuration, self.dropLoc, startPos=startPos)
            bounceProp = Effects.createZBounce(self.gag, 2, self.dropLoc, 0.5, 1.5)
            objAnimShrink = Sequence(Wait(0.5), Func(self.gag.reparentTo, render), animProp, bounceProp)
            objectTrack.append(objAnimShrink)
            dropShadow = loader.loadModel("phase_3/models/props/drop_shadow.bam")
            dropShadow.reparentTo(render)
            dropShadow.setPos(self.dropLoc)
            dropShadow.setScale(self.getShadowScale())
            shadowTrack = Sequence(
                LerpScaleInterval(
                    dropShadow, self.fallDuration + 0.1, dropShadow.getScale(), startScale=Point3(0.01, 0.01, 0.01)
                ),
                Wait(0.3),
                Func(dropShadow.removeNode),
            )
            self.objTrack = Parallel(
                Sequence(Wait(self.fallDuration), Func(self.completeDrop)), objectTrack, shadowTrack
            )
            self.objTrack.start()
            self.dropLoc = None
        return

    def onActivate(self, ignore, suit):
        self.objTrack.finish()
        self.objTrack = None
        if not suit.isDead():
            suit.setAnimState("drop-react")
        suit.d_disableMovement(wantRay=True)
        self.gag.setPos(suit.find("**/joint_head").getPos(render))
        if self.name == CIGlobals.FlowerPot:
            self.gag.setZ(self.gag, 3)
        bounce = Effects.createScaleZBounce(self.gag, 1, self.gag.getScale(render), 0.3, 0.75)
        dummyNode = suit.attachNewNode("fallOffNode")
        dummyNode.setX(2)
        dummyNode.setY(-2)
        flightIval = FlightProjectileInterval(
            self.gag, startPos=self.gag.getPos(render), endPos=dummyNode.getPos(render), duration=0.8, gravityMult=0.35
        )
        Sequence(Parallel(bounce, flightIval), Wait(self.stunTime), Func(suit.d_enableMovement)).start()
        dummyNode.removeNode()
        del dummyNode
        return

    def buildCollisions(self):
        gagSph = CollisionSphere(0, 0, self.sphereZ, self.sphereSize)
        gagSensor = CollisionNode("gagSensor")
        gagSensor.addSolid(gagSph)
        sensorNP = self.gag.attachNewNode(gagSensor)
        sensorNP.setCollideMask(BitMask32(0))
        sensorNP.node().setFromCollideMask(CIGlobals.WallBitmask | CIGlobals.FloorBitmask)
        event = CollisionHandlerEvent()
        event.set_in_pattern("%fn-into")
        event.set_out_pattern("%fn-out")
        base.cTrav.addCollider(sensorNP, event)
        self.avatar.acceptOnce("gagSensor-into", self.onCollision)