def walk(self, speed=0.2):
     self.currentPathIndex += 1
     if len(self.pathQueue) <= self.currentPathIndex:
         if self.getCurrentOrNextState() == 'Pursue':
             if self.getClosestPoint() != self.currentKey:
                 # Wow, the player ran off somewhere else! Go there!
                 if self.numTries >= self.maxTries:
                     # Dang it, give up, we can't get to them!
                     self.request('GoBackToGuardSpot')
                 else:
                     self.runToClosestPoint()
         elif self.getCurrentOrNextState() == 'GoBackToGuardSpot':
             self.request('Guard')
         return
     print self.pathQueue[self.currentPathIndex]
     if self.currentPathIndex == 1 and self.pathQueue[0] == 1:
         # We need to walk from our guard point to the first waypoint in our path
         startPoint = self.getPos(render)
         endPoint = CGG.FactoryWalkPoints[self.firstPoint]
     else:
         if self.pathQueue[0] == 0:
             self.pathQueue.remove(self.pathQueue[0])
         key = self.pathQueue[self.currentPathIndex]
         endPoint = CGG.FactoryWalkPoints[key]
         oldKey = self.pathQueue[self.currentPathIndex - 1]
         startPoint = CGG.FactoryWalkPoints[oldKey]
     self.walkTrack = NPCWalkInterval(self, endPoint, speed, startPoint)
     self.walkTrack.setDoneEvent(self.uniqueName('guardWalkDone'))
     self.acceptOnce(self.uniqueName('guardWalkDone'), self.walk)
     self.walkTrack.start()
 def createPath(self, fromCurPos=False):
     durationFactor = 0.2
     if not hasattr(self, 'currentPath'):
         self.currentPath = None
     if self.currentPath == None:
         path = random.choice(TutorialGlobals.SUIT_POINTS)
         self.currentPath = TutorialGlobals.SUIT_POINTS.index(path)
         startIndex = -1
     else:
         if fromCurPos == False:
             startIndex = int(self.currentPath)
         else:
             startIndex = -1
         self.currentPath += 1
         if self.currentPath >= len(TutorialGlobals.SUIT_POINTS):
             self.currentPath = 0
         path = TutorialGlobals.SUIT_POINTS[self.currentPath]
     endIndex = self.currentPath
     startPos = self.getPos(render)
     pathName = self.uniqueName('suitPath')
     self.walkTrack = NPCWalkInterval(self,
                                      path,
                                      startPos=startPos,
                                      name=pathName,
                                      durationFactor=durationFactor,
                                      fluid=1)
     self.walkTrack.setDoneEvent(self.walkTrack.getName())
     self.acceptOnce(self.walkTrack.getDoneEvent(), self.createPath)
     self.walkTrack.start()
     self.b_setAnimState('walk')
     self.b_setSuitState(1, startIndex, endIndex)
Example #3
0
 def walk(self, speed=0.2):
     self.currentPathIndex += 1
     if len(self.pathQueue) <= self.currentPathIndex:
         if self.getCurrentOrNextState() == 'Pursue':
             if self.getClosestPoint() != self.currentKey:
                 if self.numTries >= self.maxTries:
                     self.request('GoBackToGuardSpot')
                 else:
                     self.runToClosestPoint()
         else:
             if self.getCurrentOrNextState() == 'GoBackToGuardSpot':
                 self.request('Guard')
         return
     print self.pathQueue[self.currentPathIndex]
     if self.currentPathIndex == 1 and self.pathQueue[0] == 1:
         startPoint = self.getPos(render)
         endPoint = CGG.FactoryWalkPoints[self.firstPoint]
     else:
         if self.pathQueue[0] == 0:
             self.pathQueue.remove(self.pathQueue[0])
         key = self.pathQueue[self.currentPathIndex]
         endPoint = CGG.FactoryWalkPoints[key]
         oldKey = self.pathQueue[self.currentPathIndex - 1]
         startPoint = CGG.FactoryWalkPoints[oldKey]
     self.walkTrack = NPCWalkInterval(self, endPoint, speed, startPoint)
     self.walkTrack.setDoneEvent(self.uniqueName('guardWalkDone'))
     self.acceptOnce(self.uniqueName('guardWalkDone'), self.walk)
     self.walkTrack.start()
Example #4
0
 def createPath(self, path_key=None, durationFactor=0.2, fromCurPos=False):
     if path_key == None and not len(self.currentPathQueue):
         path_key_list = CIGlobals.SuitPathData[self.hood][self.currentPath]
         path_key = random.choice(path_key_list)
     elif len(self.currentPathQueue):
         path_key = self.currentPathQueue[0]
         self.currentPathQueue.remove(path_key)
     endIndex = CIGlobals.SuitSpawnPoints[self.hood].keys().index(path_key)
     path = CIGlobals.SuitSpawnPoints[self.hood][path_key]
     if self.walkTrack:
         self.ignore(self.walkTrack.getDoneEvent())
         self.walkTrack.clearToInitial()
         self.walkTrack = None
     if not self.currentPath or fromCurPos:
         startIndex = -1
     else:
         oldPath = self.currentPath
         startIndex = CIGlobals.SuitSpawnPoints[self.hood].keys().index(
             oldPath)
     self.currentPath = path_key
     pathName = self.uniqueName('suitPath')
     self.walkTrack = NPCWalkInterval(self,
                                      path,
                                      startPos=self.getPos(render),
                                      name=pathName,
                                      durationFactor=durationFactor,
                                      fluid=1)
     self.walkTrack.setDoneEvent(self.walkTrack.getName())
     self.startFollow()
     self.b_setSuitState(1, startIndex, endIndex)
 def createFlyPath(self):
     self.b_setAnimState('flyNeutral')
     if self.flyTrack:
         self.ignore(self.flyTrack.getDoneEvent())
         self.flyTrack.pause()
         self.flyTrack = None
     point = random.choice(EGG.EAGLE_FLY_POINTS)
     if self.currentFlyPoint == point:
         self.createFlyPath()
         return
     if self.currentFlyPoint == None:
         point_list = list(EGG.EAGLE_FLY_POINTS)
         point_list.remove(point)
         startIndex = point_list.index(random.choice(point_list))
     else:
         startIndex = -1
     self.b_setSuitState(5, startIndex, EGG.EAGLE_FLY_POINTS.index(point))
     mgRound = self.getMinigame().getRound()
     if mgRound:
         self.flyTrack = NPCWalkInterval(self, point,
             durationFactor = EGG.ROUND_2_EAGLE_SPEED[mgRound],
             startPos = self.getPos(render), fluid = 1, name = self.uniqueName('DEagleSuitAI-flyTrack'))
         self.flyTrack.setDoneEvent(self.flyTrack.getName())
         self.acceptOnce(self.flyTrack.getDoneEvent(), self.handleFlyDone)
         self.flyTrack.start()
         self.currentFlyPoint = point
     else: return
class WayPointTest:
    def __init__(self, point, number, wayPointsToTest):
        self.point = point
        self.number = number
        self.wayPointsToTest = wayPointsToTest
        del self.wayPointsToTest[number]
        self.finalList = []
        self.currentWayPointTestKey = None
        self.numberOfTests = -1
        self.movementIval = None
        self.allTestsDone = False
        print "Testing waypoint: " + str(number)
        self.testNextWayPoint()

    def allTestsCompleted(self):
        print "Done testing waypoint: " + str(self.number)
        self.allTestsDone = True

    def testNextWayPoint(self):
        self.numberOfTests += 1
        if self.movementIval:
            self.movementIval.pause()
            self.movementIval = None
        if self.numberOfTests > len(self.wayPointsToTest.keys()) - 1:
            self.allTestsCompleted()
            return
        print "Test number " + str(self.numberOfTests) + " on waypoint " + str(
            self.number)
        self.currentWayPointTestKey = self.wayPointsToTest.keys()[
            self.numberOfTests]
        self.movementIval = NPCWalkInterval(
            node,
            Point3(*self.wayPointsToTest[self.currentWayPointTestKey]['pos']),
            0.005,
            startPos=self.point,
            fluid=1)
        self.movementIval.setDoneEvent('testWayPointDone')
        base.acceptOnce(self.movementIval.getDoneEvent(),
                        self.currentTestSucceeded)
        base.acceptOnce("sensors-into", self.handleBadTest)
        self.movementIval.start()

    def handleBadTest(self, entry):
        print "Failed"
        base.ignore("sensors-into")
        base.ignore("sensors-out")
        base.ignore(self.movementIval.getDoneEvent())
        self.movementIval.pause()
        self.movementIval = None
        self.testNextWayPoint()

    def currentTestSucceeded(self):
        print "Passed"
        base.ignore("sensors-into")
        base.ignore("sensors-out")
        base.ignore(self.movementIval.getDoneEvent())
        self.finalList.append(self.currentWayPointTestKey)
        print self.finalList
        self.testNextWayPoint()
 def enterStationSlot(self, slot):
     self.cr.playGame.getPlace().fsm.request('station')
     camera.reparentTo(self)
     numSlots = len(self.circles)
     camera.setPos(self.numPlayers2CamPos[numSlots])
     camera.setPos(camera.getPos(render))
     camera.reparentTo(render)
     camera.lookAt(self)
     base.localAvatar.headsUp(slot)
     base.localAvatar.b_setAnimState('run')
     runTrack = NPCWalkInterval(base.localAvatar, slot.getPos(render), 0.1, startPos=base.localAvatar.getPos(render))
     runTrack.setDoneEvent('SlotEnterDone')
     runTrack.start()
     base.acceptOnce('SlotEnterDone', self.__handleSlotEntrance)
Example #8
0
 def enterWalking(self, startIndex, endIndex, ts=0.0):
     durationFactor = 0.2
     if startIndex > -1:
         startPos = TutorialGlobals.SUIT_POINTS[startIndex]
     else:
         startPos = self.getPos(render)
     endPos = TutorialGlobals.SUIT_POINTS[endIndex]
     self.stopMoving()
     self.moveIval = NPCWalkInterval(self,
                                     endPos,
                                     durationFactor,
                                     startPos,
                                     fluid=1)
     self.moveIval.start(ts)
     self.animFSM.request('walk')
    def enterWalking(self, pointLetter, startPointLetter, ts):

        if self.walkIval:
            self.walkIval.finish()
            self.walkIval = None

        self.nametag.clearChatText()

        self.loop('walk')

        point = WALK_POINTS[self.charId][pointLetter][0]
        lastPoint = WALK_POINTS[self.charId][startPointLetter][0]

        seq = Sequence(name=self.uniqueName('DCharWalkIval'))
        if self.charId == PLUTO:
            seq.append(ActorInterval(self, 'stand'))
        elif self.charId == SLEEP_DONALD:
            seq.append(ActorInterval(self, 'neutral2walk'))
        seq.append(Func(self.loop, 'walk'))
        ival = NPCWalkInterval(self, point, startPos=lastPoint, fluid=1)
        seq.append(ival)
        seq.append(Func(self.loop, 'neutral'))
        seq.start(ts)

        self.currentPointLetter = pointLetter

        self.walkIval = ival
Example #10
0
 def createPath(self, pathKey = None, durationFactor = 0.2, fromCurPos = False):
     currentPathQueue = self.suit.getCurrentPathQueue()
     currentPath = self.suit.getCurrentPath()
     if pathKey == None:
         pathKeyList = CIGlobals.SuitPathData[self.suit.getHood()][self.suit.getCurrentPath()]
         pathKey = random.choice(pathKeyList)
     elif len(currentPathQueue):
         pathKey = currentPathQueue[0]
         currentPathQueue.remove(pathKey)
     endIndex = CIGlobals.SuitSpawnPoints[self.suit.getHood()].keys().index(pathKey)
     path = CIGlobals.SuitSpawnPoints[self.suit.getHood()][pathKey]
     self.clearWalkTrack()
     if not currentPath or fromCurPos:
         startIndex = -1
     else:
         oldPath = currentPath
         startIndex = CIGlobals.SuitSpawnPoints[self.suit.getHood()].keys().index(oldPath)
     self.suit.currentPath = pathKey
     startPos = self.suit.getPos(render)
     pathName = self.suit.uniqueName('suitPath')
     self.walkTrack = NPCWalkInterval(self.suit, path, startPos=startPos, name=pathName, durationFactor=durationFactor, fluid=1)
     self.walkTrack.setDoneEvent(self.walkTrack.getName())
     self.startFollow()
     self.suit.b_setSuitState(1, startIndex, endIndex)
     return
