Exemplo n.º 1
0
    def use_ability(self, game_map, ability, target=None):
        results = []
        targeting = False
        area = ability.target_area
        include_self = ability.target_self

        if include_self:
            target = self.owner
            results = self.owner.fighter.attack(target, ability)
            msgs = self.owner.status_effects.process_effects(game_map=game_map, self_targeting=True)
            if msgs:
                results.extend(msgs)

        elif not target:
            radius = ability.get_range()

            entities = get_neighbours(self.owner, game_map.tiles, radius, fighters=True,
                                      include_self=include_self, algorithm=area,
                                      mark_area=True)
            if not entities and not include_self:
                msg = Message("There are no available targets in range.")
                results.append(msg)
            elif len(entities) == 1 and not ability.requires_targeting:
                target = entities[0]
                results = self.owner.fighter.attack(target, ability)
            else:
                msg = Message(msg="Use '{0}' on which target? Range: {1}".format(
                    ability.name, radius), style="question")
                results.append(msg)
                target = entities[0]
                targeting = True
        else:
            results = self.owner.fighter.attack(target, ability)

        return results, target, targeting
Exemplo n.º 2
0
    def ally_actions(self):

        for entity in self.owner.levels.current_map.entities["allies"]:
            visible = self.owner.player.light_source.fov_map.fov[entity.y,
                                                                 entity.x]
            if visible:
                if entity.fighter:
                    entity.status_effects.process_effects()
                    self.owner.render_functions.draw_stats(entity)

                if self.owner.player.fighter.dead:
                    kill_msg = self.owner.player.kill()
                    self.owner.game_state = GameStates.PLAYER_DEAD
                    self.owner.message_log.send(kill_msg)
                    self.owner.render_functions.draw_stats()
                    self.owner.fov_recompute = True
                    break

                if entity.fighter and entity.fighter.dead:
                    kill_msg = entity.kill()
                    self.owner.levels.current_map.tiles[entity.x][
                        entity.y].blocking_entity = None
                    self.owner.message_log.send(kill_msg)
                    self.owner.fov_recompute = True

                elif entity.fighter and entity.fighter.paralyzed:
                    self.owner.message_log.send(
                        Message("Your {0} friend is paralyzed!".format(
                            entity.name)))
                    self.owner.game_state = GameStates.PLAYER_TURN

                elif entity.ai:
                    target = self.owner.player
                    prev_pos_x, prev_pos_y = entity.x, entity.y
                    targets = get_neighbours(
                        entity,
                        self.owner.levels.current_map.tiles,
                        radius=3,
                        fighters=True,
                        exclude_player=True)
                    if targets:
                        target = targets[0]

                    combat_msg = entity.ai.take_turn(
                        target, self.owner.levels.current_map,
                        self.owner.levels.current_map.entities,
                        self.owner.time_counter)
                    self.owner.levels.current_map.tiles[prev_pos_x][
                        prev_pos_y].remove_entity(entity)
                    self.owner.levels.current_map.tiles[entity.x][
                        entity.y].add_entity(entity)
                    if entity.occupied_tiles is not None:
                        self.owner.levels.current_map.tiles[prev_pos_x][
                            prev_pos_y + 1].remove_entity(entity)
                        self.owner.levels.current_map.tiles[prev_pos_x + 1][
                            prev_pos_y + 1].remove_entity(entity)
                        self.owner.levels.current_map.tiles[
                            prev_pos_x + 1][prev_pos_y].remove_entity(entity)

                        self.owner.levels.current_map.tiles[entity.x][
                            entity.y + 1].add_entity(entity)
                        self.owner.levels.current_map.tiles[entity.x + 1][
                            entity.y + 1].add_entity(entity)
                        self.owner.levels.current_map.tiles[entity.x + 1][
                            entity.y].add_entity(entity)

                    self.owner.fov_recompute = True
                    if combat_msg:
                        self.owner.message_log.send(combat_msg)
                        self.owner.render_functions.draw_stats(entity)
                    if self.owner.player.fighter.dead:
                        kill_msg = self.owner.player.kill()
                        self.owner.game_state = GameStates.PLAYER_DEAD
                        self.owner.message_log.send(kill_msg)
                        self.owner.render_functions.draw_stats()
                        break
                    # Functions on monster death
                    if entity.fighter and entity.fighter.dead:
                        level_up_msg = self.owner.player.player.handle_player_exp(
                            entity.fighter)
                        kill_msg = entity.kill()
                        self.owner.levels.current_map.tiles[entity.x][
                            entity.y].blocking_entity = None
                        self.owner.message_log.send(kill_msg)
                        self.owner.message_log.send(
                            Message("I feel my power returning!"))
                        if level_up_msg:
                            self.owner.message_log.send(level_up_msg)
                        self.owner.fov_recompute = True
