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()
コード例 #2
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
コード例 #3
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 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 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

    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:
                # Yes! We see the prowler!
                return 1
        return 0

    def __guard(self, task):
        # Let me check if the target is my frustrum, and if it's a close enough distance from me.
        if (self.eyeNode.node().isInView(base.localAvatar.getPos(self.eyeNode))
                and
                self.getDistance(base.localAvatar) <= self.PROWLER_DISTANCE):
            # Now, let me check if the toon is standing right in front of me; not occluded.
            if self.__checkToon():
                # Yes! We see some one!
                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

    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

    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:
            # Hmm, I guess it was nothing.
            chat = random.choice(CGG.GuardDialog['disregard'])
            self.setChat(chat)
            self.request('TurnToGuardSpot')
            return task.done
        # Let me see the target again, so I know it's actually something.
        if (self.eyeNode.node().isInView(base.localAvatar.getPos(self.eyeNode))
                and
                self.getDistance(base.localAvatar) <= self.PROWLER_DISTANCE):
            # Now, let me check if the toon is standing right in front of me; not occluded.
            if self.__checkToon():
                # There he is!
                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):
        # Return the key of the closest point to the localAvatar.
        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:
            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)

    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 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')

    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.generateSuit(type, self.SUIT, team, self.MAX_HP, 0, False)
        base.taskMgr.add(self.__viewDistance, self.viewDistanceTaskName)
        self.setPythonTag('guard', self)
        self.eyeLight = Spotlight('eyes')
        self.eyeLens = PerspectiveLens()
        self.eyeLens.setMinFov(90.0 / (4. / 3.))
        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):
        # All the guards in the warehouse eat up a lot of frames.  This task will
        # hide the guard geometry if it's too far away.

        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)
コード例 #6
0
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()
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

    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)

    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(6.5))
        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)

    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
        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)
        # Choose a random attack and start it.
        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:
            # This is part one, all we do is stand still and wait to die.
            self.b_setAnimState('neutral')
        elif self.tutPartIndex == 1:
            # This is part two, we just walk around and wait to die.
            self.createPath()
        elif self.tutPartIndex == 2:
            # This is part three, we walk around, attack a bit, and wait to die.
            self.createPath()
            self.startAttacks()