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
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
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'
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()
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)
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