Example #11
0
 def createFlyPath(self):
     self.b_setAnimState('flyNeutral')
     if self.flyTrack:
         self.ignore(self.flyTrack.getDoneEvent())
         self.flyTrack.pause()
         self.flyTrack = None
     point = random.choice(EGG.EAGLE_FLY_POINTS)
     if self.currentFlyPoint == point:
         self.createFlyPath()
         return
     else:
         if self.currentFlyPoint == None:
             point_list = list(EGG.EAGLE_FLY_POINTS)
             point_list.remove(point)
             startIndex = point_list.index(random.choice(point_list))
         else:
             startIndex = -1
         self.b_setSuitState(5, startIndex, EGG.EAGLE_FLY_POINTS.index(point))
         mgRound = self.getMinigame().getRound()
         if mgRound:
             self.flyTrack = NPCWalkInterval(self, point, durationFactor=EGG.ROUND_2_EAGLE_SPEED[mgRound], startPos=self.getPos(render), fluid=1, name=self.uniqueName('DEagleSuitAI-flyTrack'))
             self.flyTrack.setDoneEvent(self.flyTrack.getName())
             self.acceptOnce(self.flyTrack.getDoneEvent(), self.handleFlyDone)
             self.flyTrack.start()
             self.currentFlyPoint = point
         else:
             return
         return
 def createPath(self, fromCurPos = False):
     durationFactor = 0.2
     if not hasattr(self, 'currentPath'):
         self.currentPath = None
     if self.currentPath == None:
         path = random.choice(TutorialGlobals.SUIT_POINTS)
         self.currentPath = TutorialGlobals.SUIT_POINTS.index(path)
         startIndex = -1
     else:
         if fromCurPos == False:
             startIndex = int(self.currentPath)
         else:
             startIndex = -1
         self.currentPath += 1
         if self.currentPath >= len(TutorialGlobals.SUIT_POINTS):
             self.currentPath = 0
         path = TutorialGlobals.SUIT_POINTS[self.currentPath]
     endIndex = self.currentPath
     startPos = self.getPos(render)
     pathName = self.uniqueName('suitPath')
     self.walkTrack = NPCWalkInterval(self, path, startPos=startPos, name=pathName, durationFactor=durationFactor, fluid=1)
     self.walkTrack.setDoneEvent(self.walkTrack.getName())
     self.acceptOnce(self.walkTrack.getDoneEvent(), self.createPath)
     self.walkTrack.start()
     self.b_setAnimState('walk')
     self.b_setSuitState(1, startIndex, endIndex)
     return
 def walkBackToSpawnPointWithBarrel(self):
     pos = DGG.SpawnPoints[self.spawnPoint]
     startPos = self.getPos(render)
     self.b_setSuitState(1, -1, self.spawnPoint)
     durationFactor = 0.2
     pathName = self.uniqueName('WalkBackToSpawn')
     self.walkTrack = NPCWalkInterval(self,
                                      pos,
                                      startPos=startPos,
                                      name=pathName,
                                      durationFactor=durationFactor,
                                      fluid=1)
     self.walkTrack.setDoneEvent(self.walkTrack.getName())
     self.acceptOnce(self.walkTrack.getDoneEvent(), self.__walkedBack2Spawn)
     self.walkTrack.start()
     self.b_setAnimState(
         SuitGlobals.getAnimId(SuitGlobals.getAnimByName('tray-walk')))
 def enterFlyingDown(self, startIndex, endIndex, ts = 0.0):
     startPos = TutorialGlobals.SUIT_POINTS[startIndex] + (0, 0, 50)
     endPos = TutorialGlobals.SUIT_POINTS[endIndex]
     duration = 3
     self.moveIval = LerpPosInterval(self, duration=duration, pos=endPos, startPos=startPos, fluid=1)
     self.moveIval.start(ts)
     self.animFSM.request('flyDown', [ts])
     yaw = random.uniform(0.0, 360.0)
     self.setH(yaw)
 def walkToTruck(self):
     index = DGG.WalkToTruckIndex
     pos = DGG.TruckSuitPointsByIndex[self.truckIndex]
     startPos = self.getPos(render)
     self.b_setSuitState(1, -1, index)
     durationFactor = 0.2
     pathName = self.uniqueName('WalkToTruck')
     self.walkTrack = NPCWalkInterval(self,
                                      pos,
                                      startPos=startPos,
                                      name=pathName,
                                      durationFactor=durationFactor,
                                      fluid=1)
     self.walkTrack.setDoneEvent(self.walkTrack.getName())
     self.acceptOnce(self.walkTrack.getDoneEvent(), self.__walkedToTruck)
     self.walkTrack.start()
     self.b_setAnimState(
         SuitGlobals.getAnimId(SuitGlobals.getAnimByName('walk')))
 def throwGear(self, point):
     self.gearModel.reparentTo(self.getPart("body"))
     self.gearModel.setX(0.0)
     self.gearModel.setY(-2)
     self.gearModel.setZ(5)
     self.gearModel.setPos(self.gearModel.getPos(render))
     self.gearModel.reparentTo(render)
     self.gearModel.show()
     self.gearModel.lookAt(point)
     if self.gearThrowIval:
         self.gearThrowIval.finish()
         self.gearThrowIval = None
     self.gearThrowIval = NPCWalkInterval(self.gearModel,
                                          point,
                                          durationFactor=0.01,
                                          fluid=1,
                                          lookAtTarget=False)
     self.gearThrowIval.start()
 def startMoveInterval(self, startX, startY, startZ, endX, endY, endZ,
                       duration):
     self.stopMoving()
     endPos = Point3(endX, endY, endZ)
     self.moveIval = NPCWalkInterval(self,
                                     endPos,
                                     durationFactor=duration,
                                     fluid=1)
     self.moveIval.start()
 def enterFlyingDown(self, startIndex, endIndex, ts=0.0):
     startPos = DGG.SpawnPoints[startIndex] + (0, 0, 50)
     endPos = DGG.SpawnPoints[endIndex]
     duration = 3
     self.moveIval = LerpPosInterval(self, duration=duration, pos=endPos, startPos=startPos, fluid=1)
     self.moveIval.start(ts)
     self.animFSM.request("flyDown", [ts])
     yaw = random.uniform(0.0, 360.0)
     self.setH(yaw)
 def enterFlyingUp(self, startIndex, endIndex, ts=0.0):
     startPos = DGG.SpawnPoints[startIndex]
     endPos = DGG.SpawnPoints[endIndex] + (0, 0, 50)
     duration = 3
     self.moveIval = Sequence(
         Wait(1.7), LerpPosInterval(self, duration=duration, pos=endPos, startPos=startPos, fluid=1)
     )
     self.moveIval.start(ts)
     self.animFSM.request("flyAway", [ts])
    def enterWalking(self, startIndex, endIndex, ts=0.0):
        durationFactor = 0.2
        if startIndex > -1:
            startPos = DGG.SpawnPoints[startIndex]
        else:
            startPos = self.getPos(render)
        if endIndex == DGG.WalkToTruckIndex:
            endPos = DGG.TruckSuitPointsByIndex[self.truckIndex]
        else:
            endPos = DGG.SpawnPoints[endIndex]

        self.stopMoving()

        self.moveIval = NPCWalkInterval(self,
                                        endPos,
                                        durationFactor,
                                        startPos,
                                        fluid=1)
        self.moveIval.start(ts)
 def enterWalking(self, startIndex, endIndex, ts = 0.0):
     durationFactor = 0.2
     if startIndex > -1:
         startPos = TutorialGlobals.SUIT_POINTS[startIndex]
     else:
         startPos = self.getPos(render)
     endPos = TutorialGlobals.SUIT_POINTS[endIndex]
     self.stopMoving()
     self.moveIval = NPCWalkInterval(self, endPos, durationFactor, startPos, fluid=1)
     self.moveIval.start(ts)
     self.animFSM.request('walk')
Example #22
0
 def handleGotHit(self):
     self.b_setAnimState('flail')
     if self.flyTrack:
         self.ignore(self.flyTrack.getDoneEvent())
         self.flyTrack.pause()
         self.flyTrack = None
     self.sendUpdate('fallAndExplode', [])
     self.b_setSuitState(6, -1, -1)
     self.flyTrack = Sequence(LerpPosInterval(self, duration=4.0, pos=self.getPos(render) - (0, 0, 75), startPos=self.getPos(render), blendType='easeIn'), Wait(1.5), Func(self.killMe))
     self.flyTrack.start()
     return
 def walkBackToSpawnPointWithBarrel(self):
     pos = DGG.SpawnPoints[self.spawnPoint]
     startPos = self.getPos(render)
     self.b_setSuitState(1, -1, self.spawnPoint)
     durationFactor = 0.2
     pathName = self.uniqueName('WalkBackToSpawn')
     self.walkTrack = NPCWalkInterval(self, pos, startPos=startPos, name=pathName, durationFactor=durationFactor, fluid=1)
     self.walkTrack.setDoneEvent(self.walkTrack.getName())
     self.acceptOnce(self.walkTrack.getDoneEvent(), self.__walkedBack2Spawn)
     self.walkTrack.start()
     self.b_setAnimState(SuitGlobals.getAnimId(SuitGlobals.getAnimByName('tray-walk')))
 def walkToTruck(self):
     index = DGG.WalkToTruckIndex
     pos = DGG.TruckSuitPointsByIndex[self.truckIndex]
     startPos = self.getPos(render)
     self.b_setSuitState(1, -1, index)
     durationFactor = 0.2
     pathName = self.uniqueName('WalkToTruck')
     self.walkTrack = NPCWalkInterval(self, pos, startPos=startPos, name=pathName, durationFactor=durationFactor, fluid=1)
     self.walkTrack.setDoneEvent(self.walkTrack.getName())
     self.acceptOnce(self.walkTrack.getDoneEvent(), self.__walkedToTruck)
     self.walkTrack.start()
     self.b_setAnimState(SuitGlobals.getAnimId(SuitGlobals.getAnimByName('walk')))
class DistributedDeliveryGameSuit(DistributedSuit):
    notify = directNotify.newCategory('DistributedDeliveryGameSuit')

    def __init__(self, cr):
        DistributedSuit.__init__(self, cr)
        self.truckIndex = 0

    def setTruckIndex(self, index):
        self.truckIndex = index

    def getTruckIndex(self):
        return self.truckIndex

    def enterFlyingDown(self, startIndex, endIndex, ts=0.0):
        startPos = DGG.SpawnPoints[startIndex] + (0, 0, 50)
        endPos = DGG.SpawnPoints[endIndex]
        duration = 3
        self.moveIval = LerpPosInterval(self,
                                        duration=duration,
                                        pos=endPos,
                                        startPos=startPos,
                                        fluid=1)
        self.moveIval.start(ts)
        self.animFSM.request('flyDown', [ts])
        yaw = random.uniform(0.0, 360.0)
        self.setH(yaw)

    def enterFlyingUp(self, startIndex, endIndex, ts=0.0):
        startPos = DGG.SpawnPoints[startIndex]
        endPos = DGG.SpawnPoints[endIndex] + (0, 0, 50)
        duration = 3
        self.moveIval = Sequence(
            Wait(1.7),
            LerpPosInterval(self,
                            duration=duration,
                            pos=endPos,
                            startPos=startPos,
                            fluid=1))
        self.moveIval.start(ts)
        self.animFSM.request('flyAway', [ts])

    def enterWalking(self, startIndex, endIndex, ts=0.0):
        durationFactor = 0.2
        if startIndex > -1:
            startPos = DGG.SpawnPoints[startIndex]
        else:
            startPos = self.getPos(render)
        if endIndex == DGG.WalkToTruckIndex:
            endPos = DGG.TruckSuitPointsByIndex[self.truckIndex]
        else:
            endPos = DGG.SpawnPoints[endIndex]

        self.stopMoving()

        self.moveIval = NPCWalkInterval(self,
                                        endPos,
                                        durationFactor,
                                        startPos,
                                        fluid=1)
        self.moveIval.start(ts)
