def place_stairs(self, entities): if self.owner.dungeon_level == 1: direction = StairsDirections.WORLD name = locale.t('world.cave.passage.outside') else: direction = StairsDirections.UP name = locale.t('world.cave.passage.upside') x, y = self.find_simple_empty_spot() stairs_component = Stairs(self.owner.dungeon_level, direction=direction) self.up_stairs = Entity(x, y, char='<', color=color_vars.dungeon_stone['wall'], name=name, render_order=RenderOrder.STAIRS, stairs=stairs_component) entities.append(self.up_stairs) x, y = self.find_simple_empty_spot() stairs_component = Stairs(self.owner.dungeon_level + 1) self.down_stairs = Entity(x, y, char='>', color=color_vars.dungeon_stone['wall'], name=locale.t('world.cave.passage.downside'), render_order=RenderOrder.STAIRS, stairs=stairs_component) entities.append(self.down_stairs) if self.up_stairs.x == self.down_stairs.x and self.up_stairs.y == self.down_stairs.y: self.up_stairs.char.char = '&' self.down_stairs.char.char = '&'
def place(self, game_map): for x, y in self.walls: game_map.tiles[x][y].block() game_map.tiles[x][y].place_static_entity( Entity(x, y, **self.wall_char)) x, y = self.door game_map.tiles[x][y].unblock() game_map.tiles[x][y].clear_static_entities() game_map.tiles[x][y].place_static_entity(Entity( x, y, **self.door_char)) for (x, y) in self.windows: game_map.tiles[x][y].regulatory_flags.add('blocked') game_map.tiles[x][y].regulatory_flags.discard('block_sight') game_map.tiles[x][y].clear_static_entities() game_map.tiles[x][y].place_static_entity( Entity(x, y, **self.window_char)) for x in range(self.rect.x1 + 1, self.rect.x2 - 1): for y in range(self.rect.y1 + 1, self.rect.y2 - 1): if not game_map.tiles[x][y].static_entities: game_map.tiles[x][y].place_static_entity( Entity(x, y, **self.floor_char)) game_map.tiles[x][y].regulatory_flags.add('indoor')
def __init__(self, engine, body_part_owner, body_part_name='Limb'): super().__init__(engine) self.blood_chars = { '.': 25, ',': 15, '~': 20, '`': 15, } self.default_body_part_char = '-' self.body_part_spinning_chars = ['/', '-', '\\', '|'] self.spinning_index = 0 self.spinning_chars_len = len(self.body_part_spinning_chars) self.body_part_owner = body_part_owner self.calculate_path() x, y = self.path[0] if self.engine.world_map.current_dungeon.is_void( x, y) or self.engine.world_map.current_dungeon.is_blocked( x, y): x = self.body_part_owner.x y = self.body_part_owner.y self.body_part = Entity(x, y, char=self.default_body_part_char, color=color_vars.body, name=body_part_name, render_order=RenderOrder.EFFECT) self.engine.entities.append(self.body_part) self.animation_entities = [] self.trail_length = 3
def make_fence(self, game_map): main_gate_direction, main_gate = self.rect.random_direction_side_tile() back_gate_direction = self.rect.opposite_direction(main_gate_direction) _, back_gate = self.rect.random_direction_side_tile(back_gate_direction) fence_tiles = self.rect.border_tiles + self.rect.corner_tiles fence_tiles.remove(main_gate) fence_tiles.remove(back_gate) self.place_mozaic_objects(fence_tiles, game_map, self.fence_char, 99, True) game_map.tiles[main_gate[0]][main_gate[1]].place_static_entity(Entity(main_gate[0], main_gate[1], **self.gate_char)) game_map.tiles[back_gate[0]][back_gate[1]].place_static_entity(Entity(back_gate[0], back_gate[1], **self.gate_char)) self.fence_tiles = fence_tiles self.main_gate = main_gate self.back_gate = back_gate
def initialize_tiles(self): forest_chars = { str(chr(tcod.CHAR_ARROW_N)): 25, str(chr(tcod.CHAR_VLINE)): 5, str(chr(tcod.CHAR_ARROW2_S)): 10, '|': 3, '\\': 7, '/': 7, 'T': 40, 'Y': 35, } tiles = [[None for y in range(self.height)] for x in range(self.width)] for x in range(self.width): for y in range(self.height): tile = WorldTile(biom=Biomes.FOREST, bg_color=color_vars.forest_bg) tree_entity = Entity( x, y, char=random_choice_from_dict(forest_chars), color=color_vars.forest) tile.place_static_entity(tree_entity) tiles[x][y] = tile return tiles
def place(self, game_map): super().place(game_map) for (x, y) in self.altar: game_map.tiles[x][y].block() game_map.tiles[x][y].place_static_entity( Entity(x, y, **self.altar_char))
def place(self, game_map): super().place(game_map) for (x, y) in self.inner_doors: game_map.tiles[x][y].unblock() game_map.tiles[x][y].clear_static_entities() game_map.tiles[x][y].place_static_entity(Entity(x, y, **self.door_char))
def place(self, game_map): x, y = self.campfire game_map.tiles[x][y].unblock() game_map.tiles[x][y].clear_static_entities() game_map.tiles[x][y].place_static_entity( Entity(x, y, **self.campfire_char)) for x, y in self.tents: game_map.tiles[x][y].block() game_map.tiles[x][y].clear_static_entities() game_map.tiles[x][y].place_static_entity( Entity(x, y, **self.tent_char)) for x, y in self.benches: game_map.tiles[x][y].clear_static_entities() game_map.tiles[x][y].place_static_entity( Entity(x, y, **self.bench_char))
def add_explosion_entity(self, x, y): explosion = Entity(x, y, char=self.char, color=self.color, name='Explosion', render_order=RenderOrder.EFFECT) self.explosion_entities.append(explosion) self.engine.entities.append(explosion)
def place(self, game_map): super().place(game_map) bench_char, bench_tiles = self.benches for (x, y) in bench_tiles: game_map.tiles[x][y].regulatory_flags.add('blocked') game_map.tiles[x][y].regulatory_flags.discard('block_sight') game_map.tiles[x][y].place_static_entity(Entity( x, y, **bench_char))
def plant(self, x, y, plant_info): color = plant_info['color'] if type(color) == list: color = choice(color) return Entity(x, y, char=plant_info['char'], color=color, name=plant_info['display_name'], base_name=plant_info['name'], render_order=RenderOrder.GROUND_FLORA)
def place_mozaic_objects(self, obj_list, game_map, obj_char, place_chance, blocked = False, block_sight = False): place_choices = { 'place': place_chance, 'dont': 100 - place_chance, } for (x, y) in obj_list: if random_choice_from_dict(place_choices) == 'place': game_map.tiles[x][y].place_static_entity(Entity(x, y, **obj_char)) if blocked: game_map.tiles[x][y].regulatory_flags.add('blocked') if block_sight: game_map.tiles[x][y].regulatory_flags.add('block_sight')
def get_item(self, x, y, item_choice): item = items[item_choice] item_component = None equippable_component = None if item.get('item_component'): item_component = Item(**item['item_component']) if item.get('equippable_component'): equippable_component = Equippable(**item['equippable_component']) return Entity(x, y, char=item['char'], color=item['color'], name=item['name'], render_order=RenderOrder.ITEM, item=item_component, equippable=equippable_component)
def fungi(self, x, y, plant_choice): plant_info = fungi[plant_choice] char = plant_info['char'] color = plant_info['color'] name = 'Fruiting body of {0}'.format(plant_info['name']) return Entity(x, y, char=char, color=color, name=name, base_name=plant_info['name'], render_order=RenderOrder.GROUND_FLORA)
def sapling(self, x, y, char, tile_shadowed): color = choice(saplings_colors) base_name, name = self.sapling_name(char) if not tile_shadowed: name += ' on a sunny glade' return Entity(x, y, char=char, color=color, name=name, base_name=base_name, render_order=RenderOrder.GROUND_FLORA)
def make_map(self, entities): entities.player.x = int(self.width * (2 / 3)) entities.player.y = int(self.height * (2 / 3)) self.tiles[entities.player.x][entities.player.y].regulatory_flags.add( 'visited') dungeon_entrance_x = self.width // 2 dungeon_entrance_y = self.height // 2 dungeon_tile = self.tiles[dungeon_entrance_x][dungeon_entrance_y] dungeon_tile.clear_static_entities() dungeon_tile.biom = Biomes.DUNGEON dungeon_entity = Entity(dungeon_entrance_x, dungeon_entrance_y, char=tcod.CHAR_RADIO_SET, color=tcod.darker_grey) dungeon_tile.place_static_entity(dungeon_entity)
def get_monster(self, x, y, monster_choice): monster = self.monsters[monster_choice] fighter_component = Fighter(defense=monster['defense'], power=monster['power'], xp=monster['xp']) ai_component = BasicMonster() return Entity(x, y, char=monster['char'], color=monster['color'], name=monster['name'], blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component, attributes=monster['attributes'])
def handle_blood_path(self): blood_char = random_choice_from_dict(self.blood_chars) blood_entity = Entity(self.body_part.x, self.body_part.y, char=blood_char, color=color_vars.blood, name='Drop of blood', render_order=RenderOrder.EFFECT) self.engine.world_map.current_dungeon.tiles[self.body_part.x][ self.body_part.y].place_static_entity(blood_entity) self.animation_entities.append(blood_entity) if len(self.animation_entities) > self.trail_length: entity_to_remove = self.animation_entities.pop(0) tile = self.engine.world_map.current_dungeon.tiles[ entity_to_remove.x][entity_to_remove.y] tile.remove_static_entity(entity_to_remove)
def get_tree(self): diameter = randint(1, self.average_tree_diameter * 2) tree_key = random_choice_from_dict(self.tree_choices) base_name = base_name = trees[tree_key]['name'] if diameter < 4: name = 'Trunk of {0}'.format(base_name) else: name = 'Giant trunk of {0}'.format(base_name) return Entity(-1, -1, bg_color=trees[tree_key]['color'], name=name, base_name=base_name, blocks=True, tree=Tree(diameter=diameter))
def create_player(): attributes = { 'strength': 20, 'dexterity': 10, 'constitution': 30, 'intelligence': 10, 'wisdom': 10, 'charisma': 10, } fighter_component = Fighter(defense=player_vars.defense, power=player_vars.power) inventory_component = Inventory(player_vars.inventory_size) level_component = Level() equipment_component = Equipment() caster_component = Caster(1) return Entity(0, 0, char=player_vars.char, color=color_vars.player, name=player_vars.name, blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component, level=level_component, equipment=equipment_component, attributes=attributes, caster=caster_component)
def grow_cave_entrance_zone(self, cave, zones): wall_plant_choices = weight_factor(entrance_plants['wall']) ground_plant_choices = weight_factor(entrance_plants['ground']) for entrance_zone in zones: center_x, center_y = entrance_zone['center'] for x, y in entrance_zone['coords']: if cave.tiles[x][y].static_entities: continue distance_from_center = math.sqrt( pow(center_x - x, 2) + pow(center_y - y, 2)) chance_for_growth = distance_from_center * 2 if randint(0, 100) < chance_for_growth: continue if cave.is_blocked(x, y): plant_info = entrance_plants['wall'][ random_choice_from_dict(wall_plant_choices)] else: plant_info = entrance_plants['ground'][ random_choice_from_dict(ground_plant_choices)] char = plant_info['char'] base_name = plant_info['name'] name = plant_info['display_name'] color = plant_info['color'] if type(color) == list: color = choice(color) if plant_info.get('bloom_factor'): if randint(1, 100) <= plant_info['bloom_factor']: color = plant_info['flower_color'] name = 'Blooming {0}'.format(name) plant = Entity(x, y, char=char, color=color, name=name, base_name=base_name, render_order=RenderOrder.GROUND_FLORA) cave.tiles[x][y].place_static_entity(plant)
def next_tick(self): if self.path_index >= len(self.path) or self.completed: return [] x, y = self.path[self.path_index] lightning_arc = Entity(x, y, char=random_choice_from_dict( self.lightning_chars), color=color_vars.lightning_arc, name='Lightning Arc', render_order=RenderOrder.EFFECT) self.lightning_entities.append(lightning_arc) self.engine.entities.append(lightning_arc) self.path_index += 1 if self.path_index >= len(self.path): return self.complete() return []
def next_tick(self): if 'stumble_phase' in self.regulatory_flags: blood_drop = Entity(self.entity.x, self.entity.y, char=',', color=color_vars.blood, name='Drop of blood', render_order=RenderOrder.TINY_OBJECTS) self.engine.world_map.current_dungeon.tiles[self.entity.x][ self.entity.y].place_static_entity(blood_drop) if self.can_stumble(): self.entity.x, self.entity.y = self.falling_to_tile self.entity.char.set_color(color_vars.blood) self.regulatory_flags.discard('stumble_phase') self.regulatory_flags.add('fall_phase') elif 'fall_phase' in self.regulatory_flags: self.entity.char.char = '%' self.entity.render_order = RenderOrder.CORPSE self.regulatory_flags.discard('fall_phase') return [{ 'message': Message('{0} is dead'.format(self.entity.name.capitalize()), color=color_vars.dead_entity_message) }] elif self.regulatory_flags == set(): self.entity.name = 'remains of {0}'.format(self.entity.name) self.engine.entities.remove(self.entity) tile = self.engine.world_map.current_dungeon.tiles[self.entity.x][ self.entity.y] tile.place_static_entity(self.entity) self.entity.regulatory_flags.add('moveable') tile.set_bg_color(color_vars.blood_pool) self.engine.regulatory_flags.add('fov_recompute') return self.complete() return []
def grass_plant(self, x, y, plant_choice, tile_shadowed): plant_info = one_tile_plants[plant_choice] char = plant_info['char'] base_name = plant_info['name'] name = base_name color = plant_info['color'] if plant_info.get('bloom_factor'): if randint(1, 100) <= plant_info['bloom_factor']: color = plant_info['flower_color'] name = 'blooming {0}'.format(name) name = '{0} of {1}'.format(plant_info['lifeform'], name) if not tile_shadowed: name += ' on a sunny glade' return Entity(x, y, char=char, color=color, name=name, base_name=base_name, render_order=RenderOrder.GROUND_FLORA)
def make_map(self, entities, moving_down=True): if self.encounter: self.encounter.setup_map_boundaries(0, self.owner.width - 1, 0, self.owner.height - 1) self.encounter.make_rect() rooms = [self.encounter.rect] self.create_room(rooms[0]) num_rooms = 1 else: rooms = [] num_rooms = 0 for _ in range(self.max_rooms): # random width and height w = randint(self.room_min_size, self.room_max_size) h = randint(self.room_min_size, self.room_max_size) # random position without going out of the boundaries of the map x = randint(0, self.owner.width - w - 1) y = randint(0, self.owner.height - h - 1) new_room = Rect(x, y, w, h) for other_room in rooms: if new_room.intersect(other_room): break else: # this means there are no intersections, so this room is valid self.create_room(new_room) new_x, new_y = new_room.center() if num_rooms == 0 or (self.encounter and num_rooms == 1): self.player_start = (new_x, new_y) self.place_player(entities.player) else: # all rooms after the first: # connect it to the previous room with a tunnel self.connect_room(new_room, rooms[num_rooms - 1]) self.fauna.populate_room(new_room, self.owner.dungeon_level, entities) self.loot.fill_room(new_room, self.owner.dungeon_level, entities) self.flora.grow_fungi_in_room(self.owner, new_room) rooms.append(new_room) num_rooms += 1 if moving_down: down_stairs_x = new_x down_stairs_y = new_y up_stairs_x = entities.player.x up_stairs_y = entities.player.y else: down_stairs_x = entities.player.x down_stairs_y = entities.player.y up_stairs_x = new_x up_stairs_y = new_y if not self.encounter: stairs_component = Stairs(self.owner.dungeon_level + 1) down_stairs = Entity(down_stairs_x, down_stairs_y, char='>', color=tcod.white, name='Stairs down', render_order=RenderOrder.STAIRS, stairs=stairs_component) entities.append(down_stairs) if self.owner.dungeon_level == 1: direction = StairsDirections.WORLD stairs_name = 'Stairs outside' else: direction = StairsDirections.UP stairs_name = 'Stairs up' up_stairs_component = Stairs(self.owner.dungeon_level, direction=direction) up_stairs = Entity(up_stairs_x, up_stairs_y, char='<', color=tcod.white, name=stairs_name, render_order=RenderOrder.STAIRS, stairs=up_stairs_component) entities.append(up_stairs) if self.encounter: self.connect_room(rooms[0], rooms[randint(1, len(rooms) - 1)]) self.encounter.create_on(self.owner, entities) for x in range(self.owner.width): for y in range(self.owner.height): tile = self.owner.tiles[x][y] if 'blocked' in tile.regulatory_flags: tile.set_bg_color(self.material['wall']) else: tile.set_bg_color(self.material['floor'])
def place(self, game_map): super().place(game_map) for (x, y, conf) in self.furniture: game_map.tiles[x][y].unblock() game_map.tiles[x][y].place_static_entity(Entity(x, y, **conf))
def place_plant_on_tile(self, x, y, tile, bed): plant = self.plant_chars[self.beds[bed]] plant_entity = Entity(x, y, render_order=RenderOrder.GROUND_FLORA, **plant) tile.place_static_entity(plant_entity) tile.regulatory_flags.add('cultivated')