def setAI(self): self.AIchar = AICharacter("enemy", self.np, 100, 10., 50) self.base.AIworld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() # self.AIbehaviors.wander(50, 0, 1000, 1.0) # self.AIbehaviors.seek(self.base.fighter) self.AIbehaviors.evade(self.base.fighter, 1000, 2000)
def __init__(self, base, location, team): #assign what we know off the bat #TODO chosen model currently depends on team - 0 is friendly, 1 is enemy if team == 0: self.model = "models/friend_rifleman" elif team == 1: self.model = "models/enemy_rifleman" self.viewRange = 400 #used by application to determine what character can 'see' self.contacts = [] #stores nearby objects self.target = None #stores target self.goal = None #stores movement goal (if any) self.team = team #make call to parent with this model entity.__init__(self, self.model, base, location) #add rifle to the rifleman, as one does self.weaponNode = self.exposeJoint(None, "modelRoot", "weaponNode") self.weapon = carbine(self, self.weaponNode) self.pose("highReady", 0) #add AI to this object #mass 60, movement force 0.05, max force 25 self.ai = AICharacter(str(self), self, 30, 0.05, 25) base.AIworld.addAiChar(self.ai) self.AiBehaviors = self.ai.getAiBehaviors() #load navmesh self.AiBehaviors.initPathFind(base.navmesh) #add all structures for building in base.structures: #this is super aggressive so disable for now.. self.AiBehaviors.addStaticObstacle(building)
def initActor(self): faEmpty = self.stage.find("**/{}_{}".format(self.name, self.indexNumber)) faPos = faEmpty.getPos() self.actor = Actor( "{}".format(self.modelName), { "idle": "{}-idle".format(self.modelName), "walk": "{}-walk".format(self.modelName) }) self.actor.reparentTo(self.stage) self.actor.setPos(faPos) cNode = CollisionNode("{}_{}".format(self.name, self.indexNumber)) cNode.addSolid(CollisionBox(0, 1.5, 1.5, 1)) faCollision = self.actor.attachNewNode(cNode) ##################################################### # faCollision.show() ##################################################### base.pusher.addCollider(faCollision, self.actor, base.drive.node()) base.cTrav.addCollider(faCollision, base.pusher) self.actorsList.append(self) AIchar = AICharacter("{}_{}".format(self.name, self.indexNumber), self.actor, 100, 0.05, 5) base.AIworld.addAiChar(AIchar) self.AIbehaviors = AIchar.getAiBehaviors()
def __init__(self, name, root, route, mass, movforce, maxforce): AICharacter.__init__(self, name, root, mass, movforce, maxforce) self.state = Hooded.STATE_PATROL self.initTimer = True self.attackTimer = True # we create a spotlight that will be the sentinel's eye and will be used to fire the inView method self.slight = Spotlight('slight') self.slight.setColor((1, 1, 1, 1)) lens = PerspectiveLens() lens.setNear(0.1) lens.setFar(Hooded.SIGHT) lens.setFov(Hooded.FOV) self.slight.setLens(lens) self.slnp = self.get_node_path().attachNewNode(self.slight) #TODO: Substitute for a collision polygon, so that the player class alerts an enemy of its presence #self.slight.showFrustum() self.slnp.setH(self.slnp.getH()-180) self.slnp.setPos(0, 0, Hooded.HEIGHT) self.hearing = 5.0 self.dynamicObstacles = [] self.detected = False self.pathfinding = False self.lostTarget = False self.countTime = False self.goingBack = False self.heard = False self.isProtected = False self.attacked = False self.started = False self.sentinelHandler = CollisionHandlerQueue() #TODO: Intruders should be added via an external method self.intruders = [] # this is important: as we said the inView method don't cull geometry but take everything is in sight frustum - therefore to simulate an hide and seek feature we gotta cheat a little: this ray is masked to collide with walls and so if the avatar is behind a wall the ray will be 'deflected' (we'll see how later in the sent_traverse function) - so we know who's behind a wall but we fake we can't see it. sentraygeom = CollisionSegment(0, 0, Hooded.HEIGHT, 0, Hooded.SIGHT, Hooded.HEIGHT) sentinelRay = self.get_node_path().attachNewNode(CollisionNode('sentinelray')) sentinelRay.node().addSolid(sentraygeom) # we set to the ray a cumulative masking using the or operator to detect either the avatar's body and the wall geometry sentinelRay.node().setFromCollideMask(CollisionMask.PLAYER) sentinelRay.node().setIntoCollideMask(CollisionMask.NONE) # we add the ray to the sentinel collider and now it is ready to go base.cTrav.addCollider(sentinelRay, self.sentinelHandler) self.screechsound = loader.loadSfx("assets/sounds/enemies/nazgul_scream.mp3") self.setPatrolPos(route)
class Pokemao():#Inimigos): def __init__(self,render, num): self.nome = "Pokemao" self.agi = 10 self.hp = 10 self.int = 5 self.str = 1 self.dano = 5 self.bloqueio = False self.bloqueado = False self.velocAtaque = 0.5 self.arma = None self.escudo = None self.armadura = None self.delete = False self.render = render self.loadModels(num) self.setAI() def getPos(self): return self.pokemao.getPos() def loadModels(self,num): # Seeker pokemaoPos = Vec3(-10,-30.0,2.10) self.pokemao = Actor('personagens/Modelos/Pokeperna/p1', {"andar" :"personagens/Modelos/Pokeperna/p1-andar.egg", "saltar" :"personagens/Modelos/Pokeperna/p1-saltar.egg", "correr" : "personagens/Modelos/Pokeperna/p1-correr", "abaixar" : "personagens/Modelos/Pokeperna/p1-abaixar"}) self.pokemao.reparentTo(self.render) #self.wanderer.setScale(0.5) self.pokemao.setPos(pokemaoPos) self.pokemao.setTag("inimigo",str(num)) def setAI(self): #Creating AI World self.AIworld = AIWorld(self.render) self.AIchar = AICharacter("wanderer",self.pokemao, 100, 0.05, 5) self.AIworld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() self.AIbehaviors.wander(5, 0, 10, 1.0) self.pokemao.loop("correr") #AI World update taskMgr.add(self.AIUpdate,"AIUpdate") #to update the AIWorld def AIUpdate(self,task): if self.hp < 1: #self.cleanup() self.pokemao.detachNode() self.delete = True self.AIworld.update() return Task.cont
def makeAi(self): # Make some ai character for each self.aiChar = AICharacter("Enemy" + str(self.id), self.model, -100, 0.05 + (0.05 * self.strenght), 6 + (1 * self.strenght)) self.main.AiWorld.addAiChar(self.aiChar) self.AIbehaviors = self.aiChar.getAiBehaviors() self.AIbehaviors.pursue(self.main.player.model) return self.aiChar
def setAI(self): self.AIChar = AICharacter("boss", self.enemy, 100, .05, 25) self.AIWorld.addAiChar(self.AIChar) self.AIbehaviors = self.AIChar.getAiBehaviors() self.AIbehaviors.pursue(base.camera) base.taskMgr.add(self.AIUpdate, "Boss AI Update")
def setAI(self): collisions = render.getPythonTag('WorldCollisions') collisions.addCogGroundCollision(self.cog) self.AIWorld = AIWorld(render) self.AIChar = AICharacter('Cog', self.cog.getCog(), -125, 90, -14) self.AIWorld.addAiChar(self.AIChar) self.AIBehaviors = self.AIChar.getAiBehaviors() if self.support == False: self.AIBehaviors.pathFollow(8) self.AIBehaviors.addToPath(VBase3(110.60, -0.32, 4.57)) checkpoints = self.spawn.getPath().getCheckpoints() for checkpoint in xrange(len(checkpoints)): self.AIBehaviors.addToPath(checkpoints[checkpoint].getPos()) self.AIBehaviors.startFollow() else: self.AIBehaviors.pursue(render.find('**/Toon')) self.cog.getCog().loop('walk') base.taskMgr.add(self.AIUpdate, "AIUpdate")
def setAI(self): # Flag this as an AI character #Faster enemy pursue self.AIchar = AICharacter("standby", self.enemy, 100,.05,250) self.AIWorld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() self.AIbehaviors.pursue(base.camera) self.AIbehaviors.pauseAi("pursue") #Slower enemy pursue self.AIchar2 = AICharacter("standby2", self.enemy, 100, .05, 100) self.AIWorld.addAiChar(self.AIchar2) self.AIbehaviors2 = self.AIchar2.getAiBehaviors() self.AIbehaviors2.pursue(base.camera) self.AIbehaviors2.pauseAi("pursue") base.taskMgr.add(self.AIUpdate, "Update AI")
def __init__(self, parent, model, name, ai_world, mass, movt_force, max_force): PhysicalNode.__init__(self, parent, model, name) self.mass = mass self.addCollisionSphere(1.25) self.toggleWalkAnimation() #----------------------------------------------------------------------- # Initialize Artificial Intelligence #----------------------------------------------------------------------- self.ai_char = AICharacter("ai_%s" % name, self.actor, mass, movt_force, max_force) ai_world.addAiChar(self.ai_char) aiBehaviors = self.ai_char.getAiBehaviors() equismo = base.gameState.currentState.objects['equismo'] aiBehaviors.pursue(equismo.actor)
def setAI(self): #Creating AI World self.AIworld = AIWorld(self.render) self.AIchar = AICharacter("pokeperna",self.pokeperna, 60, 0.05, 5) self.AIworld.addAiChar(self.AIchar) self.aiBehaviors = self.AIchar.getAiBehaviors() #self.aiBehaviors.initPathFind("mapa/Modelos/cidade/navmesh.csv") #Path follow (note the order is reveresed) #AI World update taskMgr.add(self.AIUpdate,"AIUpdate")
def setAI(self): #Creating AI World self.AIworld = AIWorld(self.render) self.AIchar = AICharacter("wanderer",self.pokemao, 100, 0.05, 5) self.AIworld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() self.AIbehaviors.wander(5, 0, 10, 1.0) self.pokemao.loop("correr") #AI World update taskMgr.add(self.AIUpdate,"AIUpdate")
def __init__(self, nodePath): NodePath.__init__(self, nodePath) self.actorHandle = None if isinstance(nodePath, Actor): self.actorHandle = nodePath self.aiCharHandle = AICharacter(nodePath.getName(), nodePath, 0.01, 0.01, 0.01) # default properties for a GameObject self.name = self.getName() self.scripts = { } # {string triggerType : list of string scriptTags} TODO: argsList self.passable = True #self.lifeStatus = LifeStatus.INANIMATE self.lifeStatus = LifeStatus.ALIVE self.curHP = 1 # CONSIDER: bundle HP and LifeStatus together self.maxHP = 1 self.strategy = Strategy.NEUTRAL self.spells = [] self.stopThreshold = 60 self.__processTags()
class Natan(PhysicalNode): ANIMATIONS = ["walk"] JUMP_SOUND = ["water_jumping", 7] def __init__(self, parent, model, name, ai_world, mass, movt_force, max_force): PhysicalNode.__init__(self, parent, model, name) self.mass = mass self.addCollisionSphere(1.25) self.toggleWalkAnimation() #----------------------------------------------------------------------- # Initialize Artificial Intelligence #----------------------------------------------------------------------- self.ai_char = AICharacter("ai_%s" % name, self.actor, mass, movt_force, max_force) ai_world.addAiChar(self.ai_char) aiBehaviors = self.ai_char.getAiBehaviors() equismo = base.gameState.currentState.objects['equismo'] aiBehaviors.pursue(equismo.actor) #--------------------------------------------------------------------------- # Animation #--------------------------------------------------------------------------- def toggleWalkAnimation(self): if self.model.getCurrentAnim() == "walk": self.model.stop() else: self.model.loop("walk", restart=False) #--------------------------------------------------------------------------- # Collision #--------------------------------------------------------------------------- def handleCollisionEvent(self, entry, type): normal = entry.getSurfaceNormal(self) normal.z = 0 normal.normalize() equismo = base.gameState.currentState.objects['equismo'] otherVelocity = equismo.velocity otherMass = equismo.mass self.collide(-normal, otherVelocity, otherMass, 0.75)
def __init__(self, nodePath): NodePath.__init__(self, nodePath) self.actorHandle = None if isinstance(nodePath, Actor): self.actorHandle = nodePath self.aiCharHandle = AICharacter(nodePath.getName(), nodePath, 0.01, 0.01, 0.01) # default properties for a GameObject self.name = self.getName() self.scripts = {} # {string triggerType : list of string scriptTags} TODO: argsList self.passable = True #self.lifeStatus = LifeStatus.INANIMATE self.lifeStatus = LifeStatus.ALIVE self.curHP = 1 # CONSIDER: bundle HP and LifeStatus together self.maxHP = 1 self.strategy = Strategy.NEUTRAL self.spells = [] self.stopThreshold = 60 self.__processTags()
class CogAI(DirectObject): cancelStep = False def __init__(self, cog, spawn, support = False): self.cog = cog self.spawn = spawn self.attack = True self.support = support self.flyIn() def setAI(self): collisions = render.getPythonTag('WorldCollisions') collisions.addCogGroundCollision(self.cog) self.AIWorld = AIWorld(render) self.AIChar = AICharacter('Cog', self.cog.getCog(), -125, 90, -14) self.AIWorld.addAiChar(self.AIChar) self.AIBehaviors = self.AIChar.getAiBehaviors() if self.support == False: self.AIBehaviors.pathFollow(8) self.AIBehaviors.addToPath(VBase3(110.60, -0.32, 4.57)) checkpoints = self.spawn.getPath().getCheckpoints() for checkpoint in xrange(len(checkpoints)): self.AIBehaviors.addToPath(checkpoints[checkpoint].getPos()) self.AIBehaviors.startFollow() else: self.AIBehaviors.pursue(render.find('**/Toon')) self.cog.getCog().loop('walk') base.taskMgr.add(self.AIUpdate, "AIUpdate") def calcChance(self, percent): if(random.randint(0, 100) < percent): return True else: return False def toggleAttack(self): if(self.attack): self.attack = False else: self.attack = True def AIUpdate(self, task): if(self.AIBehaviors.behaviorStatus('pathfollow') == 'done'): self.cog.getCog().loop('neutral') self.AIBehaviors.removeAi('pathfollow') toonHall = render.getPythonTag("ToonHall") toonHall.startCogEnter(self.cog) return Task.done else: if(self.cog.getHealth() > 0): if(self.calcChance(40) and self.attack): def resumeAI(task): self.AIBehaviors.resumeAi('pathfollow') self.cog.getCog().loop('walk') return Task.done def enableAttacks(task): return Task.done avatar = render.find('**/Toon') if(self.cog.getCog().getDistance(avatar) <= 20): self.AIBehaviors.pauseAi('pathfollow') self.cog.getCog().stop() self.attack = False self.cog.getCog().lookAt(avatar) self.cog.getCog().play('throw-object') attack = CogAttacks().getRandomAttack(self.cog.getLevel() * 2) attack.execute(self.cog) base.taskMgr.doMethodLater(10, enableAttacks, 'Toggle Attack') base.taskMgr.doMethodLater(3, resumeAI, 'Resume AI') self.AIWorld.update() return Task.cont else: self.AIBehaviors.removeAi('pathfollow') return Task.done def flyIn(self): phase_4 = "phase_4/models/props" cog = self.cog.getCog() collisions = render.getPythonTag('WorldCollisions') collisions.addCogCollision(self.cog) self.propeller = Actor(loader.loadModel(phase_4 + "/propeller-mod.bam"), {'chan' : loader.loadModel(phase_4 + "/propeller-chan.bam")}) self.propeller.reparentTo(cog.find('**/joint_head')) propSound = SoundBank.getSound('propeller') propSound.setLoop(True) propSound.setVolume(0.8) propSound.play() pos = cog.getPos() cog.setPos(pos.getX(), pos.getY(), pos.getZ() + 20) cog.pose('landing', 1) cog.colorScaleInterval(4.8, Vec4(1, 1, 1, 1), startColorScale=Vec4(0.2509803921568627, 0.2509803921568627, 0.2509803921568627, 0.25), blendType='easeInOut').start() path = cog.posInterval(5, pos, startPos = cog.getPos()) path.start() self.propeller.loop('chan', fromFrame=0, toFrame=3) base.taskMgr.add(self.handleCogDead, 'Handle Cog Death') base.taskMgr.doMethodLater(4, self.playInSound, 'Play In Sound', extraArgs = [propSound], appendTask = True) base.taskMgr.doMethodLater(5, self.landCog, 'Land Cog') def handleCogDead(self, task): if(self.cog.isDefeated): self.cancelStep = True collisions = render.getPythonTag('WorldCollisions') collisions.addCogGroundCollision(cog = self.cog) return Task.done else: return Task.cont def landCog(self, task): if not self.cancelStep: base.taskMgr.remove('Handle Cog Death') self.propeller.play('chan', fromFrame=35, toFrame=87) self.cog.getCog().play('landing') base.taskMgr.doMethodLater(3, self.removePropeller, 'Remove Propeller') return Task.done def removePropeller(self, task): self.propeller.cleanup() self.propeller.removeNode() self.setAI() return Task.done def playInSound(self, sound, task): if not self.cancelStep: sound.stop() SoundBank.getSound('propeller_in').play() return Task.done
class Enemy(DirectObject): #Flag for detecting hit enemy delFlag = False pauseFlag = False #Check for peaceful mode configFile = open("config.txt") configList = configFile.readlines() configFile.close() peacefulMode = configList[6].split("=")[1].translate(None,"\n") def __init__(self, model, id): self.dontSpawn = False self.id = id #init and render self.enemyNode = NodePath('enemy'+str(id)) self.AIWorld = AIWorld(base.render) self.enemyNode.reparentTo(base.render) # Load the enemy model, set the scale, and add to render self.enemy =Actor(model,{"walk":"resources/humanoid-walk"}) self.enemy.reparentTo(self.enemyNode) self.enemy.setScale(0.2) #configure hit tube self.xTop = self.enemy.getX() self.yTop = self.enemy.getY() self.zTop = self.enemy.getZ() - 15 xBot = self.xTop yBot = self.yTop zBot = self.zTop - 10 self.cs = CollisionTube(self.xTop, self.yTop, self.zTop, xBot, yBot, zBot, 20) #init cnode self.cnodepath = self.enemy.attachNewNode(CollisionNode('cnode'+str(id))) self.cnodepath.setTag('objectTag', str(id)) self.cnodepath.node().addSolid(self.cs) #so we can walk into the enemies self.chand = CollisionHandlerEvent() # must be same cTrav that was set in player, global collider thing base.cTrav.addCollider(self.cnodepath, self.chand) self.accept('cnode'+str(id), self.hit) # base settings like damage and health. modify spawner later to change these once we have a more diverse population self.health = 20*base.damageMod self.damage = 25; self.fireDelta = 0 self.fireOffset = random.randint(0, 200) self.deadFlag = False self.scrubCannon = ScrubCannon(base.camera, self.enemy) #Sets enemy position def setPos(self, x, y, z): #Set enemy position self.enemy.setPos(x, y, z) #Checks for being hit by player projectile def hit(self, damage): #access the thing hit like below, the parrent of the collision node #damage health etc below self.health = self.health-damage if self.health <= 0: self.delFlag = True self.deadFlag = True #self.destroy() if self.deadFlag and not self.dontSpawn: self.spawnPick() self.dontSpawn = True #Fires enemy projecctile def fire(self): base.taskMgr.add(self.scrubCannon.fire, "fireE") #Activate enemy AI def setAI(self): # Flag this as an AI character #Faster enemy pursue self.AIchar = AICharacter("standby", self.enemy, 100,.05,250) self.AIWorld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() self.AIbehaviors.pursue(base.camera) self.AIbehaviors.pauseAi("pursue") #Slower enemy pursue self.AIchar2 = AICharacter("standby2", self.enemy, 100, .05, 100) self.AIWorld.addAiChar(self.AIchar2) self.AIbehaviors2 = self.AIchar2.getAiBehaviors() self.AIbehaviors2.pursue(base.camera) self.AIbehaviors2.pauseAi("pursue") base.taskMgr.add(self.AIUpdate, "Update AI") #Calculate the distance between the player and the enemy. def getDistance(self): #get enemy (x,y,z) eX = self.enemy.getX() eY = self.enemy.getY() eZ = self.enemy.getZ() #get player (x,y,z) pX = base.player.playerModel.getX() pY = base.player.playerModel.getY() pZ = base.player.playerModel.getZ() #calculate the distance between the enemy and player (x,y,z) #(eX - pX)^2 x = eX - pX x = math.pow(x, 2) #(eY - pY)^2 y = eY - pY y = math.pow(y,2) #(eZ - pZ)^2 z = eZ - pZ z = math.pow(z, 2) self.dist = math.sqrt(x + y + z) return self.dist #AI behavior def AIUpdate(self,task): #if the enemy is not flaged as dead or paused then we update the AI self.max = 200 self.shoot = 140 self.min = 50 if not self.deadFlag: if not self.pauseFlag: dist = self.getDistance() self.pickuppos = self.enemy.getPos() #if the distance is less than max, resume the pursue if(dist < self.max): self.AIbehaviors.resumeAi("pursue") #also if the distance is less than 'shoot range' then enemies can fire if(dist < self.shoot): self.AIbehaviors.pauseAi("pursue") self.AIbehaviors2.resumeAi("pursue") #if the distance becomes less than the min #pause the chasing and double the firing speed if(dist < self.min): self.fireDelta = self.fireDelta *2 self.AIbehaviors.pauseAi("pursue") self.AIbehaviors2.pauseAi("pursue") if(self.peacefulMode != "True"): self.fireDelta+=1 if self.fireDelta >= 100+self.fireOffset: self.fireDelta = 0 self.fire() #else if the distance is more than 200 then don't chase or fire elif(dist >200): self.AIbehaviors.pauseAi("pursue") self.AIbehaviors2.pauseAi("pursue") else: return task.done self.AIWorld.update() return task.cont #Pauses enemyies def pause(self): self.AIbehaviors.pauseAi("pursue") self.AIbehaviors2.pauseAi("pursue") self.pauseFlag = True #Resumes enemies def resume(self): self.pauseFlag = False #Randomly spawns health pickup on enemy death def spawnPick(self): a = random.randint(0, 100) if a > 74: base.spawnPickup(self.id, self.pickuppos) #Clears enemy from the scene graph upon death def destroy(self): self.enemyNode.removeNode() self.enemy.cleanup() self.enemy.removeNode() self.cnodepath.node().clearSolids() base.cTrav.removeCollider(self.cnodepath) del self #Animation currently not functional def animate(self): self.enemy.play("walk") self.enemy.loop("walk", fromFrame = 10)
class CogAI(DirectObject): cancelStep = False def __init__(self, cog, spawn, support=False): self.cog = cog self.spawn = spawn self.attack = True self.support = support self.flyIn() def setAI(self): collisions = render.getPythonTag('WorldCollisions') collisions.addCogGroundCollision(self.cog) self.AIWorld = AIWorld(render) self.AIChar = AICharacter('Cog', self.cog.getCog(), -125, 90, -14) self.AIWorld.addAiChar(self.AIChar) self.AIBehaviors = self.AIChar.getAiBehaviors() if self.support == False: self.AIBehaviors.pathFollow(8) self.AIBehaviors.addToPath(VBase3(110.60, -0.32, 4.57)) checkpoints = self.spawn.getPath().getCheckpoints() for checkpoint in xrange(len(checkpoints)): self.AIBehaviors.addToPath(checkpoints[checkpoint].getPos()) self.AIBehaviors.startFollow() else: self.AIBehaviors.pursue(render.find('**/Toon')) self.cog.getCog().loop('walk') base.taskMgr.add(self.AIUpdate, "AIUpdate") def calcChance(self, percent): if (random.randint(0, 100) < percent): return True else: return False def toggleAttack(self): if (self.attack): self.attack = False else: self.attack = True def AIUpdate(self, task): if (self.AIBehaviors.behaviorStatus('pathfollow') == 'done'): self.cog.getCog().loop('neutral') self.AIBehaviors.removeAi('pathfollow') toonHall = render.getPythonTag("ToonHall") toonHall.startCogEnter(self.cog) return Task.done else: if (self.cog.getHealth() > 0): if (self.calcChance(40) and self.attack): def resumeAI(task): self.AIBehaviors.resumeAi('pathfollow') self.cog.getCog().loop('walk') return Task.done def enableAttacks(task): return Task.done avatar = render.find('**/Toon') if (self.cog.getCog().getDistance(avatar) <= 20): self.AIBehaviors.pauseAi('pathfollow') self.cog.getCog().stop() self.attack = False self.cog.getCog().lookAt(avatar) self.cog.getCog().play('throw-object') attack = CogAttacks().getRandomAttack( self.cog.getLevel() * 2) attack.execute(self.cog) base.taskMgr.doMethodLater(10, enableAttacks, 'Toggle Attack') base.taskMgr.doMethodLater(3, resumeAI, 'Resume AI') self.AIWorld.update() return Task.cont else: self.AIBehaviors.removeAi('pathfollow') return Task.done def flyIn(self): phase_4 = "phase_4/models/props" cog = self.cog.getCog() collisions = render.getPythonTag('WorldCollisions') collisions.addCogCollision(self.cog) self.propeller = Actor( loader.loadModel(phase_4 + "/propeller-mod.bam"), {'chan': loader.loadModel(phase_4 + "/propeller-chan.bam")}) self.propeller.reparentTo(cog.find('**/joint_head')) propSound = SoundBank.getSound('propeller') propSound.setLoop(True) propSound.setVolume(0.8) propSound.play() pos = cog.getPos() cog.setPos(pos.getX(), pos.getY(), pos.getZ() + 20) cog.pose('landing', 1) cog.colorScaleInterval(4.8, Vec4(1, 1, 1, 1), startColorScale=Vec4(0.2509803921568627, 0.2509803921568627, 0.2509803921568627, 0.25), blendType='easeInOut').start() path = cog.posInterval(5, pos, startPos=cog.getPos()) path.start() self.propeller.loop('chan', fromFrame=0, toFrame=3) base.taskMgr.add(self.handleCogDead, 'Handle Cog Death') base.taskMgr.doMethodLater(4, self.playInSound, 'Play In Sound', extraArgs=[propSound], appendTask=True) base.taskMgr.doMethodLater(5, self.landCog, 'Land Cog') def handleCogDead(self, task): if (self.cog.isDefeated): self.cancelStep = True collisions = render.getPythonTag('WorldCollisions') collisions.addCogGroundCollision(cog=self.cog) return Task.done else: return Task.cont def landCog(self, task): if not self.cancelStep: base.taskMgr.remove('Handle Cog Death') self.propeller.play('chan', fromFrame=35, toFrame=87) self.cog.getCog().play('landing') base.taskMgr.doMethodLater(3, self.removePropeller, 'Remove Propeller') return Task.done def removePropeller(self, task): self.propeller.cleanup() self.propeller.removeNode() self.setAI() return Task.done def playInSound(self, sound, task): if not self.cancelStep: sound.stop() SoundBank.getSound('propeller_in').play() return Task.done
class GameObject(NodePath): def __init__(self, nodePath): NodePath.__init__(self, nodePath) self.actorHandle = None if isinstance(nodePath, Actor): self.actorHandle = nodePath self.aiCharHandle = AICharacter(nodePath.getName(), nodePath, 0.01, 0.01, 0.01) # default properties for a GameObject self.name = self.getName() self.scripts = {} # {string triggerType : list of string scriptTags} TODO: argsList self.passable = True #self.lifeStatus = LifeStatus.INANIMATE self.lifeStatus = LifeStatus.ALIVE self.curHP = 1 # CONSIDER: bundle HP and LifeStatus together self.maxHP = 1 self.strategy = Strategy.NEUTRAL self.spells = [] self.stopThreshold = 60 self.__processTags() def setStopThreshold(self, threshold): self.stopThreshold = threshold def getStopThreshold(self): return self.stopThreshold # set properties based on tags of NodePath set in LE def __processTags(self): # passable if self.hasTag('LE-passable'): val = self.getTag('LE-passable') if val == "True": self.passable = True elif val == "False": self.passable = False else: print "ERROR: invalid value for \'LE-passable\' tag" # lifeStatus if self.hasTag('LE-lifeStatus'): val = self.getTag('LE-lifeStatus') self.lifeStatus = LifeStatus.interpretLifeStatusString(val) # HP # CONSIDER: automatically fill in one if the other is missing if self.hasTag('LE-currentHealth'): self.curHP = int(self.getTag('LE-currentHealth')) if self.hasTag('LE-maxHealth'): self.maxHP = int(self.getTag('LE-maxHealth')) # strategy if self.hasTag('LE-strategy'): val = self.getTag('LE-strategy') self.strategy = Strategy.interpretStrategyString(val) def setScripts(self, scriptsDict): # scriptsData form is # [ ( 'scriptName' , [ arg1 , arg2 ] ) , ... ] for trigger, scriptData in scriptsDict.items(): self.scripts[trigger] = scriptData def callTrigger(self, world, triggerName): if triggerName in self.scripts: scriptsData = self.scripts[triggerName] Debug.debug(__name__,str(scriptsData)) for key in sorted(scriptsData): tuple = scriptsData[key] world.scriptMgr.doScript(tuple) # CONSIDER: use world param to check scene, pass to scriptMgr to queue if scene is different else: pass # TODO: deprecated...remove def getNP(self): return self def getActorHandle(self): return self.actorHandle def getAICharacterHandle(self): return self.aiCharHandle def getAIBehaviorsHandle(self): return self.aiCharHandle.getAiBehaviors() def hasSpell(self): return (len(self.spells) > 0) def getSpell(self, index=0): if index < len(self.spells): return self.spells[index] else: print 'ERROR: tried to get a spell out of the list range' def addSpell(self, spell): self.spells.append(spell) def isPassable(self): return self.passable def getHealth(self): return self.curHP def getMaxHealth(self): return self.maxHP def decreaseHealth(self, delta): if self.lifeStatus == LifeStatus.ALIVE: self.curHP -= delta if self.curHP <= 0: self.curHP = 0 self.lifeStatus = LifeStatus.DYING # TODO: launch onDeath trigger? done in CombatMgrBase already # TODO: change status to DEAD def die(self): self.decreaseHealth(self.maxHP) def increaseHealth(self, delta): # CONSIDER: does increasing HP from 0 revive the object (switch LifeStatus) or do nothing? if self.lifeStatus == LifeStatus.ALIVE: self.curHP += delta if self.curHP > self.maxHP: self.curHP = self.maxHP def fillHealth(self): self.increaseHealth(self.maxHP) def __str__(self): return 'GameObject, name: %s' %(self.getName())
def __init__(self, pos, index, app, manager, level, style): self.position = pos self.app = app self.np = app.render.attachNewNode("enemy%d" % index) if style == 1: self.np.setColorScale(1.0, 1.0, 1.0, 1.0) self.movespeed = 2.5 self.max_movespeed = 30 else: self.movespeed = 0.5 self.max_movespeed = 25 if style == 2: self.activate_delay = 0.01 self.np.setColorScale(0.6, 1.0, 1.0, 1.0) else: self.activate_delay = 0.1 if style == 3: self.hp = 50 * level self.np.setColorScale(0.0, 1.0, 0.5, 1.0) else: self.hp = 100 * level if style == 4: self.damage = 20 self.np.setColorScale(1.0, 1.0, 0.0, 1.0) else: self.damage = 10 self.dead = 0.0 self.level = level self.style = style self.particle_clean = False # this allows us to detach the instance nodepath # on death, but keep one with no model to attach particle effects self.dnp = app.render.attachNewNode("enemy_top%d" % index) self.np.setPos(self.position) self.np.setHpr(uniform(1,360),0,0) self.np.setScale(level) colsize = 3.0 self.cn = self.np.attachNewNode(CollisionNode('enemy_cn_%d' % index)) self.cs0 = CollisionSphere(0.0, colsize/2,0.0,colsize) self.cs1 = CollisionSphere(0.0, -colsize/2,0.0,colsize) self.cs2 = CollisionSphere(0.0, -colsize/3*4,0.0,colsize/2) self.cn.node().addSolid(self.cs0) self.cn.node().addSolid(self.cs1) self.cn.node().addSolid(self.cs2) #self.cn.show() # debug self.cqueue = CollisionHandlerQueue() app.cTrav.addCollider(self.cn, self.cqueue) self.cn.node().setIntoCollideMask(BitMask32(0x01)) self.cn.node().setFromCollideMask(BitMask32(0x10)) self.last_activated = 0.0 manager.add_instance(self) # name, nodepath, mass, move_force, max_force self.ai_char = AICharacter('enemy_ai_%d' % index, self.np, 100, self.movespeed, self.max_movespeed) app.ai_world.addAiChar(self.ai_char) self.ai_b = self.ai_char.getAiBehaviors() self.ai_b.pursue(app.player.np) self.load_particle_config()
class Enemy(): def __init__(self, pos, index, app, manager, level, style): self.position = pos self.app = app self.np = app.render.attachNewNode("enemy%d" % index) if style == 1: self.np.setColorScale(1.0, 1.0, 1.0, 1.0) self.movespeed = 2.5 self.max_movespeed = 30 else: self.movespeed = 0.5 self.max_movespeed = 25 if style == 2: self.activate_delay = 0.01 self.np.setColorScale(0.6, 1.0, 1.0, 1.0) else: self.activate_delay = 0.1 if style == 3: self.hp = 50 * level self.np.setColorScale(0.0, 1.0, 0.5, 1.0) else: self.hp = 100 * level if style == 4: self.damage = 20 self.np.setColorScale(1.0, 1.0, 0.0, 1.0) else: self.damage = 10 self.dead = 0.0 self.level = level self.style = style self.particle_clean = False # this allows us to detach the instance nodepath # on death, but keep one with no model to attach particle effects self.dnp = app.render.attachNewNode("enemy_top%d" % index) self.np.setPos(self.position) self.np.setHpr(uniform(1,360),0,0) self.np.setScale(level) colsize = 3.0 self.cn = self.np.attachNewNode(CollisionNode('enemy_cn_%d' % index)) self.cs0 = CollisionSphere(0.0, colsize/2,0.0,colsize) self.cs1 = CollisionSphere(0.0, -colsize/2,0.0,colsize) self.cs2 = CollisionSphere(0.0, -colsize/3*4,0.0,colsize/2) self.cn.node().addSolid(self.cs0) self.cn.node().addSolid(self.cs1) self.cn.node().addSolid(self.cs2) #self.cn.show() # debug self.cqueue = CollisionHandlerQueue() app.cTrav.addCollider(self.cn, self.cqueue) self.cn.node().setIntoCollideMask(BitMask32(0x01)) self.cn.node().setFromCollideMask(BitMask32(0x10)) self.last_activated = 0.0 manager.add_instance(self) # name, nodepath, mass, move_force, max_force self.ai_char = AICharacter('enemy_ai_%d' % index, self.np, 100, self.movespeed, self.max_movespeed) app.ai_world.addAiChar(self.ai_char) self.ai_b = self.ai_char.getAiBehaviors() self.ai_b.pursue(app.player.np) self.load_particle_config() def update(self, time): a = 0 # Handle collsions for i in range(self.cqueue.getNumEntries()): collided_name = self.cqueue.getEntry(i).getIntoNodePath().getName() #handle bullets if collided_name[0] == 'b': bullet = self.app.bullet_manager.get_bullet(collided_name) bullet.apply_effect(self) self.app.bullet_manager.remove_bullet(collided_name) if self.cqueue.getNumEntries() != 0: self.np.setColorScale(1.0, self.hp / 100.0, self.hp / 100.0, 1.0) """ desired = self.app.player.position - self.np.getPos() angle = degrees(atan2(desired.y, desired.x)) hpr = self.np.getHpr() if hpr.x > 360: hpr.x = hpr.x - 360 if hpr.x < -360: hpr.x = hpr.x + 360 diff = angle - hpr.x if diff > 180.0: diff = diff - 360 if diff < -180.0: diff = diff + 360 if diff > 5.0: diff = 5.0 if diff < -5.0: diff = -5.0 new = Vec3(diff, 0, 0) + hpr #self.np.setHpr(new) # move forward r = radians(new.x) curr = self.np.getPos() diff = Vec3(self.movespeed * cos(r), self.movespeed * sin(r), 0) self.np.setPos(curr + diff)""" if self.hp < 0.0 and self.dead == 0.0: self.dead = time self.app.scene.remove(self) # Create particle effect before we go self.dnp.setPos(self.np.getPos()) self.particles.start(parent = self.dnp, renderParent = self.app.render) self.np.detachNode() # Drop some loot self.app.item_manager.add_item(self.np.getPos(), "soul", self.level) # Give the player some points self.app.player.score = self.app.player.score + 100 def apply_effect(self, target, timer): if self.last_activated - timer + self.activate_delay < 0.0: self.last_activated = timer target.hp = target.hp - self.damage if target.np.getName()[0] == 't': target.pursuers.append(self) #self.ai_b = self.ai_char.getAiBehaviors() #self.ai_b.pursue(self.np.getPos()) self.ai_b.pauseAi("pursue") def load_particle_config(self): self.particles = ParticleEffect() self.particles.reset() self.particles.setPos(0.000, 0.000, 0.000) self.particles.setHpr(0.000, 0.000, 0.000) self.particles.setScale(1.000, 1.000, 1.000) p0 = Particles('particles-1') # Particles parameters p0.setFactory("PointParticleFactory") p0.setRenderer("SpriteParticleRenderer") p0.setEmitter("SphereVolumeEmitter") p0.setPoolSize(20) p0.setBirthRate(0.0100) p0.setLitterSize(20) p0.setLitterSpread(0) p0.setSystemLifespan(1.0100) p0.setLocalVelocityFlag(1) p0.setSystemGrowsOlderFlag(1) # Factory parameters p0.factory.setLifespanBase(1.0000) p0.factory.setLifespanSpread(0.0000) p0.factory.setMassBase(1.0000) p0.factory.setMassSpread(0.0100) p0.factory.setTerminalVelocityBase(1200.0000) p0.factory.setTerminalVelocitySpread(0.0000) # Point factory parameters # Renderer parameters p0.renderer.setAlphaMode(BaseParticleRenderer.PRALPHAOUT) p0.renderer.setUserAlpha(0.05) # Sprite parameters p0.renderer.setTexture(self.app.loader.loadTexture('effects/dust.png')) p0.renderer.setColor(Vec4(1.00, 0.10, 0.10, 0.50)) p0.renderer.setXScaleFlag(2) p0.renderer.setYScaleFlag(2) p0.renderer.setAnimAngleFlag(0) p0.renderer.setInitialXScale(0.100 * self.level) p0.renderer.setFinalXScale(0.200 * self.level) p0.renderer.setInitialYScale(0.100 * self.level) p0.renderer.setFinalYScale(0.200 * self.level) p0.renderer.setNonanimatedTheta(0.0000) p0.renderer.setAlphaBlendMethod(BaseParticleRenderer.PPBLENDLINEAR) p0.renderer.setAlphaDisable(0) # Emitter parameters p0.emitter.setEmissionType(BaseParticleEmitter.ETRADIATE) p0.emitter.setAmplitude(1.0000) p0.emitter.setAmplitudeSpread(0.0000) p0.emitter.setOffsetForce(Vec3(0.0000, 0.0000, 0.0000)) p0.emitter.setExplicitLaunchVector(Vec3(1.0000, 0.0000, 0.0000)) p0.emitter.setRadiateOrigin(Point3(0.0000, 0.0000, 0.0000)) # Sphere Volume parameters p0.emitter.setRadius(0.1000) self.particles.addParticles(p0) f0 = ForceGroup('gravity') # Force parameters self.particles.addForceGroup(f0)
class Pokeperna(Personagem): def __init__(self,render, colisaoTerreno): self.nome = "Pokeperna" self.agi = 10 self.hp = 10 self.int = 5 self.str = 1 self.dano = 5 self.bloqueio = False self.bloqueado = False self.velocAtaque = 0.5 self.arma = None self.escudo = None self.armadura = None self.segueAlvo = None self.segue = False self.pokeperna = Actor('personagens/Modelos/Pokeperna/p1', {"andar" :"personagens/Modelos/Pokeperna/p1-andar.egg", "saltar" :"personagens/Modelos/Pokeperna/p1-saltar.egg", "correr" : "personagens/Modelos/Pokeperna/p1-correr", "abaixar" : "personagens/Modelos/Pokeperna/p1-abaixar"}) # self.pokeperna = Actor('personagens/Modelos/Pokeperna/p1', # {"atacar" : "personagens/Modelos/pokepernaTeste-atacar"}) #self.pokeperna.setScale(0.2,0.2,0.2) self.render = render self.pokeperna.setTag("Pokeperna","1") #self.pokeperna.reparentTo(self.noRobot) self.pokeperna.setPos(-10,-30.0,2.10) self.pokeperna.reparentTo(self.render) self.gerenciadorColisao = self.pokeperna.getPos() self.goForward = 0 self.goBackwards = 0 self.goLeft = 0 self.goRight = 0 self.saltar = 0 self.abaixar = 0 self.prevtime = 0 self.correr = 0 self.move = 0 self.gerenciadorColisao = colisaoTerreno self.gerenciarSelecao = 0 self.setAI() taskMgr.add(self.gerenciadorSelecao,"gerenciasSelecao") def pega(self): pass def abre(self): pass def defende(self): pass def calcDefesa(self): pass def atacar(self): self.pokeperna.play("saltar") #self.ataca = atacar def setGoLeft (self,value): self.goLeft = value def setGoRight (self,value): self.goRight = value def setGoForward (self,value): self.goForward = value def setMove (self,value): self.move = value self.aiBehaviors.pathFollow(01.0) self.aiBehaviors.addToPath(self.gerenciadorColisao.getEntry(0).getSurfacePoint(self.render)) self.aiBehaviors.addToPath(self.pokeperna.getPos()) self.pokeperna.loop("correr",) #print self.pokeperna.getAnimControl('andar').isPlaying() #print self.gerenciadorColisao.getEntry(0).getSurfacePoint(self.render) #print posicao if self.segue: self.aiBehaviors.seek(self.segueAlvo.pokemao) self.aiBehaviors.startFollow("actor") print "segue" else: self.aiBehaviors.startFollow("actor") #self.aiBehaviors.pathFindTo((self.gerenciadorColisao.getEntry(0).getSurfacePoint(self.render)),"addPath") #self.move = value def setGoBackwards (self,value): self.goBackwards = value def setSaltar(self,value): self.saltar = value def setAbaixar(self, value): self.abaixar = value def setCorrer(self, value): self.correr = value def getModel(self): return self.pokeperna def getPos(self): return self.pokeperna.getPos() def update (self, time,traverser,robotGroundHandler): elapsed = time - self.prevtime if self.goLeft: self.pokeperna.setH(self.pokeperna.getH() + elapsed * 300) if self.goRight: self.pokeperna.setH(self.pokeperna.getH() - elapsed * 300) # this code moves the avatar forward. # "forward" usually means "along the Y axis". however, since the avatar can turn, # it really means "along the Y axis relative to the direction I'm facing" # you can use the getRelativeVector () function to find out what that is forwardVec = VBase3(0,-1,0) xformedVec = self.render.getRelativeVector(self.pokeperna,forwardVec) para = True oldPos = self.pokeperna.getPos() if self.goForward: para = False if not self.pokeperna.getAnimControl('andar').isPlaying() \ and not self.pokeperna.getAnimControl('saltar').isPlaying() \ and not self.abaixar: self.pokeperna.loop("andar",restart = 0) newPos = oldPos + xformedVec * elapsed * 5 self.pokeperna.setPos(newPos) if self.goBackwards: newPos = oldPos - xformedVec * elapsed * 5 self.pokeperna.setPos(newPos) if self.correr: para = False if not self.pokeperna.getAnimControl('correr').isPlaying() \ and not self.pokeperna.getAnimControl('saltar').isPlaying() \ and not self.abaixar: self.pokeperna.loop("correr",restart = 0) newPos = oldPos + xformedVec * elapsed * 7 self.pokeperna.setPos(newPos) if self.saltar: para = False if not self.pokeperna.getAnimControl('saltar').isPlaying(): self.pokeperna.play("saltar") if self.abaixar: para = False if not self.pokeperna.getAnimControl('abaixar').isPlaying(): self.pokeperna.play("abaixar") if para: # if not self.pokeperna.getAnimControl('saltar').isPlaying(): self.pokeperna.stop() # do collisions traverser.traverse(self.render) startpos = self.pokeperna.getPos() entries = [] for i in range(robotGroundHandler.getNumEntries()): entry = robotGroundHandler.getEntry(i) entries.append(entry) entries.sort(lambda x,y: cmp(y.getSurfacePoint(self.render).getZ(), x.getSurfacePoint(self.render).getZ())) if (len(entries)>0) and (entries[0].getIntoNode().getName() == "Grid"): self.pokeperna.setZ(entries[0].getSurfacePoint(self.render).getZ()) #print entries[0].getSurfacePoint(self.render).getZ(),self.pokeperna.getPos() #self.pokeperna.setZ(1000) else: self.pokeperna.setPos(startpos) self.prevtime = time return Task.cont def setAI(self): #Creating AI World self.AIworld = AIWorld(self.render) self.AIchar = AICharacter("pokeperna",self.pokeperna, 60, 0.05, 5) self.AIworld.addAiChar(self.AIchar) self.aiBehaviors = self.AIchar.getAiBehaviors() #self.aiBehaviors.initPathFind("mapa/Modelos/cidade/navmesh.csv") #Path follow (note the order is reveresed) #AI World update taskMgr.add(self.AIUpdate,"AIUpdate") def gerenciadorSelecao(self, task): return Task.cont def AIUpdate(self,task): #print self.pokeperna.getAnimControl('andar').isPlaying() if self.move and self.aiBehaviors.behaviorStatus("pathfollow") == "done": # if not self.pokeperna.getAnimControl('andar').isPlaying(): # print "anda" # self.pokeperna.loop("andar",restart = 0) #print "gerenciadorColisao",self.gerenciadorColisao.getEntry(0).getSurfacePoint(self.render) #print "pokeperna",self.pokeperna.getPos() self.pokeperna.stop() self.pokeperna.pose("andar",0) #print "andando" else: pass #print "parado", self.move # self.pokeperna.stop() # self.pokeperna.pose("andar",0) self.AIworld.update() return Task.cont
class rifleman(entity): ''' Basic rifleman ''' #class constructor #mostly similar to entity def __init__(self, base, location, team): #assign what we know off the bat #TODO chosen model currently depends on team - 0 is friendly, 1 is enemy if team == 0: self.model = "models/friend_rifleman" elif team == 1: self.model = "models/enemy_rifleman" self.viewRange = 400 #used by application to determine what character can 'see' self.contacts = [] #stores nearby objects self.target = None #stores target self.goal = None #stores movement goal (if any) self.team = team #make call to parent with this model entity.__init__(self, self.model, base, location) #add rifle to the rifleman, as one does self.weaponNode = self.exposeJoint(None, "modelRoot", "weaponNode") self.weapon = carbine(self, self.weaponNode) self.pose("highReady", 0) #add AI to this object #mass 60, movement force 0.05, max force 25 self.ai = AICharacter(str(self), self, 30, 0.05, 25) base.AIworld.addAiChar(self.ai) self.AiBehaviors = self.ai.getAiBehaviors() #load navmesh self.AiBehaviors.initPathFind(base.navmesh) #add all structures for building in base.structures: #this is super aggressive so disable for now.. self.AiBehaviors.addStaticObstacle(building) #pass #procedure: updateState #overrides entity.updateState #things that need to be executed every frame for this character object def updateState(self): # if health below 0 is dead if self.health <= 0: self.AiBehaviors.removeAi("pathfollow") self.mainCol.clearSolids() return entity.updateState(self) timeNow = globalClock.getFrameTime() #rifleman should always stand upright. self.setP(0) #clear current contacts to get new ones self.contacts.clear() #clear current target for the same reason self.target = None # get all objects within viewRange for item in base.entities: #sanity check if item.is_empty(): base.entities.remove(item) continue if item is self: continue #otherwise retrieve other pos otherPos = item.getPos() if pointInCircle(self.getPos(), self.viewRange, otherPos) and item.team != self.team: #if within viewRange, it is a valid contact self.contacts.append(item) #if there are valid contacts if len(self.contacts) > 0: #TODO currently drop everything to shoot at something if in range self.AiBehaviors.pauseAi("pathfollow") #sort to get nearest # built in panda function compareTo apparently does what I need # seems to rate similarity but works for my purposes self.contacts.sort(key=lambda otherItem: self.getPos().compareTo( otherItem.getPos())) #target this object self.target = self.contacts[0] #little bit of vector math, get vector to target, normalize and convert to rotation newVec = self.getPos() - self.target.getPos() newVec.normalize() newVec = vectorToHPR(newVec) #now if currentHPR doesn't match add H until it does self.setH(newVec[0]) self.attack() elif self.weapon.isReloading != False: if timeNow >= self.weapon.isReloading: self.weapon.isReloading = False self.weapon.ammo['currentMag'] = self.weapon.ammo['magSize'] elif self.goal is not None: self.setGoal(self.goal) elif self.goal is None: #if not moving or attacking anything, default to high ready self.pose("highReady", 0) #handle movement if there is a goal and not shooting anyone if self.goal is not None and self.target is None and self.weapon.isReloading is False: self.move() #procedure rifleman.attack #act of rifleman shooting. While shooting, can't do anything else def attack(self): self.weapon.fire() #this is False because isReloading stores the start time of the reload if self.weapon.isReloading != False: if self.getCurrentAnim() != "reload": self.play("reload") else: if self.getCurrentAnim() != "firing": self.loop("firing") #procedure setGoal #sets a location target for this character to move to def setGoal(self, goal): self.goal = goal # go to a specific area self.AiBehaviors.pathFindTo(self.goal) #procedure move #if en route to a location, play walking animation def move(self): #set position every move self.set_prev_transform(self.getTransform(base.render)) #if completed set to none, reset animations if self.AiBehaviors.behaviorStatus("pathfollow") == "done": self.goal = None self.pose("highReady", 0) return dt = globalClock.getDt() if self.getCurrentAnim() != "walk": self.loop("walk")
class Enemy(DirectObject): def __init__(self, _main): self.main = _main self.strenght = self.main.enemyStrength self.id = id(self) self.model = loader.loadModel("Enemy") self.model.setP(-90) self.model.setH(180) self.model.hide() cs = CollisionSphere(0, 0, 0, 0.5) cnode = CollisionNode('colEnemy' + str(self.id)) cnode.addSolid(cs) self.colNP = self.model.attachNewNode(cnode) #self.colNP.show() # Game state self.health = 100 + (100 * self.strenght) self.damageDone = 0.1 + (0.1 * self.strenght) self.lastShot = 0.0 self.attackRate = 10.0 self.statusHealth = DirectWaitBar( text = "", value = self.health, range = self.health, frameSize = (0.12, 0.8, -0.12, 0.0), pos = (-0.5, 0, -0.5), barColor = (1, 0, 0, 1)) self.statusHealth.reparentTo(self.model) self.statusHealth.setDepthWrite(False) self.statusHealth.setBin('fixed', 0) self.statusHealth.setBillboardAxis() def start(self, startPos, enemyParent): self.model.show() self.model.reparentTo(enemyParent) self.model.setPos(startPos.x, startPos.y, 0) self.accept("into-" + "colEnemy" + str(self.id), self.hit) self.accept("inRange-" + "colEnemy" + str(self.id), self.startAttack) self.statusHealth.update(self.health) def stop(self): self.model.remove_node() self.ignore("into-" + "colEnemy" + str(self.id)) self.ignore("inRange-" + "colEnemy" + str(self.id)) def hit(self, _dmg): if self.health == 0: base.messenger.send("killEnemy", [self.id]) else: self.health -= _dmg self.statusHealth.update(self.health) def makeAi(self): # Make some ai character for each self.aiChar = AICharacter("Enemy" + str(self.id), self.model, -100, 0.05 + (0.05 * self.strenght), 6 + (1 * self.strenght)) self.main.AiWorld.addAiChar(self.aiChar) self.AIbehaviors = self.aiChar.getAiBehaviors() self.AIbehaviors.pursue(self.main.player.model) return self.aiChar def startAttack(self, _inRange=False): if _inRange: self.isAttacking = True self.simpleAttack() #taskMgr.remove("StartAttack") #elif _inRange: # pass # taskMgr.add(self.attack, "StartAttack") def attack(self, task): dt = globalClock.getDt() self.lastShot += dt if self.lastShot >= self.attackRate: self.lastShot -= self.attackRate base.messenger.send("doDamageToPlayer", [self.damageDone]) return task.again def simpleAttack(self): base.messenger.send("doDamageToPlayer", [self.damageDone])
class GameObject(NodePath): def __init__(self, nodePath): NodePath.__init__(self, nodePath) self.actorHandle = None if isinstance(nodePath, Actor): self.actorHandle = nodePath self.aiCharHandle = AICharacter(nodePath.getName(), nodePath, 0.01, 0.01, 0.01) # default properties for a GameObject self.name = self.getName() self.scripts = { } # {string triggerType : list of string scriptTags} TODO: argsList self.passable = True #self.lifeStatus = LifeStatus.INANIMATE self.lifeStatus = LifeStatus.ALIVE self.curHP = 1 # CONSIDER: bundle HP and LifeStatus together self.maxHP = 1 self.strategy = Strategy.NEUTRAL self.spells = [] self.stopThreshold = 60 self.__processTags() def setStopThreshold(self, threshold): self.stopThreshold = threshold def getStopThreshold(self): return self.stopThreshold # set properties based on tags of NodePath set in LE def __processTags(self): # passable if self.hasTag('LE-passable'): val = self.getTag('LE-passable') if val == "True": self.passable = True elif val == "False": self.passable = False else: print "ERROR: invalid value for \'LE-passable\' tag" # lifeStatus if self.hasTag('LE-lifeStatus'): val = self.getTag('LE-lifeStatus') self.lifeStatus = LifeStatus.interpretLifeStatusString(val) # HP # CONSIDER: automatically fill in one if the other is missing if self.hasTag('LE-currentHealth'): self.curHP = int(self.getTag('LE-currentHealth')) if self.hasTag('LE-maxHealth'): self.maxHP = int(self.getTag('LE-maxHealth')) # strategy if self.hasTag('LE-strategy'): val = self.getTag('LE-strategy') self.strategy = Strategy.interpretStrategyString(val) def setScripts(self, scriptsDict): # scriptsData form is # [ ( 'scriptName' , [ arg1 , arg2 ] ) , ... ] for trigger, scriptData in scriptsDict.items(): self.scripts[trigger] = scriptData def callTrigger(self, world, triggerName): if triggerName in self.scripts: scriptsData = self.scripts[triggerName] Debug.debug(__name__, str(scriptsData)) for key in sorted(scriptsData): tuple = scriptsData[key] world.scriptMgr.doScript(tuple) # CONSIDER: use world param to check scene, pass to scriptMgr to queue if scene is different else: pass # TODO: deprecated...remove def getNP(self): return self def getActorHandle(self): return self.actorHandle def getAICharacterHandle(self): return self.aiCharHandle def getAIBehaviorsHandle(self): return self.aiCharHandle.getAiBehaviors() def hasSpell(self): return (len(self.spells) > 0) def getSpell(self, index=0): if index < len(self.spells): return self.spells[index] else: print 'ERROR: tried to get a spell out of the list range' def addSpell(self, spell): self.spells.append(spell) def isPassable(self): return self.passable def getHealth(self): return self.curHP def getMaxHealth(self): return self.maxHP def decreaseHealth(self, delta): if self.lifeStatus == LifeStatus.ALIVE: self.curHP -= delta if self.curHP <= 0: self.curHP = 0 self.lifeStatus = LifeStatus.DYING # TODO: launch onDeath trigger? done in CombatMgrBase already # TODO: change status to DEAD def die(self): self.decreaseHealth(self.maxHP) def increaseHealth(self, delta): # CONSIDER: does increasing HP from 0 revive the object (switch LifeStatus) or do nothing? if self.lifeStatus == LifeStatus.ALIVE: self.curHP += delta if self.curHP > self.maxHP: self.curHP = self.maxHP def fillHealth(self): self.increaseHealth(self.maxHP) def __str__(self): return 'GameObject, name: %s' % (self.getName())
class Enemy: def __init__(self, base, n, x, y, z): self.base = base self.n = n self.health = 4 self.np = base.loader.loadModel("./mdl/enemy.egg") self.np.setColor(1, 1, 0, 1) self.np.reparentTo(base.render) self.np.setPos(x, y, z) self.np.setAlphaScale(0.) base.target = self self.radar = OnscreenImage(image="./png/radar.png", pos=Vec3(0), scale=0.01) self.radar.setTransparency(TransparencyAttrib.MAlpha) # collisions cn = CollisionNode("enemy" + str(n)) cn.addSolid(CollisionBox(0, 2.5, 2, 0.5)) cn.setCollideMask(BitMask32(0x1) | BitMask32(0x2)) # cc = self.np.attachNewNode(cn) self.np.attachNewNode(cn) base.accept("fighter-into-enemy" + str(n), self.ship_collision) base.accept("bullet-into-enemy" + str(n), self.bullet_collision) base.accept("missile-into-enemy" + str(n), self.missile_collision) # sound self.snd_crash = base.loader.loadSfx("./snd/crash.flac") self.snd_blip = base.audio3d.loadSfx("./snd/blip.flac") self.snd_hit = base.loader.loadSfx("./snd/hit.flac") self.snd_explode = base.loader.loadSfx("./snd/explosion.flac") base.audio3d.attachSoundToObject(self.snd_blip, self.np) base.audio3d.setSoundVelocityAuto(self.snd_blip) base.audio3d.attachSoundToObject(self.snd_crash, self.np) base.audio3d.setSoundVelocityAuto(self.snd_crash) base.audio3d.attachSoundToObject(self.snd_hit, self.np) base.audio3d.setSoundVelocityAuto(self.snd_hit) base.audio3d.attachSoundToObject(self.snd_explode, self.np) base.audio3d.setSoundVelocityAuto(self.snd_explode) self.snd_blip.setLoop(True) self.snd_blip.play() self.setAI() def setAI(self): self.AIchar = AICharacter("enemy", self.np, 100, 10., 50) self.base.AIworld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() # self.AIbehaviors.wander(50, 0, 1000, 1.0) # self.AIbehaviors.seek(self.base.fighter) self.AIbehaviors.evade(self.base.fighter, 1000, 2000) # self.base.taskMgr.doMethodLater(1, self.call_status, "task-call-status") def call_status(self, task): status = self.AIbehaviors.behaviorStatus("evade") print("status: ", status) return task.again def explode(self): self.snd_blip.stop() self.base.audio3d.detachSound(self.snd_blip) self.base.audio3d.detachSound(self.snd_crash) self.base.audio3d.detachSound(self.snd_hit) self.radar.hide() self.np.hide() self.base.taskMgr.remove("fighter-into-enemy" + str(self.n)) self.base.taskMgr.remove("bullet-into-enemy" + str(self.n)) self.base.taskMgr.remove("missile-into-enemy" + str(self.n)) self.base.taskMgr.remove("enemy-hit-task") self.base.taskMgr.remove("enemy-crash-task") self.snd_explode.play() self.part = Explosion(self.base) self.part.pn.setPos(self.np.getPos()) self.base.taskMgr.doMethodLater(5, self.remove_part, "task-remove-part") def cleanup(self): self.base.audio3d.detachSound(self.snd_explode) self.base.AIworld.removeAiChar("enemy") self.base.target = None self.radar.destroy() self.np.removeNode() self.base.fuel += 500 self.base.gen_enemy() def ship_collision(self, entry): # degree of shaking depends on my speed/velocity (mvel) self.health -= 1 self.base.fuel -= 500 d = exp(0.047 * self.base.mvel - 7.) self.snd_crash.play() self.base.taskMgr.add(self.enemy_crash, "enemy-crash-task", extraArgs=[d], appendTask=True) def enemy_crash(self, d, task): if task.time < 5: f = (5. - task.time) / 5. s = 3000. * f x = uniform(-s, s) y = uniform(-s, s) self.base.repos(x, y, d) return task.cont return task.done def bullet_collision(self, entry): self.snd_hit.play() objNP = entry.getFromNodePath().findNetTag("bullet") objNP.removeNode() self.health -= 1 if self.health == 0: self.explode() else: self.base.taskMgr.add(self.enemy_hit, "enemy-hit-task") def missile_collision(self, entry): self.snd_hit.play() objNP = entry.getFromNodePath().findNetTag("missile") objNP.removeNode() self.explode() def enemy_hit(self, task): if task.time < 3: f = (3. - task.time) / 3. self.np.setColor(1, 1 - f, 0, 1) self.np.setAlphaScale(f) return task.cont return task.done def remove_part(self, task): self.part.pe.cleanup() self.cleanup() return task.done
class Enemy: def __init__(self, base, n, x, y, z): self.base = base self.n = n self.health = 4 self.np = base.loader.loadModel("./mdl/enemy.egg") self.np.setColor(1, 1, 0, 1) self.np.reparentTo(base.render) self.np.setPos(x, y, z) self.np.setAlphaScale(0.) base.target = self self.radar = OnscreenImage(image="./png/radar.png", pos=Vec3(0), scale=0.01) self.radar.setTransparency(TransparencyAttrib.MAlpha) # collisions cn = CollisionNode("enemy"+str(n)) cn.addSolid(CollisionBox(0, 2.5, 2, 0.5)) cn.setCollideMask(BitMask32(0x1) | BitMask32(0x2)) # cc = self.np.attachNewNode(cn) self.np.attachNewNode(cn) base.accept("fighter-into-enemy"+str(n), self.ship_collision) base.accept("bullet-into-enemy"+str(n), self.bullet_collision) base.accept("missile-into-enemy"+str(n), self.missile_collision) # sound self.snd_crash = base.loader.loadSfx("./snd/crash.flac") self.snd_blip = base.audio3d.loadSfx("./snd/blip.flac") self.snd_hit = base.loader.loadSfx("./snd/hit.flac") self.snd_explode = base.loader.loadSfx("./snd/explosion.flac") base.audio3d.attachSoundToObject(self.snd_blip, self.np) base.audio3d.setSoundVelocityAuto(self.snd_blip) base.audio3d.attachSoundToObject(self.snd_crash, self.np) base.audio3d.setSoundVelocityAuto(self.snd_crash) base.audio3d.attachSoundToObject(self.snd_hit, self.np) base.audio3d.setSoundVelocityAuto(self.snd_hit) base.audio3d.attachSoundToObject(self.snd_explode, self.np) base.audio3d.setSoundVelocityAuto(self.snd_explode) self.snd_blip.setLoop(True) self.snd_blip.play() self.setAI() def setAI(self): self.AIchar = AICharacter("enemy", self.np, 100, 10., 50) self.base.AIworld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() # self.AIbehaviors.wander(50, 0, 1000, 1.0) # self.AIbehaviors.seek(self.base.fighter) self.AIbehaviors.evade(self.base.fighter, 1000, 2000) # self.base.taskMgr.doMethodLater(1, self.call_status, "task-call-status") def call_status(self, task): status = self.AIbehaviors.behaviorStatus("evade") print("status: ", status) return task.again def explode(self): self.snd_blip.stop() self.base.audio3d.detachSound(self.snd_blip) self.base.audio3d.detachSound(self.snd_crash) self.base.audio3d.detachSound(self.snd_hit) self.radar.hide() self.np.hide() self.base.taskMgr.remove("fighter-into-enemy"+str(self.n)) self.base.taskMgr.remove("bullet-into-enemy"+str(self.n)) self.base.taskMgr.remove("missile-into-enemy"+str(self.n)) self.base.taskMgr.remove("enemy-hit-task") self.base.taskMgr.remove("enemy-crash-task") self.snd_explode.play() self.part = Explosion(self.base) self.part.pn.setPos(self.np.getPos()) self.base.taskMgr.doMethodLater(5, self.remove_part, "task-remove-part") def cleanup(self): self.base.audio3d.detachSound(self.snd_explode) self.base.AIworld.removeAiChar("enemy") self.base.target = None self.radar.destroy() self.np.removeNode() self.base.fuel += 500 self.base.gen_enemy() def ship_collision(self, entry): # degree of shaking depends on my speed/velocity (mvel) self.health -= 1 self.base.fuel -= 500 d = exp(0.047 * self.base.mvel - 7.) self.snd_crash.play() self.base.taskMgr.add(self.enemy_crash, "enemy-crash-task", extraArgs=[d], appendTask=True) def enemy_crash(self, d, task): if task.time < 5: f = (5. - task.time) / 5. s = 3000.*f x = uniform(-s, s) y = uniform(-s, s) self.base.repos(x, y, d) return task.cont return task.done def bullet_collision(self, entry): self.snd_hit.play() objNP = entry.getFromNodePath().findNetTag("bullet") objNP.removeNode() self.health -= 1 if self.health == 0: self.explode() else: self.base.taskMgr.add(self.enemy_hit, "enemy-hit-task") def missile_collision(self, entry): self.snd_hit.play() objNP = entry.getFromNodePath().findNetTag("missile") objNP.removeNode() self.explode() def enemy_hit(self, task): if task.time < 3: f = (3. - task.time) / 3. self.np.setColor(1, 1-f, 0, 1) self.np.setAlphaScale(f) return task.cont return task.done def remove_part(self, task): self.part.pe.cleanup() self.cleanup() return task.done
class Boss(Enemy): #Spawns boss enemy def __init__(self, model, ident): Enemy.__init__(self, model, ident) self.enemy = Actor(model) self.enemy.reparentTo(self.enemyNode) self.enemy.setScale(5) self.health = 200 self.damage = 20 self.weapon = ChargeCannon(base.camera, self.enemy) #configure hit tube self.cs = CollisionTube(0, 0, 0, 0, 0, 0, 1.5) #init cnode self.cnodepath = self.enemy.attachNewNode(CollisionNode('cnode'+str(id))) self.cnodepath.setTag('objectTag', str(id)) self.cnodepath.node().addSolid(self.cs) #so we can walk into the enimies self.chand = CollisionHandlerEvent() # must be same cTrav that was set in player, global collider thing base.cTrav.addCollider(self.cnodepath, self.chand) self.accept('cnode'+str(id), self.hit) #Fires boss projectile def fire(self): base.taskMgr.add(self.weapon.fire, "boss fire") #Adds boss AI def setAI(self): self.AIChar = AICharacter("boss", self.enemy, 100, .05, 25) self.AIWorld.addAiChar(self.AIChar) self.AIbehaviors = self.AIChar.getAiBehaviors() self.AIbehaviors.pursue(base.camera) base.taskMgr.add(self.AIUpdate, "Boss AI Update") #Updates boss AI def AIUpdate(self,task): if not self.deadFlag: if not self.pauseFlag: self.AIbehaviors.resumeAi("pursue") self.fireDelta+=1 if self.fireDelta >= 90: self.fireDelta = 0 self.fire() self.pickuppos = self.enemy.getPos() self.AIWorld.update() return Task.cont def pause(self): self.AIbehaviors.pauseAi("pursue") self.pauseFlag = True def resume(self): #self.AIbehaviors.resumeAi("puruse") self.pauseFlag = False