Example #26
0
class DistributedTutorialSuit(DistributedSuit):
    notify = directNotify.newCategory('DistributedTutorialSuit')

    def enterFlyingDown(self, startIndex, endIndex, ts=0.0):
        startPos = TutorialGlobals.SUIT_POINTS[startIndex] + (0, 0, 6.5 * 4.8)
        endPos = TutorialGlobals.SUIT_POINTS[endIndex]
        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
        self.moveIval = LerpPosInterval(self,
                                        duration=timeTillLanding,
                                        pos=endPos,
                                        startPos=startPos,
                                        fluid=1)
        self.moveIval.start(ts)
        self.animFSM.request('flyDown', [ts])
        yaw = random.uniform(0.0, 360.0)
        self.setH(yaw)

    def enterWalking(self, startIndex, endIndex, ts=0.0):
        durationFactor = 0.2
        if startIndex > -1:
            startPos = TutorialGlobals.SUIT_POINTS[startIndex]
        else:
            startPos = self.getPos(render)
        endPos = TutorialGlobals.SUIT_POINTS[endIndex]
        self.stopMoving()
        self.moveIval = NPCWalkInterval(self,
                                        endPos,
                                        durationFactor,
                                        startPos,
                                        fluid=1)
        self.moveIval.start(ts)
        self.animFSM.request('walk')
 def enterFlyingUp(self, startIndex, endIndex, ts=0.0):
     startPos = DGG.SpawnPoints[startIndex]
     endPos = DGG.SpawnPoints[endIndex] + (0, 0, 50)
     duration = 3
     self.moveIval = Sequence(
         Wait(1.7),
         LerpPosInterval(self,
                         duration=duration,
                         pos=endPos,
                         startPos=startPos,
                         fluid=1))
     self.moveIval.start(ts)
     self.animFSM.request('flyAway', [ts])
 def enterFlyingDown(self, startIndex, endIndex, ts=0.0):
     startPos = DGG.SpawnPoints[startIndex] + (0, 0, 50)
     endPos = DGG.SpawnPoints[endIndex]
     duration = 3
     self.moveIval = LerpPosInterval(self,
                                     duration=duration,
                                     pos=endPos,
                                     startPos=startPos,
                                     fluid=1)
     self.moveIval.start(ts)
     self.animFSM.request('flyDown', [ts])
     yaw = random.uniform(0.0, 360.0)
     self.setH(yaw)
 def enterWalking(self, startIndex, endIndex, ts=0.0):
     durationFactor = 0.2
     if startIndex > -1:
         startPos = DGG.SpawnPoints[startIndex]
     else:
         startPos = self.getPos(render)
     if endIndex == DGG.WalkToTruckIndex:
         endPos = DGG.TruckSuitPointsByIndex[self.truckIndex]
     else:
         endPos = DGG.SpawnPoints[endIndex]
     self.stopMoving()
     self.moveIval = NPCWalkInterval(self, endPos, durationFactor, startPos, fluid=1)
     self.moveIval.start(ts)
 def testNextWayPoint(self):
     self.numberOfTests += 1
     if self.movementIval:
         self.movementIval.pause()
         self.movementIval = None
     if self.numberOfTests > len(self.wayPointsToTest.keys()) - 1:
         self.allTestsCompleted()
         return
     print "Test number " + str(self.numberOfTests) + " on waypoint " + str(
         self.number)
     self.currentWayPointTestKey = self.wayPointsToTest.keys()[
         self.numberOfTests]
     self.movementIval = NPCWalkInterval(
         node,
         Point3(*self.wayPointsToTest[self.currentWayPointTestKey]['pos']),
         0.005,
         startPos=self.point,
         fluid=1)
     self.movementIval.setDoneEvent('testWayPointDone')
     base.acceptOnce(self.movementIval.getDoneEvent(),
                     self.currentTestSucceeded)
     base.acceptOnce("sensors-into", self.handleBadTest)
     self.movementIval.start()
class DistributedTutorialSuit(DistributedSuit):
    notify = directNotify.newCategory('DistributedTutorialSuit')

    def enterFlyingDown(self, startIndex, endIndex, ts = 0.0):
        startPos = TutorialGlobals.SUIT_POINTS[startIndex] + (0, 0, 50)
        endPos = TutorialGlobals.SUIT_POINTS[endIndex]
        duration = 3
        self.moveIval = LerpPosInterval(self, duration=duration, pos=endPos, startPos=startPos, fluid=1)
        self.moveIval.start(ts)
        self.animFSM.request('flyDown', [ts])
        yaw = random.uniform(0.0, 360.0)
        self.setH(yaw)

    def enterWalking(self, startIndex, endIndex, ts = 0.0):
        durationFactor = 0.2
        if startIndex > -1:
            startPos = TutorialGlobals.SUIT_POINTS[startIndex]
        else:
            startPos = self.getPos(render)
        endPos = TutorialGlobals.SUIT_POINTS[endIndex]
        self.stopMoving()
        self.moveIval = NPCWalkInterval(self, endPos, durationFactor, startPos, fluid=1)
        self.moveIval.start(ts)
        self.animFSM.request('walk')
    def enterWalking(self, startIndex, endIndex, ts = 0.0):
        durationFactor = 0.2
        if startIndex > -1:
            startPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[startIndex]
            startPos = CIGlobals.SuitSpawnPoints[self.getHood()][startPoint]
        else:
            startPos = self.getPos(render)
        endPoint = CIGlobals.SuitSpawnPoints[self.getHood()].keys()[endIndex]
        endPos = CIGlobals.SuitSpawnPoints[self.getHood()][endPoint]

        if self.moveIval:
            self.moveIval.pause()
            self.moveIval = None

        self.moveIval = NPCWalkInterval(self, endPos, durationFactor, startPos, fluid = 1)
        self.moveIval.start(ts)
        self.animFSM.request('walk')
 def enterEagleFly(self, startIndex, endIndex, ts=0.0):
     durationFactor = self.getFlySpeed()
     if startIndex > -1:
         startPos = EGG.EAGLE_FLY_POINTS[startIndex]
     else:
         startPos = self.getPos(render)
     endPos = EGG.EAGLE_FLY_POINTS[endIndex]
     if self.moveIval:
         self.moveIval.pause()
         self.moveIval = None
     self.moveIval = NPCWalkInterval(self,
                                     endPos,
                                     durationFactor=durationFactor,
                                     startPos=startPos,
                                     fluid=1)
     self.moveIval.start(ts)
     return
def doPath():
    global path
    if not len(path):
        suit.loop('neutral')
        return
    endX, endY = path[0]
    endPoint = Point3(endX, endY, 0)
    startPoint = suit.getPos(render)
    path.remove(path[0])
    ival = NPCWalkInterval(suit, endPoint, 0.2, startPoint)
    ival.setDoneEvent(suit.uniqueName('guardWalkDone'))
    base.acceptOnce(suit.uniqueName('guardWalkDone'), doPath)
    ival.start()
    suit.loop('walk')
Example #35
0
 def enterStationSlot(self, slot):
     self.cr.playGame.getPlace().fsm.request('station')
     camera.reparentTo(self)
     numSlots = len(self.circles)
     camera.setPos(self.numPlayers2CamPos[numSlots])
     camera.setPos(camera.getPos(render))
     camera.reparentTo(render)
     camera.lookAt(self)
     base.localAvatar.headsUp(slot)
     base.localAvatar.setAnimState('run')
     runTrack = NPCWalkInterval(base.localAvatar, slot.getPos(render), 0.1, startPos=base.localAvatar.getPos(render))
     runTrack.setDoneEvent('SlotEnterDone')
     runTrack.start()
     base.acceptOnce('SlotEnterDone', self.__handleSlotEntrance)
 def handleGotHit(self):
     self.b_setAnimState('flail')
     if self.flyTrack:
         self.ignore(self.flyTrack.getDoneEvent())
         self.flyTrack.pause()
         self.flyTrack = None
     self.sendUpdate('fallAndExplode', [])
     self.b_setSuitState(6, -1, -1)
     self.flyTrack = Sequence(
         LerpPosInterval(
             self,
             duration = 4.0,
             pos = self.getPos(render) - (0, 0, 75),
             startPos = self.getPos(render),
             blendType = 'easeIn'
         ),
         Wait(1.5),
         Func(self.killMe)
     )
     self.flyTrack.start()
Example #37
0
 def enterFlyingDown(self, startIndex, endIndex, ts=0.0):
     startPos = TutorialGlobals.SUIT_POINTS[startIndex] + (0, 0, 6.5 * 4.8)
     endPos = TutorialGlobals.SUIT_POINTS[endIndex]
     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
     self.moveIval = LerpPosInterval(self,
                                     duration=timeTillLanding,
                                     pos=endPos,
                                     startPos=startPos,
                                     fluid=1)
     self.moveIval.start(ts)
     self.animFSM.request('flyDown', [ts])
     yaw = random.uniform(0.0, 360.0)
     self.setH(yaw)
Example #38
0
def getMoveIvalFromPath(suit, path, elapsedT, isClient, seqName):
    moveIval = Sequence(name=suit.uniqueName(seqName))
    if isClient:
        moveIval.append(Func(suit.animFSM.request, 'walk'))
    for i in xrange(len(path)):
        if i == 0:
            continue
        waypoint = path[i]
        lastWP = path[i - 1]
        moveIval.append(Func(suit.headsUp, Point3(*waypoint)))
        ival = NPCWalkInterval(
            suit,
            Point3(*waypoint),
            startPos=Point3(*lastWP),
            fluid=1,
            name=suit.uniqueName('doWalkIval' + str(i)),
            duration=(Point2(waypoint[0], waypoint[1]) -
                      Point2(lastWP[0], lastWP[1])).length() * 0.2)
        moveIval.append(ival)
    if isClient:
        moveIval.append(Func(suit.animFSM.request, 'neutral'))
    return moveIval
class DistributedDeliveryGameSuit(DistributedSuit):
    notify = directNotify.newCategory("DistributedDeliveryGameSuit")

    def __init__(self, cr):
        DistributedSuit.__init__(self, cr)
        self.truckIndex = 0

    def setTruckIndex(self, index):
        self.truckIndex = index

    def getTruckIndex(self):
        return self.truckIndex

    def enterFlyingDown(self, startIndex, endIndex, ts=0.0):
        startPos = DGG.SpawnPoints[startIndex] + (0, 0, 50)
        endPos = DGG.SpawnPoints[endIndex]
        duration = 3
        self.moveIval = LerpPosInterval(self, duration=duration, pos=endPos, startPos=startPos, fluid=1)
        self.moveIval.start(ts)
        self.animFSM.request("flyDown", [ts])
        yaw = random.uniform(0.0, 360.0)
        self.setH(yaw)

    def enterFlyingUp(self, startIndex, endIndex, ts=0.0):
        startPos = DGG.SpawnPoints[startIndex]
        endPos = DGG.SpawnPoints[endIndex] + (0, 0, 50)
        duration = 3
        self.moveIval = Sequence(
            Wait(1.7), LerpPosInterval(self, duration=duration, pos=endPos, startPos=startPos, fluid=1)
        )
        self.moveIval.start(ts)
        self.animFSM.request("flyAway", [ts])

    def enterWalking(self, startIndex, endIndex, ts=0.0):
        durationFactor = 0.2
        if startIndex > -1:
            startPos = DGG.SpawnPoints[startIndex]
        else:
            startPos = self.getPos(render)
        if endIndex == DGG.WalkToTruckIndex:
            endPos = DGG.TruckSuitPointsByIndex[self.truckIndex]
        else:
            endPos = DGG.SpawnPoints[endIndex]
        self.stopMoving()
        self.moveIval = NPCWalkInterval(self, endPos, durationFactor, startPos, fluid=1)
        self.moveIval.start(ts)
Example #40
0
class SuitPathBehavior(SuitBehaviorBase):

    def __init__(self, suit, exitOnWalkFinish = True):
        SuitBehaviorBase.__init__(self, suit)
        self.walkTrack = None
        self.exitOnWalkFinish = exitOnWalkFinish
        self.isEntered = 0
        return

    def unload(self):
        SuitBehaviorBase.unload(self)
        self.clearWalkTrack()
        del self.exitOnWalkFinish
        del self.walkTrack

    def createPath(self, pathKey = None, durationFactor = 0.2, fromCurPos = False):
        currentPathQueue = self.suit.getCurrentPathQueue()
        currentPath = self.suit.getCurrentPath()
        if pathKey == None:
            pathKeyList = CIGlobals.SuitPathData[self.suit.getHood()][self.suit.getCurrentPath()]
            pathKey = random.choice(pathKeyList)
        elif len(currentPathQueue):
            pathKey = currentPathQueue[0]
            currentPathQueue.remove(pathKey)
        endIndex = CIGlobals.SuitSpawnPoints[self.suit.getHood()].keys().index(pathKey)
        path = CIGlobals.SuitSpawnPoints[self.suit.getHood()][pathKey]
        self.clearWalkTrack()
        if not currentPath or fromCurPos:
            startIndex = -1
        else:
            oldPath = currentPath
            startIndex = CIGlobals.SuitSpawnPoints[self.suit.getHood()].keys().index(oldPath)
        self.suit.currentPath = pathKey
        startPos = self.suit.getPos(render)
        pathName = self.suit.uniqueName('suitPath')
        self.walkTrack = NPCWalkInterval(self.suit, path, startPos=startPos, name=pathName, durationFactor=durationFactor, fluid=1)
        self.walkTrack.setDoneEvent(self.walkTrack.getName())
        self.startFollow()
        self.suit.b_setSuitState(1, startIndex, endIndex)
        return

    def getDistance(self, point1, point2):
        return (point1.getXy() - point2.getXy()).length()

    def getPath(self, start_key, target_key, nodes):
        path = []
        for node in nodes:
            if node.key == start_key:
                start_node = node
            elif node.key == target_key:
                target_node = node

        current_node = target_node
        while current_node.parent != start_node:
            path.append(current_node.key)
            current_node = current_node.parent

        path.append(start_key)
        return list(reversed(path))

    def findPath(self, area, start_key, target_key):
        start_point = CIGlobals.SuitSpawnPoints[area][start_key]
        target_point = CIGlobals.SuitSpawnPoints[area][target_key]
        nodes = []
        open_nodes = []
        closed_nodes = []
        for key, point in CIGlobals.SuitSpawnPoints[area].items():
            g_cost = self.getDistance(point, start_point)
            h_cost = self.getDistance(point, target_point)
            node = Node(g_cost, h_cost, key, point)
            nodes.append(node)

        for node in nodes:
            if node.key == start_key:
                open_nodes.append(node)

        while len(open_nodes):
            f_cost_list = []
            for node in open_nodes:
                f_cost_list.append(node.f_cost)

            lowest_f_cost = min(f_cost_list)
            current = None
            for node in open_nodes:
                if lowest_f_cost == node.f_cost:
                    current = node

            open_nodes.remove(current)
            closed_nodes.append(current)
            if current.key == target_key:
                return self.getPath(start_key, target_key, nodes)
            neighbor_keys = CIGlobals.SuitPathData[area][current.key]
            for neighbor_key in neighbor_keys:
                isClosed = False
                for node in closed_nodes:
                    if node.key == neighbor_key:
                        isClosed = True
                        break

                if isClosed:
                    continue
                neighbor = None
                for node in nodes:
                    if node.key == neighbor_key:
                        neighbor = node
                        break

                nm_cost_2_neighbor = current.g_cost + self.getDistance(current.point, neighbor.point)
                if neighbor not in open_nodes or nm_cost_2_neighbor < neighbor.g_cost:
                    neighbor.g_cost = nm_cost_2_neighbor
                    neighbor.h_cost = self.getDistance(target_point, neighbor.point)
                    neighbor.f_cost = neighbor.g_cost + neighbor.h_cost
                    neighbor.parent = current
                    if neighbor not in open_nodes:
                        open_nodes.append(neighbor)

        return

    def clearWalkTrack(self):
        if self.walkTrack:
            self.ignore(self.walkTrack.getDoneEvent())
            self.walkTrack.clearToInitial()
            self.walkTrack = None
            if hasattr(self, 'suit'):
                self.suit.d_stopMoveInterval()
        return

    def startFollow(self):
        self.suit.b_setAnimState('walk')
        if self.walkTrack:
            self.acceptOnce(self.walkTrack.getName(), self.__walkDone)
            self.walkTrack.start()

    def __walkDone(self):
        self.clearWalkTrack()
        if not self.suit.isDead():
            self.suit.b_setAnimState('neutral')
            if self.exitOnWalkFinish == True:
                self.exit()

    def getWalkTrack(self):
        return self.walkTrack

    def isWalking(self):
        if self.walkTrack:
            return self.walkTrack.isPlaying()
        return False
