Example #1
0
command_result AI::onupdate_register(color_ostream & out)
{
    command_result res = CR_OK;
    if (res == CR_OK)
        res = pop.onupdate_register(out);
    if (res == CR_OK)
        res = plan.onupdate_register(out);
    if (res == CR_OK)
        res = stocks.onupdate_register(out);
    if (res == CR_OK)
        res = camera.onupdate_register(out);
    if (res == CR_OK)
    {
        status_onupdate = events.onupdate_register("df-ai status", 3 * 28 * 1200, 3 * 28 * 1200, [this](color_ostream & out) { debug(out, status()); });
        time_paused = 0;
        pause_onupdate = events.onupdate_register_once("df-ai unpause", [this](color_ostream &) -> bool
        {
            if (!*pause_state && world->status.popups.empty())
            {
                Gui::getViewCoords(last_good_x, last_good_y, last_good_z);
                time_paused = 0;
                return false;
            }

            time_paused++;

            if (time_paused == enabler->fps * 10)
            {
                timeout_sameview(10, [this](color_ostream &) { unpause(); });
                time_paused = -enabler->fps;
            }

            return false;
        });
        tag_enemies_onupdate = events.onupdate_register("df-ai tag_enemies", 1200, 1200, [this](color_ostream & out) { tag_enemies(out); });
        events.onstatechange_register_once("world unload watcher", [this](color_ostream & out, state_change_event st) -> bool
        {
            if (st == SC_WORLD_UNLOADED)
            {
                debug(out, "world unloaded, disabling self");
                onupdate_unregister(out);
                return true;
            }
            statechanged(out, st);
            return false;
        });
    }
    return res;
}
Example #2
0
File: ai.cpp Project: sv-esk/df-ai
command_result AI::onupdate_register(color_ostream & out)
{
    command_result res = CR_OK;
    if (res == CR_OK)
        res = pop->onupdate_register(out);
    if (res == CR_OK)
        res = plan->onupdate_register(out);
    if (res == CR_OK)
        res = stocks->onupdate_register(out);
    if (res == CR_OK)
        res = camera->onupdate_register(out);
    if (res == CR_OK)
        res = embark->onupdate_register(out);
    if (res == CR_OK)
    {
        status_onupdate = events.onupdate_register("df-ai status", 3*28*1200, 3*28*1200, [this](color_ostream & out) { debug(out, status()); });
        last_unpause = std::time(nullptr);
        pause_onupdate = events.onupdate_register_once("df-ai unpause", [this](color_ostream & out) -> bool
                {
                    if (std::time(nullptr) < last_unpause + 11)
                        return false;
                    if (*pause_state)
                    {
                        timeout_sameview(10, [](color_ostream & out) { AI::unpause(); });
                        last_unpause = std::time(nullptr);
                    }
                    return false;
                });
        events.onstatechange_register_once([this](color_ostream & out, state_change_event st) -> bool
                {
                    if (st == SC_WORLD_UNLOADED)
                    {
                        debug(out, "world unloaded, disabling self");
                        onupdate_unregister(out);
                        return true;
                    }
                    statechanged(out, st);
                    return false;
                });
    }
    return res;
}
Example #3
0
File: ai.cpp Project: sv-esk/df-ai
void AI::statechanged(color_ostream & out, state_change_event st)
{
    // automatically unpause the game (only for game-generated pauses)
    if (st == SC_PAUSED)
    {
        auto la = std::find_if(world->status.announcements.rbegin(), world->status.announcements.rend(), [](df::report *a) -> bool
                {
                    return announcements->flags[a->type].bits.PAUSE;
                });
        if (la != world->status.announcements.rend() &&
                (*la)->year == *cur_year &&
                (*la)->time == *cur_year_tick)
        {
            handle_pause_event(out, *la);
        }
        else
        {
            unpause();
            debug(out, "pause without an event");
        }
    }
    else if (st == SC_VIEWSCREEN_CHANGED)
    {
        df::viewscreen *curview = Gui::getCurViewscreen(true);
        df::viewscreen_textviewerst *view = strict_virtual_cast<df::viewscreen_textviewerst>(curview);
        if (view)
        {
            std::ostringstream text;
            for (auto it = view->formatted_text.begin(); it != view->formatted_text.end(); it++)
            {
                if ((*it)->text)
                {
                    text << " " << (*it)->text;
                }
            }

            std::string stripped = text.str();
            stripped.erase(std::remove(stripped.begin(), stripped.end(), ' '), stripped.end());

            if (stripped.find("I" "am" "your" "liaison" "from" "the" "Mountainhomes." "Let's" "discuss" "your" "situation.") != std::string::npos ||
                    stripped.find("I" "look" "forward" "to" "our" "meeting" "next" "year.") != std::string::npos ||
                    stripped.find("A" "diplomat" "has" "left" "unhappy.") != std::string::npos ||
                    stripped.find("You" "have" "disrespected" "the" "trees" "in" "this" "area," "but" "this" "is" "what" "we" "have" "come" "to" "expect" "from" "your" "stunted" "kind." "Further" "abuse" "cannot" "be" "tolerated." "Let" "this" "be" "a" "warning" "to" "you.") != std::string::npos ||
                    stripped.find("Greetings" "from" "the" "woodlands." "We" "have" "much" "to" "discuss.") != std::string::npos ||
                    stripped.find("Although" "we" "do" "not" "always" "see" "eye" "to" "eye" "(ha!)," "I" "bid" "you" "farewell." "May" "you" "someday" "embrace" "nature" "as" "you" "embrace" "the" "rocks" "and" "mud.") != std::string::npos)
            {
                debug(out, "exit diplomat textviewerst:" + text.str());
                timeout_sameview([](color_ostream & out)
                        {
                            AI::feed_key(interface_key::LEAVESCREEN);
                        });
            }
            else if (stripped.find("A" "vile" "force" "of" "darkness" "has" "arrived!") != std::string::npos ||
                    stripped.find("have" "brought" "the" "full" "forces" "of" "their" "lands" "against" "you.") != std::string::npos ||
                    stripped.find("The" "enemy" "have" "come" "and" "are" "laying" "siege" "to" "the" "fortress.") != std::string::npos ||
                    stripped.find("The" "dead" "walk." "Hide" "while" "you" "still" "can!") != std::string::npos)
            {
                debug(out, "exit siege textviewerst:" + text.str());
                timeout_sameview([](color_ostream & out)
                        {
                            AI::feed_key(interface_key::LEAVESCREEN);
                            unpause();
                        });
            }
            else if (stripped.find("Your" "strength" "has" "been" "broken.") != std::string::npos ||
                    stripped.find("Your" "settlement" "has" "crumbled" "to" "its" "end.") != std::string::npos ||
                    stripped.find("Your" "settlement" "has" "been" "abandoned.") != std::string::npos)
            {
                debug(out, "you just lost the game:" + text.str());
                debug(out, "Exiting AI");
                onupdate_unregister(out);

                // get rid of all the remaining event handlers
                events.clear();

                embark->register_restart_timer(out);

                // don't unpause, to allow for 'die'
            }
            else
            {
                debug(out, "[ERROR] paused in unknown textviewerst:" + text.str());
            }
        }
        else if (strict_virtual_cast<df::viewscreen_topicmeetingst>(curview))
        {
            debug(out, "exit diplomat topicmeetingst");
            timeout_sameview([](color_ostream & out)
                    {
                        AI::feed_key(interface_key::OPTION1);
                    });
        }
        else if (strict_virtual_cast<df::viewscreen_topicmeeting_takerequestsst>(curview))
        {
            debug(out, "exit diplomat topicmeeting_takerequestsst");
            timeout_sameview([](color_ostream & out)
                    {
                        AI::feed_key(interface_key::LEAVESCREEN);
                    });
        }
        else if (strict_virtual_cast<df::viewscreen_requestagreementst>(curview))
        {
            debug(out, "exit diplomat requestagreementst");
            timeout_sameview([](color_ostream & out)
                    {
                        AI::feed_key(interface_key::LEAVESCREEN);
                    });
        }
        else if (strict_virtual_cast<df::viewscreen_movieplayerst>(curview))
        {
            Screen::dismiss(curview);
            camera->check_record_status();
        }
        else if (virtual_identity *ident = virtual_identity::get(curview))
        {
            std::string cvname = ident->getName();
            if (seen_cvname.insert(cvname).second)
            {
                debug(out, "[ERROR] paused in unknown viewscreen " + cvname);
            }
        }
    }
}
Example #4
0
File: ai.cpp Project: sv-esk/df-ai
void AI::handle_pause_event(color_ostream & out, df::report *announce)
{
    // unsplit announce text
    std::string fulltext = announce->text;
    auto idx = std::find(world->status.announcements.rbegin(), world->status.announcements.rend(), announce);
    while (announce->flags.bits.continuation)
    {
        idx++;
        if (idx == world->status.announcements.rend())
            break;
        announce = *idx;
        fulltext = announce->text + " " + fulltext;
    }
    debug(out, "pause: " + fulltext);

    switch (announce->type)
    {
        case announcement_type::MEGABEAST_ARRIVAL:
            {
                debug(out, "pause: uh oh, megabeast...");
                bool found = false;
                for (auto it = world->units.active.rbegin(); it != world->units.active.rend(); it++)
                {
                    if ((*it)->flags2.bits.visitor_uninvited)
                    {
                        pop->military_all_squads_attack_unit(out, *it);
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    debug(out, "[ERROR] could not find megabeast");
                }
                break;
            }
        case announcement_type::BERSERK_CITIZEN:
            debug(out, "pause: berserk");
            break;
        case announcement_type::UNDEAD_ATTACK:
            debug(out, "pause: i see dead people");
            break;
        case announcement_type::CAVE_COLLAPSE:
            debug(out, "pause: kevin?");
            break;
        case announcement_type::DIG_CANCEL_DAMP:
        case announcement_type::DIG_CANCEL_WARM:
            camera->ignore_pause();
            debug(out, "pause: lazy miners");
            break;
        case announcement_type::BIRTH_CITIZEN:
            debug(out, "pause: newborn");
            break;
        case announcement_type::BIRTH_ANIMAL:
            break;
        case announcement_type::D_MIGRANTS_ARRIVAL:
        case announcement_type::D_MIGRANT_ARRIVAL:
        case announcement_type::MIGRANT_ARRIVAL:
        case announcement_type::NOBLE_ARRIVAL:
        case announcement_type::FORT_POSITION_SUCCESSION:
            debug(out, "pause: more minions");
            break;
        case announcement_type::DIPLOMAT_ARRIVAL:
        case announcement_type::LIAISON_ARRIVAL:
        case announcement_type::CARAVAN_ARRIVAL:
        case announcement_type::TRADE_DIPLOMAT_ARRIVAL:
            debug(out, "pause: visitors");
            break;
        case announcement_type::STRANGE_MOOD:
        case announcement_type::MOOD_BUILDING_CLAIMED:
        case announcement_type::ARTIFACT_BEGUN:
        case announcement_type::MADE_ARTIFACT:
            debug(out, "pause: mood");
            break;
        case announcement_type::FEATURE_DISCOVERY:
        case announcement_type::STRUCK_DEEP_METAL:
            debug(out, "pause: dig dig dig");
            break;
        case announcement_type::TRAINING_FULL_REVERSION:
            debug(out, "pause: born to be wild");
            break;
        case announcement_type::NAMED_ARTIFACT:
            debug(out, "pause: hallo");
            break;
        default:
            {
                const static std::string prefix("AMBUSH");
                std::string type(ENUM_KEY_STR(announcement_type, announce->type));
                if (std::mismatch(prefix.begin(), prefix.end(), type.begin()).first == prefix.end())
                {
                    debug(out, "pause: an ambush!");
                }
                else
                {
                    debug(out, "pause: unhandled pausing event " + type);
                    // return;
                }
                break;
            }
    }

    if (announcements->flags[announce->type].bits.DO_MEGA)
    {
        timeout_sameview([](color_ostream & out)
                {
                    unpause();
                });
    }
    else
    {
        unpause();
    }
}