Ejemplo n.º 1
0
def create_monster(name):
    _base = Base(name='player',
                 char='@',
                 color=libtcod.white,
                 render_order=RenderOrder.ACTOR)
    _body = Body()
    _health = Health()
    _inv = Inventory()
    _job = Job.BARBARIAN
    _pos = Position()
    _race = Race.HUMAN
    _soul = Soul(eccentricity=5, rank=10)
    _status = Status()

    monster = Entity(base=_base,
                     body=_body,
                     health=_health,
                     inv=_inv,
                     job=_job,
                     pos=_pos,
                     race=_race,
                     soul=_soul,
                     status=_status)
    monster.health.points = monster.health.max

    return monster
Ejemplo n.º 2
0
def create_soul(entity):
    _soul_rank = entity.soul.rank
    _soul_eccentricity = entity.soul.eccentricity
    _soul_number = entity.soul.soul

    _soul = Soul(_soul_eccentricity, _soul_rank)
    _soul.number = _soul_number

    _base = Base(name='soul',
                 char='*',
                 color=libtcod.dark_green,
                 render_order=RenderOrder.SOUL)
    _pos = Position()

    soul_item = Entity(base=_base, pos=_pos, soul=_soul)

    return soul_item
Ejemplo n.º 3
0
def create_monster_(difficulty):
    _rank = pick_rank(difficulty)
    _race = pick_race(difficulty)
    _job = pick_job(_race)

    _ai = AI(brain=BRAIN.ZOMBIE)
    _body = Body()
    _health = Health()
    _pos = Position()
    _soul = Soul(eccentricity=_race.value['eccentricity'],
                 rank=_rank.value['rank'])
    _status = Status()

    _name = str(_rank.value['name']).capitalize() + ' ' + str(
        _race.value['name']).capitalize() + ' ' + str(
            _job.value['name']).capitalize()
    _color = _rank.value['color']
    _char = _race.value['char']

    _base = Base(name=_name,
                 char=_char,
                 color=_color,
                 render_order=RenderOrder.ACTOR)

    monster = Entity(ai=_ai,
                     base=_base,
                     body=_body,
                     health=_health,
                     job=_job,
                     pos=_pos,
                     race=_race,
                     soul=_soul,
                     status=_status)
    monster.health.points = monster.health.max

    equip_monster(monster)

    return monster