class DistributedEagleSuitAI(DistributedSuitAI):
    notify = directNotify.newCategory("DistributedEagleSuitAI")

    def __init__(self, air):
        DistributedSuitAI.__init__(self, air)
        self.mg = None
        self.flyTrack = None
        self.currentFlyPoint = None
        self.flySpeed = 0.0

    def setMinigame(self, mg):
        self.mg = mg

    def getMinigame(self):
        return self.mg

    def handleGotHit(self):
        self.b_setAnimState('flail')
        if self.flyTrack:
            self.ignore(self.flyTrack.getDoneEvent())
            self.flyTrack.pause()
            self.flyTrack = None
        self.sendUpdate('fallAndExplode', [])
        self.b_setSuitState(6, -1, -1)
        self.flyTrack = Sequence(
            LerpPosInterval(
                self,
                duration = 4.0,
                pos = self.getPos(render) - (0, 0, 75),
                startPos = self.getPos(render),
                blendType = 'easeIn'
            ),
            Wait(1.5),
            Func(self.killMe)
        )
        self.flyTrack.start()

    def killMe(self):
        self.disable()
        self.requestDelete()

    def setFlySpeed(self, value):
        self.flySpeed = value

    def b_setFlySpeed(self, value):
        self.sendUpdate('setFlySpeed', [value])
        self.setFlySpeed(value)

    def getFlySpeed(self):
        return self.flySpeed

    def spawn(self):
        # spawn() also exists in DistributedSuitAI, but we're not doing
        # anything that a normal suit would do here, so don't even call
        # DistributedSuitAI.spawn.

        if not self.getMinigame():
            self.notify.error("Tried to spawn before self.mg was set!")
        
        self.b_setAnimState('flyNeutral')
        point = random.choice(EGG.EAGLE_FLY_POINTS)
        self.setPos(point)
        self.d_setPos(*point)

        self.b_setFlySpeed(EGG.ROUND_2_EAGLE_SPEED[self.getMinigame().getRound()])

        self.createFlyPath()
        self.b_setParent(CIGlobals.SPRender)

    def createFlyPath(self):
        self.b_setAnimState('flyNeutral')
        if self.flyTrack:
            self.ignore(self.flyTrack.getDoneEvent())
            self.flyTrack.pause()
            self.flyTrack = None
        point = random.choice(EGG.EAGLE_FLY_POINTS)
        if self.currentFlyPoint == point:
            self.createFlyPath()
            return
        if self.currentFlyPoint == None:
            point_list = list(EGG.EAGLE_FLY_POINTS)
            point_list.remove(point)
            startIndex = point_list.index(random.choice(point_list))
        else:
            startIndex = -1
        self.b_setSuitState(5, startIndex, EGG.EAGLE_FLY_POINTS.index(point))
        mgRound = self.getMinigame().getRound()
        if mgRound:
            self.flyTrack = NPCWalkInterval(self, point,
                durationFactor = EGG.ROUND_2_EAGLE_SPEED[mgRound],
                startPos = self.getPos(render), fluid = 1, name = self.uniqueName('DEagleSuitAI-flyTrack'))
            self.flyTrack.setDoneEvent(self.flyTrack.getName())
            self.acceptOnce(self.flyTrack.getDoneEvent(), self.handleFlyDone)
            self.flyTrack.start()
            self.currentFlyPoint = point
        else: return

    def handleFlyDone(self):
        self.createFlyPath()

    def delete(self):
        del self.currentFlyPoint
        del self.mg
        if self.flyTrack:
            self.ignore(self.flyTrack.getDoneEvent())
            self.flyTrack.pause()
            self.flyTrack = None
        DistributedSuitAI.delete(self)
class VicePresident(Avatar):
    notify = directNotify.newCategory("VicePresident")

    def __init__(self):
        Avatar.__init__(self)
        self.fsm = ClassicFSM('VicePresident', [
            State('off', self.enterOff, self.exitOff),
            State('throwGear', self.enterThrowGear, self.exitThrowGear),
            State('neutral', self.enterNeutral, self.exitNeutral),
            State('jump', self.enterJump, self.exitJump),
            State('emerge', self.enterEmerge, self.exitEmerge),
            State('knockDown', self.enterKnockDown, self.exitKnockDown),
            State('riseUp', self.enterRiseUp, self.exitRiseUp)
        ], 'off', 'off')
        self.fsm.enterInitialState()
        self.track = None
        self.treads = None
        self.rearDoor = None
        self.frontDoor = None
        self.gearModel = None
        self.gearThrowIval = None
        self.knockedDown = False
        self.chirps = base.audio3d.loadSfx("phase_4/audio/sfx/SZ_TC_bird1.mp3")
        base.audio3d.attachSoundToObject(self.chirps, self)
        self.vp_torso_node = NodePath('vp_torso_node')

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterRiseUp(self, ts=0):
        if hasattr(self, 'uniqueName'):
            name = self.uniqueName('vpRiseUp')
        else:
            name = 'vpRiseUp'
        sfx = base.audio3d.loadSfx("phase_9/audio/sfx/CHQ_VP_raise_up.mp3")
        base.audio3d.attachSoundToObject(sfx, self)
        self.track = Sequence(Func(base.playSfx, sfx),
                              ActorInterval(self, "up"),
                              name=name)
        self.knockedDown = False
        self.track.setDoneEvent(self.track.getName())
        self.acceptOnce(self.track.getDoneEvent(), self.fsm.request,
                        ["neutral"])
        self.track.start(ts)

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

    def enterKnockDown(self, ts=0):
        if hasattr(self, 'uniqueName'):
            name = self.uniqueName('vpKnockDown')
        else:
            name = 'vpKnockDown'
        sfx = base.audio3d.loadSfx("phase_5/audio/sfx/AA_sound_aoogah.mp3")
        base.audio3d.attachSoundToObject(sfx, self)
        self.track = Sequence(Func(base.playSfx, sfx),
                              ActorInterval(self, "fall"),
                              name=name)
        self.knockedDown = True
        self.track.setDoneEvent(self.track.getName())
        self.acceptOnce(self.track.getDoneEvent(), self.fsm.request,
                        ["neutral"])
        self.track.start(ts)

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

    def enterEmerge(self, ts=0):
        if hasattr(self, 'uniqueName'):
            name = self.uniqueName('emergeTrack')
        else:
            name = 'emergeTrack'
        self.setScale(0.1)
        emergeSfx = base.audio3d.loadSfx(
            "phase_5/audio/sfx/TL_train_track_appear.mp3")
        base.audio3d.attachSoundToObject(emergeSfx, self)
        self.track = Sequence(Func(base.playSfx, emergeSfx),
                              LerpScaleInterval(self,
                                                duration=1.2,
                                                scale=1.0,
                                                startScale=0.05,
                                                blendType='easeOut'),
                              name=name)
        self.track.setDoneEvent(self.track.getName())
        self.acceptOnce(self.track.getDoneEvent(), self.fsm.request,
                        ["neutral"])
        self.track.start(ts)
        self.loop('stand-angry')

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

    def enterNeutral(self, ts=0):
        if self.getCurrentAnim() != 'stand-angry':
            if self.knockedDown:
                base.playSfx(self.chirps, looping=1)
                self.loop("dn_neutral")
            else:
                self.loop("stand-angry")
        self.track = NPCLookInterval(self.vp_torso_node,
                                     Vec3(0, 0, 0),
                                     blendType='easeInOut',
                                     name='lookAtCenter',
                                     isBackwards=False)
        self.track.start(ts)

    def exitNeutral(self):
        self.stop()
        self.chirps.stop()

    def enterJump(self, ts=0):
        if hasattr(self, 'uniqueName'):
            name = self.uniqueName('vpJump')
        else:
            name = 'vpJump'
        jumpSfx = base.audio3d.loadSfx(
            "phase_5/audio/sfx/General_throw_miss.mp3")
        landSfx = base.audio3d.loadSfx(
            "phase_3.5/audio/sfx/ENC_cogfall_apart.mp3")
        base.audio3d.attachSoundToObject(jumpSfx, self)
        base.audio3d.attachSoundToObject(landSfx, self)
        self.track = Sequence(Func(self.play, "jump"),
                              Func(base.playSfx, jumpSfx),
                              Wait(1.2),
                              Func(base.playSfx, landSfx),
                              Wait(1.8),
                              name=name)
        self.track.setDoneEvent(self.track.getName())
        self.acceptOnce(self.track.getDoneEvent(), self.fsm.request,
                        ["neutral"])
        self.track.start(ts)

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

    def enterThrowGear(self, point, ts=0):
        lookNode = render.attachNewNode('pointNode')
        lookNode.setPos(point)
        #self.gearModel.reparentTo(render)
        #self.gearModel.setPos(point)
        throwSfx = base.audio3d.loadSfx(
            "phase_9/audio/sfx/CHQ_VP_frisbee_gears.mp3")
        base.audio3d.attachSoundToObject(throwSfx, self)
        if hasattr(self, 'uniqueName'):
            name = self.uniqueName('vpThrowGear')
        else:
            name = 'vpThrowGear'
        self.track = Sequence(NPCLookInterval(self.vp_torso_node,
                                              lookNode,
                                              blendType='easeInOut',
                                              isBackwards=False),
                              Func(VicePresident.throwGear, self, point),
                              Func(base.playSfx, throwSfx),
                              ActorInterval(self, "throw"),
                              name=name)
        self.track.setDoneEvent(self.track.getName())
        self.acceptOnce(self.track.getDoneEvent(), self.fsm.request,
                        ["neutral"])
        self.track.start(ts)
        lookNode.removeNode()
        del lookNode

    def throwGear(self, point):
        self.gearModel.reparentTo(self.getPart("body"))
        self.gearModel.setX(0.0)
        self.gearModel.setY(-2)
        self.gearModel.setZ(5)
        self.gearModel.setPos(self.gearModel.getPos(render))
        self.gearModel.reparentTo(render)
        self.gearModel.show()
        self.gearModel.lookAt(point)
        if self.gearThrowIval:
            self.gearThrowIval.finish()
            self.gearThrowIval = None
        self.gearThrowIval = NPCWalkInterval(self.gearModel,
                                             point,
                                             durationFactor=0.01,
                                             fluid=1,
                                             lookAtTarget=False)
        self.gearThrowIval.start()

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

    def destroy(self):
        if 'head' in self._Actor__commonBundleHandles:
            del self._Actor__commonBundleHandles['head']
        if 'body' in self._Actor__commonBundleHandles:
            del self._Actor__commonBundleHandles['body']
        if 'legs' in self._Actor__commonBundleHandles:
            del self._Actor__commonBundleHandles['legs']
        if self.treads:
            self.treads.removeNode()
            self.treads = None
        if self.gearThrowIval:
            self.gearThrowIval.finish()
            self.gearThrowIval = None
        if self.gearModel:
            self.gearModel.removeNode()
            self.gearModel = None
        if self.track:
            self.ignore(self.track.getDoneEvent())
            self.track.finish()
            self.track = None
        self.rearDoor = None
        self.frontDoor = None
        if self.vp_torso_node:
            self.vp_torso_node.removeNode()
            self.vp_torso_node = None
        self.removePart("head")
        self.removePart("body")
        self.removePart("legs")

    def generate(self):
        self.generateLegs()
        self.generateBody()
        self.generateHead()
        self.generateTreads()
        self.generateGear()
        self.parentParts()

    def parentParts(self):
        self.attach('head', 'body', 'joint34')
        self.treads.reparentTo(self.getPart("legs").find('**/joint_axle'))
        self.vp_torso_node.reparentTo(
            self.getPart("legs").find('**/joint_legs'))
        self.getPart("body").reparentTo(self.vp_torso_node)
        self.getPart("body").setH(180)

        self.frontDoor.setR(-80)
        self.rearDoor.setR(77)

    def generateGear(self):
        self.gearModel = loader.loadModel("phase_9/models/char/gearProp.bam")
        self.gearModel.setScale(0.25)
        self.gearModel.hide()

    def generateTreads(self):
        self.treads = loader.loadModel(
            "phase_9/models/char/bossCog-treads.bam")

    def generateLegs(self):
        self.loadModel("phase_9/models/char/bossCog-legs-zero.bam", "legs")
        self.loadAnims(
            {
                "stand-angry":
                "phase_9/models/char/bossCog-legs-Fb_neutral.bam",
                "stand-happy":
                "phase_9/models/char/bossCog-legs-Ff_neutral.bam",
                "jump": "phase_9/models/char/bossCog-legs-Fb_jump.bam",
                "throw": "phase_9/models/char/bossCog-legs-Fb_UpThrow.bam",
                "fall": "phase_9/models/char/bossCog-legs-Fb_firstHit.bam",
                "up": "phase_9/models/char/bossCog-legs-Fb_down2Up.bam",
                "dn_neutral":
                "phase_9/models/char/bossCog-legs-Fb_downNeutral.bam",
                "dn_throw":
                "phase_9/models/char/bossCog-legs-Fb_DownThrow.bam",
                "speech": "phase_9/models/char/bossCog-legs-Ff_speech.bam",
                "wave": "phase_9/models/char/bossCog-legs-wave.bam",
                "downhit": "phase_9/models/char/bossCog-legs-Fb_firstHit.bam"
            }, "legs")

        self.frontDoor = self.controlJoint(None, "legs", "joint_doorFront")
        self.rearDoor = self.controlJoint(None, "legs", "joint_doorRear")

    def generateBody(self):
        self.loadModel("phase_9/models/char/sellbotBoss-torso-zero.bam",
                       "body")
        self.loadAnims(
            {
                "stand-angry":
                "phase_9/models/char/bossCog-torso-Fb_neutral.bam",
                "stand-happy":
                "phase_9/models/char/bossCog-torso-Ff_neutral.bam",
                "jump": "phase_9/models/char/bossCog-torso-Fb_jump.bam",
                "throw": "phase_9/models/char/bossCog-torso-Fb_UpThrow.bam",
                "fall": "phase_9/models/char/bossCog-torso-Fb_firstHit.bam",
                "up": "phase_9/models/char/bossCog-torso-Fb_down2Up.bam",
                "dn_neutral":
                "phase_9/models/char/bossCog-torso-Fb_downNeutral.bam",
                "dn_throw":
                "phase_9/models/char/bossCog-torso-Fb_DownThrow.bam",
                "speech": "phase_9/models/char/bossCog-torso-Ff_speech.bam",
                "wave": "phase_9/models/char/bossCog-torso-wave.bam",
                "downhit": "phase_9/models/char/bossCog-torso-Fb_firstHit.bam"
            }, "body")

    def generateHead(self):
        self.loadModel("phase_9/models/char/sellbotBoss-head-zero.bam", "head")
        self.loadAnims(
            {
                "stand-angry":
                "phase_9/models/char/bossCog-head-Fb_neutral.bam",
                "stand-happy":
                "phase_9/models/char/bossCog-head-Ff_neutral.bam",
                "jump": "phase_9/models/char/bossCog-head-Fb_jump.bam",
                "throw": "phase_9/models/char/bossCog-head-Fb_UpThrow.bam",
                "fall": "phase_9/models/char/bossCog-head-Fb_firstHit.bam",
                "up": "phase_9/models/char/bossCog-head-Fb_down2Up.bam",
                "dn_neutral":
                "phase_9/models/char/bossCog-head-Fb_downNeutral.bam",
                "dn_throw":
                "phase_9/models/char/bossCog-head-Fb_DownThrow.bam",
                "speech": "phase_9/models/char/bossCog-head-Ff_speech.bam",
                "wave": "phase_9/models/char/bossCog-head-wave.bam",
                "downhit": "phase_9/models/char/bossCog-head-Fb_firstHit.bam"
            }, "head")
