def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') wait = action.get('wait') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') take_stairs = action.get('take_stairs') level_up = action.get('level_up') show_character_screen = action.get('show_character_screen') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location(entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif wait: game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message(Message('There is nothing here to pick up.', libtcod.yellow)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend(player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True libtcod.console_clear(con) break else: message_log.add_message(Message('There are no stairs here.', libtcod.yellow)) if level_up: if level_up == 'hp': player.fighter.max_hp += 20 player.fighter.hp += 20 elif level_up == 'str': player.fighter.power += 1 elif level_up == 'def': player.fighter.defense += 1 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') xp = player_turn_result.get('xp') 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 item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if xp: leveled_up = player.level.add_xp(xp) message_log.add_message(Message('You gain {0} experience points.'.format(xp))) if leveled_up: message_log.add_message(Message( 'Your battle skills grow stronger! You reached level {0}'.format( player.level.current_level) + '!', libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: 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 if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 map_width = 80 map_height = 43 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } fighter_component = Fighter(hp=30, defense=2, power=5) player = Entity(0, 0, '@', libtcod.white, "Player", blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component) entities = [player] libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False) con = libtcod.console_new(screen_width, screen_height) panel = libtcod.console_new(screen_width, panel_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) fov_recompute = True fov_map = initialize_fov(game_map) message_log = MessageLog(message_x, message_width, message_height) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors) libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location(entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_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.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: 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 if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50), } player = Entity(int(screen_width / 2), int(screen_height / 2), '@', libtcod.white) npc = Entity(int(screen_width / 2 - 5), int(screen_height / 2), '@', libtcod.yellow) entities = [npc, player] libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GRAYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial', False) con = libtcod.console.Console(screen_width, screen_height) game_map = GameMap(map_width, map_height) game_map.generate_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player) fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False libtcod.console_flush() clear_all(con, entities) key = libtcod.console_check_for_keypress() action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move: dx, dy = move if not game_map.is_blocked(player.x + dx, player.y + dy): player.move(dx, dy) fov_recompute = True if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) time.sleep(.01)
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None libtcod.sys_set_fps(24) while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') quick_inventory = action.get('quick_inventory') inventory_index = action.get('inventory_index') exit = action.get('exit') fullscreen = action.get('fullscreen') take_stairs = action.get('take_stairs') level_up = action.get('level_up') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') show_character_screen = action.get('show_character_screen') quickslot_index = action.get('quickslot_index') quick_slot = action.get('quick_use') examine_entity = action.get('examine_entity') enemies_afoot = False for entity in entities: if libtcod.map_is_in_fov(fov_map, entity.x, entity.y) and entity.ai: enemies_afoot = True break player_turn_results = [] if right_click and game_state == game_state.PLAYERS_TURN and not enemies_afoot: (x, y) = mouse_action['right_click'] move_target = lambda: None setattr(move_target, 'x', x) setattr(move_target, 'y', y) if game_map.tiles[x][y].explored: game_state = game_state.CLICK_MOVE if game_state == game_state.CLICK_MOVE: if enemies_afoot: game_state = game_state.ENEMY_TURN if game_state != game_state.ENEMY_TURN: if player.distance_to(move_target) < 1: game_state = game_state.PLAYERS_TURN else: if player.move_astar(move_target, entities, game_map, max_path=300, check_explored=True): fov_recompute = True else: game_state = game_state.PLAYERS_TURN if (move or left_click or (enemies_afoot and right_click)) and game_state == GameStates.PLAYERS_TURN: if move: dx, dy = move else: if left_click: target_x, target_y = mouse_action['left_click'] else: target_x, target_y = mouse_action['right_click'] dx = target_x - player.x dy = target_y - player.y distance = math.sqrt(dx**2 + dy**2) if distance != 0: dx = int(round(dx / distance)) dy = int(round(dy / distance)) else: dx = 0 dy = 0 destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target and target != player: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) elif target: message_log.add_message( Message('You take a short rest', libtcod.white)) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', libtcod.yellow)) if quick_slot: for item in player.inventory.items: if item.uID == player.quick_use.quick_list[quick_slot - 1]: player_turn_results.extend( player.inventory.use(item, entities=entities, fov_map=fov_map)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if examine_entity: previous_game_state = game_state game_state = GameStates.EXAMINE_SCREEN if quick_inventory: previous_game_state = game_state game_state = GameStates.QUICK_USE if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend( player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) elif game_state == GameStates.QUICK_USE: player_turn_results.extend(player.quick_use.add_item(0, item)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True libtcod.console_clear(con) break else: message_log.add_message( Message('There are no stairs here.', libtcod.yellow)) if level_up: if level_up == 'hp': player.fighter.max_hp += 20 player.fighter.hp += 20 elif level_up == 'str': player.fighter.base_power += 1 elif level_up == 'def': player.fighter.base_defense += 1 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN, GameStates.QUICK_USE, GameStates.EXAMINE_SCREEN): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) elif game_state == GameStates.LEVEL_UP: level_up_menu(con, 'Level up! Choose a stat to raise:', player, 40, screen_width, screen_height) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # resolve and display the results for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') equip = player_turn_result.get('equip') xp = player_turn_result.get('xp') evoked = player_turn_result.get('evoked') item_slotted = player_turn_result.get('item_slotted') 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 item_slotted: game_state = GameStates.PLAYERS_TURN if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed or evoked: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if equip: equip_results = player.equipment.toggle_equip(equip) for equip_result in equip_results: equipped = equip_result.get('equipped') unequipped = equip_result.get('unequipped') if equipped: message_log.add_message( Message('You equipped the {0}'.format( equipped.name))) if unequipped: message_log.add_message( Message('You unequipped the {0}'.format( unequipped.name))) game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if xp: leveled_up = player.level.add_xp(xp) message_log.add_message( Message('You gain {0} experience points.'.format(xp))) if leveled_up: message_log.add_message( Message( 'Your battle skills grow stronger! You reached level {0}' .format(player.level.current_level) + '!', libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if game_state == GameStates.ENEMY_TURN or game_state == game_state.CLICK_MOVE: # before anybody takes their turn player_eot = player.fighter.EndofTurn() process_turn(player, player_eot, message_log) for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) process_turn(player, enemy_turn_results, message_log) # Manage conditions and end of turn effects if entity.fighter: enemy_turn_results = entity.fighter.EndofTurn() process_turn(player, enemy_turn_results, message_log) if game_state == GameStates.PLAYER_DEAD: break else: if game_state != game_state.CLICK_MOVE: game_state = GameStates.PLAYERS_TURN
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') take_stairs = action.get('take_stairs') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', libtcod.yellow)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend( player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True libtcod.console_clear(con) break else: message_log.add_message( Message('There are no stairs here.', libtcod.yellow)) if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: if game_state == GameStates.PLAYER_DEAD: return True else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') 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 item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: 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 if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): # Screen informations screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 10 fov_algorithm = 0 fov_light_walls = True fov_radius = 20 # Colors for the rooms colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } # Creates the entities in the game, in this case an npc and user player = Entity(int(screen_width/2), int(screen_height/2), '@', libtcod.white) npc = Entity(int(screen_width/2 -5), int(screen_height/2-5), '@', libtcod.yellow) entities = [npc, player] con = libtcod.console_new(screen_width,screen_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player) fov_recompute = True fov_map =initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False) while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get ('exit') fullscreen = action.get('fullscreen') if move : dx, dy = move if not game_map.is_blocked(player.x + dx, player.y + dy): player.move(dx, dy) fov_recompute = True if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(): # Defaults for screen screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 colors = { 'dark_wall': tcod.Color(0, 0, 100), 'dark_ground': tcod.Color(50, 50, 150) } player = Entity(int(screen_width / 2), int(screen_height / 2), '@', tcod.white) npc = Entity(int(screen_width / 2 - 5), int(screen_height / 2), '@', tcod.white) entities = [npc, player] # Describes which font to use tcod.console_set_custom_font( 'arial10x10.png', tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_TCOD) # Renders initial screen tcod.console_init_root(screen_width, screen_height, 'TCOD Tutorial Revised', False) con = tcod.console_new(screen_width, screen_height) game_map = GameMap(map_width, map_height) key = tcod.Key() mouse = tcod.Mouse() # Main game loop while not tcod.console_is_window_closed(): tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS, key, mouse) render_all(con, entities, game_map, screen_width, screen_height, colors) tcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') enable_exit = action.get('exit') enable_fullscreen = action.get('fullscreen') if move: dx, dy = move if not game_map.is_blocked(player.x + dx, player.y + dy): player.move(dx, dy) if enable_exit: return True if enable_fullscreen: tcod.console_set_fullscreen(not tcod.console_is_fullscreen())
def main(): screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 4 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 colors = { 'dark_wall': tcod.Color(0, 0, 100), 'dark_ground': tcod.Color(50, 50, 150), 'light_wall': tcod.Color(130, 110, 50), 'light_ground': tcod.Color(200, 180, 50) } fighter_component = Fighter(hp=30, defense=2, power=5) player = Entity(0, 0, '@', tcod.white, 'Player', blocks=True, fighter=fighter_component) entities = [player] tcod.console_set_custom_font( '.\\assets\\fonts\\arial10x10.png', tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_TCOD) tcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', fullscreen=False) con = tcod.console_new(screen_width, screen_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) fov_recompute = True fov_map = initialize_fov(game_map) key = tcod.Key() mouse = tcod.Mouse() game_state = GameStates.PLAYERS_TURN while not tcod.console_is_window_closed(): tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False tcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') msg = action.get('msg') if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entites_at_location( entities, destination_x, destination_y) if target: player.fighter.attack(target) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN print('Enemy Turn!') if exit: print('Thanks for playing!') return True if fullscreen: tcod.console_set_fullscreen(not tcod.console_is_fullscreen()) if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: entity.ai.take_turn(player, fov_map, game_map, entities) game_state = GameStates.PLAYERS_TURN print('Player Turn!') if msg: tcod.console_print(con, 1, 1, ' ') tcod.console_print(con, 1, 1, msg) print('window was closed')
def main(): # screen size in pixels screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } player = Entity(0, 0, "@", libtcod.white) entities = [player] # selecting a custom font through libtcod # using a picture of all the characters for the font libtcod.console_set_custom_font( "arial10x10.png", libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) # renders the actual window # boolean attribute is True if fullscreen libtcod.console_init_root( screen_width, screen_height, "roguelike tutorial", False) con = libtcod.console_new(screen_width, screen_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() # game loop while not libtcod.console_is_window_closed(): # event listener for mouse and keypad input libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False # this puts everything on the screen libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get("move") exit = action.get("exit") fullscreen = action.get("fullscreen") if move: dx, dy = move if not game_map.is_blocked(player.x + dx, player.y + dy): player.move(dx, dy) fov_recompute = True # if the key is ESC... if exit: # exit window return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(): screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 map_width = 80 map_height = 43 room_max_size = 10 room_min_size = 6 max_rooms = 30 # field of view fov_algorithm = 0 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 max_items_per_room = 2 colors = { 'dark_wall': libtcod.Color(0, 0, 50), 'light_wall': libtcod.Color(130, 110, 50), 'dark_ground': libtcod.Color(50, 50, 150), 'light_ground': libtcod.Color(200, 180, 50) } fighter_component = Fighter(hp=30, defense=2, power=5) inventory_component = Inventory(26) player = Entity(0, 0, '@', libtcod.black, 'Murderhobo', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component) entities = [player] libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Murderhobo 1E', False) con = libtcod.console_new(screen_width, screen_height) panel = libtcod.console_new(screen_width, panel_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room, max_items_per_room) fov_recompute = True fov_map = initialize_fov(game_map) message_log = MessageLog(message_x, message_width, message_height) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location(entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message(Message('There is nothing here to pick up.', libtcod.yellow)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend(player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') 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 item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: 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 if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target and target.z == player.z: player.push(target, entities, fov_map, game_map) else: player.move(dx, dy, fov_map) fov_recompute = True game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', libtcod.yellow)) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') 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.ENEMY_TURN: player.depth += 10 if player.depth % 30 == 0: game_map.place_entities(0, entities, 2, 0) for entity in entities: if entity.name == 'Boulder': if entity.z < 0: entities.remove(entity) else: entity.z -= 1 elif entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) if entity.z > 0: guyintheway = get_blocking_entities_at_location( entities, entity.x, entity.y) if guyintheway: entity.x = entity.x + randint(-1, 1) entity.y = entity.y + randint(-1, 1) if entity.x == 0 and entity.y == 0: entity.x = entity.x + randint(-1, 1) entity.y = entity.y + randint(-1, 1) entity.z -= 1 target = get_blocking_entities_at_location( entities, entity.x, entity.y) if target: if not target == entity: if target.z == 0: entities.remove(target) else: target.z -= 1 for enemy_turn_result in enemy_turn_results: 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 if game_state == GameStates.PLAYER_DEAD: libtcod.console_clear(0) break else: game_state = GameStates.PLAYERS_TURN
def main(): screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 'BASIC' fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 max_room_items = 2 colors = { 'dark_wall': (0, 0, 100), 'dark_ground': (50, 50, 150), 'light_wall': (130, 110, 50), 'light_ground': (200, 180, 50), 'desaturated_green': (63, 127, 63), 'darker_green': (0, 127, 0), 'dark_red': (191, 0, 0), 'white': (255, 255, 255), 'black': (0, 0, 0), 'red': (255, 0, 0), 'orange': (255, 127, 0), 'light_red': (255, 114, 114), 'darker_red': (127, 0, 0), "violet": (148, 0, 211) } fighter_component = Fighter(hp=30, defense=2, power=5) inventory = [] inventory_width = 50 player = Entity(0, 0, '@', (255, 255, 255), 'Player', render_order=RenderOrder.ACTOR, blocks=True, fighter=fighter_component) entities = [player] tdl.set_font('arial10x10.png', greyscale=True, altLayout=True) root_console = tdl.init(screen_width, screen_height, title='Roguelike Tutorial Revised') con = tdl.Console(screen_width, screen_height) panel = tdl.Console(screen_width, panel_height) game_map = GameMap(map_width, map_height) make_map(game_map, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room, colors, max_room_items) fov_recompute = True message_log = MessageLog(message_x, message_width, message_height) mouse_coordinates = (0, 0) game_state = GameStates.PLAYERS_TURN while not tdl.event.is_window_closed(): if fov_recompute: game_map.compute_fov(player.x, player.y, fov=fov_algorithm, radius=fov_radius, light_walls=fov_light_walls) render_all(con, panel, entities, player, game_map, fov_recompute, root_console, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse_coordinates, colors) tdl.flush() clear_all(con, entities) fov_recompute = False for event in tdl.event.get(): if event.type == 'KEYDOWN': user_input = event break elif event.type == 'MOUSEMOTION': mouse_coordinates = event.cell else: user_input = None if not user_input: continue action = handle_keys(user_input) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') pickup = action.get('pickup') open_inventory = action.get('inventory') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if game_map.walkable[destination_x, destination_y]: target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if pickup and game_state == GameStates.PLAYERS_TURN: # pick up an item for entity in entities: # look for an item in the player's tile if entity.x == player.x and entity.y == player.y and entity.item: pickup_results = entity.item.pick_up( entities, inventory, colors) player_turn_results.extend(pickup_results) break game_state = GameStates.ENEMY_TURN if open_inventory: inventory_menu(root_console, "Inventory", inventory, inventory_width, screen_height, screen_width, colors, mouse_coordinates) if exit: return True if fullscreen: tdl.set_fullscreen(not tdl.get_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_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, colors) else: message = kill_monster(dead_entity, colors) message_log.add_message(message) if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, game_map, entities) for enemy_turn_result in enemy_turn_results: 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, colors) else: message = kill_monster(dead_entity, colors) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): game_exit = False random_seed = datetime.now() print(random_seed) random.seed(random_seed) dungeon = Dungeon(MAP_SETTINGS) dungeon.build_dungeon() game_map = dungeon.game_map fov_update: bool = True initialize_fov(game_map=game_map) player = Entity("Player", dungeon.starting_position, char=Tiles.PLAYER, color="white", blocks=True) # npc = Entity("NPC", Point(player.x + 1, player.y + 1), char="@", color="yellow") entities = dungeon.place_entities(player) camera = Camera(player) terminal.refresh() game_state = GameStates.PLAYER_TURN while not game_exit: key = None if terminal.has_input(): key = terminal.read() if fov_update: update_fov(game_map, player.position) render_all(entities, game_map=game_map, fov_update=fov_update, camera=camera) fov_update = False terminal.refresh() clear_all(entities) action = handle_keys(key) move = action.get("move") game_exit = action.get("exit", False) # if action.get("rebuild"): # random_seed = datetime.now() # print(f"Rebuilding dungeon with new random seed: {random_seed}") # random.seed(random_seed) # dungeon = Dungeon(MAP_SETTINGS) # dungeon.build_dungeon() # game_map = dungeon.game_map # fov_update = True if game_state == GameStates.ENEMY_TURN: for entity in entities[1:]: print(f"The {entity} ponders the meaning of its existence.") game_state = GameStates.PLAYER_TURN if move and game_state == GameStates.PLAYER_TURN: point = player.position + move if not game_map.blocked(point): target = blocking_entities(entities, point) if target: print( f"You kick the {target} in the shins, much to its annoyance!" ) else: player.move(move) fov_update = True game_state = GameStates.ENEMY_TURN
def play_game(player, entities, game_map, message_log, game_state, constants): fov_recompute: bool = True game_state: GameStates = GameStates.PLAYERS_TURN previous_game_state: GameStates = game_state camera = Camera() mouse_coordinates = (0, 0) targeting_item = None while True: if fov_recompute: game_map.compute_fov(x=player.x, y=player.y, radius=constants["fov_radius"], light_walls=constants["fov_light_walls"], algorithm=constants["fov_algorithm"]) render_all(entities=entities, player=player, game_map=game_map, message_log=message_log, bar_width=constants["bar_width"], panel_y=constants["panel_y"], coordinates=mouse_coordinates, camera=camera, game_state=game_state, targeting_item=targeting_item) fov_recompute = False terminal.refresh() clear_all_entities(entities, camera) if terminal.has_input(): key: int = terminal.read() if key == terminal.TK_MOUSE_MOVE: mouse_coordinates = (terminal.state(terminal.TK_MOUSE_X), terminal.state(terminal.TK_MOUSE_Y)) action = handle_keys(key, game_state) mouse_action = handle_mouse(key, camera) escape = action.get('escape') movement = action.get('movement') pickup = action.get("pickup") show_inventory = action.get("show_inventory") drop_inventory = action.get("drop_inventory") inventory_index = action.get("inventory_index") take_stairs = action.get("take_stairs") pass_turn = action.get("pass_turn") left_click = mouse_action.get("left_click") right_click = mouse_action.get('right_click') player_turn_results = [] if movement and game_state == GameStates.PLAYERS_TURN: dx, dy = movement destination_x: int = player.x + dx destination_y: int = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target: Entity = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if pass_turn: game_state = GameStates.ENEMY_TURN if pickup: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message("There is nothing here to pick up.", "light yellow")) if show_inventory: previus_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend( player.inventory.use(item, entities=entities, game_map=game_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend( player.inventory.drop_item(item)) game_state = GameStates.ENEMY_TURN if take_stairs: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_recompute = True terminal.clear() break else: message_log.add_message( Message('There are no stairs here.', "yellow")) if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, game_map=game_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if escape: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): game_state = previus_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True for player_turn_result in player_turn_results: message = player_turn_result.get("message") dead_entity = player_turn_result.get("dead") item_added = player_turn_result.get("item_added") item_consumed = player_turn_result.get("consumed") item_dropped = player_turn_result.get("item_dropped") item_quantity_dropped = player_turn_result.get( "item_quantity_dropped") targeting = player_turn_result.get("targeting") targeting_cancelled = player_turn_result.get( "targeting_cancelled") if message: message_log.add_message(message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) 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 item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if item_quantity_dropped: item_copy = deepcopy(item_quantity_dropped) item_copy.item.quantity = 1 entities.append(item_copy) game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message( targeting_item.item.targeting_message) player_effect_results = resolve_effects(player.fighter) for effect_result in player_effect_results: message = effect_result.get("message") dead_entity = effect_result.get("dead") if message: message_log.add_message(message) if dead_entity: message, game_state = kill_player(dead_entity) message_log.add_message(message) break if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: monster = entity.fighter enemy_turn_results = entity.ai.take_turn( player, game_map, entities) for enemy_turn_result in enemy_turn_results: 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 if game_state == GameStates.PLAYER_DEAD: break monster_effect_results = resolve_effects(monster) for effect_result in monster_effect_results: message = effect_result.get("message") dead_entity = effect_result.get("dead") drop_loot = effect_result.get("drop_loot") 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 if drop_loot: for item in drop_loot["items"]: item.x = drop_loot["x"] item.y = drop_loot["y"] entities.append(item) else: game_state = GameStates.PLAYERS_TURN terminal.clear()