def update_monster_actor_state(self): # Perform Stealth Check if self.notice_player_check(): self.parent.monster_actor_state.value = MonsterActorState.HUNTING elif (not self.can_see_player() and # forget player check. self.parent.monster_actor_state.value == MonsterActorState.HUNTING and rng.coin_flip() and rng.coin_flip() and rng.coin_flip()): self.parent.monster_actor_state.value = MonsterActorState.WANDERING
def _knock_away_entity(self, target_entity): if rng.coin_flip(): knock_position = geometry.other_side_of_point(self.parent.position.value, target_entity.position.value) old_target_position = target_entity.position.value target_entity.mover.try_move(knock_position) self.parent.mover.try_move(old_target_position) if rng.coin_flip(): entity_stunned_turn(self.parent, target_entity)
def effect(self, damage, source_entity, damage_types=[]): if rng.coin_flip(): self.parent.effect_queue.add( entityeffect.EffectRemover( self.parent, "paralyze", message=NO_LONGER_PARALYZED_MESSAGE))
def effect(self, damage, source_entity, damage_types=[]): if (damage >= 1 and source_entity and source_entity.has("health_modifier") and not DamageTypes.REFLECT in damage_types and source_entity != self.parent and rng.coin_flip()): damage_effect = entityeffect.UndodgeableAttackEntityEffect( self.parent, self.damage, [DamageTypes.MAGIC, DamageTypes.REFLECT]) source_entity.effect_queue.add(damage_effect)
def generate_dungeon_floor(open_area, depth): if rng.coin_flip(): rooms = random.randrange(4, 9) room_area = open_area * 0.7 / rooms return generate_dungeon_exploded_rooms(depth, rooms, room_area, 0.3) else: rooms = random.randrange(10, 14) room_area = open_area * 0.4 / rooms return generate_dungeon_exploded_rooms(depth, rooms, room_area, 0.5)
def effect(self, damage, source_entity, damage_types=[]): if (damage >= 1 and source_entity and source_entity.has("health_modifier") and not DamageTypes.REFLECT in damage_types and source_entity != self.parent and rng.coin_flip()): damage_effect = entityeffect.UndodgeableAttackEntityEffect(self.parent, self.damage, [DamageTypes.MAGIC, DamageTypes.REFLECT]) source_entity.effect_queue.add(damage_effect)
def place_health_potions(dungeon_level, game_state): health_potions_to_spawn = 0 for _ in range(2): if rng.coin_flip(): health_potions_to_spawn += 1 if dungeon_level.depth == 0: health_potions_to_spawn += 2 health_potions_to_spawn += 1 for _ in range(health_potions_to_spawn): potion = item.new_health_potion(game_state) place_piece_on_random_walkable_tile_not_on_item_or_feature(potion, dungeon_level)
def place_health_potions(dungeon_level, game_state): health_potions_to_spawn = 0 for _ in range(2): if rng.coin_flip(): health_potions_to_spawn += 1 if dungeon_level.depth == 0: health_potions_to_spawn += 2 health_potions_to_spawn += 1 for _ in range(health_potions_to_spawn): potion = item.new_health_potion(game_state) place_piece_on_random_walkable_tile_not_on_item_or_feature( potion, dungeon_level)
def act(self, destination): if not self.parent.dungeon_mask.can_see_point(destination): return if coin_flip(): # Should be replaced by spell resist. return targets = self.parent.dungeon_level.value.get_tile_or_unknown( destination).get_entities() if not any(targets): return for target_entity in targets: if target_entity.dungeon_mask.can_see_point( self.parent.position.value): target_entity.effect_queue.add(self.effect_factory()) self.add_energy_spent_to_entity(self.parent)
def hurt(self, damage, entity=None, damage_types=[]): """ Damages the entity by reducing hp by damage. """ if damage == 0 and rng.coin_flip(): damage = 1 # You should never be completely safe if damage == 0: return damage self.parent.health.hp.decrease(damage) self._animate_hurt(damage_types) if self.parent.health.is_dead(): self.parent.health.killer = entity self._call_damage_taken_effect(damage, entity, damage_types) return damage
def dfs_tunnler_with_random_restart(start_position, min_length, max_length, size, direction_list): position = start_position direction_ = random.sample(direction_list, 1)[0] visited = set() while len(visited) < size: direction_ = direction.turn_left_or_right(direction_) length = random.randint(min_length, max_length) visited.add(position) for _ in range(length): if len(visited) >= size: break position = geo.add_2d(position, direction_) visited.add(position) if rng.coin_flip(): position = start_position return visited
def turn_left_or_right(direction): if rng.coin_flip(): return turn_left(direction) else: return turn_right(direction)
def generate_dungeon_exploded_rooms(depth, rooms, room_area, rectangle_room_chance): aprox_room_radius = math.sqrt(room_area) * 1.2 room_distance = aprox_room_radius grid_side = int(max(rooms / 2 + 1, math.sqrt(rooms + 1) + 1)) triangle_points = shapegenerator.triangle_points(room_distance, grid_side, grid_side) room_positions = random.sample(triangle_points, rooms) minor_room_positions = set() room_graph = graph.Graph() corridors_points = set() for room_position in room_positions: room_graph.add_point(room_position) while not room_graph.is_connected(): edge = random.sample(room_positions, 2) while room_graph.has_edge(edge[0], edge[1]): edge = random.sample(room_positions, 2) room_graph.add_edge(edge[0], edge[1]) mid_point = random.sample( shapegenerator.get_opposite_rectangle_corners(edge[0], edge[1]), 1)[0] minor_room_positions.add(mid_point) corridor = shapegenerator.three_point_rectangle_draw( edge[0], mid_point, edge[1]) corridors_points.update(corridor) # Corridor and small corner room shape generation open_points = corridors_points used_roms_positions = [] for position in room_positions: if random.random() > rectangle_room_chance: used_roms_positions.append(position) if rng.coin_flip(): room_points = shapegenerator.random_explosion( position, room_area, direction.AXIS_DIRECTIONS) else: room_points = shapegenerator.fractal_rectangle(position, 3, 3) open_points.update(room_points) for position in minor_room_positions: room_points = shapegenerator.random_explosion( position, room_area / 4, direction.AXIS_DIRECTIONS) open_points.update(room_points) open_points = shapegenerator.smooth_shape(open_points) open_points = shapegenerator.smooth_shape(open_points) possible_door_points = set() for position in set(room_positions) - set(used_roms_positions): width = random.randrange(3, 8) height = random.randrange(3, 8) offset_x = random.randrange(width) offset_y = random.randrange(height) top_left_corner = geo.sub_2d(position, (offset_x, offset_y)) bottom_right_corner = geo.add_2d(top_left_corner, (width, height)) room_points = shapegenerator.get_rectangle_shape( top_left_corner, bottom_right_corner) surrounding_points = shapegenerator.get_rectangle_shape( geo.sub_2d(top_left_corner, (1, 1)), geo.add_2d(bottom_right_corner, (1, 1))) - room_points open_points.update(room_points) possible_door_points |= surrounding_points # Redraw corridors to make sure no dead rooms appear. open_points.update(corridors_points) plant_points = set() if rng.coin_flip() or rng.coin_flip(): for room_position in room_positions: if rng.coin_flip() and rng.coin_flip(): continue room_x, room_y = room_position variance = 7 chasm_start_point = (random.randrange(room_x - variance, room_x + variance), random.randrange(room_y - variance, room_y + variance)) plant_points.update( shapegenerator.random_explosion(chasm_start_point, room_area * 0.2, direction.AXIS_DIRECTIONS)) # Chasm shape generation chasm_points = set() for room_position in room_positions: room_x, room_y = room_position variance = 10 chasm_start_point = (random.randrange(room_x - variance, room_x + variance), random.randrange(room_y - variance, room_y + variance)) chasm_points.update( shapegenerator.random_explosion(chasm_start_point, room_area * 0.8, direction.AXIS_DIRECTIONS)) chasm_points = shapegenerator.smooth_shape(chasm_points) chasm_points = shapegenerator.smooth_shape(chasm_points) # Normalize Points to dungeon frame = (2, 2) # Just to be safe we won't try to draw outside Dungeon. level_shape = shapegenerator.Shape(open_points) plant_shape = shapegenerator.Shape(plant_points) chasm_shape = shapegenerator.Shape(chasm_points) possible_door_shape = shapegenerator.Shape(possible_door_points) dungeon_rect = shapegenerator.Shape(open_points | chasm_points).calc_rect() dungeon_rect_with_frame = dungeon_rect.expanded_by(frame) normalized_chasm_points = chasm_shape.offset_points( geo.sub_2d(frame, dungeon_rect.top_left)) normalized_plant_points = plant_shape.offset_points( geo.sub_2d(frame, dungeon_rect.top_left)) normalized_possible_door_points = possible_door_shape.offset_points( geo.sub_2d(frame, dungeon_rect.top_left)) normalized_open_points = level_shape.offset_points( geo.sub_2d(frame, dungeon_rect.top_left)) # Apply shapes to dungeon dungeon_level = get_full_wall_dungeon(dungeon_rect_with_frame.width, dungeon_rect_with_frame.height, depth) brush = SinglePointBrush(ReplaceComponent(terrain.Chasm)) apply_brush_to_points(dungeon_level, normalized_chasm_points, brush) brush = SinglePointBrush(ReplaceComponent(terrain.Floor)) apply_brush_to_points(dungeon_level, normalized_open_points, brush) brush = SinglePointBrush(ReplaceComponent(dungeonfeature.new_plant)) apply_brush_to_terrains_with_flag(dungeon_level, normalized_plant_points, brush, terrain.Floor.FLOOR_FLAG) door_brush = DoorIfSuitableBrush() apply_brush_to_points(dungeon_level, normalized_possible_door_points, door_brush) feature_positions = random.sample(normalized_open_points, 4) place_up_down_stairs(dungeon_level, feature_positions[0], feature_positions[1]) _place_feature_replace_terrain_with_floor(dungeonfeature.new_fountain(), dungeon_level, feature_positions[2]) if rng.coin_flip(): _place_feature_replace_terrain_with_floor( dungeonfeature.new_blood_fountain(), dungeon_level, feature_positions[3]) return dungeon_level
def generate_dungeon_exploded_rooms(depth, rooms, room_area, rectangle_room_chance): aprox_room_radius = math.sqrt(room_area) * 1.2 room_distance = aprox_room_radius grid_side = int(max(rooms / 2 + 1, math.sqrt(rooms + 1) + 1)) triangle_points = shapegenerator.triangle_points(room_distance, grid_side, grid_side) room_positions = random.sample(triangle_points, rooms) minor_room_positions = set() room_graph = graph.Graph() corridors_points = set() for room_position in room_positions: room_graph.add_point(room_position) while not room_graph.is_connected(): edge = random.sample(room_positions, 2) while room_graph.has_edge(edge[0], edge[1]): edge = random.sample(room_positions, 2) room_graph.add_edge(edge[0], edge[1]) mid_point = random.sample(shapegenerator.get_opposite_rectangle_corners(edge[0], edge[1]), 1)[0] minor_room_positions.add(mid_point) corridor = shapegenerator.three_point_rectangle_draw(edge[0], mid_point, edge[1]) corridors_points.update(corridor) # Corridor and small corner room shape generation open_points = corridors_points used_roms_positions = [] for position in room_positions: if random.random() > rectangle_room_chance: used_roms_positions.append(position) if rng.coin_flip(): room_points = shapegenerator.random_explosion(position, room_area, direction.AXIS_DIRECTIONS) else: room_points = shapegenerator.fractal_rectangle(position, 3, 3) open_points.update(room_points) for position in minor_room_positions: room_points = shapegenerator.random_explosion(position, room_area / 4, direction.AXIS_DIRECTIONS) open_points.update(room_points) open_points = shapegenerator.smooth_shape(open_points) open_points = shapegenerator.smooth_shape(open_points) possible_door_points = set() for position in set(room_positions) - set(used_roms_positions): width = random.randrange(3, 8) height = random.randrange(3, 8) offset_x = random.randrange(width) offset_y = random.randrange(height) top_left_corner = geo.sub_2d(position, (offset_x, offset_y)) bottom_right_corner = geo.add_2d(top_left_corner, (width, height)) room_points = shapegenerator.get_rectangle_shape(top_left_corner, bottom_right_corner) surrounding_points = shapegenerator.get_rectangle_shape(geo.sub_2d(top_left_corner, (1, 1)), geo.add_2d(bottom_right_corner, (1, 1))) - room_points open_points.update(room_points) possible_door_points |= surrounding_points # Redraw corridors to make sure no dead rooms appear. open_points.update(corridors_points) plant_points = set() if rng.coin_flip() or rng.coin_flip(): for room_position in room_positions: if rng.coin_flip() and rng.coin_flip(): continue room_x, room_y = room_position variance = 7 chasm_start_point = (random.randrange(room_x - variance, room_x + variance), random.randrange(room_y - variance, room_y + variance)) plant_points.update(shapegenerator.random_explosion(chasm_start_point, room_area * 0.2, direction.AXIS_DIRECTIONS)) # Chasm shape generation chasm_points = set() for room_position in room_positions: room_x, room_y = room_position variance = 10 chasm_start_point = (random.randrange(room_x - variance, room_x + variance), random.randrange(room_y - variance, room_y + variance)) chasm_points.update(shapegenerator.random_explosion(chasm_start_point, room_area * 0.8, direction.AXIS_DIRECTIONS)) chasm_points = shapegenerator.smooth_shape(chasm_points) chasm_points = shapegenerator.smooth_shape(chasm_points) # Normalize Points to dungeon frame = (2, 2) # Just to be safe we won't try to draw outside Dungeon. level_shape = shapegenerator.Shape(open_points) plant_shape = shapegenerator.Shape(plant_points) chasm_shape = shapegenerator.Shape(chasm_points) possible_door_shape = shapegenerator.Shape(possible_door_points) dungeon_rect = shapegenerator.Shape(open_points | chasm_points).calc_rect() dungeon_rect_with_frame = dungeon_rect.expanded_by(frame) normalized_chasm_points = chasm_shape.offset_points(geo.sub_2d(frame, dungeon_rect.top_left)) normalized_plant_points = plant_shape.offset_points(geo.sub_2d(frame, dungeon_rect.top_left)) normalized_possible_door_points = possible_door_shape.offset_points(geo.sub_2d(frame, dungeon_rect.top_left)) normalized_open_points = level_shape.offset_points(geo.sub_2d(frame, dungeon_rect.top_left)) # Apply shapes to dungeon dungeon_level = get_full_wall_dungeon(dungeon_rect_with_frame.width, dungeon_rect_with_frame.height, depth) brush = SinglePointBrush(ReplaceComponent(terrain.Chasm)) apply_brush_to_points(dungeon_level, normalized_chasm_points, brush) brush = SinglePointBrush(ReplaceComponent(terrain.Floor)) apply_brush_to_points(dungeon_level, normalized_open_points, brush) brush = SinglePointBrush(ReplaceComponent(dungeonfeature.new_plant)) apply_brush_to_terrains_with_flag(dungeon_level, normalized_plant_points, brush, terrain.Floor.FLOOR_FLAG) door_brush = DoorIfSuitableBrush() apply_brush_to_points(dungeon_level, normalized_possible_door_points, door_brush) feature_positions = random.sample(normalized_open_points, 4) place_up_down_stairs(dungeon_level, feature_positions[0], feature_positions[1]) _place_feature_replace_terrain_with_floor(dungeonfeature.new_fountain(), dungeon_level, feature_positions[2]) if rng.coin_flip(): _place_feature_replace_terrain_with_floor(dungeonfeature.new_blood_fountain(), dungeon_level, feature_positions[3]) return dungeon_level
def effect(self, damage, source_entity, damage_types=[]): if rng.coin_flip(): self.parent.effect_queue.add(entityeffect.EffectRemover(self.parent, "paralyze", message=NO_LONGER_PARALYZED_MESSAGE))