class DistributedDeliveryGameSuitAI(DistributedSuitAI):
    notify = directNotify.newCategory('DistributedDeliveryGameSuitAI')

    def __init__(self, air, mg):
        DistributedSuitAI.__init__(self, air)
        self.mg = mg
        self.truck = random.choice(self.mg.trucks)
        self.truckIndex = self.mg.trucks.index(self.truck)
        self.spawnPoint = None

    def walkToTruck(self):
        index = DGG.WalkToTruckIndex
        pos = DGG.TruckSuitPointsByIndex[self.truckIndex]
        startPos = self.getPos(render)
        self.b_setSuitState(1, -1, index)
        durationFactor = 0.2
        pathName = self.uniqueName('WalkToTruck')
        self.walkTrack = NPCWalkInterval(self,
                                         pos,
                                         startPos=startPos,
                                         name=pathName,
                                         durationFactor=durationFactor,
                                         fluid=1)
        self.walkTrack.setDoneEvent(self.walkTrack.getName())
        self.acceptOnce(self.walkTrack.getDoneEvent(), self.__walkedToTruck)
        self.walkTrack.start()
        self.b_setAnimState(
            SuitGlobals.getAnimId(SuitGlobals.getAnimByName('walk')))

    def __walkedToTruck(self):
        self.truck.suitPickUpBarrel(self.doId)
        self.walkBackToSpawnPointWithBarrel()

    def walkBackToSpawnPointWithBarrel(self):
        pos = DGG.SpawnPoints[self.spawnPoint]
        startPos = self.getPos(render)
        self.b_setSuitState(1, -1, self.spawnPoint)
        durationFactor = 0.2
        pathName = self.uniqueName('WalkBackToSpawn')
        self.walkTrack = NPCWalkInterval(self,
                                         pos,
                                         startPos=startPos,
                                         name=pathName,
                                         durationFactor=durationFactor,
                                         fluid=1)
        self.walkTrack.setDoneEvent(self.walkTrack.getName())
        self.acceptOnce(self.walkTrack.getDoneEvent(), self.__walkedBack2Spawn)
        self.walkTrack.start()
        self.b_setAnimState(
            SuitGlobals.getAnimId(SuitGlobals.getAnimByName('tray-walk')))

    def __walkedBack2Spawn(self):
        self.b_setSuitState(3, self.spawnPoint, self.spawnPoint)
        base.taskMgr.doMethodLater(10, self.__finished,
                                   self.uniqueName('finishSuit'))

    def __finished(self, task):
        self.mg.suits.remove(self)
        self.truck.barrelDroppedOff()
        self.requestDelete()
        return task.done

    def spawn(self):
        pos = random.choice(DGG.SpawnPoints)
        index = DGG.SpawnPoints.index(pos)
        self.spawnPoint = index
        self.b_setSuitState(2, index, index)
        flyTrack = self.posInterval(3, pos, startPos=pos + (0, 0, 50))
        flyTrack.start()
        self.track = Sequence()
        self.track.append(Wait(5.4))
        self.track.append(Func(self.b_setAnimState, 'neutral'))
        self.track.append(Wait(1.0))
        self.track.append(Func(self.walkToTruck))
        self.track.start()
        self.b_setParent(CIGlobals.SPRender)

    def delete(self):
        base.taskMgr.remove(self.uniqueName('finishSuit'))
        if hasattr(self, 'walkTrack') and self.walkTrack:
            self.ignore(self.walkTrack.getDoneEvent())
            self.walkTrack.finish()
            self.walkTrack = None
        self.mg = None
        self.truck = None
        self.truckIndex = None
        self.spawnPoint = None
        DistributedSuitAI.delete(self)
