Пример #1
0
//--------------------------------------------------------- MOVE RULES
bool Move_rules::can_move(Actor& actor) const
{
    if (can_move_cmn_)
    {
        return true;
    }

    auto& prop_handler = actor.prop_handler();

    //If not allowing normal move, check if any property overrides this
    for (size_t i = 0; i < size_t(Prop_id::END); ++i)
    {
        const Prop_id id = Prop_id(i);

        if (prop_handler.has_prop(id) && can_move_if_have_prop_[i])
        {
            return true;
        }
    }

    return false;
}
Пример #2
0
void act()
{
    //=======================================================================
    // TESTS
    //=======================================================================
    for (Actor* actor : game_time::actors_)
    {
#ifdef NDEBUG
        (void)actor;
#else
        assert(utils::is_pos_inside_map(actor->pos));
#endif
    }

    //=======================================================================

    //Abort?
    //TODO: Reimplement this
//    if(input::is_key_held(SDLK_ESCAPE))
//    {
//        config::toggle_bot_playing();
//    }

    //Check if we are finished with the current run, if so, go back to DLVL 1
    if (map::dlvl >= DLVL_LAST)
    {
        TRACE << "Starting new run on first dungeon level" << endl;
        map_travel::init();
        map::dlvl = 1;
        return;
    }

    Prop_handler& prop_handler = map::player->get_prop_handler();

    //Keep an allied Mi-go around to help getting out of sticky situations
    bool has_allied_mon = false;

    for (const Actor* const actor : game_time::actors_)
    {
        if (map::player->is_leader_of(actor))
        {
            has_allied_mon = true;
            break;
        }
    }

    if (!has_allied_mon)
    {
        actor_factory::summon(map::player->pos, {Actor_id::mi_go}, false, map::player);
    }

    //Occasionally apply RFear (to avoid getting stuck on fear-causing monsters)
    if (rnd::one_in(7))
    {
        prop_handler.try_apply_prop(new Prop_rFear(Prop_turns::specific, 4), true);
    }

    //Occasionally apply Burning to a random actor (helps to avoid getting stuck)
    if (rnd::one_in(10))
    {
        const int ELEMENT = rnd::range(0, game_time::actors_.size() - 1);
        Actor* const actor = game_time::actors_[ELEMENT];

        if (actor != map::player)
        {
            actor->get_prop_handler().try_apply_prop(new Prop_burning(Prop_turns::std), true);
        }
    }

    //Occasionally teleport (to avoid getting stuck)
    if (rnd::one_in(200))
    {
        map::player->teleport();
    }

    //Occasionally send a TAB command to attack nearby monsters
    if (rnd::coin_toss())
    {
        input::handle_map_mode_key_press(Key_data(SDLK_TAB));
        return;
    }

    //Occasionally apply a random property to exercise the prop code
    if (rnd::one_in(10))
    {
        vector<Prop_id> prop_bucket;

        for (size_t i = 0; i < size_t(Prop_id::END); ++i)
        {
            if (prop_data::data[i].allow_test_on_bot)
            {
                prop_bucket.push_back(Prop_id(i));
            }
        }

        Prop_id prop_id = prop_bucket[rnd::range(0, prop_bucket.size() - 1)];
        Prop* const prop = prop_handler.mk_prop(prop_id, Prop_turns::specific, 5);

        prop_handler.try_apply_prop(prop, true);
    }

    //Handle blocking door
    for (int dx = -1; dx <= 1; ++dx)
    {
        for (int dy = -1; dy <= 1; ++dy)
        {
            const Pos p(map::player->pos + Pos(dx, dy));
            auto* const f = map::cells[p.x][p.y].rigid;

            if (f->get_id() == Feature_id::door)
            {
                Door* const door = static_cast<Door*>(f);
                door->reveal(false);

                if (door->is_stuck())
                {
                    f->hit(Dmg_type::physical, Dmg_method::kick, map::player);
                    return;
                }
            }
        }
    }

    //If we are terrified, wait in place
    bool props[size_t(Prop_id::END)];
    map::player->get_prop_handler().get_prop_ids(props);

    if (props[int(Prop_id::terrified)])
    {
        if (walk_to_adj_cell(map::player->pos))
        {
            return;
        }
    }

    find_path_to_stairs();

    walk_to_adj_cell(cur_path_.back());
}