def take_turn(self): """ | Normal Turn Routine | Mobs take turns if the player can hear it #TODO Change to Mob's FOH | If they're close enough, they attack """ from render import message from utils import a_star_search, applyBonus, revertBonus mob = self.owner status = self.status delta = self.statusDelta speed = 1 # Base speed of 1 tick, to prevent infinite mob action loops if libtcod.map_is_in_fov(gvar.foh_map, mob.x, mob.y): # Normal Behaviour if not status: if mob.distance_to(gvar.game.player) >= 2: # Move towards the player, if she's too far away destination = a_star_search(gvar.game.player.currentmap(), (mob.x, mob.y),(gvar.game.player.x, gvar.game.player.y)) # Perform A*-Search if destination == [(mob.x, mob.y), (mob.x, mob.y)]: # idle for the next 3 turns, if no path to player is found self.status = 'idle' #@TODO Should have prevented A*-Overload, doesn't seem to work self.statusDelta = 3 mob.move_to(destination[-2]) speed = self.owner.fighter.movement_speed() elif sum(gvar.game.player.fighter.hl) > 0: # Player is close enough, perform an attack speed = mob.fighter.attack(gvar.game.player.fighter) # Confusion - Moves to random directions, also -4 dodgeDV penalty elif status == 'confusion': applyBonus('dodgeDV', -4, self.owner.fighter) if delta > 0: self.owner.move(libtcod.random_get_int(0, -1, 1), libtcod.random_get_int(0, -1, 1)) self.statusDelta -= 1 else: revertBonus('dodgeDV', -4, self.owner.fighter) self.status = None message('The smoke around the ' + self.owner.name + ' disappears.', libtcod.violet) if self.owner.fighter is not None: speed = self.owner.fighter.movement_speed() # Idle - Don't do anything, Speed 3 elif status == 'idle': if delta > 0: self.statusDelta -= 1 else: self.status = None speed = 3 return speed
def is_reachable(self, start, end, crossborder=False): """ | perform an a-star search from start to end | and return Boolean, if end was reached | If the crossborder flag is set, it performs 15 searches from random spots on the map, | which doesn't guarantee reachability, but the probability of non-reachability is sufficiently low """ from utils import a_star_search from render import render_all if not crossborder: path = a_star_search(self, start, end, ignore_types=['door']) if end not in path: return False return True else: for i in range(15): end = self.random_room().random_spot() path = a_star_search(self, start, end, ignore_types=['door']) if end not in path: return False return True
def restore_accessibility(self, room): """ | Checks, if every exit of the given room is reachable from the other exits. | If one exit is not reachable from the other, builds a bridge between the two. """ from utils import a_star_search for entrance in room.get_exits(): for exit in room.get_exits(): if entrance == exit: continue else: if not self.is_reachable(entrance, exit): bridge_path = a_star_search(self, entrance, exit, ignore_ai_blocks=True) for bridge_tile in bridge_path: self.set_floor(bridge_tile[0], bridge_tile[1])