1

I'm using libtcod and python to make a roguelike; the tutorial I'm following the monsters only follow you if you're in their field of view. Obviously this is insufficient; as it means you can turn a corner and they don't follow you around the corner.
I tried something like this;

class BasicMonster:
    def take_turn(self, seen):
        self.seen = False
        monster = self.owner

        if lib.map_is_in_fov(fov_map, monster.x, monster.y):
            self.seen == True

            if self.seen == True:
                self.move_towards(player.x, player.y)

To no avail. It raises

TypeError: take_turn() takes exactly 2 arguments (1 given)

Not sure how to implement this.

I'm calling I'm calling take_turn under

if game_state == 'playing' and player_action != 'didnt-take-turn': 
    for object in objects: 
        if object.ai: 
            object.ai.take_turn()
sloth
  • 99,095
  • 21
  • 171
  • 219
  • 3
    how are you calling `take_turn`? I don't see that code anywhere here – inspectorG4dget Sep 16 '13 at 00:34
  • Tip: `if self.seen == True:` could just be `if self.seen:` here. Also, the `self.seen == True` line does nothing; what is it supposed to do? (Be after/inside the `if` with only one `=`, maybe?) – Ry- Sep 16 '13 at 00:37
  • It's supposed to set the monster's variable "seen" to True so that they've been seen and will then move towards the player until one of them is dead. – user2782303 Sep 16 '13 at 01:56
  • And I'm calling take_turn under if game_state == 'playing' and player_action != 'didnt-take-turn': for object in objects: if object.ai: object.ai.take_turn() – user2782303 Sep 16 '13 at 02:43

2 Answers2

1

A simple solution is to keep track of the position of the player the last time the monster saw the player.

When the player moves out of view, simply move towards that last position.

class BasicMonster:

    def __init__(self):
        self.last_player_pos = None

    def take_turn(self):
        monster = self.owner
        if libtcod.map_is_in_fov(fov_map, monster.x, monster.y):
            # store position we last saw the player
            self.last_player_pos = player.x, player.y 

            #move towards player if far away
            # ... rest of code here ...
        else:
            if self.last_player_pos:
                monster.move_towards(*self.last_player_pos)

This is of course very simple (and exploitable), but you'll get the idea. Further steps could be creating some sort of time-out and/or tracking the player by sound/scent or anything not related to FOV.

sloth
  • 99,095
  • 21
  • 171
  • 219
1

Scent-tracking is a very effective way to control monster movement; I've used a variation in my C++ roguelike project that sets a 'scent trail', which makes it possible to 'confuse' a monster by backtracking or walking over your own scent multiple times.

I only have experience with C++, but if you search for 'libtcod C++ tutorial', it should bring the page with the scent routine up in the first few results. It should be easy enough to get the general idea.

Good luck!