예제 #1
0
def pick_monster(game_map, room_id, room_x, room_y, monster_template):
    name, char, colour, hits, weapon = monster_template

    weapon_name, weapon_char, weapon_colour, weapon_power, weapon_uses = weapon

    weapon_stats = Weapon(weapon_power, weapon_uses)
    monster_weapon = Item(game_map,
                          room_id,
                          room_x,
                          room_y,
                          weapon_name,
                          weapon_char,
                          weapon_colour,
                          weapon=weapon_stats)

    fighter_component = Fighter(hits, left_hand=monster_weapon)
    ai_component = BasicMonster()
    monster = Actor(game_map,
                    room_id,
                    room_x,
                    room_y,
                    name,
                    char,
                    colour,
                    fighter=fighter_component,
                    ai=ai_component)

    return monster
예제 #2
0
    def new_game(cls) -> Game:
        game = cls()
        game.map_generator: Optional[MapGenerator] = MapGenerator(
            map_width=CONSTANTS.map_width, map_height=CONSTANTS.map_height)
        game.current_state: Optional[GameStates] = GameStates.PLAYER_TURN
        game.previous_state: Optional[GameStates] = GameStates.PLAYER_TURN

        fighter_component: Fighter = Fighter(
            hp=CONSTANTS.player_hp,
            defense=CONSTANTS.player_defense,
            power=CONSTANTS.player_power,
        )
        inventory_component: Inventory = Inventory(capacity=26)
        level_component = Level()
        equipment_component = Equipment()
        player: Optional[Entity] = Entity(position=Point(0, 0),
                                          char="@",
                                          color=Colors.WHITE,
                                          name="Player",
                                          blocks=True,
                                          render_order=RenderLayer.ACTOR,
                                          fighter=fighter_component,
                                          inventory=inventory_component,
                                          level=level_component,
                                          equipment=equipment_component)
        game.player: Optional[Entity] = player
        game.entities: Optional[List[Entity]] = [player]

        equippable_component = Equippable(slot=EquipmentSlots.MAIN_HAND,
                                          power_bonus=2)
        dagger = Entity(position=Point(0, 0),
                        char="-",
                        color=Colors.SKY,
                        name="Dagger",
                        equippable=equippable_component)
        game.player.inventory.add_item(dagger)
        game.player.equipment.toggle_equip(dagger)

        game.message_log: Optional[MessageLog] = MessageLog(
            x=CONSTANTS.message_x,
            width=CONSTANTS.message_width,
            height=CONSTANTS.message_height,
        )
        game.game_running: bool = True
        game.camera: Optional[Camera] = Camera(player=game.player)

        return game
예제 #3
0
	def __init__(self):
		global playermaxhl
		from mechanics import player_death
		from components import Object,Fighter
		from utils import PriorityQueue

		self.player = Object(currentDungeon=None, currentLevel=0, x=0, y=0, char=chr(2), color=libtcod.white, name='player', blocks=True, inventory=[])
		compFighter = Fighter(hl=[1,2,2,1], essence=2, strength=1, dexterity=1, stamina=1, death_function=player_death)
		playermaxhl = compFighter.hl
		self.player.fighter = compFighter
		self.player.fighter.owner = self.player

		self.ticks = PriorityQueue()

		self.game_msgs = []
		self.last_die_rolls = []
		self.game_state = 'playing'
예제 #4
0
def place_mob_pack(map, x, y, mobToSpawn, packsize):
	""" Places a pack of mobs at the given position. """
	from components import Object,Fighter,MobAI
	from mechanics import mob_death

	for mob in range(1, packsize+1):
		if map.is_blocked(x, y, ai=True):
			(x, y) = map.unblocked_spot_in(4, x, y)
		compAI = MobAI()
		mob = Object(map.owner, map.owner.maps.index(map), x, y, str(mobToSpawn["character"]), color=libtcod.Color(mobToSpawn["color"][0],mobToSpawn["color"][1],mobToSpawn["color"][2]), name=mobToSpawn["name"], blocks=True, exp=mobToSpawn["exp"], ai=compAI)
		compFighter = Fighter(
								hl=mobToSpawn["hl"],
								essence=mobToSpawn["essence"],
								strength=mobToSpawn["strength"],
								dexterity=mobToSpawn["dexterity"],
								skills=mobToSpawn["skills"],
								death_function=mob_death
							)
		mob.fighter = compFighter
		mob.fighter.owner = mob

		map.objects.append(mob)
		mob.send_to_front()
