Ejemplo n.º 1
0
def _place_random_creatures(new_map, player):
    start_region = new_map.region[player.pos.x][player.pos.y]
    terrain_chances = {
        'lake' : { None : 10 },
        'marsh' : { None : 10, bestiary.swamp_goblin : 10 },
        'desert' : { None : 20, bestiary.hyena_pair : 5, bestiary.gazelle : 10 },
        'scrub' : { None : 20, bestiary.hyena : 2, bestiary.gazelle : 4,
                    bestiary.deer : 4, bestiary.wolf : 2 },
        'forest' : { None : 20, bestiary.deer : 10, bestiary.wolf_pair : 5,
                     bestiary.bear : 3 },
        'rock' : { None : 10, bestiary.snow_leopard : 1 },
        'ice' : { None : 10, bestiary.snow_leopard : 1 }
    }
    for r in range(len(new_map.region_seeds)):
        if (r == start_region or
            (new_map.quarry_regions and r in new_map.quarry_regions)):
            continue
        fn = _random_choice(terrain_chances[new_map.region_terrain[r]])
        if fn is not None:
            pos = algebra.Location(new_map.region_seeds[r][0], new_map.region_seeds[r][1])
            while new_map.is_blocked_at(pos):
                pos += actions.random_direction()
                pos.bound(algebra.Rect(0, 0, new_map.width-1, new_map.height-1))
            if new_map.caravanserai and new_map.caravanserai.bounds.contains(pos):
                continue
            # print('Creature in region ' + str(r) + ' at ' + str(pos.x) + ' ' + str(pos.y))
            fn(new_map, pos, player)
Ejemplo n.º 2
0
def ignoring_monster(monster, player, metadata):
    """
    A creature that moves randomly (q.v. confused_monster) and ignores
    the player unless hurt, in which case it becomes hostile or scared.
    """
    _spotting(monster, metadata)

    if metadata.active_turns > 0:
        metadata.active_turns -= 1
        if monster.fighter.last_attacker:
            if monster.fighter.unarmed_damage > 2:
                monster.ai = AI(
                    hostile_monster,
                    hostile_monster_metadata(monster.fighter.last_attacker))
            else:
                monster.old_ai = monster.ai
                monster.ai = AI(
                    fleeing_monster,
                    hostile_monster_metadata(monster.fighter.last_attacker))
            monster.ai.set_owner(monster)
            return monster.ai.take_turn(player)
        # TODO: this movement may fail, so the monster will appear to
        # move less when in constricted quarters.
        if metadata.on_idle and not metadata.on_idle(player):
            actions.move(monster, actions.random_direction())
Ejemplo n.º 3
0
def territorial_monster(monster, player, metadata):
    """
    Move randomly but near home until approached or hurt
    """
    _spotting(monster, metadata)

    if metadata.active_turns > 0:
        metadata.active_turns -= 1

        # In the grander scheme of things this should reset to territorial
        # after killing its prey, but that doesn't matter so long as we only
        # go hostile on the player.
        if monster.fighter.last_attacker:
            monster.ai = AI(
                hostile_monster,
                hostile_monster_metadata(monster.fighter.last_attacker))
            monster.ai.set_owner(monster)
            return monster.ai.take_turn(player)
        if monster.distance_to_obj(player) < metadata.radius:
            log.message(
                monster.name.capitalize() + ' decides ' + player.name +
                ' is too close!', libtcod.red)
            monster.ai = AI(hostile_monster, hostile_monster_metadata(player))
            monster.ai.set_owner(monster)
            return monster.ai.take_turn(player)
        while True:
            trial_dir = actions.random_direction()
            candidate = monster.pos + trial_dir
            cand_dist = candidate.distance(metadata.home)
            if ((cand_dist < metadata.radius
                 or cand_dist < monster.pos.distance(metadata.home))
                    and not monster.current_map.is_blocked_at(candidate)):
                actions.move(monster, trial_dir)
                return
Ejemplo n.º 4
0
def hyena_pair(new_map, pos, player):
    return (_hostile_monster(new_map, pos, player, 'C', 'hyena',
                            libtcod.amber, hp=12, unarmed_damage=3,
                            skills={'grappling':20}),
        _hostile_monster(new_map, pos + actions.random_direction(), player, 'C', 'hyena',
                            libtcod.amber, hp=12, unarmed_damage=3,
                            skills={'grappling':20}))