Example #44
0
class FactorySneakGuardSuit(Suit, FSM):
    notify = directNotify.newCategory('FactorySneakGuardSuit')
    SUIT = 'mrhollywood'
    VIEW_DISTANCE_TASK_NAME = 'ViewDistanceTask'
    MAX_VIEW_DISTANCE = 100.0
    GUARD_DIED_DELAY = 6.0
    MAX_HP = 200
    PROWLER_DISTANCE = 40.0
    IN_VIEW = 'somethingInSight'
    HEARD = 'heard'
    TRY_TO_CONFIRM_TIME = 5.0

    def __init__(self, world, guardKey):
        Suit.__init__(self)
        FSM.__init__(self, 'FactorySneakGuardSuit')
        self.gameWorld = world
        self.guardKey = guardKey
        self.viewDistanceTaskName = self.VIEW_DISTANCE_TASK_NAME + '-' + str(
            id(self))
        self.diedTaskName = 'GuardDied-' + str(id(self))
        self.health = 0
        self.maxHealth = self.MAX_HP
        self.eyeLight = None
        self.eyeLens = None
        self.eyeNode = None
        self.moveTrack = None
        self.trav = None
        self.rayNP = None
        self.queue = None
        self.currentKey = self.guardKey
        self.firstPoint = CGG.GuardPointData[self.guardKey]
        self.walkTrack = None
        self.pathQueue = []
        self.currentPathIndex = 0
        return

    def enterGuard(self):
        self.loop('neutral')
        pos, hpr = CGG.FactoryGuardPoints[self.guardKey]
        self.setHpr(hpr - (180, 0, 0))
        self.setPos(pos)
        base.taskMgr.add(self.__guard, self.taskName('guard'))

    def __checkToon(self):
        self.rayNP.lookAt(base.localAvatar)
        self.trav.traverse(render)
        if self.queue.getNumEntries() > 0:
            self.queue.sortEntries()
            hitObj = self.queue.getEntry(0).getIntoNodePath()
            print hitObj
            isLocalAvatar = hitObj.getParent().getPythonTag('localAvatar')
            if isLocalAvatar == 1:
                return 1
        return 0

    def __guard(self, task):
        if self.eyeNode.node().isInView(base.localAvatar.getPos(
                self.eyeNode)) and self.getDistance(
                    base.localAvatar) <= self.PROWLER_DISTANCE:
            if self.__checkToon():
                self.request('SeekTarget', self.IN_VIEW)
                return task.done
        return task.cont

    def exitGuard(self):
        base.taskMgr.remove(self.taskName('guard'))

    def enterTurnToGuardSpot(self):
        self.loop('walk')
        _, hpr = CGG.FactoryGuardPoints[self.guardKey]
        self.moveTrack = LerpHprInterval(self,
                                         duration=1.0,
                                         hpr=hpr,
                                         startHpr=self.getHpr())
        self.moveTrack.setDoneEvent(self.uniqueName('TurnedToGuardSpot'))
        self.acceptOnce(self.moveTrack.getDoneEvent(), self.request, ['Guard'])
        self.moveTrack.start()

    def exitTurnToGuardSpot(self):
        if self.moveTrack:
            self.ignore(self.moveTrack.getDoneEvent())
            self.moveTrack.finish()
            self.moveTrack = None
        return

    def enterSeekTarget(self, event):
        dialogue = random.choice(CGG.GuardDialog[event])
        self.setChat(dialogue)
        self.loop('walk')
        self.moveTrack = NPCLookInterval(self, base.localAvatar)
        self.moveTrack.setDoneEvent(self.uniqueName('SeekLocalAvatar'))
        self.acceptOnce(self.moveTrack.getDoneEvent(), self.request,
                        ['TryToConfirmTarget'])
        self.moveTrack.start()

    def exitSeekTarget(self):
        if self.moveTrack:
            self.ignore(self.moveTrack.getDoneEvent())
            self.moveTrack.finish()
            self.moveTrack = None
        return

    def enterTryToConfirmTarget(self):
        self.loop('neutral')
        base.taskMgr.add(self.__tryToConfirmTarget,
                         self.uniqueName('TryToConfirmTarget'))

    def __tryToConfirmTarget(self, task):
        if task.time >= self.TRY_TO_CONFIRM_TIME:
            chat = random.choice(CGG.GuardDialog['disregard'])
            self.setChat(chat)
            self.request('TurnToGuardSpot')
            return task.done
        if self.eyeNode.node().isInView(base.localAvatar.getPos(
                self.eyeNode)) and self.getDistance(
                    base.localAvatar) <= self.PROWLER_DISTANCE:
            if self.__checkToon():
                chat = random.choice(CGG.GuardDialog['spot'])
                self.setChat(chat)
                self.request('Pursue')
                return task.done
        return task.cont

    def exitTryToConfirmTarget(self):
        base.taskMgr.remove(self.uniqueName('TryToConfirmTarget'))

    def enterGoBackToGuardSpot(self):
        self.walkBackToGuardSpot()

    def walkBackToGuardSpot(self):
        self.currentPathIndex = 0
        self.pathQueue = SuitPathFinder.find_path(CGG.FactoryWalkPoints,
                                                  CGG.FactoryWayPointData,
                                                  self.currentKey,
                                                  self.guardKey)
        self.currentKey = self.guardKey
        self.walk(0.2)
        self.loop('walk')

    def exitGoBackToGuardSpot(self):
        pass

    def enterPursue(self):
        self.numTries = 0
        self.maxTries = 3
        self.runToClosestPoint()
        self.setPlayRate(1.5, 'walk')
        self.loop('walk')
        messenger.send('guardPursue')

    def getClosestPoint(self):
        closestPoint = None
        pointKey2range = {}
        for key, point in CGG.FactoryWalkPoints.items():
            dummyNode = render.attachNewNode('dummyNode')
            dummyNode.setPos(point)
            pointKey2range[key] = base.localAvatar.getDistance(dummyNode)
            dummyNode.removeNode()

        ranges = []
        for distance in pointKey2range.values():
            ranges.append(distance)

        ranges.sort()
        for key in pointKey2range.keys():
            distance = pointKey2range[key]
            if distance == ranges[0]:
                closestPoint = key
                break

        return closestPoint

    def runToClosestPoint(self):
        self.numTries += 1
        closestPoint = self.getClosestPoint()
        self.currentPathIndex = 0
        startKey = None
        if self.currentKey == self.guardKey and self.firstPoint in CGG.GuardPointData:
            startKey = CGG.GuardPointData[self.firstPoint]
        else:
            startKey = self.currentKey
        self.pathQueue = SuitPathFinder.find_path(CGG.FactoryWalkPoints,
                                                  CGG.FactoryWayPointData,
                                                  startKey, closestPoint)
        if self.currentKey == self.guardKey:
            self.pathQueue.insert(0, 1)
        else:
            self.pathQueue.insert(0, 0)
        self.currentKey = closestPoint
        self.walk(0.1)
        return

    def walk(self, speed=0.2):
        self.currentPathIndex += 1
        if len(self.pathQueue) <= self.currentPathIndex:
            if self.getCurrentOrNextState() == 'Pursue':
                if self.getClosestPoint() != self.currentKey:
                    if self.numTries >= self.maxTries:
                        self.request('GoBackToGuardSpot')
                    else:
                        self.runToClosestPoint()
            else:
                if self.getCurrentOrNextState() == 'GoBackToGuardSpot':
                    self.request('Guard')
            return
        print self.pathQueue[self.currentPathIndex]
        if self.currentPathIndex == 1 and self.pathQueue[0] == 1:
            startPoint = self.getPos(render)
            endPoint = CGG.FactoryWalkPoints[self.firstPoint]
        else:
            if self.pathQueue[0] == 0:
                self.pathQueue.remove(self.pathQueue[0])
            key = self.pathQueue[self.currentPathIndex]
            endPoint = CGG.FactoryWalkPoints[key]
            oldKey = self.pathQueue[self.currentPathIndex - 1]
            startPoint = CGG.FactoryWalkPoints[oldKey]
        self.walkTrack = NPCWalkInterval(self, endPoint, speed, startPoint)
        self.walkTrack.setDoneEvent(self.uniqueName('guardWalkDone'))
        self.acceptOnce(self.uniqueName('guardWalkDone'), self.walk)
        self.walkTrack.start()

    def exitPursue(self):
        self.setPlayRate(1.0, 'walk')
        del self.numTries
        if self.walkTrack:
            self.ignore(self.walkTrack.getDoneEvent())
            self.walkTrack.pause()
            self.walkTrack = None
        messenger.send('guardStopPursue')
        return

    def uniqueName(self, name):
        return self.taskName(name)

    def taskName(self, name):
        return name + '-' + str(id(self))

    def setHealth(self, hp):
        self.health = hp

    def getHealth(self):
        return self.health

    def shot(self):
        dialogue = random.choice(CGG.GuardDialog['shot'])
        self.setChat(dialogue)

    def dead(self):
        self.request('Off')
        self.animFSM.request('die')
        base.taskMgr.doMethodLater(self.GUARD_DIED_DELAY, self.__diedDone,
                                   self.diedTaskName)

    def __diedDone(self, task):
        self.gameWorld.deleteGuard(self)
        return task.done

    def generate(self):
        data = CIGlobals.SuitBodyData[self.SUIT]
        type = data[0]
        team = data[1]
        self.team = team
        self.level = 12
        self.suit = type
        Suit.generate(self, SuitBank.MrHollywood, 0, hideFirst=False)
        self.suit = type
        base.taskMgr.add(self.__viewDistance, self.viewDistanceTaskName)
        self.setPythonTag('guard', self)
        self.eyeLight = Spotlight('eyes')
        self.eyeLens = PerspectiveLens()
        self.eyeLens.setMinFov(90.0 / (4.0 / 3.0))
        self.eyeLight.setLens(self.eyeLens)
        self.eyeNode = self.headModel.attachNewNode(self.eyeLight)
        self.eyeNode.setZ(-5)
        self.eyeNode.setY(-4.5)
        self.trav = CollisionTraverser(self.uniqueName('eyeTrav'))
        ray = CollisionRay(0, 0, 0, 0, 1, 0)
        rayNode = CollisionNode('ToonFPS.rayNode')
        rayNode.addSolid(ray)
        rayNode.setFromCollideMask(CGG.GuardBitmask | CIGlobals.WallBitmask)
        rayNode.setIntoCollideMask(BitMask32.allOff())
        self.rayNP = base.camera.attachNewNode(rayNode)
        self.rayNP.setZ(3)
        self.queue = CollisionHandlerQueue()
        self.trav.addCollider(self.rayNP, self.queue)
        self.trav.addCollider(self.gameWorld.mg.avatarBody, self.queue)
        self.request('Guard')

    def __viewDistance(self, task):
        if self.getDistance(base.localAvatar) > self.MAX_VIEW_DISTANCE:
            if not self.isHidden():
                self.hide()
        else:
            if self.isHidden():
                self.show()
        task.delayTime = 1.0
        return task.again

    def disable(self):
        self.request('Off')
        base.taskMgr.remove(self.taskName('guard'))
        base.taskMgr.remove(self.diedTaskName)
        base.taskMgr.remove(self.viewDistanceTaskName)
        self.trav = None
        if self.rayNP:
            self.rayNP.removeNode()
            self.rayNP = None
        self.queue = None
        self.currentPathIndex = None
        if self.eyeNode:
            self.eyeNode.removeNode()
            self.eyeNode = None
            self.eyeLens = None
            self.eyeLight = None
        self.viewDistanceTaskName = None
        self.guardKey = None
        self.gameWorld = None
        self.pathQueue = None
        if self.walkTrack:
            self.ignore(self.walkTrack.getDoneEvent())
            self.walkTrack.finish()
            self.walkTrack = None
        Suit.disable(self)
        return