예제 #5
0
    def place_entities(
        self,
        entities: List[Entity],
        min_monsters: int,
    ):
        max_monsters: int = from_dungeon_level(
            table=[[10, 1], [14, 4], [18, 6]],
            dungeon_level=self.dungeon_level)
        max_items: int = from_dungeon_level(table=[[8, 1], [16, 4]],
                                            dungeon_level=self.dungeon_level)

        number_of_monsters: int = random.randint(min_monsters, max_monsters)
        number_of_items: int = random.randint(1, max_items)

        monster_chances: Dict[str, int] = {
            "orc":
            80,
            "troll":
            from_dungeon_level(table=[[15, 3], [30, 5], [60, 7]],
                               dungeon_level=self.dungeon_level)
        }

        item_chances: Dict[str, int] = {
            "healing_potion":
            35,
            "sword":
            from_dungeon_level(table=[[5, 4]],
                               dungeon_level=self.dungeon_level),
            "shield":
            from_dungeon_level(table=[[15, 8]],
                               dungeon_level=self.dungeon_level),
            "lightning_scroll":
            from_dungeon_level(table=[[25, 4]],
                               dungeon_level=self.dungeon_level),
            "fireball_scroll":
            from_dungeon_level(table=[[25, 6]],
                               dungeon_level=self.dungeon_level),
            "confusion_scroll":
            from_dungeon_level(table=[[10, 2]],
                               dungeon_level=self.dungeon_level)
        }

        for i in range(number_of_monsters):
            point: Point = random.choice(self.cave)

            if not any(
                [entity for entity in entities if entity.position == point]):
                monster_choice = random_choice_from_dict(monster_chances)
                if monster_choice == "orc":
                    fighter_component: Fighter = Fighter(hp=20,
                                                         defense=0,
                                                         power=4,
                                                         xp=35)
                    ai_component: BasicMonster = BasicMonster()
                    monster: Entity = Entity(
                        position=point,
                        char="o",
                        color=Colors.LIGHT_GREEN,
                        name="Orc",
                        blocks=True,
                        render_order=RenderLayer.ACTOR,
                        fighter=fighter_component,
                        ai=ai_component,
                    )
                else:
                    fighter_component: Fighter = Fighter(hp=30,
                                                         defense=2,
                                                         power=8,
                                                         xp=100)
                    ai_component: BasicMonster = BasicMonster()
                    monster: Entity = Entity(
                        position=point,
                        char="T",
                        color=Colors.DARKER_GREEN,
                        name="Troll",
                        blocks=True,
                        render_order=RenderLayer.ACTOR,
                        fighter=fighter_component,
                        ai=ai_component,
                    )

                entities.append(monster)

        for i in range(number_of_items):
            point: Point = random.choice(self.cave)

            if not any(
                [entity for entity in entities if entity.position == point]):
                item_choice: str = random_choice_from_dict(item_chances)

                if item_choice == "healing_potion":
                    item_component: Item = Item(use_function=heal, amount=40)
                    item: Entity = Entity(
                        position=point,
                        char="!",
                        color=Colors.VIOLET,
                        name="Healing Potion",
                        render_order=RenderLayer.ITEM,
                        item=item_component,
                    )
                elif item_choice == "sword":
                    equippable_component = Equippable(
                        slot=EquipmentSlots.MAIN_HAND, power_bonus=3)
                    item = Entity(position=point,
                                  char="/",
                                  color=Colors.SKY,
                                  name="Sword",
                                  equippable=equippable_component)
                elif item_choice == "shield":
                    equippable_component = Equippable(
                        slot=EquipmentSlots.OFF_HAND, defense_bonus=1)
                    item = Entity(position=point,
                                  char="[",
                                  color=Colors.DARKER_ORANGE,
                                  name="Shield",
                                  equippable=equippable_component)
                elif item_choice == "fireball_scroll":
                    item_component: Item = Item(
                        use_function=cast_fireball,
                        targeting=True,
                        targeting_message=Message(
                            "Left-click a target tile for the fireball, or right-click to cancel.",
                            Colors.LIGHT_CYAN,
                        ),
                        damage=25,
                        radius=3,
                    )
                    item = Entity(
                        position=point,
                        char="#",
                        color=Colors.RED,
                        name="Fireball Scroll",
                        render_order=RenderLayer.ITEM,
                        item=item_component,
                    )
                elif item_choice == "confusion_scroll":
                    item_component: Item = Item(
                        use_function=cast_confuse,
                        targeting=True,
                        targeting_message=Message(
                            "Left-click an enemy to confuse it, or right-click to cancel.",
                            Colors.LIGHT_CYAN,
                        ),
                    )
                    item: Entity = Entity(
                        position=point,
                        char="#",
                        color=Colors.LIGHT_PINK,
                        name="Confusion Scroll",
                        render_order=RenderLayer.ITEM,
                        item=item_component,
                    )
                else:
                    item_component: Item = Item(use_function=cast_lightning,
                                                damage=40,
                                                maximum_range=5)
                    item: Entity = Entity(
                        position=point,
                        char="#",
                        color=Colors.YELLOW,
                        name="Lightning Scroll",
                        render_order=RenderLayer.ITEM,
                        item=item_component,
                    )

                entities.append(item)