Ejemplo n.º 4
0
    def place_entities(self, room, entities):
        '''Place monsters and items randomly into a room on the map.'''
        max_monsters_per_room = from_dungeon_level([[2, 1], [3, 4], [5, 6]],
                                                   self.dlevel)
        max_items_per_room = from_dungeon_level([[1, 1], [2, 4]], self.dlevel)
        number_of_monsters = randint(0, max_monsters_per_room)
        number_of_items = randint(0, max_items_per_room)

        monster_chances = {
            "orc": 80,
            "troll": from_dungeon_level([[15, 3], [30, 5], [60, 7]],
                                        self.dlevel)
        }
        item_chances = {
            "healing_potion": 35,
            "sword": from_dungeon_level([[5, 4]], self.dlevel),
            "shield": from_dungeon_level([[15, 8]], self.dlevel),
            "lightning_scroll": from_dungeon_level([[25, 4]], self.dlevel),
            "fireball_scroll": from_dungeon_level([[25, 6]], self.dlevel),
            "confusion_scroll": from_dungeon_level([[10, 2]], self.dlevel)
        }

        # place monsters
        for i in range(number_of_monsters):
            x, y = choice(room.coords)
            if not any([e for e in entities if e.x == x and e.y == y]):
                monster_choice = random_choice_from_dict(monster_chances)
                if monster_choice == "orc":
                    fighter_component = Fighter(hp=20,
                                                defense=0,
                                                power=4,
                                                xp=35)
                    ai_component = BasicMonster()
                    inv_component = Inventory(5)
                    soul_char = choice([".", "*", "+"])
                    soul_color = choice([tcod.red, tcod.orange, tcod.yellow])
                    m_soul = Soul(soul_char, soul_color)
                    m_name = "Orc" + str(len(entities))
                    monster = Entity(len(entities),
                                     x,
                                     y,
                                     'o',
                                     tcod.desaturated_green,
                                     m_name,
                                     blocks=True,
                                     soul=m_soul,
                                     fighter=fighter_component,
                                     ai=ai_component,
                                     inventory=inv_component,
                                     render_order=RenderOrder.ACTOR)
                else:
                    fighter_component = Fighter(hp=30,
                                                defense=2,
                                                power=8,
                                                xp=100)
                    ai_component = BasicMonster()
                    inv_component = Inventory(10)
                    soul_char = choice(["*", "+"])
                    soul_color = choice([tcod.orange, tcod.yellow, tcod.green])
                    m_soul = Soul(soul_char, soul_color)
                    m_name = "Troll" + str(len(entities))
                    monster = Entity(len(entities),
                                     x,
                                     y,
                                     'T',
                                     tcod.darker_green,
                                     m_name,
                                     blocks=True,
                                     soul=m_soul,
                                     fighter=fighter_component,
                                     ai=ai_component,
                                     inventory=inv_component,
                                     render_order=RenderOrder.ACTOR)

                entities.append(monster)

        # place items
        for i in range(number_of_items):
            x, y = choice(room.coords)
            if not any([e for e in entities if e.x == x and e.y == y]):
                item_choice = random_choice_from_dict(item_chances)
                if item_choice == "healing_potion":
                    item_component = Item(use_function=heal, amount=40)
                    item = Entity(len(entities),
                                  x,
                                  y,
                                  '!',
                                  tcod.violet,
                                  "Healing Potion",
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_choice == "sword":
                    equippable_component = Equippable(EquipmentSlots.MAIN_HAND,
                                                      power_bonus=3)
                    item = Entity(len(entities),
                                  x,
                                  y,
                                  "/",
                                  tcod.sky,
                                  "Sword",
                                  equippable=equippable_component)
                elif item_choice == "shield":
                    equippable_component = Equippable(EquipmentSlots.OFF_HAND,
                                                      defense_bonus=1)
                    item = Entity(len(entities),
                                  x,
                                  y,
                                  "[",
                                  tcod.dark_orange,
                                  "Shield",
                                  equippable=equippable_component)
                elif item_choice == "fireball_scroll":
                    msg_str = (f"Left-click a target tile for the fireball, "
                               f"or right-click to cancel.")
                    msg = Message(msg_str, tcod.light_cyan)
                    item_component = Item(use_function=cast_fireball,
                                          targeting=True,
                                          targeting_message=msg,
                                          damage=25,
                                          radius=3)
                    item = Entity(len(entities),
                                  x,
                                  y,
                                  "#",
                                  tcod.red,
                                  "Fireball Scroll",
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_choice == "confusion_scroll":
                    msg_str = (f"Left-click an enemy to confuse it, "
                               f"or right-click to cancel")
                    msg = Message(msg_str, tcod.light_cyan)
                    item_component = Item(use_function=cast_confuse,
                                          targeting=True,
                                          targeting_message=msg)
                    item = Entity(len(entities),
                                  x,
                                  y,
                                  "#",
                                  tcod.light_pink,
                                  "Confusion Scroll",
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                else:
                    item_component = Item(use_function=cast_lightning,
                                          damage=40,
                                          max_range=5)
                    item = Entity(len(entities),
                                  x,
                                  y,
                                  "#",
                                  tcod.yellow,
                                  "Lightning Scroll",
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                entities.append(item)
def handle_player_actions(actions, in_handle, entities, game_map, console,
                          panel_ui, panel_map, curr_entity, controlled_entity,
                          player, omnivision, message_log,
                          mouse_x, mouse_y, timeq, game_state, prev_state,
                          constants, debug_f):
    # pull constants
    mapset = constants["mapset"]
    fov_radius = constants["fov_radius"]
    fov_light_walls = constants["fov_light_walls"]
    fov_algorithm = constants["fov_algorithm"]
    # setup stuff
    next_turn = False
    curr_entity = curr_entity
    controlled_entity = controlled_entity
    player = player
    entities = entities
    omnivision = omnivision
    timeq = timeq
    want_exit = False
    render_update = False

    for action in actions:
        # out of turn actions
        want_exit = action.get("exit")
        fullscreen = action.get("fullscreen")
        mousemotion = action.get("mousemotion")
        msg_up = action.get("msg_up")
        msg_down = action.get("msg_down")
        show_inventory = action.get("show_inventory")
        drop_inventory = action.get("drop_inventory")
        take_stairs = action.get("take_stairs")
        show_character_screen = action.get("show_character_screen")

        # debug actions
        omnivis = action.get("omnivis")
        switch_char = action.get("switch_char")
        map_gen = action.get("map_gen")
        graph_gen = action.get("graph_gen")
        test = action.get("test")

        if want_exit:  # {"exit": True}
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN):
                game_state = prev_state
                want_exit = False
                render_update = True
            else:
                want_exit = True

        if fullscreen:  # {"fullscreen": True}
            next_turn = False
            render_update = True
            tcod.console_set_fullscreen(not tcod.console_is_fullscreen())

        # TODO: I'm not super happy about how this works
        #       but not sure how to elegantly tag render_update when the list
        #       of entities being moused over changes
        if mousemotion:  # {"mousemotion": (x, y)}
            render_update = True

        if msg_up:
            if message_log.bottom < message_log.length - message_log.height:
                message_log.scroll(1)
                render_update = True

        if msg_down:
            if message_log.bottom > 0:
                message_log.scroll(-1)
                render_update = True

        if show_inventory:
            render_update = True
            next_turn = False
            prev_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            render_update = True
            next_turn = False
            prev_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if take_stairs:
            for entity in entities:
                if (entity.stairs and entity.x == controlled_entity.x
                        and entity.y == controlled_entity.y):
                    game_map.dlevel += 1
                    game_map.tiles = game_map.initialize_tiles()
                    entities = [player, controlled_entity]
                    game_map.make_map(player, entities, **mapset)
                    # set up time system
                    actors = [e for e in entities if e.ai]
                    timeq = deque(sorted(actors, key=lambda e: e.time_to_act))
                    curr_entity = timeq.popleft()
                    next_turn = True
                    # FOV calculation setup
                    render_update = True
                    for entity in actors:
                        entity.fov_map = initialize_fov(game_map)
                        recompute_fov(game_map, entity, fov_radius,
                                      fov_light_walls, fov_algorithm)
                    break
            else:
                msg = Message("There are no stairs here.", tcod.yellow)
                message_log.add_message(msg)

        if show_character_screen:
            render_update = True
            next_turn = False
            prev_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if omnivis:  # {"omnivis": True}
            next_turn = False
            render_update = True
            omnivision = not omnivision

        if switch_char:  # {"switch_char": True}
            next_turn = False
            render_update = True
            index = controlled_entity.ident + 1
            if index >= len(entities):
                controlled_entity = entities[0]
            else:
                controlled_entity = entities[index]
            # only switch to controllable entities
            while not controlled_entity.soul:
                index = controlled_entity.ident + 1
                if index >= len(entities):
                    controlled_entity = entities[0]
                else:
                    controlled_entity = entities[index]

        if map_gen:  # {"map_gen": True}
            next_turn = True
            render_update = True
            game_map.seed = randint(0, 99999)
            game_map.tiles = game_map.initialize_tiles()
            player_soul = Soul("@", tcod.azure)
            player_gnosis = Gnosis()
            player_fighter = Fighter(hp=30, defense=2, power=5)
            player_ai = IdleMonster()
            player_inventory = Inventory(26)
            player = Entity(0, 0, 0, "&", tcod.yellow, "Player", blocks=True,
                            fighter=player_fighter, ai=player_ai,
                            soul=player_soul, gnosis=player_gnosis,
                            inventory=player_inventory,
                            render_order=RenderOrder.ACTOR)
            entities = [player]
            controlled_entity = player
            game_map.make_map(player, entities, **mapset)
            # set up time system
            actors = [e for e in entities if e.ai]
            timeq = deque(sorted(actors, key=lambda e: e.time_to_act))
            curr_entity = timeq.popleft()
            next_turn = True
            # FOV calculation setup
            render_update = True
            for entity in actors:
                if entity.ident == 0:
                    entity.fov_map = init_fov_etheric(game_map)
                else:
                    entity.fov_map = initialize_fov(game_map)
                recompute_fov(game_map, entity, fov_radius, fov_light_walls,
                              fov_algorithm)

        if graph_gen:  # {"graph_gen": True}
            game_map.make_graph()

        if test:  # {"test": True}
            pass

    return (next_turn, curr_entity, controlled_entity, entities, player,
            timeq, omnivision, render_update, want_exit, game_state,
            prev_state)
def handle_entity_actions(actions, in_handle, entities, timeq, game_map,
                          console, message_log, controlled_entity, player,
                          game_state, prev_state, targeting_item, debug_f):
    action_cost = 0
    next_turn = True
    controlled_entity = controlled_entity
    render_update = False
    game_state = game_state
    prev_state = prev_state
    targeting_item = targeting_item

    # TODO: rewrite to use object features: while len(action) > 0: action = action.popleft()
    for action in actions:
        # turn actions
        message = action.get("message")
        move = action.get("move")
        move_astar = action.get("move_astar")
        melee = action.get("melee")
        wait = action.get("wait")
        spawn_etheric = action.get("spawn_etheric")
        despawn_etheric = action.get("despawn_etheric")
        possess = action.get("possess")
        unpossess = action.get("unpossess")
        pickup = action.get("pickup")
        item_added = action.get("item_added")
        use_item = action.get("use_item")
        drop_item = action.get("drop_item")
        item_dropped = action.get("item_dropped")
        targeting = action.get("targeting")
        cancel_target = action.get("cancel_target")
        dead = action.get("dead")
        xp = action.get("xp")
        level_up = action.get("level_up")
        equip = action.get("equip")

        if message:  # {"message": message_string}
            render_update = True
            message_log.add_message(message)

        if move:  # {"move": (entity, dx, dy)}
            action_cost = 100
            next_turn = True
            entity, dx, dy = move
            # don't let entities move out of the map's boundaries
            if not (entity.x + dx < 0 or entity.y + dy < 0
                    or entity.x + dx >= game_map.width
                    or entity.y + dy >= game_map.height):
                entity.move(dx, dy)

        if move_astar:  # {"move_astar": (entity, target)}
            action_cost = 100
            next_turn = True
            entity, target = move_astar
            entity.move_astar(target, entities, game_map)

        if melee:  # {"melee": (entity, target)}
            action_cost = 100
            next_turn = True
            entity, target = melee
            melee_results = entity.fighter.attack(target)
            for action in melee_results:
                xp = action.get("xp")
                if xp:
                    action["xp"] = [entity, xp[1]]
            actions.extend(melee_results)

        if wait:  # {"wait": int_time}
            action_cost = wait
            next_turn = True

        if spawn_etheric:  # {"spawn_etheric": (entity, dest_x, dest_y)}
            action_cost = 100
            next_turn = True
            render_update = True
            spawner, dest_x, dest_y = spawn_etheric
            result_str = f"You manifest your etheric body!"
            message_log.add_message(Message(result_str, tcod.light_gray))
            etheric_soul = Soul(spawner.gnosis.char, spawner.gnosis.color)
            etheric_body = Etheric(move_range=spawner.gnosis.move_range,
                                   duration=spawner.gnosis.duration)
            etheric_fighter = Fighter(hp=1, defense=0, power=0)
            etheric_ai = IdleMonster()
            possessor = Entity(len(entities), dest_x, dest_y,
                               spawner.gnosis.char, spawner.gnosis.color,
                               "EBody", blocks=False,
                               etheric=etheric_body, soul=etheric_soul,
                               fighter=etheric_fighter, ai=etheric_ai,
                               render_order=RenderOrder.ACTOR,
                               speed=spawner.gnosis.speed)
            possessor.owner = spawner
            possessor.fov_map = init_fov_etheric(game_map)
            possessor.fov_recompute = True
            entities.append(possessor)
            for index, entity in enumerate(timeq):
                if entity.time_to_act > possessor.time_to_act:
                    timeq.insert(index, possessor)
                    break
            else:
                timeq.append(possessor)
            controlled_entity = possessor

        if despawn_etheric:  # {"despawn_etheric": entity}
            action_cost = 50
            next_turn = True
            render_update = True
            entity = despawn_etheric
            owner = entity.owner
            controlled_entity = owner
            entities.remove(entity)
            entity.speed = 0

        if possess:  # {"possess": (entity, target)}
            action_cost = 100
            next_turn = True
            render_update = True
            possessor, target = possess
            result_str = f"You possess the {target.name}!"
            message_log.add_message(Message(result_str, tcod.light_gray))
            target.possessor = possessor
            controlled_entity = target

        if unpossess:  # {"unpossess": (entity, dest_x, dest_y)}
            action_cost = 100
            next_turn = True
            render_update = True
            entity, dest_x, dest_y = unpossess
            result_str = f"You stop possessing the {controlled_entity.name}!"
            message_log.add_message(Message(result_str, tcod.light_gray))
            controlled_entity = entity.possessor
            controlled_entity.x = dest_x
            controlled_entity.y = dest_y
            controlled_entity.fov_recompute = True
            entity.possessor = None

        if pickup and controlled_entity.inventory:
            next_turn = True
            render_update = True
            for entity in entities:
                if (entity.item
                        and entity.x == controlled_entity.x
                        and entity.y == controlled_entity.y):
                    results = controlled_entity.inventory.add_item(entity)
                    actions.extend(results)
                    break
            else:
                msg_str = "There is nothing here to pick up."
                message_log.add_message(Message(msg_str, tcod.yellow))

        if item_added:
            entities.remove(item_added)

        if use_item:
            render_update = True
            use_results = controlled_entity.inventory.use(use_item,
                                                          entities=entities)
            if any([u_r for u_r in use_results if u_r.get("consumed")]):
                action_cost = 50
                next_turn = True
                # TODO: hack to clear targeting after item use, don't like it
                if use_item is targeting_item:
                    targeting_item = None
                    game_state = prev_state
            # TODO: hack to clear targeting after item use, don't like it
            else:
                use_item.item.target_x = None
                use_item.item.target_y = None
            actions.extend(use_results)

        if drop_item:
            render_update = True
            drop_results = controlled_entity.inventory.drop(drop_item)
            if any([d_r for d_r in drop_results if d_r.get("item_dropped")]):
                action_cost = 50
                next_turn = True
            actions.extend(drop_results)

        if item_dropped:
            entities.append(item_dropped)

        # TODO: There has to be a better way to handle targeting than this
        if targeting:
            render_update = True
            next_turn = False
            prev_state = GameStates.NORMAL_TURN
            game_state = GameStates.TARGETING
            targeting_item = targeting
            message_log.add_message(targeting_item.item.targeting_message)

        if cancel_target:
            game_state = prev_state
            render_update = True
            next_turn = False
            message_log.add_message(Message("Targeting cancelled",
                                            tcod.light_cyan))

        if dead:  # {"dead": entity}
            render_update = True
            if dead == controlled_entity:
                controlled_entity = entities[0]
                controlled_entity.x = dead.x
                controlled_entity.y = dead.y
                controlled_entity.fov_recompute = True
            message = kill_entity(dead)
            message_log.add_message(message)

        if xp:  # {"xp": [entity, xp]}
            entity, xp_gain = xp
            if entity is not None and entity.level:
                level_from_xp = entity.level.add_xp(xp_gain)
                msg_str = f"{entity.name} gains {xp_gain} experience points."
                msg = Message(msg_str, tcod.white)
                message_log.add_message(msg)
                if level_from_xp:
                    msg_str = (f"{entity.name} grows stronger!  They have "
                               f"reached level {entity.level.current_level}!")
                    message_log.add_message(Message(msg_str, tcod.yellow))
                    if entity is controlled_entity:
                        prev_state = game_state
                        game_state = GameStates.LEVEL_UP

        if level_up:  # {"level_up": [entity, ("hp"|"str"|"def")]}
            entity, choice = level_up
            if choice == "hp":
                entity.fighter.base_max_hp += 20
                entity.fighter.hp += 20
            elif choice == "str":
                entity.fighter.base_power += 1
            elif choice == "def":
                entity.fighter.base_defense += 1
            game_state = prev_state
            render_update = True
            next_turn = False

        if equip:  # {"equip": [entity, item]}
            entity, item = equip
            equip_results = entity.equipment.toggle_equip(item)

            for equip_result in equip_results:
                # {"equipped": [entity, item]}
                # {"dequipped": [entity, item]}
                equipped = equip_result.get("equipped")
                dequipped = equip_result.get("dequipped")
                if dequipped:
                    entity, item = dequipped
                    msg_str = f"{entity.name} dequipped the {item.name}"
                    message_log.add_message(Message(msg_str, tcod.white))
                if equipped:
                    entity, item = equipped
                    msg_str = f"{entity.name} equipped the {item.name}"
                    message_log.add_message(Message(msg_str, tcod.white))
                if dequipped or equipped:
                    next_turn = True
                    render_update = True
                    action_cost = 50

    return (action_cost, next_turn, controlled_entity, render_update,
            game_state, prev_state, targeting_item)
Ejemplo n.º 7
0
def get_game_variables(constants, root_console, panel_map, debug_f):

    # object setup
    player_soul = Soul("@", tcod.azure)
    player_fighter = Fighter(hp=100, defense=1, power=2)
    player_ai = IdleMonster()
    player_inventory = Inventory(26)
    player_level = Level()
    player_equipment = Equipment()
    player_gnosis = Gnosis()
    player = Entity(0,
                    0,
                    0,
                    "@",
                    tcod.yellow,
                    "Player",
                    blocks=True,
                    soul=player_soul,
                    gnosis=player_gnosis,
                    fighter=player_fighter,
                    ai=player_ai,
                    inventory=player_inventory,
                    render_order=RenderOrder.ACTOR,
                    level=player_level,
                    equipment=player_equipment)
    entities = [player]
    controlled_entity = player
    equippable_component = Equippable(EquipmentSlots.MAIN_HAND, power_bonus=2)
    dagger = Entity(len(entities),
                    0,
                    0,
                    "-",
                    tcod.sky,
                    "Dagger",
                    equippable=equippable_component)
    player.inventory.add_item(dagger)
    player.equipment.toggle_equip(dagger)
    game_state = GameStates.NORMAL_TURN
    prev_state = GameStates.NORMAL_TURN

    message_log = MessageLog(constants["message_x"],
                             constants["message_width"],
                             constants["message_height"], 100)

    # create initial game map
    # game_map = GameMap(map_width, map_height, seed, con=con, debug=debug_f)
    # game_map = GameMapRandomRooms(map_width, map_height, seed, con=con, debug=debug_f)
    game_map = GameMapBSP(constants["map_width"],
                          constants["map_height"],
                          constants["seed"],
                          dlevel=1,
                          con=root_console,
                          debug=debug_f)
    game_map.make_map(player, entities, **constants["mapset"])

    # set up time system
    actors = [e for e in entities if e.ai]
    timeq = deque(sorted(actors, key=lambda entity: entity.time_to_act))
    curr_entity = timeq.popleft()
    next_turn = True

    # FOV calculation setup
    render_update = True

    for entity in actors:
        if entity.etheric:
            entity.fov_map = init_fov_etheric(game_map)
        else:
            entity.fov_map = initialize_fov(game_map)
        recompute_fov(game_map, entity, constants["fov_radius"],
                      constants["fov_light_walls"], constants["fov_algorithm"])

    # TODO: there has to be a better way to handle targeting than this
    targeting_item = None

    return (player, entities, controlled_entity, curr_entity, game_state,
            prev_state, message_log, game_map, timeq, next_turn, render_update,
            targeting_item)