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