def cansee(self, start, end): points = pathfinder.lineto(start, end) # if the distance is only one (original point and destination point), still can see if len(points) <= 2: return True for point in points: if not self.istransparent(point): return False return True
def update(self): self.updatecombo() # weight management if self.getparam("weight limit") is not None: totalw = self.gettotalweight() if totalw > int(self.getparam("weight limit")): if self.player: self.gameengine.gameevent.report("you can't carry so much weight!", None, None, None) coord = (self.x, self.y+1) if self.gameengine.mapfield.ispassable(coord): self.setposition(coord) # ai if not self.player: # not applicable for player actions = 0 # failsafe for monsters which can't decide maxactions = 100 iterations = 0 while self.canact(actions): iterations += 1 if iterations > maxactions: break if self.gameengine.mapfield.getplayer() is None: return playerpos = self.gameengine.mapfield.getplayer().getposition() position = self.getposition() # I like to collect various things, if there are any under me, take them! if self.getflag("collector"): # if I am near home, I'll put there my items if self.home is not None and len(self.inventory) > 0: if pathfinder.isnear(self.home.getposition(), self.getposition()): self.giveall(self.home) actions += 1 localitems = self.gameengine.mapfield.getitems(self.getposition()) if len(localitems) > 0: for witem in localitems: self.pick(witem) actions += 1 # I shoot random things if self.getflag("randomshot") and self.gameengine.mapfield.cansee(position, playerpos) and self.canact(actions): bestranged = self.getbestranged() if bestranged is not None and self.firetime == 0: vector = self.gameengine.mapfield.getrandomnearby(self.getposition()) vector = (vector[0] - self.getposition()[0], vector[1]) vector = (vector[0], vector[1] - self.getposition()[1]) self.fire(vector, bestranged) actions += 1 if self.getparam("firelimit") is not None: self.firetime = int(self.getparam("firelimit")) if self.getflag("selfdestruct") and self.canact(actions) and self.gameengine.mapfield.cansee(position, playerpos): if pathfinder.isnear(playerpos, position): self.setparam("hp", 0) # I have ranged capability and see the target if self.getflag("ranged") and self.gameengine.mapfield.cansee(position, playerpos) and self.canact(actions): bestranged = self.getbestranged() if bestranged is not None and self.firetime == 0: # if the player is near me and I have better attack than ranged weapon, then bash him if pathfinder.isnear(playerpos, position) and \ bestranged.getparam("damage") is not None and int(bestranged.getparam("damage")) < int(self.getparam("attack")): False # if is in range an line, shoot! else: direct = pathfinder.finddirection(position, playerpos) if direct is not None: wrange = int(bestranged.getparam("range")) linetotarget = pathfinder.lineto(position, playerpos) linetotarget = linetotarget[1:-1] if len(linetotarget) < wrange: # check if there is anything in the path canshoot = True for p in linetotarget: if not self.gameengine.mapfield.ispassable(p): canshoot = False if canshoot: self.fire(direct, bestranged) self.gameengine.gameevent.report( self.getname() + " fired " + bestranged.getname() + "!") actions += 1 if self.getparam("firelimit") is not None: self.firetime = int(self.getparam("firelimit")) break # to prevent jumping in the own line of fire # if can move then move to player if not self.getflag("nomove") and not self.getflag("ground") and self.canact(actions): # i am a thief and want to steal harpoons if self.getflag("harpoon thief"): # search for nearby item itemnear = False localitems = self.gameengine.mapfield.getitems(self.getposition()) if len(localitems) > 0: for witem in localitems: if witem.getflag("harpoon"): self.pick(witem) actions += 1 continue for lookeditem in self.gameengine.mapfield.items: if lookeditem.getflag("harpoon"): if pathfinder.isnear(self.getposition(), lookeditem.getposition()): itemnear = True # item will not fall, go directly to it if self.gameengine.mapfield.isgrounded(lookeditem.getposition()): goto = self.gameengine.mapfield.findpath(self.getposition(), lookeditem.getposition()) # item will fail, go below else: downpos = lookeditem.x, lookeditem.y + 1 # will fall on me, wait if downpos == self.getposition(): actions += 1 break # will fall near, go for it elif pathfinder.isnear(self.getposition(), downpos): goto = self.gameengine.mapfield.findpath(self.getposition(), downpos) # will fall too far, go for previous position first else: goto = self.gameengine.mapfield.findpath(self.getposition(), lookeditem.getposition()) self.action(goto) actions += 1 break # there is item nearby, do not move to player if itemnear: continue # i am standard monster and want to kill the diver or wander randomly if self.canact(actions): goto = None if self.lastseen == position: self.lastseen = None if self.gameengine.mapfield.cansee(position, playerpos): # I will remember where I've seen target self.lastseen = playerpos # i am coward, i won't go near player if self.getflag("coward"): # player is already nearby find safe place if possible if pathfinder.isnear(position, playerpos): safepos = [] for n in self.gameengine.mapfield.getneighbors(position[0], position[1]): if not pathfinder.isnear(n, playerpos): if self.gameengine.mapfield.ispassable(n): safepos.append(n) if len(safepos) > 0: goto = self.gameengine.mapfield.findpath(position, safepos[ random.randint(0, len(safepos)-1)]) else: self.action(self.gameengine.mapfield.getrandomnearby(position)) # player is still distant else: goto = self.gameengine.mapfield.findpath(position, playerpos) # too close! if goto is not None: if pathfinder.isnear(playerpos, goto): actions += 1 continue else: goto = self.gameengine.mapfield.findpath(position, playerpos) if goto is not None: self.action(goto) else: # wander randomly self.action(self.gameengine.mapfield.getrandomnearby(position)) # if I can't see player, I will go to place where I've last seen target elif self.lastseen is not None: goto = self.gameengine.mapfield.findpath(position, self.lastseen) if goto is not None: self.action(goto) # can't see target even here, where I've last seen him else: # wander randomly self.action(self.gameengine.mapfield.getrandomnearby(position)) actions += 1 # can move only on ground if self.getflag("ground") and not self.getflag("nomove") and self.canact(actions): position = self.getposition() if not self.player: # if the player is nearby, I will cut him if len(pathfinder.lineto(position, playerpos)) == 2: self.action(playerpos) actions += 1 # I don't have anything to hold to, I will fall if not self.gameengine.mapfield.isgrounded(self.getposition()): self.action((self.x, self.y + 1)) # or i will wander by one direction else: if self.canact(actions): if self.direction is None: directions = [-1, 1] self.direction = directions[random.randint(0, 1)] goto = self.gameengine.mapfield.getpassableground(self.getposition(), self.direction) if goto is None: self.direction *= -1 self.action(goto) # check isgrounded, if not fall down if self.getflag("ground") and not self.gameengine.mapfield.isgrounded(self.getposition()): coord = (self.x, self.y+1) if self.gameengine.mapfield.ispassable(coord): self.setposition(coord) actions += 1 # manage spawners, applicable for player if self.getparam("firelimit") is not None: if self.firetime > 0: self.firetime -= 1 if self.getflag("spawner"): # spawn children if there are less than should be if len(self.children) < int(self.getparam("spawnlimit")): self.respawntime += 1 if self.respawntime >= int(self.getparam("respawntime")): #spawnpos = self.gameengine.mapfield.getrandomnearby(self.getposition()) #if spawnpos is not None: #todo: spawn position should be besides, but should not move yet child = Monster(self.gameengine.moninfo[self.getparam("spawn")], self.gameengine) child.home = self #child.setposition(spawnpos) child.setposition(self.getposition()) self.children.append(child) self.gameengine.mapfield.addmonster(child) self.respawntime = 0
def update(self): self.updatecombo() # weight management if self.getparam("weight limit") is not None: totalw = self.gettotalweight() if totalw > int(self.getparam("weight limit")): if self.player: self.gameengine.gameevent.report( "you can't carry so much weight!", None, None, None) coord = (self.x, self.y + 1) if self.gameengine.mapfield.ispassable(coord): self.setposition(coord) # ai if not self.player: # not applicable for player actions = 0 # failsafe for monsters which can't decide maxactions = 100 iterations = 0 while self.canact(actions): iterations += 1 if iterations > maxactions: break if self.gameengine.mapfield.getplayer() is None: return playerpos = self.gameengine.mapfield.getplayer().getposition() position = self.getposition() # I like to collect various things, if there are any under me, take them! if self.getflag("collector"): # if I am near home, I'll put there my items if self.home is not None and len(self.inventory) > 0: if pathfinder.isnear(self.home.getposition(), self.getposition()): self.giveall(self.home) actions += 1 localitems = self.gameengine.mapfield.getitems( self.getposition()) if len(localitems) > 0: for witem in localitems: self.pick(witem) actions += 1 # I shoot random things if self.getflag( "randomshot") and self.gameengine.mapfield.cansee( position, playerpos) and self.canact(actions): bestranged = self.getbestranged() if bestranged is not None and self.firetime == 0: vector = self.gameengine.mapfield.getrandomnearby( self.getposition()) vector = (vector[0] - self.getposition()[0], vector[1]) vector = (vector[0], vector[1] - self.getposition()[1]) self.fire(vector, bestranged) actions += 1 if self.getparam("firelimit") is not None: self.firetime = int(self.getparam("firelimit")) if self.getflag("selfdestruct") and self.canact( actions) and self.gameengine.mapfield.cansee( position, playerpos): if pathfinder.isnear(playerpos, position): self.setparam("hp", 0) # I have ranged capability and see the target if self.getflag("ranged") and self.gameengine.mapfield.cansee( position, playerpos) and self.canact(actions): bestranged = self.getbestranged() if bestranged is not None and self.firetime == 0: # if the player is near me and I have better attack than ranged weapon, then bash him if pathfinder.isnear(playerpos, position) and \ bestranged.getparam("damage") is not None and int(bestranged.getparam("damage")) < int(self.getparam("attack")): False # if is in range an line, shoot! else: direct = pathfinder.finddirection( position, playerpos) if direct is not None: wrange = int(bestranged.getparam("range")) linetotarget = pathfinder.lineto( position, playerpos) linetotarget = linetotarget[1:-1] if len(linetotarget) < wrange: # check if there is anything in the path canshoot = True for p in linetotarget: if not self.gameengine.mapfield.ispassable( p): canshoot = False if canshoot: self.fire(direct, bestranged) self.gameengine.gameevent.report( self.getname() + " fired " + bestranged.getname() + "!") actions += 1 if self.getparam( "firelimit") is not None: self.firetime = int( self.getparam("firelimit")) break # to prevent jumping in the own line of fire # if can move then move to player if not self.getflag("nomove") and not self.getflag( "ground") and self.canact(actions): # i am a thief and want to steal harpoons if self.getflag("harpoon thief"): # search for nearby item itemnear = False localitems = self.gameengine.mapfield.getitems( self.getposition()) if len(localitems) > 0: for witem in localitems: if witem.getflag("harpoon"): self.pick(witem) actions += 1 continue for lookeditem in self.gameengine.mapfield.items: if lookeditem.getflag("harpoon"): if pathfinder.isnear(self.getposition(), lookeditem.getposition()): itemnear = True # item will not fall, go directly to it if self.gameengine.mapfield.isgrounded( lookeditem.getposition()): goto = self.gameengine.mapfield.findpath( self.getposition(), lookeditem.getposition()) # item will fail, go below else: downpos = lookeditem.x, lookeditem.y + 1 # will fall on me, wait if downpos == self.getposition(): actions += 1 break # will fall near, go for it elif pathfinder.isnear( self.getposition(), downpos): goto = self.gameengine.mapfield.findpath( self.getposition(), downpos) # will fall too far, go for previous position first else: goto = self.gameengine.mapfield.findpath( self.getposition(), lookeditem.getposition()) self.action(goto) actions += 1 break # there is item nearby, do not move to player if itemnear: continue # i am standard monster and want to kill the diver or wander randomly if self.canact(actions): goto = None if self.lastseen == position: self.lastseen = None if self.gameengine.mapfield.cansee( position, playerpos): # I will remember where I've seen target self.lastseen = playerpos # i am coward, i won't go near player if self.getflag("coward"): # player is already nearby find safe place if possible if pathfinder.isnear(position, playerpos): safepos = [] for n in self.gameengine.mapfield.getneighbors( position[0], position[1]): if not pathfinder.isnear(n, playerpos): if self.gameengine.mapfield.ispassable( n): safepos.append(n) if len(safepos) > 0: goto = self.gameengine.mapfield.findpath( position, safepos[random.randint( 0, len(safepos) - 1)]) else: self.action( self.gameengine.mapfield. getrandomnearby(position)) # player is still distant else: goto = self.gameengine.mapfield.findpath( position, playerpos) # too close! if goto is not None: if pathfinder.isnear(playerpos, goto): actions += 1 continue else: goto = self.gameengine.mapfield.findpath( position, playerpos) if goto is not None: self.action(goto) else: # wander randomly self.action( self.gameengine.mapfield.getrandomnearby( position)) # if I can't see player, I will go to place where I've last seen target elif self.lastseen is not None: goto = self.gameengine.mapfield.findpath( position, self.lastseen) if goto is not None: self.action(goto) # can't see target even here, where I've last seen him else: # wander randomly self.action( self.gameengine.mapfield.getrandomnearby( position)) actions += 1 # can move only on ground if self.getflag("ground") and not self.getflag( "nomove") and self.canact(actions): position = self.getposition() if not self.player: # if the player is nearby, I will cut him if len(pathfinder.lineto(position, playerpos)) == 2: self.action(playerpos) actions += 1 # I don't have anything to hold to, I will fall if not self.gameengine.mapfield.isgrounded( self.getposition()): self.action((self.x, self.y + 1)) # or i will wander by one direction else: if self.canact(actions): if self.direction is None: directions = [-1, 1] self.direction = directions[random.randint( 0, 1)] goto = self.gameengine.mapfield.getpassableground( self.getposition(), self.direction) if goto is None: self.direction *= -1 self.action(goto) # check isgrounded, if not fall down if self.getflag( "ground") and not self.gameengine.mapfield.isgrounded( self.getposition()): coord = (self.x, self.y + 1) if self.gameengine.mapfield.ispassable(coord): self.setposition(coord) actions += 1 # manage spawners, applicable for player if self.getparam("firelimit") is not None: if self.firetime > 0: self.firetime -= 1 if self.getflag("spawner"): # spawn children if there are less than should be if len(self.children) < int(self.getparam("spawnlimit")): self.respawntime += 1 if self.respawntime >= int(self.getparam("respawntime")): #spawnpos = self.gameengine.mapfield.getrandomnearby(self.getposition()) #if spawnpos is not None: #todo: spawn position should be besides, but should not move yet child = Monster( self.gameengine.moninfo[self.getparam("spawn")], self.gameengine) child.home = self #child.setposition(spawnpos) child.setposition(self.getposition()) self.children.append(child) self.gameengine.mapfield.addmonster(child) self.respawntime = 0