Example #45
0
class DistributedSuitAI(DistributedAvatarAI, DistributedSmoothNodeAI):
    notify = directNotify.newCategory("DistributedSuitAI")

    def __init__(self, air):
        try:
            self.DistributedSuitAI_initialized
            return
        except:
            self.DistributedSuitAI_initialized = 1
        DistributedAvatarAI.__init__(self, air)
        DistributedSmoothNodeAI.__init__(self, air)
        self.itemDropper = SuitItemDropper(self)
        self.avatarType = CIGlobals.Suit
        self.aiChar = None
        self.aiBehaviors = None
        self.walkTrack = None
        self.name = ""
        self.anim = "neutral"
        self.state = "alive"
        self.damage = 0
        self.health = 132
        self.type = "A"
        self.team = "c"
        self.head = "bigcheese"
        self.name = "The Big Cheese"
        self.skeleton = 0
        self.dmg_lbl = None
        self.lbl_int = None
        self.bean = None
        self.boss = None
        self.brain = None
        self.startPoint = -1
        self.endPoint = -1
        self.suitState = 0
        self.walkPaused = 0
        self.attacking = False
        self.suitHealTrack = None
        self.continuePathId = 0
        self.attackId = 0
        self.mgr = None
        self.backup = 0
        self.difficulty = None
        self.track = None
        self.lateX = 0
        self.lateY = 0
        self.stateTimestamp = 0
        self.animState2animId = {
            'off': 13,
            'neutral': 10,
            'walk': 9,
            'die': 5,
            'attack': 7,
            'flydown': 1,
            'pie': 4,
            'win': 12,
            'flyaway': 14,
            'rollodex': 3,
            'flyNeutral': 15,
            'flail': 0,
            'drop': 6,
            'drop-react': 16,
            'squirt-large': 8,
            'squirt-small': 11,
            'soak': 2,
        }
        self.animId2animState = {
            v: k
            for k, v in self.animState2animId.items()
        }
        self.level = 0
        self.currentPathQueue = []
        return

    def resetPathQueue(self):
        self.currentPathQueue = []

    def setLevel(self, level):
        self.level = level

    def d_setLevel(self, level):
        self.sendUpdate('setLevel', [level])

    def b_setLevel(self, level):
        self.d_setLevel(level)
        self.setLevel(level)

    def getLevel(self):
        return self.level

    def setLatePos(self, x, y):
        self.lateX = x
        self.lateY = y

    def getLatePos(self):
        return [self.lateX, self.lateY]

    def setSuitState(self, index, startPoint, endPoint):
        if index == 0:
            self.setLatePos(self.getX(render), self.getY(render))
        self.suitState = index
        self.startPoint = startPoint
        self.endPoint = endPoint

    def d_setSuitState(self, index, startPoint, endPoint):
        self.stateTimestamp = globalClockDelta.getFrameNetworkTime()
        self.sendUpdate('setSuitState',
                        [index, startPoint, endPoint, self.stateTimestamp])

    def b_setSuitState(self, index, startPoint, endPoint):
        self.d_setSuitState(index, startPoint, endPoint)
        self.setSuitState(index, startPoint, endPoint)

    def getSuitState(self):
        return [
            self.suitState, self.startPoint, self.endPoint, self.stateTimestamp
        ]

    def setDifficulty(self, difficulty):
        self.difficulty = difficulty

    def getDifficulty(self):
        return self.difficulty

    def setBackup(self, backup):
        self.backup = backup

    def isBackup(self):
        return self.backup

    def setManager(self, mgr):
        self.mgr = mgr
        self.hood = CogBattleGlobals.HoodIndex2HoodName[
            self.getManager().getBattle().getHoodIndex()]

    def getManager(self):
        return self.mgr

    def printPos(self, task):
        print self.getPos(render)
        print self.getHpr(render)
        return task.cont

    def spawn(self):
        self.brain = CogBrainAI.CogBrain(self)
        landspot = random.choice(CIGlobals.SuitSpawnPoints[self.hood].keys())
        path = CIGlobals.SuitSpawnPoints[self.hood][landspot]
        index = CIGlobals.SuitSpawnPoints[self.hood].keys().index(landspot)
        self.b_setSuitState(2, index, index)
        self.currentPath = landspot
        track = self.posInterval(3, path, startPos=path + (0, 0, 50))
        track.start()
        yaw = random.uniform(0.0, 360.0)
        self.setH(yaw)
        if self.track:
            self.track.pause()
            self.track = None
        self.track = Sequence(Wait(5.4), Func(self.b_setAnimState, 'neutral'),
                              Wait(1.0), Func(self.startRoaming))
        self.track.start()
        self.b_setParent(CIGlobals.SPRender)

    def startRoaming(self):
        if self.head == "vp" or self.isBackup():
            # If this is a vp or a backup cog, do the random attacks.
            self.startAttacks()
        taskMgr.add(self.monitorHealth, self.uniqueName('monitorHealth'))
        if self.head == "vp":
            self.boss = SuitBoss.SuitBoss(self)
            self.boss.startBoss()
        else:
            self.brain.start()

    def startAttacks(self):
        if self.head != "vp":
            attackTime = random.randint(8, 20)
        else:
            attackTime = random.randint(8, 12)
        taskMgr.doMethodLater(attackTime, self.attackTask,
                              self.uniqueName('attackTask'))

    def attackTask(self, task):
        if self.brain.fsm.getCurrentState().getName() == "runAway":
            # Attack while running away... ain't nobody got time for that!
            delay = random.randint(6, 12)
            task.delayTime = delay
            return task.again
        if self.head == "vp":
            # We can't attack while we're flying
            if not self.boss.getFlying():
                self.chooseVictim()
        else:
            self.chooseVictim()
        if self.head != "vp":
            delay = random.randint(6, 15)
        else:
            delay = random.randint(6, 12)
        task.delayTime = delay
        return task.again

    def enableMovement(self):
        self.brain.start()
        if self.head != "vp":
            attackTime = random.randint(8, 20)
        else:
            attackTime = random.randint(8, 12)
        taskMgr.doMethodLater(attackTime, self.attackTask,
                              self.uniqueName('attackTask'))

    def disableMovement(self):
        taskMgr.remove(self.uniqueName('attackTask'))
        taskMgr.remove(self.uniqueName('continueSuitRoam'))
        if self.suitHealTrack:
            self.suitHealTrack.pause()
            self.suitHealTrack = None
        self.brain.end()
        self.b_setSuitState(3, -1, -1)
        if self.head != "vp":
            if self.walkTrack:
                self.ignore(self.walkTrack.getName())
                self.walkTrack.clearToInitial()
                self.walkTrack = None
        self.d_interruptAttack()

    def chooseVictim(self):
        toons = []
        for key in self.air.doId2do.keys():
            val = self.air.doId2do[key]
            if val.__class__.__name__ == "DistributedToonAI" or val.__class__.__name__ == "DistributedSuitAI" or val.__class__.__name__ == "DistributedPieTurretAI":
                if val.zoneId == self.zoneId:
                    if val.__class__.__name__ == "DistributedSuitAI" and val.head == "vp" \
                    and val.doId != self.doId or val.__class__.__name__ == "DistributedToonAI" or val.__class__.__name__ == "DistributedPieTurretAI":
                        # We can be a medic and heal the fellow VP...
                        if not val.isDead():
                            if self.getDistance(val) <= 40:
                                if val.__class__.__name__ == "DistributedToonAI":
                                    if not val.getGhost():
                                        toons.append(val)
                                else:
                                    toons.append(val)
        if toons == []:
            return
        toon = random.randint(0, len(toons) - 1)
        self.disableMovement()
        self.headsUp(toons[toon])
        self.attackToon(toons[toon])
        self.setAttacking(True)

    def attackToon(self, av):
        if av.__class__.__name__ in [
                "DistributedSuitAI", "DistributedPieTurretAI"
        ]:
            # Why would I pick pocket my boss?
            attack = random.randint(0, 6)
            attackName = SuitAttacks.SuitAttackLengths.keys()[attack]
        else:
            if self.head in ['vp']:
                attack = random.randint(0, 6)
                attackName = SuitAttacks.SuitAttackLengths.keys()[attack]
            else:
                attackName = random.choice(
                    SuitAttacks.SuitAttackLengths.keys())
                attack = SuitAttacks.SuitAttackLengths.keys().index(attackName)
        attackTaunt = random.randint(
            0,
            len(CIGlobals.SuitAttackTaunts[attackName]) - 1)
        timestamp = globalClockDelta.getFrameNetworkTime()
        self.sendUpdate('doAttack', [attack, av.doId, timestamp])
        if av.__class__.__name__ in [
                "DistributedSuitAI", "DistributedPieTurretAI"
        ]:
            distance = self.getDistance(av)
            speed = 50.0
            if attackName == "glowerpower":
                speed = 100.0
            timeUntilHeal = distance / speed
            if av.__class__.__name__ == "DistributedSuitAI":
                self.d_setChat(CIGlobals.SuitHealTaunt)
            else:
                self.d_setChat(
                    CIGlobals.SuitAttackTaunts[attackName][attackTaunt])
            if attackName != "glowerpower":
                if self.type == "C":
                    timeUntilRelease = 2.2
                else:
                    timeUntilRelease = 3.0
            else:
                timeUntilRelease = 1.0
            currentBossPos = av.getPos(render)
            hp = int(self.maxHealth /
                     SuitAttacks.SuitAttackDamageFactors[attackName])
            self.suitHealTrack = Sequence(
                Wait(timeUntilRelease + timeUntilHeal),
                Func(self.attemptToHealBoss, av, currentBossPos, hp))
            self.suitHealTrack.start()
        else:
            self.d_setChat(CIGlobals.SuitAttackTaunts[attackName][attackTaunt])
        time = SuitAttacks.SuitAttackLengths[attackName]
        if self.track:
            self.track.pause()
            self.track = None
        taskMgr.doMethodLater(SuitAttacks.SuitAttackLengths[attackName],
                              self.continuePathTask,
                              self.uniqueName('continueSuitRoam'))

    def attemptToHealBoss(self, boss, currBossPos, hp):
        if not boss.isEmpty():
            if (boss.getPos(render) - currBossPos).length() <= 1:
                if not boss.isDead():
                    if boss.__class__.__name__ == "DistributedSuitAI":
                        boss.b_setHealth(boss.getHealth() + hp)
                        boss.d_announceHealth(1, hp)
                    else:
                        # Turret
                        boss.b_setHealth(boss.getHealth() - hp)
                        boss.d_announceHealth(0, hp)
                    self.d_handleWeaponTouch()

    def continuePathTask(self, task):
        self.setAttacking(False)
        if self.head != "vp":
            if self.brain.fsm.getCurrentState().getName() == "followBoss":
                # If we're protecting the boss, don't walk away from him!
                return task.done
            else:
                self.brain.neutral_startLookingForToons()
                self.brain.start()
                return task.done
        self.continuePath()
        return task.done

    def d_handleWeaponTouch(self):
        self.sendUpdate("handleWeaponTouch", [])

    def continuePath(self):
        # Create a new path for the Suit if they are stuck...
        if self.head != "vp":
            if self.walkTrack:
                self.ignore(self.walkTrack.getName())
                self.walkTrack.clearToInitial()
                self.walkTrack = None
            self.brain.end()
            self.brain.start()
        else:
            self.b_setAnimState("neutral")

    def setAttacking(self, value):
        self.attacking = value

    def getAttacking(self):
        return self.attacking

    def monitorHealth(self, task):
        if self.health <= 0:
            taskMgr.remove(self.uniqueName('attackTask'))
            taskMgr.remove(self.uniqueName('continueSuitRoam'))
            if self.suitHealTrack:
                self.suitHealTrack.pause()
                self.suitHealTrack = None
            self.b_setSuitState(3, -1, -1)
            if self.walkTrack:
                self.ignore(self.walkTrack.getName())
                self.walkTrack.clearToInitial()
                self.walkTrack = None
            self.d_interruptAttack()
            self.brain.end()
            if self.head == "vp":
                self.boss.stopBoss()
            if self.track:
                self.track.pause()
                self.track = None

            anim2WaitTime = {
                'pie': 2.0,
                'drop': 6.0,
                'drop-react': 3.5,
                'squirt-small': 4.0,
                'squirt-large': 4.9,
                'soak': 6.5,
                'neutral': 0.0,
                'walk': 0.0
            }
            self.track = Sequence(Wait(anim2WaitTime[self.getAnimStateStr()]),
                                  Func(self.killSuit))
            self.track.start()

            return task.done
        return task.cont

    def isWalking(self):
        if self.walkTrack:
            return self.walkTrack.isPlaying()
        else:
            return False

    def killSuit(self):
        self.b_setAnimState('die')
        if self.track:
            self.track.pause()
            self.track = None
        self.track = Sequence(Wait(6.0), Func(self.closeSuit))
        self.track.start()

    def closeSuit(self):
        # Drop the jellybeans I stole before I die!
        self.itemDropper.drop()
        self.getManager().deadSuit(self.doId)
        self.disable()
        self.requestDelete()

    def createPath(self, path_key=None, durationFactor=0.2, fromCurPos=False):
        if path_key == None and not len(self.currentPathQueue):
            path_key_list = CIGlobals.SuitPathData[self.hood][self.currentPath]
            path_key = random.choice(path_key_list)
        elif len(self.currentPathQueue):
            path_key = self.currentPathQueue[0]
            self.currentPathQueue.remove(path_key)
        endIndex = CIGlobals.SuitSpawnPoints[self.hood].keys().index(path_key)
        path = CIGlobals.SuitSpawnPoints[self.hood][path_key]
        if self.walkTrack:
            self.ignore(self.walkTrack.getDoneEvent())
            self.walkTrack.clearToInitial()
            self.walkTrack = None
        if not self.currentPath or fromCurPos:
            startIndex = -1
        else:
            oldPath = self.currentPath
            startIndex = CIGlobals.SuitSpawnPoints[self.hood].keys().index(
                oldPath)
        self.currentPath = path_key
        pathName = self.uniqueName('suitPath')
        self.walkTrack = NPCWalkInterval(self,
                                         path,
                                         startPos=self.getPos(render),
                                         name=pathName,
                                         durationFactor=durationFactor,
                                         fluid=1)
        self.walkTrack.setDoneEvent(self.walkTrack.getName())
        self.startFollow()
        self.b_setSuitState(1, startIndex, endIndex)

    def startFollow(self):
        #self.b_setAnimState('walk')
        if self.walkTrack:
            self.acceptOnce(self.walkTrack.getName(), self.walkDone)
            self.walkTrack.start()

    def walkDone(self):
        if self.walkTrack:
            self.walkTrack.finish()
            self.walkTrack = None
        self.b_setAnimState('neutral')
        self.createPath()

    def toonHitByWeapon(self, weaponId, avId):
        sender = self.air.getMsgSender()
        weapon = SuitAttacks.SuitAttackLengths.keys()[weaponId]
        if not weapon in [
                "pickpocket", "fountainpen", "hangup", "buzzword",
                "razzledazzle", "jargon", "mumbojumbo", 'doubletalk',
                'schmooze', 'fingerwag', 'filibuster'
        ]:
            self.d_handleWeaponTouch()
        dmg = int(self.maxHealth / SuitAttacks.SuitAttackDamageFactors[weapon])
        toon = self.air.doId2do.get(avId, None)
        if toon:
            hp = toon.getHealth() - dmg
            if hp < 0:
                hp = 0
            toon.b_setHealth(hp)
            toon.d_announceHealth(0, dmg)
            if toon.isDead():
                self.b_setAnimState('win')
                taskMgr.remove(self.uniqueName('continueSuitRoam'))
                taskMgr.doMethodLater(6.0, self.continuePathTask,
                                      self.uniqueName('continueSuitRoam'))

    def turretHitByWeapon(weaponId, avId):
        weapon = SuitAttacks.SuitAttackLengths.keys()[weaponId]
        if not weapon in ["pickpocket", "fountainpen", "hangup"]:
            self.d_handleWeaponTouch()
        dmg = int(self.maxHealth / CIGlobals.SuitAttackDamageFactors[weapon])
        turret = self.air.doId2do.get(avId, None)
        if turret:
            turret.b_setHealth(turret.getHealth() - 1)
            turret.d_announceHealth(0, dmg)

    def setSuit(self, suitType, head, team, skeleton):
        self.type = suitType
        self.head = head
        self.team = team
        self.skeleton = skeleton
        self.health = CIGlobals.getSuitHP(self.level)
        self.maxHealth = self.health
        self.itemDropper.calculate()

    def b_setSuit(self, suitType, head, team, skeleton):
        self.d_setSuit(suitType, head, team, skeleton)
        self.setSuit(suitType, head, team, skeleton)

    def d_setSuit(self, suitType, head, team, skeleton):
        self.sendUpdate("setSuit", [suitType, head, team, skeleton])

    def getSuit(self):
        return tuple((self.type, self.head, self.team, self.skeleton))

    def setAnimState(self, anim):
        self.anim = anim

    def b_setAnimState(self, anim):
        if type(anim) == types.StringType:
            anim = self.animState2animId[anim]
        self.d_setAnimState(anim)
        self.setAnimState(anim)

    def d_setAnimState(self, anim):
        timestamp = globalClockDelta.getFrameNetworkTime()
        self.sendUpdate("setAnimState", [anim, timestamp])

    def getAnimState(self):
        return self.anim

    def getAnimStateStr(self):
        return self.animId2animState[self.getAnimState()]

    def d_interruptAttack(self):
        self.sendUpdate("interruptAttack", [])

    def d_setAttack(self, attack):
        self.sendUpdate("setAttack", [attack])

    def announceGenerate(self):
        DistributedAvatarAI.announceGenerate(self)
        if self.track:
            self.track.pause()
            self.track = None
        Sequence(Wait(0.1), Func(self.spawn)).start()

    def generate(self):
        DistributedAvatarAI.generate(self)
        DistributedSmoothNodeAI.generate(self)

    def disable(self):
        try:
            self.DistributedSuitAI_disabled
        except:
            self.DistributedSuitAI_disabled = 1
            if self.track:
                self.track.pause()
                self.track = None
            taskMgr.remove(self.uniqueName('monitorHealth'))
            taskMgr.remove(self.uniqueName('attackTask'))
            taskMgr.remove(self.uniqueName('continueSuitRoam'))
            if self.suitHealTrack:
                self.suitHealTrack.pause()
                self.suitHealTrack = None
            if self.walkTrack:
                self.ignore(self.walkTrack.getName())
                self.walkTrack.clearToInitial()
                self.walkTrack = None
            if self.boss:
                self.boss.stopBoss()
                self.boss = None
            if self.brain:
                self.brain.end()
                self.brain = None
            self.itemDropper.cleanup()
            self.itemDropper = None
            self.aiChar = None
            self.aiBehaviors = None
            self.continuePathId = None
            self.attackId = None
            self.name = None
            self.anim = None
            self.state = None
            self.damage = None
            self.health = None
            self.backup = None
            self.type = None
            self.team = None
            self.head = None
            self.skeleton = 0
            self.dmg_lbl = None
            self.currentPath = None
            self.lbl_int = None
            self.bean = None
            self.avatarType = None
            self.lateX = None
            self.lateY = None
            self.currentPathQueue = None
            DistributedAvatarAI.disable(self)
        return

    def delete(self):
        try:
            self.DistributedSuitAI_deleted
        except:
            self.DistributedSuitAI_deleted = 1
            del self.aiChar
            del self.brain
            del self.aiBehaviors
            del self.boss
            del self.continuePathId
            del self.attackId
            del self.name
            del self.anim
            del self.state
            del self.damage
            del self.health
            del self.type
            del self.team
            del self.head
            del self.skeleton
            del self.dmg_lbl
            del self.lbl_int
            del self.bean
            del self.currentPath
            del self.avatarType
            del self.walkTrack
            del self.suitHealTrack
            del self.backup
            del self.lateX
            del self.lateY
            del self.currentPathQueue
            DistributedAvatarAI.delete(self)
            DistributedSmoothNodeAI.delete(self)
        return
