def get_game_variables(constants): fighter_component = Fighter(hp=1250, defense=10, power=40) inventory_component = Inventory(26) level_component = Level() equipment_component = Equipment() player = Entity(0, 0, 197, libtcod.Color(15, 77, 0), 'Wrpgnyth', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component, level=level_component, equipment=equipment_component) entities = [player] equippable_component = Equippable(EquipmentSlots.TENTACLE, power_bonus=20) tentaclaws = Entity(0, 0, 218, libtcod.red, 'Tentaclaws', equippable=equippable_component) player.inventory.add_item(tentaclaws) player.equipment.toggle_equip(tentaclaws) equippable_component = Equippable(EquipmentSlots.TENTACLE, power_bonus=20, defense_bonus=20) aluminitetentasleeve = Entity(0, 0, 192, libtcod.silver, 'Aluminite Tentasleeve', equippable=equippable_component) player.inventory.add_item(aluminitetentasleeve) player.equipment.toggle_equip(aluminitetentasleeve) game_map = GameMap(constants['map_width'], constants['map_height']) game_map.make_map(constants['max_rooms'], constants['room_min_size'], constants['room_max_size'], constants['map_width'], constants['map_height'], player, entities) message_log = MessageLog(constants['message_x'], constants['message_width'], constants['message_height']) game_state = GameStates.PLAYERS_TURN return player, entities, game_map, message_log, game_state
def place_consumables(m, chunks, consumable_count): def has_consumables_left(): for val in consumable_count.values(): if val > 0: return True def get_consumable(): while True: itemtype = random.choice(list(consumable_count.keys())) if consumable_count[itemtype] > 0: consumable_count[itemtype] -= 1 return itemtype() placed_consumables = [] # not two consumables in the same square while has_consumables_left(): c = random.choice(chunks) occupied = True while occupied: x = random.randint(c.x + 1, c.x + c.width - 2) y = random.randint(c.y + 1, c.y + c.height - 2) occupied = False for ent in m.entities: if ent.pos == Pos(x, y): occupied = True if (x, y) in placed_consumables: occupied = True placed_consumables.append((x, y)) drawable_component = Drawable(Assets.get().consumable) consumable_component = get_consumable() name = consumable_component.name.capitalize() consumable = Entity( x, y, name, render_order=RenderOrder.ITEM, drawable=drawable_component, consumable=consumable_component, ) m.entities.append(consumable)
def place_enemies(self, chunk_x, chunk_y, entities): enemies_num = randint(0, MAX_MONSTERS_PER_CHUNK) for _ in range(0, enemies_num): x = chunk_x * MAP_WIDTH + randint(0, self.width - 1) y = chunk_y * MAP_HEIGHT + randint(0, self.height - 1) if not any([entity for entity in entities if entity.x == x and entity.y == y]): if randint(0, 100) < 50: m_glyph, m_color, m_name, m_fighter_stats, m_ai, m_ai_args = mon_dat.monsters['dessert_snake'] else: m_glyph, m_color, m_name, m_fighter_stats, m_ai, m_ai_args = mon_dat.monsters['dessert_snake'] m_color_r, m_color_g, m_color_b = m_color m_hp, m_def, m_atkval = m_fighter_stats monster_fighter_component = Fighter(m_hp, m_def, m_atkval) monster = Entity(x, y, m_glyph, tcod.color.Color(m_color_r, m_color_g, m_color_b), m_name, RenderOrder.ENTITY, blocks=True, fighter=monster_fighter_component, ai=m_ai()) entities.append(monster)
def init_new_game(): game_world = GameWorld() player_fighter_component = Fighter(hp=200, defense=2, attack_value=20) player = Entity(int((constants.WORLD_WIDTH * constants.MAP_WIDTH / 2) + constants.MAP_WIDTH / 2), int((constants.WORLD_HEIGHT * constants.MAP_HEIGHT / 2) + constants.MAP_HEIGHT / 2), '@', tcod.white, constants.PLAYER_NAME, RenderOrder.ENTITY, fighter=player_fighter_component) px, py = game_world.get_chunk_pos_from_player_pos(player.x, player.y) game_world.chunks[px][py].property = ChunkProperty.START game_map = GameMap(constants.MAP_WIDTH, constants.MAP_HEIGHT, game_world.chunks[px][py]) print(f"PLAYER POS: {player.x}, {player.y}") print(f"CURRENT CHUNK: {px} {py}") entities = [player] close_entities = [] game_map.place_entities(px, py, entities) return { 'game_world': game_world, 'player': player, 'game_map': game_map, 'entities': entities, 'close_entities': close_entities }
def add_light(x, y): drawable_component = Drawable(Assets.get().light) light_component = Light(brightness=4) light = Entity( x, y, "Light", render_order=RenderOrder.DECOR, drawable=drawable_component, light=light_component, ) m.entities.append(light)
def get_game_variables(constants: Dict) -> Tuple: # initialize player/fighter and inventory fighter_component = Fighter(hp=100, defense=1, power=2) inventory_component = Inventory(26) level_component = Level() equipment_component = Equipment() player = Entity(int(constants['screen_width'] / 2), int(constants['screen_height'] / 2), "@", constants['colors'].get('player'), 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component, level=level_component, equipment=equipment_component) entities = [player] # set up inventory stuff equippable_component = Equippable(EquipmentSlots.MAIN_HAND, power_bonus=2) dagger = Entity(0, 0, '-', tcod.sky, 'Dagger', equippable=equippable_component) player.inventory.add_item(dagger) player.equipment.toggle_equip(dagger) # initialize game map game_map = GameMap(constants['map_width'], constants['map_height']) game_map.make_map(constants['max_rooms'], constants['room_min_size'], constants['room_max_size'], constants['map_width'], constants['map_height'], player, entities, constants['colors']) # initialize blank message log message_log = MessageLog(constants['message_x'], constants['message_width'], constants['message_height']) # set initial game state game_state = GameStates.PLAYERS_TURN return player, entities, game_map, message_log, game_state
def place_stairs(m, chunks): stairs_component = Stairs(m.dungeon_level + 1) drawable_component = Drawable(Assets.get().stairs) posx = chunks[-1].x + chunks[-1].width // 2 posy = chunks[-1].y + chunks[-1].height // 2 down_stairs = Entity( posx, posy, "Stairs", render_order=RenderOrder.STAIRS, stairs=stairs_component, drawable=drawable_component, ) m.entities.append(down_stairs)
def get_game_variables(constants): fighter_component = Fighter(hp=100, defense=1, power=2) inventory_component = Inventory(26) level_component = Level() equipment_component = Equipment() player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component, level=level_component, equipment=equipment_component) entities = [player] equippable_component = Equippable(EquipmentSlots.MAIN_HAND, power_bonus=2) dagger = Entity(0, 0, '-', libtcod.sky, 'Dagger', equippable=equippable_component) player.inventory.add_item(dagger) player.equipment.toggle_equip(dagger) game_map = GameMap(constants['map_width'], constants['map_height']) game_map.make_map(constants['max_rooms'], constants['room_min_size'], constants['room_max_size'], constants['map_width'], constants['map_height'], player, entities) message_log = MessageLog(constants['message_x'], constants['message_width'], constants['message_height']) game_state = GameStates.PLAYERS_TURN return player, entities, game_map, message_log, game_state
def place_stairs(game_map, stairs_data): x = stairs_data["x"] y = stairs_data["y"] stairs_component = Stairs(game_map.dungeon_level + 1) drawable_component = Drawable(Assets.get().stairs) stairs = Entity( x, y, "Stairs", render_order=RenderOrder.STAIRS, stairs=stairs_component, drawable=drawable_component, ) return [stairs]
def kill_monster(monster: Entity) -> Message: death_message = Message(f'{monster.name.capitalize()} is dead!', tcod.orange) monster.char = '%' monster.color = tcod.dark_red monster.blocks = False monster.fighter = None monster.ai = None monster.name = f'remains of {monster.name.capitalize()}' monster.render_order = RenderOrder.CORPSE return death_message
def load_keys(data, game_map): retr = [] assets = Assets.get() for key_data in data["keys"]: drawable_component = Drawable(assets.key) key = Entity( key_data["x"], key_data["y"], "Key", render_order=RenderOrder.ITEM, key=Key(), drawable=drawable_component, ) retr.append(key) game_map.num_keys_total = len(retr) return retr
def place_ingredients(m, chunks, ingredient_count): def has_ingredients_left(): for val in ingredient_count.values(): if val > 0: return True def get_ingredient(): while True: ingredient = random.choice(list(ingredient_count.keys())) if ingredient_count[ingredient] > 0: ingredient_count[ingredient] -= 1 return ingredient placed_ingredients = [] # not two ingredients in the same square while has_ingredients_left(): c = random.choice(chunks) occupied = True while occupied: x = random.randint(c.x + 1, c.x + c.width - 2) y = random.randint(c.y + 1, c.y + c.height - 2) occupied = False for ent in m.entities: if ent.pos == Pos(x, y): occupied = True if (x, y) in placed_ingredients: occupied = True placed_ingredients.append((x, y)) drawable_component = Drawable(Assets.get().ingredient) ingredient_component = get_ingredient() name = ingredient_component.name.capitalize() ingredient = Entity( x, y, f"{name} ingredient", render_order=RenderOrder.ITEM, drawable=drawable_component, ingredient=ingredient_component, ) m.entities.append(ingredient)
def place_keys(m, chunks, key_ratio): num_rooms_with_keys = math.floor(len(chunks) * key_ratio) if num_rooms_with_keys > len(chunks[1:-1]): # if it's a map with few rooms num_rooms_with_keys = len(chunks[1:-1]) # sample random rooms but not in the first room, not in the room with stairs rooms_with_keys = random.sample(chunks[1:-1], k=num_rooms_with_keys) placed_keys = [] # not two keys in the same square for _, c in enumerate(rooms_with_keys): occupied = True while occupied: x = random.randint(c.x + 1, c.x + c.width - 2) y = random.randint(c.y + 1, c.y + c.height - 2) occupied = False for cm in c.monsters: if cm.pos == Pos(x, y): occupied = True if (x, y) in placed_keys: occupied = True placed_keys.append((x, y)) drawable_component = Drawable(Assets.get().key) key = Entity(x, y, "Key", render_order=RenderOrder.ITEM, key=Key(), drawable=drawable_component,) m.entities.append(key) m.num_keys_total = num_rooms_with_keys
def kill_player(player: Entity) -> Tuple[Message, GameStates]: player.char = '%' player.color = tcod.dark_red player.fighter.hp = 0 return Message('You died!', tcod.red), GameStates.PLAYER_DEAD
def init_new_game(self, params): choice = params self.player = None self.levels = None self.time_counter = None # Create player inventory_component = Inventory(26) f_data = self.data.fighters["player"] fighter_component = Fighter(hp=f_data["hp"], ac=f_data["ac"], ev=f_data["ev"], power=f_data["power"], mv_spd=f_data["mv_spd"], atk_spd=f_data["atk_spd"], size=f_data["size"], fov=f_data["fov"]) light_component = LightSource(radius=fighter_component.fov) player_component = Player(50) abilities_component = Abilities("player") status_effects_component = StatusEffects("player") summoner_component = Summoner() player = Entity(1, 1, 3, player_component.char["player"], "default", "player", blocks=True, player=player_component, fighter=fighter_component, inventory=inventory_component, light_source=light_component, summoner=summoner_component, indicator_color="gray", abilities=abilities_component, status_effects=status_effects_component, stand_on_messages=False) player.player.avatar["player"] = fighter_component avatar_f_data = self.data.fighters[choice] a_fighter_component = Fighter(hp=avatar_f_data["hp"], ac=avatar_f_data["ac"], ev=avatar_f_data["ev"], power=avatar_f_data["power"], mv_spd=avatar_f_data["mv_spd"], atk_spd=avatar_f_data["atk_spd"], size=avatar_f_data["size"], fov=avatar_f_data["fov"]) player.player.avatar[choice] = a_fighter_component player.player.avatar[choice].owner = player player.abilities.initialize_abilities(choice) player.player.char[choice] = tilemap()["monsters"][choice] player.player.char_exp[choice] = 20 player.player.avatar[choice].max_hp += 20 player.player.avatar[choice].hp += 20 player.player.avatar[choice].power += 1 player.player.insights = 200 self.player = player character_menu = MenuData(name="avatar_info", params=self.player) self.menus.create_or_show_menu(character_menu) message_log = MessageLog(4) self.message_log = message_log self.message_log.owner = self # Initialize game camera game_camera = Camera(1, 1, self.ui.viewport.w, self.ui.viewport.h, self.options) self.game_camera = game_camera self.game_camera.owner = self levels = Levels(tileset=self.options.gfx) self.levels = levels self.levels.owner = self blt.clear_area(2, self.ui.viewport.offset_h + self.ui.offset_y + 1, self.ui.viewport.x, 1) # if settings.gfx == "ascii": # player.char = tilemap()["player"] # player.color = "lightest green" self.levels.change("hub") self.fov_recompute = True self.game_state = GameStates.PLAYER_TURN self.time_counter = self.TimeCounter(owner=self)
def make_map(self, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities): rooms = [] num_rooms = 0 center_of_last_room_x = None center_of_last_room_y = None for r in range(max_rooms): # Random width and height w = randint(room_min_size, room_max_size) h = randint(room_min_size, room_max_size) # Random position without going out of the boundaries of the map x = randint(0, map_width - w - 1) y = randint(0, map_height - h - 1) # "Rect" class makes rectangles easier to work with new_room = Rect(x, y, w, h) # Run through the other rooms and see if they intersect with this one for other_room in rooms: if new_room.intersect(other_room): break else: # This means there are no intersections, so this room is valid # "Paint" it to the map's tiles self.create_room(new_room) # Center coordinates of new room, will be useful later (new_x, new_y) = new_room.center() center_of_last_room_x = new_x center_of_last_room_y = new_y if num_rooms == 0: # This is the first room, where the player starts at player.x = new_x player.y = new_y else: # All rooms after the first: # Connect it to the previous room with a tunnel # Center coordinates of previous room (prev_x, prev_y) = rooms[num_rooms - 1].center() # Flip a coin (random number that is either 0 or 1) if randint(0, 1) == 1: # First move horizontally, then vertically self.create_h_tunnel(prev_x, new_x, prev_y) self.create_v_tunnel(prev_y, new_y, new_x) else: # First move vertically, then horizontally self.create_v_tunnel(prev_y, new_y, prev_x) self.create_h_tunnel(prev_x, new_x, new_y) self.place_entities(new_room, entities) # Finally, append the new room to the list rooms.append(new_room) num_rooms += 1 trail_component = Trail(self.dungeon_level + 1) down_trail = Entity(center_of_last_room_x, center_of_last_room_y, 205, libtcod.Color(140, 60, 10), 'Trail', render_order=RenderOrder.TRAIL, trail=trail_component) entities.append(down_trail)
def place_entities(self, room, entities): max_monsters_per_room = from_dungeon_level( [[2, 1], [3, 4], [5, 6], [7, 10]], self.dungeon_level) min_monsters_per_room = from_dungeon_level( [[0, 1], [1, 4], [2, 6], [6, 10], [3, 11]], self.dungeon_level) max_items_per_room = from_dungeon_level([[1, 1], [2, 4], [3, 7]], self.dungeon_level) # Get a random number of monsters number_of_monsters = randint(min_monsters_per_room, max_monsters_per_room) number_of_items = randint(0, max_items_per_room) monster_chances = { 'kanga': from_dungeon_level([[25, 3], [70, 6], [5, 10], [70, 11], [30, 16]], self.dungeon_level), 'dingo': from_dungeon_level([[60, 1], [45, 4], [20, 7], [5, 10], [20, 11]], self.dungeon_level), 'joey': from_dungeon_level([[20, 1], [15, 2], [10, 3], [0, 10], [10, 11]], self.dungeon_level), 'goanna': from_dungeon_level( [[20, 6], [70, 9], [10, 10], [70, 11], [55, 16]], self.dungeon_level), 'killer_bees': from_dungeon_level([[5, 1], [100, 10], [5, 11]], self.dungeon_level), 'dropbear': from_dungeon_level( [[15, 9], [5, 10], [35, 11], [55, 14], [70, 16]], self.dungeon_level) } item_chances = { 'lesser_med_kit': from_dungeon_level([[25, 1], [20, 5], [1, 7]], self.dungeon_level), 'morphine_pack': from_dungeon_level([[5, 5], [20, 7], [5, 9]], self.dungeon_level), 'tentacruels': from_dungeon_level([[5, 3]], self.dungeon_level), 'energy_shield': from_dungeon_level([[15, 6]], self.dungeon_level), 'plasma_grenade': from_dungeon_level([[10, 3], [12, 5]], self.dungeon_level), 'stun_grenade': from_dungeon_level([[10, 2], [15, 4]], self.dungeon_level), 'ray_gun': from_dungeon_level([[3, 6], [5, 8]], self.dungeon_level), 'shock_charge': from_dungeon_level([[5, 1], [13, 3]], self.dungeon_level), 'med_kit': from_dungeon_level([[5, 7], [25, 9]], self.dungeon_level), 'whippy_willow_twig': from_dungeon_level([[15, 1]], self.dungeon_level), 'goanna_skin_hat': from_dungeon_level([[5, 1], [15, 3]], self.dungeon_level), 'aluminite_neck_brace': from_dungeon_level([[5, 2], [10, 4]], self.dungeon_level), 'dropbear_fur_vest': from_dungeon_level([[5, 3], [7, 6]], self.dungeon_level) } for i in range(number_of_monsters): # Choose a random location in the room x = randint(room.x1 + 1, room.x2 - 1) y = randint(room.y1 + 1, room.y2 - 1) if not any([ entity for entity in entities if entity.x == x and entity.y == y ]): monster_choice = random_choice_from_dict(monster_chances) if monster_choice == 'kanga': statbase = randint(30, 45) + self.dungeon_level rand_hp = statbase * 15 rand_def = statbase rand_power = round(statbase * 2.5) rand_xp = statbase * 3 fighter_component = Fighter(hp=rand_hp, defense=rand_def, power=rand_power, xp=rand_xp) ai_component = BasicMonster() monster = Entity(x, y, 196, libtcod.Color(218, 42, 32), 'Kanga', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component) elif monster_choice == 'dingo': statbase = randint(15, 20) + self.dungeon_level rand_hp = statbase * 15 rand_def = statbase rand_power = round(statbase * 3.5) rand_xp = statbase * 3 fighter_component = Fighter(hp=rand_hp, defense=rand_def, power=rand_power, xp=rand_xp) ai_component = BasicMonster() monster = Entity(x, y, 191, libtcod.Color(165, 42, 42), 'Dingo', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component) elif monster_choice == 'goanna': statbase = randint(45, 55) + self.dungeon_level rand_hp = statbase * 15 rand_def = statbase rand_power = statbase * 3 rand_xp = statbase * 3 fighter_component = Fighter(hp=rand_hp, defense=rand_def, power=rand_power, xp=rand_xp) ai_component = BasicMonster() monster = Entity(x, y, 186, libtcod.Color(25, 42, 0), 'Goanna', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component) elif monster_choice == 'dropbear': statbase = randint(60, 65) + self.dungeon_level rand_hp = statbase * 10 rand_def = statbase + self.dungeon_level rand_power = statbase * 4 rand_xp = statbase * 4 fighter_component = Fighter(hp=rand_hp, defense=rand_def, power=rand_power, xp=rand_xp) ai_component = BasicMonster() monster = Entity(x, y, 191, libtcod.Color(33, 33, 33), 'Dropbear', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component) elif monster_choice == 'killer_bees': statbase = randint(8, 10) + self.dungeon_level rand_hp = statbase * 7 rand_def = statbase rand_power = round(statbase * 12) rand_xp = round(statbase * 2.5) fighter_component = Fighter(hp=rand_hp, defense=rand_def, power=rand_power, xp=rand_xp) ai_component = BasicMonster() monster = Entity(x, y, 201, libtcod.yellow, 'Killer Bee', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component) else: statbase = randint(9, 20) + self.dungeon_level rand_hp = statbase * 15 rand_def = statbase rand_power = round(statbase * 2.5) rand_xp = statbase * 3 fighter_component = Fighter(hp=rand_hp, defense=rand_def, power=rand_power, xp=rand_xp) ai_component = BasicMonster() monster = Entity(x, y, 179, libtcod.Color(218, 42, 32), 'Joey', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component) entities.append(monster) for i in range(number_of_items): x = randint(room.x1 + 1, room.x2 - 1) y = randint(room.y1 + 1, room.y2 - 1) if not any([ entity for entity in entities if entity.x == x and entity.y == y ]): item_choice = random_choice_from_dict(item_chances) if item_choice == 'lesser_med_kit': item_component = Item(use_function=heal, amount=200) item = Entity(x, y, 195, libtcod.violet, 'Lesser Med Kit', render_order=RenderOrder.ITEM, item=item_component) elif item_choice == 'morphine_pack': item_component = Item(use_function=morphine_pack, amount=350) item = Entity(x, y, 195, libtcod.Color(40, 30, 0), 'Morphine Pack', render_order=RenderOrder.ITEM, item=item_component) elif item_choice == 'med_kit': item_component = Item(use_function=morphine_pack, amount=500) item = Entity(x, y, 195, libtcod.Color(255, 30, 0), 'Med Kit', render_order=RenderOrder.ITEM, item=item_component) elif item_choice == 'tentacruels': equippable_component = Equippable(EquipmentSlots.TENTACLE, power_bonus=40) item = Entity(x, y, 218, libtcod.purple, 'Tentacruel', equippable=equippable_component) elif item_choice == 'energy_shield': equippable_component = Equippable(EquipmentSlots.TENTACLE, defense_bonus=50, max_hp_bonus=250) item = Entity(x, y, 217, libtcod.cyan, 'Energy Shield', equippable=equippable_component) elif item_choice == 'whippy_willow_twig': equippable_component = Equippable(EquipmentSlots.TENTACLE, power_bonus=15) item = Entity(x, y, 188, libtcod.Color(53, 38, 0), 'Whippy Willow Twig', equippable=equippable_component) elif item_choice == 'goanna_skin_hat': equippable_component = Equippable(EquipmentSlots.HELMET, power_bonus=5, defense_bonus=10) item = Entity(x, y, 200, libtcod.Color(20, 38, 0), 'Goanna Skin Hat', equippable=equippable_component) elif item_choice == 'aluminite_neck_brace': equippable_component = Equippable(EquipmentSlots.NECK, defense_bonus=5) item = Entity(x, y, 204, libtcod.silver, 'Aluminite Neck Brace', equippable=equippable_component) elif item_choice == 'dropbear_fur_vest': equippable_component = Equippable( EquipmentSlots.CHEST_PLATE, max_hp_bonus=100, defense_bonus=25) item = Entity(x, y, 185, libtcod.Color(30, 30, 30), 'Dropbear Fur Vest', equippable=equippable_component) elif item_choice == 'plasma_grenade': item_component = Item( use_function=use_plasma_grenade, targeting=True, targeting_message=Message( 'Left-click an enemy to lob the Plasma Grenade at it, or right-click to cancel.', libtcod.light_cyan), damage=250, radius=3) item = Entity(x, y, 193, libtcod.cyan, 'Plasma Grenade', render_order=RenderOrder.ITEM, item=item_component) elif item_choice == 'ray_gun': item_component = Item(use_function=use_ray_gun, damage=80, maximum_range=11) item = Entity(x, y, 187, libtcod.Color(180, 180, 180), 'Ray Gun', render_order=RenderOrder.ITEM, item=item_component) elif item_choice == 'stun_grenade': item_component = Item( use_function=use_stun_grenade, targeting=True, targeting_message=Message( 'Left-click an enemy to lob the Stun Grenade at it, or right-click to cancel.', libtcod.light_cyan)) item = Entity(x, y, 193, libtcod.Color(0, 40, 0), 'Stun Grenade', render_order=RenderOrder.ITEM, item=item_component) else: item_component = Item(use_function=use_shock_charge, damage=350, maximum_range=5) item = Entity(x, y, 194, libtcod.yellow, 'Shock Charge', render_order=RenderOrder.ITEM, item=item_component) entities.append(item)
def place_entities(self, room, entities): max_monsters_per_room = from_dungeon_level([[2, 1], [3, 4], [5, 6]], self.dungeon_level) max_items_per_room = from_dungeon_level([[1, 1], [2, 4]], self.dungeon_level) # Get a random number of monsters number_of_monsters = randint(0, max_monsters_per_room) # Get a random number of items number_of_items = randint(0, max_items_per_room) monster_chances = { 'orc': 40, 'troll': from_dungeon_level([[5, 0], [40, 1], [70, 2]], self.dungeon_level), 'skeleton': from_dungeon_level([[55, 0], [40, 1], [20, 2]], self.dungeon_level) } item_chances = { 'healing_potion': 35, 'sword': from_dungeon_level([[5, 4]], self.dungeon_level), 'shield': from_dungeon_level([[15, 8]], self.dungeon_level), 'lightning_scroll': from_dungeon_level([[25, 4]], self.dungeon_level), 'fireball_scroll': from_dungeon_level([[25, 6]], self.dungeon_level), 'confusion_scroll': from_dungeon_level([[10, 2]], self.dungeon_level) } for i in range(number_of_monsters): # Choose a random location in the room x = randint(room.x1 + 1, room.x2 - 1) y = randint(room.y1 + 1, room.y2 - 1) # Check if an entity is already in that location if not any([ entity for entity in entities if entity.x == x and entity.y == y ]): monster_choice = random_choice_from_dict(monster_chances) if monster_choice == 'orc': fighter_component = Fighter(hp=20, defense=1, power=4, xp=25) ai_component = BasicMonster() monster = Entity(x, y, 'o', libtcod.desaturated_green, 'Orc', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component) elif monster_choice == 'troll': fighter_component = Fighter(hp=25, defense=2, power=6, xp=95) ai_component = BasicMonster() monster = Entity(x, y, 'T', libtcod.darker_green, 'Troll', blocks=True, fighter=fighter_component, render_order=RenderOrder.ACTOR, ai=ai_component) else: fighter_component = Fighter(hp=10, defense=0, power=2, xp=15) ai_component = BasicMonster() monster = Entity(x, y, 's', libtcod.white, 'Skeleton', blocks=True, fighter=fighter_component, render_order=RenderOrder.ACTOR, ai=ai_component) entities.append(monster) for i in range(number_of_items): x = randint(room.x1 + 1, room.x2 - 1) y = randint(room.y1 + 1, room.y2 - 1) if not any([ entity for entity in entities if entity.x == x and entity.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(x, y, '!', libtcod.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(x, y, '/', libtcod.sky, 'Sword', equippable=equippable_component) elif item_choice == 'shield': equippable_component = Equippable(EquipmentSlots.OFF_HAND, defense_bonus=1) item = Entity(x, y, '[', libtcod.darker_orange, 'Shield', equippable=equippable_component) elif item_choice == 'fireball_scroll': item_component = Item( use_function=cast_fireball, targeting=True, targeting_message=Message( 'Left-click a target tile for the fireball, or right-click to cancel.', libtcod.light_cyan), damage=25, radius=3) item = Entity(x, y, '#', libtcod.red, 'Fireball Scroll', render_order=RenderOrder.ITEM, item=item_component) elif item_choice == 'confusion_scroll': item_component = Item( use_function=cast_confuse, targeting=True, targeting_message=Message( 'Left-click an enemy to confuse it, or right-click to cancel.', libtcod.light_cyan)) item = Entity(x, y, '#', libtcod.light_pink, 'Confusion Scroll', render_order=RenderOrder.ITEM, item=item_component) else: item_component = Item(use_function=cast_lightning, damage=40, maximum_range=5) item = Entity(x, y, '#', libtcod.yellow, 'Lightning Scroll', render_order=RenderOrder.ITEM, item=item_component) entities.append(item)
def turn_taking_actions(self, wait=None, move=None, interact=None, pickup=None, stairs=None, examine=None, use_ability=None, key=None): if wait or move or interact or pickup or stairs or use_ability and not self.owner.player.fighter.dead: self.owner.player.status_effects.process_effects( game_map=self.owner.levels.current_map) if self.owner.player.fighter.paralyzed: msg = Message("You are paralyzed!") self.owner.message_log.send(msg) self.owner.time_counter.take_turn(1) if wait: self.owner.time_counter.take_turn(1) # player.player.spirit_power -= 1 msg = Message("You wait a turn.") self.owner.message_log.send(msg) self.owner.game_state = GameStates.ENEMY_TURN self.owner.fov_recompute = True elif move: dx, dy = move destination_x = self.owner.player.x + dx destination_y = self.owner.player.y + dy # Handle player attack if not self.owner.levels.current_map.is_blocked( destination_x, destination_y): target = self.owner.levels.current_map.tiles[destination_x][ destination_y].blocking_entity if target: results = self.owner.player.fighter.attack( target, self.owner.player.player.sel_weapon) self.owner.message_log.send(results) # player.player.spirit_power -= 0.5 self.owner.time_counter.take_turn(1) self.owner.render_functions.draw_stats(target) else: if self.owner.player.fighter.mv_spd <= 0: msg = Message("You are unable to move!") self.owner.message_log.send(msg) self.owner.time_counter.take_turn(1) else: prev_pos_x, prev_pos_y = self.owner.player.x, self.owner.player.y self.owner.player.move(dx, dy) self.owner.time_counter.take_turn( 1 / self.owner.player.fighter.mv_spd) self.owner.fov_recompute = True self.owner.levels.current_map.tiles[prev_pos_x][ prev_pos_y].remove_entity(self.owner.player) self.owner.levels.current_map.tiles[ self.owner.player.x][ self.owner.player.y].add_entity( self.owner.player) self.owner.game_state = GameStates.ENEMY_TURN elif self.owner.levels.current_map.tiles[destination_x][ destination_y].is_door: door = self.owner.levels.current_map.tiles[destination_x][ destination_y].door interact_msg = door.interaction(self.owner.levels.current_map) self.owner.message_log.send(interact_msg) self.owner.time_counter.take_turn(1) self.owner.game_state = GameStates.ENEMY_TURN self.owner.fov_recompute = True elif interact: entities = get_neighbours(self.owner.player, self.owner.levels.current_map.tiles) interact_msg = None for entity in entities: if entity.door: interact_msg = entity.door.interaction( self.owner.levels.current_map) self.owner.message_log.send(interact_msg) elif entity.item: interact_msg = entity.item.interaction( self.owner.levels.current_map) self.owner.message_log.send(interact_msg) if interact_msg: self.owner.time_counter.take_turn(1) self.owner.game_state = GameStates.ENEMY_TURN self.owner.fov_recompute = True elif pickup: pickup_msg = self.owner.player.inventory.add_item( self.owner.levels.current_map) if pickup_msg: self.owner.message_log.send(pickup_msg) self.owner.time_counter.take_turn(1) self.owner.game_state = GameStates.ENEMY_TURN self.owner.fov_recompute = True else: msg = Message("There is nothing here to pick up.") self.owner.message_log.send(msg) elif stairs: stairs_component = self.owner.levels.current_map.tiles[ self.owner.player.x][self.owner.player.y].stairs if stairs_component: results = stairs_component.interaction(self.owner.levels) self.owner.message_log.send(results) self.owner.time_counter.take_turn(1) self.owner.render_functions.draw_messages() self.owner.fov_recompute = True elif examine: self.owner.game_state = GameStates.TARGETING cursor_component = Cursor() cursor = Entity(self.owner.player.x, self.owner.player.y, 5, 0xE800 + 1746, "light yellow", "cursor", cursor=cursor_component, stand_on_messages=False) self.owner.cursor = cursor self.owner.levels.current_map.tiles[self.owner.cursor.x][ self.owner.cursor.y].add_entity(self.owner.cursor) self.owner.levels.current_map.entities["cursor"] = [ self.owner.cursor ] self.owner.fov_recompute = True elif use_ability: if key == blt.TK_Z: ability = self.owner.player.player.sel_utility else: ability = self.owner.player.player.sel_attack result, target, targeting = self.owner.player.player.use_ability( self.owner.levels.current_map, ability) if target: self.owner.render_functions.draw_stats(target) if targeting: self.owner.game_state = GameStates.TARGETING cursor_component = Cursor(targeting_ability=ability) cursor = Entity(target.x, target.y, 5, 0xE800 + 1746, "light yellow", "cursor", cursor=cursor_component, stand_on_messages=False) self.owner.cursor = cursor self.owner.levels.current_map.tiles[self.owner.cursor.x][ self.owner.cursor.y].add_entity(self.owner.cursor) self.owner.levels.current_map.entities["cursor"] = [ self.owner.cursor ] else: self.owner.time_counter.take_turn(1) self.owner.game_state = GameStates.ENEMY_TURN self.owner.message_log.send(result) self.owner.fov_recompute = True if self.owner.player.fighter.summoning: msg = self.owner.player.summoner.process( game_map=self.owner.levels.current_map) if msg: self.owner.message_log.send(msg) self.owner.fov_recompute = True
def place_entities(self, room, entities, colors): # get a random number of monsters, and items max_monsters_per_room = from_dungeon_level([[2, 1], [3, 4], [5, 6]], self.dungeon_level) max_items_per_room = from_dungeon_level([[1, 1], [2, 4]], self.dungeon_level) num_monsters = randint(0, max_monsters_per_room) num_items = randint(0, max_items_per_room) monster_chances = { 'orc': 80, 'troll': from_dungeon_level([[15, 3], [30, 5], [60, 7]], self.dungeon_level) } item_chances = { 'healing_potion': 35, 'sword': from_dungeon_level([[5, 4]], self.dungeon_level), 'shield': from_dungeon_level([[15, 8]], self.dungeon_level), 'lightning_scroll': from_dungeon_level([[25, 4]], self.dungeon_level), 'fireball_scroll': from_dungeon_level([[25, 6]], self.dungeon_level), 'confusion_scroll': from_dungeon_level([[10, 2]], self.dungeon_level) } for i in range(num_monsters): # choose a random location in the room x = randint(room.x1 + 1, room.x2 - 1) y = randint(room.y1 + 1, room.y2 - 1) if not any([ entity for entity in entities if entity.x == x and entity.y == y ]): monster_chance = random_choice_from_dict(monster_chances) if monster_chance == 'orc': fighter_component = Fighter(hp=20, defense=0, power=4, xp=35) ai_component = BasicMonster() monster = Entity(x, y, 'o', colors.get('orc'), 'Orc', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component) else: fighter_component = Fighter(hp=30, defense=2, power=8, xp=100) ai_component = BasicMonster() monster = Entity(x, y, 'T', colors.get('troll'), 'Troll', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component) entities.append(monster) for i in range(num_items): x = randint(room.x1 + 1, room.x2 - 1) y = randint(room.y1 + 1, room.y2 - 1) if not any([ entity for entity in entities if entity.x == x and entity.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(x, y, '!', colors.get('magic_item'), 'Healing Potion', render_order=RenderOrder.ITEM, item=item_component) elif item_choice == 'sword': equippable_component = Equippable(EquipmentSlots.MAIN_HAND, power_bonus=3) item = Entity(x, y, '/', tcod.sky, 'Sword', equippable=equippable_component) elif item_choice == 'shield': equippable_component = Equippable(EquipmentSlots.MAIN_HAND, defense_bonus=1) item = Entity(x, y, '[', tcod.darker_orange, 'Shield', equippable=equippable_component) elif item_choice == 'fireball_scroll': item_component = Item( use_function=cast_fireball, targeting=True, targeting_message=Message( 'Left-click a target tile fot the fireball, or right-click to cancel', tcod.light_cyan), damage=25, radius=3) item = Entity(x, y, '*', colors.get('magic_item'), 'Fireball Scroll', render_order=RenderOrder.ITEM, item=item_component) elif item_choice == 'confusion_scroll': item_component = Item( use_function=cast_confuse, targeting=True, targeting_message=Message( 'Left-click an enemy to confuse it, or right-click to cancel', tcod.light_cyan), damage=12, radius=3) item = Entity(x, y, '?', colors.get('magic_item'), 'Confusion Scroll', render_order=RenderOrder.ITEM, item=item_component) else: item_component = Item(use_function=cast_lightning, damage=40, maximum_range=5) item = Entity(x, y, '&', colors.get('magic_item'), 'Lighning Scroll', render_order=RenderOrder.ITEM, item=item_component) entities.append(item)
def make_map(self, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, colors): rooms = [] num_rooms = 0 center_of_last_room_x = None center_of_last_room_y = None for r in range(max_rooms): # random width and height w = randint(room_min_size, room_max_size) h = randint(room_min_size, room_max_size) # random position without going out of boundaries x = randint(0, map_width - w - 1) y = randint(0, map_height - h - 1) # 'rect' class makes rectangles easy new_room = Rect(x, y, w, h) for other_room in rooms: if new_room.intersect(other_room): break else: # no intersections, it's a good room self.create_room(new_room) # center coordinates of new room (new_x, new_y) = new_room.center() center_of_last_room_x = new_x center_of_last_room_y = new_y if num_rooms == 0: # this means it is first room player.x = new_x player.y = new_y else: # all rooms after first # connec to previous room # center coords of previous room (prev_x, prev_y) = rooms[num_rooms - 1].center() # flip a coin (random 0, or 1) if randint(0, 1) == 1: # make horizontal tunnel first self.create_h_tunnel(prev_x, new_x, prev_y) self.create_v_tunnel(prev_y, new_y, new_x) else: # make vertical tunnel first self.create_v_tunnel(prev_y, new_y, prev_x) self.create_h_tunnel(prev_x, new_x, new_y) # add monsters to the room self.place_entities(new_room, entities, colors) # append new room to rooms rooms.append(new_room) num_rooms += 1 stairs_component = Stairs(self.dungeon_level + 1) down_stairs = Entity(center_of_last_room_x, center_of_last_room_y, '>', tcod.white, 'Stairs', render_order=RenderOrder.STAIRS, stairs=stairs_component) entities.append(down_stairs)
def process(self, game_map): msgs = [] if not self.summoning and self.summoned_entities: summons = [] for entity in self.summoned_entities: summons.append(entity.name) game_map.entities["allies"].remove(entity) game_map.tiles[entity.x][entity.y].remove_entity(entity) del entity self.summoned_entities = [] self.owner.fighter.summoning = False self.summoning = [""] if len(summons) > 1: msg = Message( "Your trusty companions {0} return back to the spirit plane!" .format(", ".join(summons))) else: msg = Message( "Your trusty companion {0} returns back to the spirit plane!" .format(summons[0])) msgs.append(msg) return msgs elif self.summoning and not self.summoned_entities: if len(self.summoning) <= self.rank: name = self.summoning[-1] else: name = self.summoning[self.rank] char = tilemap()["monsters"][name] color = get_monster_color(name) f_data = json_data.data.fighters[name] remarks = f_data["remarks"] fighter_component = Fighter(hp=f_data["hp"], ac=f_data["ac"], ev=f_data["ev"], power=f_data["power"], mv_spd=f_data["mv_spd"], atk_spd=f_data["atk_spd"], size=f_data["size"], fov=f_data["fov"]) ai_component = BasicMonster(ally=True) light_component = LightSource(radius=fighter_component.fov) abilities_component = Abilities(name) status_effects_component = StatusEffects(name) neighbours = get_neighbours(self.owner, game_map=game_map.tiles, radius=3, algorithm="square", empty_tiles=True) summon_tile = choice(neighbours) entity_name = name monster = Entity(summon_tile.x, summon_tile.y, 3, char, color, entity_name, blocks=True, fighter=fighter_component, ai=ai_component, light_source=light_component, abilities=abilities_component, status_effects=status_effects_component, remarks=remarks, indicator_color="light green") monster.light_source.initialize_fov(game_map) game_map.tiles[summon_tile.x][summon_tile.y].add_entity(monster) game_map.entities["allies"].append(monster) self.summoned_entities.append(monster) msg = Message("A friendly {0} appears!".format(entity_name)) msgs.append(msg) remark_str = "{0}: {1}".format(monster.colored_name, choice(monster.remarks)) remark_msg = Message(msg=remark_str, style="dialog") msgs.append(remark_msg) return msgs return msgs