Exemplo n.º 3
0
    def targeting_actions(self,
                          move=False,
                          examine=False,
                          main_menu=False,
                          use_ability=False,
                          interact=False):

        if move:
            if self.owner.cursor.cursor.targeting_ability:
                include_self = self.owner.cursor.cursor.targeting_ability.target_self
                radius = self.owner.cursor.cursor.targeting_ability.get_range()
                entities = get_neighbours(self.owner.player,
                                          self.owner.levels.current_map.tiles,
                                          radius,
                                          include_self=include_self,
                                          fighters=True,
                                          mark_area=True)
                entities_in_range = list(
                    filter(
                        lambda entity: self.owner.player.light_source.fov_map.
                        fov[entity.y, entity.x], entities))

                msg = self.owner.cursor.cursor.select_next(
                    entities_in_range, self.owner.levels.current_map.tiles)
                if msg:
                    self.owner.message_log.send(msg)
                self.owner.fov_recompute = True

            else:
                dx, dy = move
                destination_x = self.owner.cursor.x + dx
                destination_y = self.owner.cursor.y + dy
                x, y = self.owner.game_camera.get_coordinates(
                    destination_x, destination_y)

                if 0 < x < self.owner.game_camera.width - 1 and 0 < y < self.owner.game_camera.height - 1:
                    prev_pos_x, prev_pos_y = self.owner.cursor.x, self.owner.cursor.y
                    self.owner.cursor.move(dx, dy)
                    self.owner.levels.current_map.tiles[prev_pos_x][
                        prev_pos_y].remove_entity(self.owner.cursor)
                    self.owner.levels.current_map.tiles[self.owner.cursor.x][
                        self.owner.cursor.y].add_entity(self.owner.cursor)
                    self.owner.fov_recompute = True

        elif main_menu or examine:
            self.owner.game_state = GameStates.PLAYER_TURN
            self.owner.levels.current_map.tiles[self.owner.cursor.x][
                self.owner.cursor.y].remove_entity(self.owner.cursor)
            del self.owner.levels.current_map.entities["cursor"]
            self.owner.cursor = None
            self.owner.fov_recompute = True
            return True

        elif (use_ability
              or interact) and self.owner.cursor.cursor.targeting_ability:
            target = self.owner.levels.current_map.tiles[self.owner.cursor.x][
                self.owner.cursor.y].blocking_entity

            result, target, targeting = self.owner.player.player.use_ability(
                self.owner.levels.current_map,
                self.owner.cursor.cursor.targeting_ability, target)
            if target:
                self.owner.render_functions.draw_stats(target)
            self.owner.time_counter.take_turn(1)
            self.owner.game_state = GameStates.ENEMY_TURN
            self.owner.message_log.send(result)
            self.owner.levels.current_map.tiles[self.owner.cursor.x][
                self.owner.cursor.y].remove_entity(self.owner.cursor)
            del self.owner.levels.current_map.entities["cursor"]
            self.owner.cursor = None
            self.owner.fov_recompute = True

        # if self.owner.player.fighter.paralyzed:
        #     self.owner.message_log.send("You are paralyzed!")
        #     self.owner.time_counter.take_turn(1)
        #     self.owner.game_state = GameStates.ENEMY_TURN

        return False