class DistributedDeliveryGameSuitAI(DistributedSuitAI):
    notify = directNotify.newCategory('DistributedDeliveryGameSuitAI')

    def __init__(self, air, mg):
        DistributedSuitAI.__init__(self, air)
        self.mg = mg
        self.truck = random.choice(self.mg.trucks)
        self.truckIndex = self.mg.trucks.index(self.truck)
        self.spawnPoint = None
        return

    def walkToTruck(self):
        index = DGG.WalkToTruckIndex
        pos = DGG.TruckSuitPointsByIndex[self.truckIndex]
        startPos = self.getPos(render)
        self.b_setSuitState(1, -1, index)
        durationFactor = 0.2
        pathName = self.uniqueName('WalkToTruck')
        self.walkTrack = NPCWalkInterval(self, pos, startPos=startPos, name=pathName, durationFactor=durationFactor, fluid=1)
        self.walkTrack.setDoneEvent(self.walkTrack.getName())
        self.acceptOnce(self.walkTrack.getDoneEvent(), self.__walkedToTruck)
        self.walkTrack.start()
        self.b_setAnimState(SuitGlobals.getAnimId(SuitGlobals.getAnimByName('walk')))

    def __walkedToTruck(self):
        self.truck.suitPickUpBarrel(self.doId)
        self.walkBackToSpawnPointWithBarrel()

    def walkBackToSpawnPointWithBarrel(self):
        pos = DGG.SpawnPoints[self.spawnPoint]
        startPos = self.getPos(render)
        self.b_setSuitState(1, -1, self.spawnPoint)
        durationFactor = 0.2
        pathName = self.uniqueName('WalkBackToSpawn')
        self.walkTrack = NPCWalkInterval(self, pos, startPos=startPos, name=pathName, durationFactor=durationFactor, fluid=1)
        self.walkTrack.setDoneEvent(self.walkTrack.getName())
        self.acceptOnce(self.walkTrack.getDoneEvent(), self.__walkedBack2Spawn)
        self.walkTrack.start()
        self.b_setAnimState(SuitGlobals.getAnimId(SuitGlobals.getAnimByName('tray-walk')))

    def __walkedBack2Spawn(self):
        self.b_setSuitState(3, self.spawnPoint, self.spawnPoint)
        base.taskMgr.doMethodLater(10, self.__finished, self.uniqueName('finishSuit'))

    def __finished(self, task):
        self.mg.suits.remove(self)
        self.truck.barrelDroppedOff()
        self.requestDelete()
        return task.done

    def spawn(self):
        pos = random.choice(DGG.SpawnPoints)
        index = DGG.SpawnPoints.index(pos)
        self.spawnPoint = index
        self.b_setSuitState(2, index, index)
        flyTrack = self.posInterval(3, pos, startPos=pos + (0, 0, 50))
        flyTrack.start()
        self.track = Sequence()
        self.track.append(Wait(5.4))
        self.track.append(Func(self.b_setAnimState, 'neutral'))
        self.track.append(Wait(1.0))
        self.track.append(Func(self.walkToTruck))
        self.track.start()
        self.b_setParent(CIGlobals.SPRender)

    def delete(self):
        base.taskMgr.remove(self.uniqueName('finishSuit'))
        if hasattr(self, 'walkTrack') and self.walkTrack:
            self.ignore(self.walkTrack.getDoneEvent())
            self.walkTrack.finish()
            self.walkTrack = None
        self.mg = None
        self.truck = None
        self.truckIndex = None
        self.spawnPoint = None
        DistributedSuitAI.delete(self)
        return
Example #47
0
class DistributedEagleSuitAI(DistributedSuitAI):
    notify = directNotify.newCategory('DistributedEagleSuitAI')

    def __init__(self, air):
        DistributedSuitAI.__init__(self, air)
        self.mg = None
        self.flyTrack = None
        self.currentFlyPoint = None
        self.flySpeed = 0.0
        return

    def setMinigame(self, mg):
        self.mg = mg

    def getMinigame(self):
        return self.mg

    def handleGotHit(self):
        self.b_setAnimState('flail')
        if self.flyTrack:
            self.ignore(self.flyTrack.getDoneEvent())
            self.flyTrack.pause()
            self.flyTrack = None
        self.sendUpdate('fallAndExplode', [])
        self.b_setSuitState(6, -1, -1)
        self.flyTrack = Sequence(LerpPosInterval(self, duration=4.0, pos=self.getPos(render) - (0, 0, 75), startPos=self.getPos(render), blendType='easeIn'), Wait(1.5), Func(self.killMe))
        self.flyTrack.start()
        return

    def killMe(self):
        self.disable()
        self.requestDelete()

    def setFlySpeed(self, value):
        self.flySpeed = value

    def b_setFlySpeed(self, value):
        self.sendUpdate('setFlySpeed', [value])
        self.setFlySpeed(value)

    def getFlySpeed(self):
        return self.flySpeed

    def spawn(self):
        if not self.getMinigame():
            self.notify.error('Tried to spawn before self.mg was set!')
        self.b_setAnimState('flyNeutral')
        point = random.choice(EGG.EAGLE_FLY_POINTS)
        self.setPos(point)
        self.d_setPos(*point)
        self.b_setFlySpeed(EGG.ROUND_2_EAGLE_SPEED[self.getMinigame().getRound()])
        self.createFlyPath()
        self.b_setParent(CIGlobals.SPRender)

    def createFlyPath(self):
        self.b_setAnimState('flyNeutral')
        if self.flyTrack:
            self.ignore(self.flyTrack.getDoneEvent())
            self.flyTrack.pause()
            self.flyTrack = None
        point = random.choice(EGG.EAGLE_FLY_POINTS)
        if self.currentFlyPoint == point:
            self.createFlyPath()
            return
        else:
            if self.currentFlyPoint == None:
                point_list = list(EGG.EAGLE_FLY_POINTS)
                point_list.remove(point)
                startIndex = point_list.index(random.choice(point_list))
            else:
                startIndex = -1
            self.b_setSuitState(5, startIndex, EGG.EAGLE_FLY_POINTS.index(point))
            mgRound = self.getMinigame().getRound()
            if mgRound:
                self.flyTrack = NPCWalkInterval(self, point, durationFactor=EGG.ROUND_2_EAGLE_SPEED[mgRound], startPos=self.getPos(render), fluid=1, name=self.uniqueName('DEagleSuitAI-flyTrack'))
                self.flyTrack.setDoneEvent(self.flyTrack.getName())
                self.acceptOnce(self.flyTrack.getDoneEvent(), self.handleFlyDone)
                self.flyTrack.start()
                self.currentFlyPoint = point
            else:
                return
            return

    def handleFlyDone(self):
        self.createFlyPath()

    def delete(self):
        del self.currentFlyPoint
        del self.mg
        if self.flyTrack:
            self.ignore(self.flyTrack.getDoneEvent())
            self.flyTrack.pause()
            self.flyTrack = None
        DistributedSuitAI.delete(self)
        return
class DistributedTutorialSuitAI(DistributedSuitAI):
    notify = directNotify.newCategory('DistributedTutorialSuitAI')
    ATTACK_IVAL_RANGE = [3, 15]

    def __init__(self, air, index, tut, avatarId):
        DistributedSuitAI.__init__(self, air)
        self.tutPartIndex = index
        self.tutorial = tut
        self.avatarId = avatarId
        self.currentPath = None
        self.walkTrack = None
        return

    def delete(self):
        base.taskMgr.remove(self.uniqueName('monitorHealth'))
        base.taskMgr.remove(self.uniqueName('doAttack'))
        base.taskMgr.remove(self.uniqueName('scwaa'))
        self.stopAttacks()
        if self.track:
            self.track.pause()
            self.track = None
        if self.walkTrack:
            self.walkTrack.pause()
            self.walkTrack = None
        if self.currentPath:
            self.currentPath = None
        self.tutorial = None
        self.tutPartIndex = None
        self.avatarId = None
        DistributedSuitAI.delete(self)
        return

    def spawn(self):
        pos = TutorialGlobals.SUIT_POINTS[TutorialGlobals.SUIT_SPAWN_POINT]
        index = TutorialGlobals.SUIT_POINTS.index(pos)
        self.spawnPoint = index
        self.b_setSuitState(2, index, index)
        flyTrack = self.posInterval(3, pos, startPos=pos + (0, 0, 50))
        flyTrack.start()
        self.track = Sequence()
        self.track.append(Wait(5.4))
        self.track.append(Func(self.b_setAnimState, 'neutral'))
        self.track.append(Wait(1.0))
        self.track.append(Func(self.startAI))
        self.track.start()
        self.b_setParent(CIGlobals.SPRender)
        taskMgr.add(self.monitorHealth, self.uniqueName('monitorHealth'))

    def createPath(self, fromCurPos = False):
        durationFactor = 0.2
        if not hasattr(self, 'currentPath'):
            self.currentPath = None
        if self.currentPath == None:
            path = random.choice(TutorialGlobals.SUIT_POINTS)
            self.currentPath = TutorialGlobals.SUIT_POINTS.index(path)
            startIndex = -1
        else:
            if fromCurPos == False:
                startIndex = int(self.currentPath)
            else:
                startIndex = -1
            self.currentPath += 1
            if self.currentPath >= len(TutorialGlobals.SUIT_POINTS):
                self.currentPath = 0
            path = TutorialGlobals.SUIT_POINTS[self.currentPath]
        endIndex = self.currentPath
        startPos = self.getPos(render)
        pathName = self.uniqueName('suitPath')
        self.walkTrack = NPCWalkInterval(self, path, startPos=startPos, name=pathName, durationFactor=durationFactor, fluid=1)
        self.walkTrack.setDoneEvent(self.walkTrack.getName())
        self.acceptOnce(self.walkTrack.getDoneEvent(), self.createPath)
        self.walkTrack.start()
        self.b_setAnimState('walk')
        self.b_setSuitState(1, startIndex, endIndex)
        return

    def monitorHealth(self, task):
        if self.health <= 0:
            self.tutorial.sendUpdateToAvatarId(self.avatarId, 'suitNoHealth', [self.tutPartIndex])
            if self.walkTrack:
                self.ignore(self.walkTrack.getDoneEvent())
                self.walkTrack.pause()
                self.walkTrack = None
            self.b_setSuitState(0, -1, -1)
            currentAnim = SuitGlobals.getAnimByName(self.anim)
            self.clearTrack()
            base.taskMgr.remove(self.uniqueName('scwaa'))
            self.stopAttacks()
            if currentAnim:
                self.track = Sequence(Wait(currentAnim.getDeathHoldTime()), Func(self.killSuit))
                self.track.start()
            else:
                self.killSuit()
            return Task.done
        else:
            return Task.cont

    def setSuit(self, plan, variant = 0):
        DistributedSuitAI.setSuit(self, plan, variant, self.tutorial)

    def closeSuit(self):
        DistributedSuitAI.closeSuit(self)
        self.tutorial.sendUpdateToAvatarId(self.avatarId, 'suitExploded', [self.tutPartIndex])

    def startAttacks(self):
        base.taskMgr.doMethodLater(random.randint(*self.ATTACK_IVAL_RANGE), self.__doAttack, self.uniqueName('doAttack'))

    def __doAttack(self, task):
        base.taskMgr.remove(self.uniqueName('scwaa'))
        target = self.air.doId2do.get(self.avatarId)
        if not target:
            return task.done
        self.clearTrack()
        self.b_setSuitState(0, -1, -1)
        self.b_setAnimState('neutral')
        self.headsUp(target)
        attack = random.choice(self.suitPlan.getAttacks())
        attackIndex = SuitAttacks.SuitAttackLengths.keys().index(attack)
        attackTaunt = random.randint(0, len(CIGlobals.SuitAttackTaunts[attack]) - 1)
        timestamp = globalClockDelta.getFrameNetworkTime()
        if self.isDead():
            self.stopAttacks()
            return task.done
        self.sendUpdate('doAttack', [attackIndex, target.doId, timestamp])
        self.d_setChat(CIGlobals.SuitAttackTaunts[attack][attackTaunt])
        attackLength = SuitAttacks.SuitAttackLengths[attack]
        base.taskMgr.doMethodLater(attackLength, self.__suitContinueWalkAfterAttack, self.uniqueName('scwaa'))
        task.delayTime = random.randint(*self.ATTACK_IVAL_RANGE)
        return task.again

    def __suitContinueWalkAfterAttack(self, task):
        self.createPath(fromCurPos=True)
        return task.done

    def stopAttacks(self):
        base.taskMgr.remove(self.uniqueName('doAttack'))

    def startAI(self):
        if self.tutPartIndex == 0:
            self.b_setAnimState('neutral')
        elif self.tutPartIndex == 1:
            self.createPath()
        elif self.tutPartIndex == 2:
            self.createPath()
            self.startAttacks()