예제 #6
0
파일: engine.py 프로젝트: Gazhole/7DRL2019
def main():
    tdl.set_font('terminal16x16.png', greyscale=True,
                 altLayout=False)  # Load the font from a png.
    tdl.set_fps(100)

    map_width = 20
    map_height = 20

    room_width = 30
    room_height = 30

    screen_width = room_width + 22
    screen_height = room_height + 22

    root_console = tdl.init(screen_width, screen_height, title='7DRL 2019')
    top_panel_console = tdl.Console(screen_width, 10)
    view_port_console = tdl.Console(room_width, room_height)
    bottom_panel_console = tdl.Console(screen_width, 10)
    message_log = MessageLog(0, 0, screen_width, 9)

    entities = []

    game_map = GameMap(map_width, map_height)

    sword_stats = Weapon(2, 10)
    player_weapon = Item(game_map,
                         "0x0",
                         0,
                         0,
                         "Sword",
                         "|", (255, 255, 255),
                         weapon=sword_stats)
    player_stats = Fighter(hits=10, left_hand=player_weapon)
    player = Actor(game_map,
                   "2x2",
                   15,
                   10,
                   "Player",
                   "@", (255, 255, 255),
                   fighter=player_stats)
    entities.append(player)

    generate_map(game_map, entities, player)

    all_consoles = [
        root_console, view_port_console, bottom_panel_console,
        top_panel_console
    ]

    fov_algorithm = "BASIC"
    fov_light_walls = True
    fov_radius = 50
    fov_recompute = True

    game_state = GameStates.PLAYER_TURN

    while not tdl.event.is_window_closed():
        if fov_recompute:  # Compute the field of view to show changes.
            game_map.rooms[player.map_x][player.map_y]\
                .compute_fov(player.room_x, player.room_y,
                             fov=fov_algorithm, radius=fov_radius, light_walls=fov_light_walls, sphere=True)

            render_all(all_consoles, game_map, entities, player, fov_recompute,
                       message_log)
            tdl.flush()
            clear_all(view_port_console, entities)
            fov_recompute = False

        for event in tdl.event.get():
            if event.type == 'KEYUP':
                user_input = event
                break

        else:
            user_input = None

        if not user_input:
            continue

        action = handle_keys(user_input)

        move = action.get('move')
        exit_game = action.get('exit_game')
        select_hand = action.get('select_hand')
        drop_item = action.get('drop_item')
        pickup_item = action.get('pickup_item')
        shuffle_rooms = action.get('shuffle_rooms')

        player_turn_results = []

        if shuffle_rooms:
            message = game_map.shuffle_rooms(player, entities)
            message_log.add_message(message)
            fov_recompute = True

        # TODO at the moment these functions are doing all the leg work and player_turn_results isn't used. Rectify.

        if select_hand and game_state == GameStates.PLAYER_TURN:
            player.fighter.selected_hand = select_hand
            fov_recompute = True

        if drop_item and game_state == GameStates.PLAYER_TURN:
            message = player.fighter.drop_item(game_map, entities)
            message_log.add_message(message)
            game_state = GameStates.ENEMY_TURN
            fov_recompute = True

        if pickup_item and game_state == GameStates.PLAYER_TURN:
            message = player.fighter.pickup_item(entities)
            message_log.add_message(message)
            game_state = GameStates.ENEMY_TURN
            fov_recompute = True

        if move and game_state == GameStates.PLAYER_TURN:
            dx, dy = move
            destination_room_x = player.room_x + dx
            destination_room_y = player.room_y + dy

            if destination_room_x < 0:
                dx = 0

                if player.map_x - 1 < 0:
                    player.map_x = map_width - 1
                else:
                    player.map_x -= 1

                player.room_x = room_width - 1

            if destination_room_x == room_width:
                destination_room_x -= 1
                dx = 0

                if player.map_x + 1 > map_width - 1:
                    player.map_x = 0
                else:
                    player.map_x += 1

                player.room_x = 0

            if destination_room_y < 0:
                dy = 0

                if player.map_y - 1 < 0:
                    player.map_y = map_height - 1
                else:
                    player.map_y -= 1

                player.room_y = room_height - 1

            if destination_room_y == room_height:
                destination_room_y -= 1
                dy = 0

                if player.map_y + 1 > map_height - 1:
                    player.map_y = 0
                else:
                    player.map_y += 1

                player.room_y = 0

            if game_map.rooms[player.map_x][player.map_y].walkable[
                    destination_room_x, destination_room_y]:
                target = get_blocking_entities_at_location(
                    entities, player.map_x, player.map_y, destination_room_x,
                    destination_room_y)

                if target:  # Combat here
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(
                        attack_results
                    )  # Add the result of the last turn to the list
                    fov_recompute = True

                else:
                    player.move(dx, dy)  # Or just move
                    player.set_current_room(game_map)

                    # TODO: Bug with the new room layouts - some cause change of room to break.
                    print("MapPos: ",
                          player.map_x,
                          ",",
                          player.map_y,
                          end=" / ")
                    print("RoomPos: ", player.room_x, ",", player.room_y)
                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN  # Switch over the enemy's turn.

        if exit_game:
            return True

        for player_turn_result in player_turn_results:
            message = player_turn_result.get("message")  # Pull any messages
            dead_entity = player_turn_result.get(
                "dead")  # Or anything that died

            if message:
                message_log.add_message(
                    message
                )  # Add the message (if any) to the message log to print on screen.

            if dead_entity:  # If anything died...
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)  # Game over
                else:
                    message = kill_monster(
                        dead_entity
                    )  # Print a death message for monster, add exp

                message_log.add_message(message)  # Print messages to screen.

        player_turn_results.clear()  # Clear ready for next turn.

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.map_x == player.map_x and entity.map_y == player.map_y:
                    if entity.ai:  # If the entity has some intelligence (monsters, npc)
                        enemy_turn_results = entity.ai.take_turn(
                            player, game_map, entities)

                        for enemy_turn_result in enemy_turn_results:  # Same deal as the player turns
                            message = enemy_turn_result.get("message")
                            dead_entity = enemy_turn_result.get("dead")

                            if message:
                                message_log.add_message(message)

                            if dead_entity:
                                if dead_entity == player:
                                    message, game_state = kill_player(
                                        dead_entity)
                                else:
                                    message = kill_monster(dead_entity)

                                message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                        enemy_turn_results.clear()

                    if game_state == GameStates.PLAYER_DEAD:
                        break

            else:
                game_state = GameStates.PLAYER_TURN