Exemplo n.º 4
0
    def turn_taking_actions(self,
                            wait=None,
                            move=None,
                            interact=None,
                            pickup=None,
                            stairs=None,
                            examine=None,
                            use_ability=None,
                            key=None):

        if wait or move or interact or pickup or stairs or use_ability and not self.owner.player.fighter.dead:
            self.owner.player.status_effects.process_effects(
                game_map=self.owner.levels.current_map)
            if self.owner.player.fighter.paralyzed:
                msg = Message("You are paralyzed!")
                self.owner.message_log.send(msg)
                self.owner.time_counter.take_turn(1)

        if wait:
            self.owner.time_counter.take_turn(1)
            # player.player.spirit_power -= 1
            msg = Message("You wait a turn.")
            self.owner.message_log.send(msg)
            self.owner.game_state = GameStates.ENEMY_TURN
            self.owner.fov_recompute = True

        elif move:
            dx, dy = move
            destination_x = self.owner.player.x + dx
            destination_y = self.owner.player.y + dy

            # Handle player attack
            if not self.owner.levels.current_map.is_blocked(
                    destination_x, destination_y):
                target = self.owner.levels.current_map.tiles[destination_x][
                    destination_y].blocking_entity
                if target:
                    results = self.owner.player.fighter.attack(
                        target, self.owner.player.player.sel_weapon)
                    self.owner.message_log.send(results)
                    # player.player.spirit_power -= 0.5
                    self.owner.time_counter.take_turn(1)
                    self.owner.render_functions.draw_stats(target)

                else:
                    if self.owner.player.fighter.mv_spd <= 0:
                        msg = Message("You are unable to move!")
                        self.owner.message_log.send(msg)
                        self.owner.time_counter.take_turn(1)
                    else:
                        prev_pos_x, prev_pos_y = self.owner.player.x, self.owner.player.y
                        self.owner.player.move(dx, dy)
                        self.owner.time_counter.take_turn(
                            1 / self.owner.player.fighter.mv_spd)
                        self.owner.fov_recompute = True
                        self.owner.levels.current_map.tiles[prev_pos_x][
                            prev_pos_y].remove_entity(self.owner.player)
                        self.owner.levels.current_map.tiles[
                            self.owner.player.x][
                                self.owner.player.y].add_entity(
                                    self.owner.player)

                self.owner.game_state = GameStates.ENEMY_TURN

            elif self.owner.levels.current_map.tiles[destination_x][
                    destination_y].is_door:
                door = self.owner.levels.current_map.tiles[destination_x][
                    destination_y].door
                interact_msg = door.interaction(self.owner.levels.current_map)
                self.owner.message_log.send(interact_msg)
                self.owner.time_counter.take_turn(1)
                self.owner.game_state = GameStates.ENEMY_TURN
                self.owner.fov_recompute = True

        elif interact:
            entities = get_neighbours(self.owner.player,
                                      self.owner.levels.current_map.tiles)
            interact_msg = None
            for entity in entities:
                if entity.door:
                    interact_msg = entity.door.interaction(
                        self.owner.levels.current_map)
                    self.owner.message_log.send(interact_msg)
                elif entity.item:
                    interact_msg = entity.item.interaction(
                        self.owner.levels.current_map)
                    self.owner.message_log.send(interact_msg)
            if interact_msg:
                self.owner.time_counter.take_turn(1)
                self.owner.game_state = GameStates.ENEMY_TURN
                self.owner.fov_recompute = True

        elif pickup:
            pickup_msg = self.owner.player.inventory.add_item(
                self.owner.levels.current_map)

            if pickup_msg:
                self.owner.message_log.send(pickup_msg)
                self.owner.time_counter.take_turn(1)
                self.owner.game_state = GameStates.ENEMY_TURN
                self.owner.fov_recompute = True
            else:
                msg = Message("There is nothing here to pick up.")
                self.owner.message_log.send(msg)

        elif stairs:
            stairs_component = self.owner.levels.current_map.tiles[
                self.owner.player.x][self.owner.player.y].stairs
            if stairs_component:
                results = stairs_component.interaction(self.owner.levels)
                self.owner.message_log.send(results)
                self.owner.time_counter.take_turn(1)
                self.owner.render_functions.draw_messages()
                self.owner.fov_recompute = True

        elif examine:
            self.owner.game_state = GameStates.TARGETING
            cursor_component = Cursor()
            cursor = Entity(self.owner.player.x,
                            self.owner.player.y,
                            5,
                            0xE800 + 1746,
                            "light yellow",
                            "cursor",
                            cursor=cursor_component,
                            stand_on_messages=False)
            self.owner.cursor = cursor
            self.owner.levels.current_map.tiles[self.owner.cursor.x][
                self.owner.cursor.y].add_entity(self.owner.cursor)
            self.owner.levels.current_map.entities["cursor"] = [
                self.owner.cursor
            ]
            self.owner.fov_recompute = True

        elif use_ability:
            if key == blt.TK_Z:
                ability = self.owner.player.player.sel_utility
            else:
                ability = self.owner.player.player.sel_attack
            result, target, targeting = self.owner.player.player.use_ability(
                self.owner.levels.current_map, ability)
            if target:
                self.owner.render_functions.draw_stats(target)
            if targeting:
                self.owner.game_state = GameStates.TARGETING

                cursor_component = Cursor(targeting_ability=ability)
                cursor = Entity(target.x,
                                target.y,
                                5,
                                0xE800 + 1746,
                                "light yellow",
                                "cursor",
                                cursor=cursor_component,
                                stand_on_messages=False)
                self.owner.cursor = cursor
                self.owner.levels.current_map.tiles[self.owner.cursor.x][
                    self.owner.cursor.y].add_entity(self.owner.cursor)
                self.owner.levels.current_map.entities["cursor"] = [
                    self.owner.cursor
                ]
            else:
                self.owner.time_counter.take_turn(1)
                self.owner.game_state = GameStates.ENEMY_TURN

            self.owner.message_log.send(result)
            self.owner.fov_recompute = True

        if self.owner.player.fighter.summoning:
            msg = self.owner.player.summoner.process(
                game_map=self.owner.levels.current_map)
            if msg:
                self.owner.message_log.send(msg)
            self.owner.fov_recompute = True