Ejemplo n.º 5
0
def territorial_monster(monster, player, metadata):
    """
    Move randomly but near home until approached or hurt
    """
    _spotting(monster, metadata)

    if metadata.active_turns > 0:
        metadata.active_turns -= 1

        # In the grander scheme of things this should reset to territorial
        # after killing its prey, but that doesn't matter so long as we only
        # go hostile on the player.
        if monster.fighter.last_attacker:
            monster.ai = AI(hostile_monster,
                            hostile_monster_metadata(monster.fighter.last_attacker))
            monster.ai.set_owner(monster)
            return monster.ai.take_turn(player)
        if monster.distance_to_obj(player) < metadata.radius:
            log.message(monster.name.capitalize() + ' decides ' + player.name +
                ' is too close!', libtcod.red)
            monster.ai = AI(hostile_monster,
                            hostile_monster_metadata(player))
            monster.ai.set_owner(monster)
            return monster.ai.take_turn(player)
        while True:
            trial_dir = actions.random_direction()
            candidate = monster.pos + trial_dir
            cand_dist = candidate.distance(metadata.home)
            if ((cand_dist < metadata.radius or
                 cand_dist < monster.pos.distance(metadata.home)) and
                    not monster.current_map.is_blocked_at(candidate)):
                actions.move(monster, trial_dir)
                return
Ejemplo n.º 6
0
def wolf_pair(new_map, pos, player):
    return (_hostile_monster(new_map, pos, player, 'C', 'wolf',
                            libtcod.darker_orange, hp=16, unarmed_damage=4,
                            skills={'grappling':30}),
        _hostile_monster(new_map, pos + actions.random_direction(), player, 'C', 'wolf',
                                    libtcod.darker_orange, hp=16, unarmed_damage=4,
                                    skills={'grappling':30}))
Ejemplo n.º 7
0
def confused_monster(monster, player, metadata):
    if metadata.num_turns > 0:
        actions.move(monster, actions.random_direction())
        metadata.num_turns -= 1
    else:
        # Restore the previous AI (this one will be deleted
        # because it's not referenced anymore)
        monster.ai = metadata.old_ai
        log.message(monster.name.capitalize() + ' is no longer confused!',
                    libtcod.red)
Ejemplo n.º 8
0
def confused_monster(monster, player, metadata):
    if metadata.num_turns > 0:
        actions.move(monster, actions.random_direction())
        metadata.num_turns -= 1
    else:
        # Restore the previous AI (this one will be deleted
        # because it's not referenced anymore)
        monster.ai = metadata.old_ai
        log.message(monster.name.capitalize() +
                    ' is no longer confused!', libtcod.red)
Ejemplo n.º 9
0
def _place_random_creatures(new_map, player):
    start_region = new_map.region[player.pos.x][player.pos.y]
    terrain_chances = {
        'lake': {
            None: 10
        },
        'marsh': {
            None: 10,
            bestiary.swamp_goblin: 10
        },
        'desert': {
            None: 20,
            bestiary.hyena_pair: 5,
            bestiary.gazelle: 10
        },
        'scrub': {
            None: 20,
            bestiary.hyena: 2,
            bestiary.gazelle: 4,
            bestiary.deer: 4,
            bestiary.wolf: 2
        },
        'forest': {
            None: 20,
            bestiary.deer: 10,
            bestiary.wolf_pair: 5,
            bestiary.bear: 3
        },
        'rock': {
            None: 10,
            bestiary.snow_leopard: 1
        },
        'ice': {
            None: 10,
            bestiary.snow_leopard: 1
        }
    }
    for r in range(len(new_map.region_seeds)):
        if (r == start_region
                or (new_map.quarry_regions and r in new_map.quarry_regions)):
            continue
        fn = _random_choice(terrain_chances[new_map.region_terrain[r]])
        if fn is not None:
            pos = algebra.Location(new_map.region_seeds[r][0],
                                   new_map.region_seeds[r][1])
            while new_map.is_blocked_at(pos):
                pos += actions.random_direction()
                pos.bound(
                    algebra.Rect(0, 0, new_map.width - 1, new_map.height - 1))
            if new_map.caravanserai and new_map.caravanserai.bounds.contains(
                    pos):
                continue
            # print('Creature in region ' + str(r) + ' at ' + str(pos.x) + ' ' + str(pos.y))
            fn(new_map, pos, player)
