예제 #1
0
 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
예제 #2
0
 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
예제 #3
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
예제 #4
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