Exemplo n.º 5
0
    def process(self, game_map=None):
        msg = None

        if self.process_instantly:
            self.process_instantly = False

        if self.source.dead and self.name == "strangle":
            self.duration = 0

        if self.heal:
            msg = self.owner.heal(self.power[self.rank])
            return self, msg

        if self.duration <= 0:

            if self.hit_penalty:
                self.owner.hit_penalty -= self.hit_penalty[self.rank]
            if self.drain_stats:
                self.owner.ac += self.drain_stats[self.rank]
                self.owner.ev += self.drain_stats[self.rank]
            if self.slow_amount:
                self.owner.mv_spd += self.slow_amount
            if self.delayed_damage:
                self.owner.take_damage(self.delayed_damage)
            if self.paralyze:
                self.owner.paralyzed = False
            if self.fly:
                self.owner.ev -= self.fly_ev_boost
                self.owner.flying = False
            if self.reveal:
                self.owner.revealing = False
            if self.summoning:
                self.summoning = None
                self.owner.owner.summoner.summoning = None
                self.owner.owner.summoner.rank = self.rank
            self.owner.effects.remove(self.description)
            return self, msg

        if self.summoning:
            self.owner.summoning = True
            self.owner.owner.summoner.summoning = self.summoning
            self.owner.owner.summoner.rank = self.rank

        if self.dps:
            self.owner.take_damage(self.dps[self.rank])

        if self.hit_penalty:
            if self.description not in self.owner.effects:
                self.owner.hit_penalty += self.hit_penalty[self.rank]

        if self.drain_stats:
            if self.description not in self.owner.effects:
                self.owner.hit_penalty -= self.drain_stats[self.rank]
                self.owner.ac -= self.drain_stats[self.rank]
                self.owner.ev -= self.drain_stats[self.rank]

        if self.slow:
            if self.description not in self.owner.effects:
                self.slow_amount = self.owner.mv_spd - self.owner.mv_spd * self.slow[self.rank]
                self.owner.mv_spd -= self.slow_amount

        if self.paralyze:
            if random() <= self.chance[self.rank]:
                self.owner.paralyzed = True
            else:
                self.owner.paralyzed = True

        if self.fly:
            if self.description not in self.owner.effects:
                self.fly_ev_boost = ceil(self.owner.ev * self.power[self.rank] - self.owner.ev)
                self.owner.ev += self.fly_ev_boost
                self.owner.flying = True

        if self.reveal:
            neighbours = get_neighbours(self.owner.owner, game_map.tiles, include_self=False,
                                        fighters=False, mark_area=True,
                                        radius=self.reveal.radius[self.rank], algorithm="square")
            for entity in neighbours:
                if entity.hidden:
                    entity.hidden = False
            if self.description not in self.owner.effects:
                self.owner.revealing = True

        if self.description not in self.owner.effects:
            self.owner.effects.append(self.description)
        self.duration -= 1

        return None, msg