Ejemplo n.º 10
0
def hyena_pair(new_map, pos, player):
    return (_hostile_monster(new_map,
                             pos,
                             player,
                             'C',
                             'hyena',
                             libtcod.amber,
                             hp=12,
                             unarmed_damage=3,
                             skills={'grappling': 20}),
            _hostile_monster(new_map,
                             pos + actions.random_direction(),
                             player,
                             'C',
                             'hyena',
                             libtcod.amber,
                             hp=12,
                             unarmed_damage=3,
                             skills={'grappling': 20}))
Ejemplo n.º 11
0
def wolf_pair(new_map, pos, player):
    return (_hostile_monster(new_map,
                             pos,
                             player,
                             'C',
                             'wolf',
                             libtcod.darker_orange,
                             hp=16,
                             unarmed_damage=4,
                             skills={'grappling': 30}),
            _hostile_monster(new_map,
                             pos + actions.random_direction(),
                             player,
                             'C',
                             'wolf',
                             libtcod.darker_orange,
                             hp=16,
                             unarmed_damage=4,
                             skills={'grappling': 30}))
Ejemplo n.º 12
0
def make_map(player, dungeon_level):
    """
    Creates a new simple map at the given dungeon level.
    Sets player.current_map to the new map, and adds the player as the first
    object.
    """
    new_map = map.OutdoorMap(config.OUTDOOR_MAP_WIDTH,
                             config.OUTDOOR_MAP_HEIGHT, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    _build_map(new_map)

    # Might want to change this later, but this is required in creature placement
    # routines so we know what region the player starts in so there isn't a
    # wandering monster jumping down their throat. Unless, of course, this
    # start point is on a *region border* and there's a monster in the next
    # region over...
    player.pos = algebra.Location(config.OUTDOOR_MAP_WIDTH - 8, 12)

    _place_random_creatures(new_map, player)
    _inhabit_rotunda(new_map, new_map.peak)
    if new_map.caravanserai:
        compound_cartographer.inhabit_caravanserai(new_map, player)
    if new_map.quarry_regions:
        _inhabit_quarry(new_map, player)

    # make sure we're not starting on top of an object or terrain feature
    while (new_map.terrain_at(player.pos).name != 'ground'):
        # subtle bug? doesn't use the map-building random number generator
        player.pos = player.pos + actions.random_direction()
        player.pos.bound(
            algebra.Rect(0, 0, new_map.width - 1, new_map.height - 1))

    new_map.initialize_fov()
    # setting an instancemethod breaks shelve save games
    # new_map.xp_visit = type(map.BaseMap.xp_visit)(_mountain_exploration, new_map, map.BaseMap)
    new_map.xp_visit = _mountain_exploration
    return True
Ejemplo n.º 13
0
def make_map(player, dungeon_level):
    """
    Creates a new simple map at the given dungeon level.
    Sets player.current_map to the new map, and adds the player as the first
    object.
    """
    new_map = map.OutdoorMap(config.OUTDOOR_MAP_WIDTH, config.OUTDOOR_MAP_HEIGHT, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    _build_map(new_map)

    # Might want to change this later, but this is required in creature placement
    # routines so we know what region the player starts in so there isn't a
    # wandering monster jumping down their throat. Unless, of course, this
    # start point is on a *region border* and there's a monster in the next
    # region over...
    player.pos = algebra.Location(config.OUTDOOR_MAP_WIDTH - 8, 12)

    _place_random_creatures(new_map, player)
    _inhabit_rotunda(new_map, new_map.peak)
    if new_map.caravanserai:
        compound_cartographer.inhabit_caravanserai(new_map, player)
    if new_map.quarry_regions:
        _inhabit_quarry(new_map, player)

    # make sure we're not starting on top of an object or terrain feature
    while (new_map.terrain_at(player.pos).name != 'ground'):
        # subtle bug? doesn't use the map-building random number generator
        player.pos = player.pos + actions.random_direction()
        player.pos.bound(algebra.Rect(0, 0, new_map.width - 1, new_map.height - 1))

    new_map.initialize_fov()
    # setting an instancemethod breaks shelve save games
    # new_map.xp_visit = type(map.BaseMap.xp_visit)(_mountain_exploration, new_map, map.BaseMap)
    new_map.xp_visit = _mountain_exploration
    return True
Ejemplo n.º 14
0
def ignoring_monster(monster, player, metadata):
    """
    A creature that moves randomly (q.v. confused_monster) and ignores
    the player unless hurt, in which case it becomes hostile or scared.
    """
    _spotting(monster, metadata)

    if metadata.active_turns > 0:
        metadata.active_turns -= 1
        if monster.fighter.last_attacker:
            if monster.fighter.unarmed_damage > 2:
                monster.ai = AI(hostile_monster,
                                hostile_monster_metadata(monster.fighter.last_attacker))
            else:
                monster.old_ai = monster.ai
                monster.ai = AI(fleeing_monster,
                                hostile_monster_metadata(monster.fighter.last_attacker))
            monster.ai.set_owner(monster)
            return monster.ai.take_turn(player)
        # TODO: this movement may fail, so the monster will appear to
        # move less when in constricted quarters.
        if metadata.on_idle and not metadata.on_idle(player):
            actions.move(monster, actions.random_direction())
Ejemplo n.º 15
0
def make_map(player, dungeon_level):
    """
    """
    old_map = player.current_map

    new_map = map.DungeonMap(MINE_SIZE, MINE_SIZE, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    old_quarry_stairs = old_map.quarry_stairs
    _link_up_stairs(new_map, old_map, old_quarry_stairs)
    _create_entries(new_map, old_quarry_stairs)
    _descend_stairs(new_map, player, old_quarry_stairs)
    _dig_some_caves(new_map, old_quarry_stairs)
    _dig_mine_tunnels(new_map)

    map_bounds = algebra.Rect(1, 1, new_map.width - 1, new_map.height - 1)
    for x in range(1, new_map.width - 1):
        for y in range(1, new_map.height - 1):
            if libtcod.random_get_float(new_map.rng, 0., 1.) < 0.2:
                new_map.terrain[x][y] = map.TERRAIN_GROUND

    ca_cartographer._generation(new_map, map_bounds, 7, 1)
    ca_cartographer._generation(new_map, map_bounds, 5, 1)

    # Redig the initial rooms because the CA can fill in the stairs
    for i in range(3):
        _create_room(new_map, new_map.rooms[i])

    for i in range(3):
        stair_pos = old_quarry_stairs[i].dest_position
        ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y,
                                   map.TERRAIN_GROUND, map.TERRAIN_FLOOR)

    for x in range(1, new_map.width - 1):
        for y in range(1, new_map.height - 1):
            if new_map.terrain[x][y] == map.TERRAIN_GROUND:
                new_map.terrain[x][y] = map.TERRAIN_WALL

    #for x in range(0, new_map.width):
    #    new_map.terrain[x][0] = map.TERRAIN_WALL
    #    new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL
    #for y in range(0, new_map.height):
    #    new_map.terrain[0][y] = map.TERRAIN_WALL
    #    new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL

    zone_divisor = MINE_SIZE / 3
    slime_zone = new_map.rnd(0, 2)
    while True:
        undead_zone = new_map.rnd(0, 2)
        if undead_zone != slime_zone:
            break

    for r in range(3, len(new_map.rooms)):
        if new_map.rnd(1, 4) < 3:
            room = new_map.rooms[r]
            zone = room.center().x / zone_divisor
            if zone == slime_zone:
                if new_map.rnd(1, 2) == 1:
                    bestiary.slime(new_map,
                                   _find_floor_near_room(new_map,
                                                         room), player)
                    bestiary.slime(new_map,
                                   _find_floor_near_room(new_map,
                                                         room), player)
                else:
                    bestiary.jelly(new_map,
                                   _find_floor_near_room(new_map,
                                                         room), player)
            elif zone == undead_zone:
                bestiary.ghul(new_map, _find_floor_near_room(new_map, room),
                              player)
            else:
                bestiary.worm(new_map, _find_floor_near_room(new_map, room),
                              player)

    r = new_map.rnd(3, len(new_map.rooms) - 1)
    pos = new_map.rooms[r].center()
    while new_map.is_blocked_at(pos):
        pos += actions.random_direction()

    new_map.objects.insert(0,
                           Object(pos, '%', "hero's corpse", libtcod.dark_red))
    sword = miscellany.the_black_sword()
    sword.pos = pos
    new_map.objects.insert(0, sword)

    new_map.initialize_fov()
    new_map.xp_visit = _dungeon_exploration
    return False  # Don't need to generate stairs in caller thanks to _link_up_stairs()
Ejemplo n.º 16
0
def make_map(player, dungeon_level):
    """
    """
    old_map = player.current_map

    new_map = map.DungeonMap(MINE_SIZE, MINE_SIZE, dungeon_level)
    new_map.objects.append(player)
    player.current_map = new_map
    player.camera_position = algebra.Location(0, 0)
    new_map.random_seed = libtcod.random_save(0)
    new_map.rng = libtcod.random_new_from_seed(new_map.random_seed)

    old_quarry_stairs = old_map.quarry_stairs
    _link_up_stairs(new_map, old_map, old_quarry_stairs)
    _create_entries(new_map, old_quarry_stairs)
    _descend_stairs(new_map, player, old_quarry_stairs)
    _dig_some_caves(new_map, old_quarry_stairs)
    _dig_mine_tunnels(new_map)

    map_bounds = algebra.Rect(1, 1, new_map.width-1, new_map.height-1)
    for x in range(1, new_map.width-1):
        for y in range(1, new_map.height-1):
            if libtcod.random_get_float(new_map.rng, 0., 1.) < 0.2:
                new_map.terrain[x][y] = map.TERRAIN_GROUND

    ca_cartographer._generation(new_map, map_bounds, 7, 1)
    ca_cartographer._generation(new_map, map_bounds, 5, 1)

    # Redig the initial rooms because the CA can fill in the stairs
    for i in range(3):
        _create_room(new_map, new_map.rooms[i])

    for i in range(3):
        stair_pos = old_quarry_stairs[i].dest_position
        ca_cartographer._floodfill(new_map, stair_pos.x, stair_pos.y,
            map.TERRAIN_GROUND, map.TERRAIN_FLOOR)

    for x in range(1, new_map.width-1):
        for y in range(1, new_map.height-1):
            if new_map.terrain[x][y] == map.TERRAIN_GROUND:
                new_map.terrain[x][y] = map.TERRAIN_WALL

    #for x in range(0, new_map.width):
    #    new_map.terrain[x][0] = map.TERRAIN_WALL
    #    new_map.terrain[x][new_map.height-1] = map.TERRAIN_WALL
    #for y in range(0, new_map.height):
    #    new_map.terrain[0][y] = map.TERRAIN_WALL
    #    new_map.terrain[new_map.width-1][y] = map.TERRAIN_WALL

    zone_divisor = MINE_SIZE / 3
    slime_zone = new_map.rnd(0, 2)
    while True:
        undead_zone = new_map.rnd(0, 2)
        if undead_zone != slime_zone:
            break

    for r in range(3, len(new_map.rooms)):
        if new_map.rnd(1, 4) < 3:
            room = new_map.rooms[r]
            zone = room.center().x / zone_divisor
            if zone == slime_zone:
                if new_map.rnd(1, 2) == 1:
                    bestiary.slime(new_map, _find_floor_near_room(new_map, room), player)
                    bestiary.slime(new_map, _find_floor_near_room(new_map, room), player)
                else:
                    bestiary.jelly(new_map, _find_floor_near_room(new_map, room), player)
            elif zone == undead_zone:
                bestiary.ghul(new_map, _find_floor_near_room(new_map, room), player)
            else:
                bestiary.worm(new_map, _find_floor_near_room(new_map, room), player)

    r = new_map.rnd(3, len(new_map.rooms) - 1)
    pos = new_map.rooms[r].center()
    while new_map.is_blocked_at(pos):
        pos += actions.random_direction()

    new_map.objects.insert(0, Object(pos, '%', "hero's corpse", libtcod.dark_red))
    sword = miscellany.the_black_sword()
    sword.pos = pos
    new_map.objects.insert(0, sword)

    new_map.initialize_fov()
    new_map.xp_visit = _dungeon_exploration
    return False  # Don't need to generate stairs in caller thanks to _link_up_stairs()