Exemplo n.º 6
0
    def process(self, game_map):
        msgs = []
        if not self.summoning and self.summoned_entities:
            summons = []
            for entity in self.summoned_entities:
                summons.append(entity.name)
                game_map.entities["allies"].remove(entity)
                game_map.tiles[entity.x][entity.y].remove_entity(entity)
                del entity
            self.summoned_entities = []
            self.owner.fighter.summoning = False
            self.summoning = [""]
            if len(summons) > 1:
                msg = Message(
                    "Your trusty companions {0} return back to the spirit plane!"
                    .format(", ".join(summons)))
            else:
                msg = Message(
                    "Your trusty companion {0} returns back to the spirit plane!"
                    .format(summons[0]))
            msgs.append(msg)
            return msgs

        elif self.summoning and not self.summoned_entities:
            if len(self.summoning) <= self.rank:
                name = self.summoning[-1]
            else:
                name = self.summoning[self.rank]
            char = tilemap()["monsters"][name]
            color = get_monster_color(name)
            f_data = json_data.data.fighters[name]
            remarks = f_data["remarks"]
            fighter_component = Fighter(hp=f_data["hp"],
                                        ac=f_data["ac"],
                                        ev=f_data["ev"],
                                        power=f_data["power"],
                                        mv_spd=f_data["mv_spd"],
                                        atk_spd=f_data["atk_spd"],
                                        size=f_data["size"],
                                        fov=f_data["fov"])
            ai_component = BasicMonster(ally=True)
            light_component = LightSource(radius=fighter_component.fov)
            abilities_component = Abilities(name)
            status_effects_component = StatusEffects(name)
            neighbours = get_neighbours(self.owner,
                                        game_map=game_map.tiles,
                                        radius=3,
                                        algorithm="square",
                                        empty_tiles=True)
            summon_tile = choice(neighbours)
            entity_name = name
            monster = Entity(summon_tile.x,
                             summon_tile.y,
                             3,
                             char,
                             color,
                             entity_name,
                             blocks=True,
                             fighter=fighter_component,
                             ai=ai_component,
                             light_source=light_component,
                             abilities=abilities_component,
                             status_effects=status_effects_component,
                             remarks=remarks,
                             indicator_color="light green")
            monster.light_source.initialize_fov(game_map)
            game_map.tiles[summon_tile.x][summon_tile.y].add_entity(monster)
            game_map.entities["allies"].append(monster)
            self.summoned_entities.append(monster)
            msg = Message("A friendly {0} appears!".format(entity_name))
            msgs.append(msg)
            remark_str = "{0}: {1}".format(monster.colored_name,
                                           choice(monster.remarks))
            remark_msg = Message(msg=remark_str, style="dialog")
            msgs.append(remark_msg)
            return msgs

        return msgs
Exemplo n.º 7
0
    def take_turn(self, target, game_map, entities, time):
        monster = self.owner
        if not self.action_begin:
            self.last_action = time.get_last_turn()
        time_to_act = time.get_turn() - self.last_action
        action_cost = 0
        combat_msgs = []
        self.owner.light_source.recompute_fov(monster.x, monster.y)

        if self.ally and target.player:
            if monster.distance_to(target) > 1:
                monster.move_astar(target, entities, game_map)
            elif randint(0, 4) == 0:
                tiles = get_neighbours(self.owner,
                                       game_map.tiles,
                                       algorithm="square",
                                       empty_tiles=True)
                target_tile = choice(tiles)
                self.owner.move_to_tile(target_tile.x, target_tile.y)
                if self.owner.remarks:
                    remark = choice(self.owner.remarks)
                    combat_msgs.append(
                        Message("{0}: {1}".format(self.owner.colored_name,
                                                  remark),
                                style="dialog"))

        elif self.owner.light_source.fov_map.fov[target.y, target.x]:

            self.target_seen = True
            self.target_last_seen_x = target.x
            self.target_last_seen_y = target.y
            self.action_begin = True

            while action_cost < time_to_act:

                if monster.distance_to(
                        target
                ) == 1 and self.owner.fighter.atk_spd <= time_to_act - action_cost:
                    if target.fighter.hp > 0:
                        combat_msg, skill = self.choose_skill()
                        if skill is None:
                            combat_msgs.extend(combat_msg)
                            return combat_msgs
                        combat_msg = monster.fighter.attack(target, skill)
                        combat_msgs.extend(combat_msg)
                        action_cost += 1
                        #self.last_action += action_cost

                    else:
                        break

                elif 1 / self.owner.fighter.mv_spd <= time_to_act - action_cost and monster.distance_to(
                        target) >= 2:
                    if randint(0, 4) == 0:
                        if self.owner.remarks:
                            remark = choice(self.owner.remarks)
                            combat_msgs.append(
                                Message(msg="{0}: {1}".format(
                                    self.owner.colored_name, remark),
                                        style="dialog"))
                    monster.move_astar(target, entities, game_map)
                    action_cost += 1 / monster.fighter.mv_spd
                    #self.last_action += action_cost

                else:
                    break

            self.last_action += action_cost

        elif self.target_seen:
            self.action_begin = False
            if not monster.x == self.target_last_seen_x and not monster.y == self.target_last_seen_y:
                monster.move_astar(target, entities, game_map)

        else:
            self.action_begin = False

        return combat_msgs