예제 #1
0
std::string FightersDestroyedEvent::CombatLogDescription(int viewing_empire_id) const {
    if (events.empty())
        return "";

    const auto& events_to_show = events;
    auto num_events_remaining = events.size();
    std::stringstream ss;

    // Use show_events_for_empire to show events in this order: viewing empire,
    // ALL_EMPIRES and then the remainder.
    auto show_events_for_empire =
        [&ss, &num_events_remaining, &events_to_show, &viewing_empire_id]
        (boost::optional<int> show_empire_id) {
            int count;
            int target_empire_id;
            for (const auto& index_and_event : events_to_show) {
                std::tie(target_empire_id, count) = index_and_event;

                // Skip if this is not the particular attacker requested
                if (show_empire_id && *show_empire_id != target_empire_id)
                    continue;

                // Skip if no particular empire was requested and this empire is the viewing
                // empire or ALL_EMPIRES
                if (!show_empire_id && (target_empire_id == viewing_empire_id || target_empire_id == ALL_EMPIRES))
                    continue;

                auto count_str = std::to_string(index_and_event.second);
                auto target_empire_link = EmpireLink(target_empire_id);
                const auto&& target_link = FighterOrPublicNameLink(
                    viewing_empire_id, INVALID_OBJECT_ID, target_empire_id);

                if (count == 1) {
                    const std::string& template_str = UserString("ENC_COMBAT_FIGHTER_INCAPACITATED_STR");
                    ss << str(FlexibleFormat(template_str) % target_empire_link % target_link);
                }else {
                    const std::string& template_str = UserString("ENC_COMBAT_FIGHTER_INCAPACITATED_REPEATED_STR");
                    ss << str(FlexibleFormat(template_str) % count_str % target_empire_link % target_link);
                }
                if (--num_events_remaining > 0)
                    ss << "\n";
            }
        };

    // Sort the events by viewing empire, then ALL_EMPIRES and then other empires.
    show_events_for_empire(viewing_empire_id);
    show_events_for_empire(ALL_EMPIRES);
    show_events_for_empire(boost::none);

    return ss.str();
}
예제 #2
0
boost::statechart::result PlayingGame::react(const EndGame& msg) {
    if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) PlayingGame.EndGame";
    Message::EndGameReason reason;
    std::string reason_player_name;
    ExtractMessageData(msg.m_message, reason, reason_player_name);
    std::string reason_message;
    bool error = false;
    switch (reason) {
    case Message::LOCAL_CLIENT_DISCONNECT:
        Client().EndGame(true);
        reason_message = UserString("SERVER_LOST");
        break;
    case Message::PLAYER_DISCONNECT:
        Client().EndGame(true);
        reason_message = boost::io::str(FlexibleFormat(UserString("PLAYER_DISCONNECTED")) % reason_player_name);
        error = true;
        break;
    case Message::YOU_ARE_ELIMINATED:
        Client().EndGame(true);
        reason_message = UserString("PLAYER_DEFEATED");
        break;
    }
    ClientUI::MessageBox(reason_message, error);
    return transit<IntroMenu>();
}
예제 #3
0
bool SpecialsPanel::EventFilter(GG::Wnd* w, const GG::WndEvent& event) {
    if (event.Type() != GG::WndEvent::RClick)
        return false;
    const GG::Pt& pt = event.Point();

    for (std::map<std::string, StatisticIcon*>::const_iterator it = m_icons.begin();
            it != m_icons.end(); ++it)
    {
        if (it->second != w)
            continue;

        std::string popup_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % UserString(it->first));

        GG::MenuItem menu_contents;
        menu_contents.next_level.push_back(GG::MenuItem(popup_label, 1, false, false));
        GG::PopupMenu popup(pt.x, pt.y, ClientUI::GetFont(), menu_contents, ClientUI::TextColor(),
                            ClientUI::WndOuterBorderColor(), ClientUI::WndColor(), ClientUI::EditHiliteColor());

        if (!popup.Run() || popup.MenuID() != 1) {
            return false;
            break;
        }

        ClientUI::GetClientUI()->ZoomToSpecial(it->first);
        return true;
    }
    return false;
}
예제 #4
0
std::string IncapacitationEvent::CombatLogDescription(int viewing_empire_id) const {
    std::shared_ptr<const UniverseObject> object = GetUniverseObject(object_id);
    std::string template_str, object_str;
    int owner_id = object_owner_id;

    if (!object && object_id < 0) {
        template_str = UserString("ENC_COMBAT_FIGHTER_INCAPACITATED_STR");
        object_str = UserString("OBJ_FIGHTER");

    } else if (!object) {
        template_str = UserString("ENC_COMBAT_UNKNOWN_DESTROYED_STR");
        object_str = UserString("ENC_COMBAT_UNKNOWN_OBJECT");

    } else if (object->ObjectType() == OBJ_PLANET) {
        template_str = UserString("ENC_COMBAT_PLANET_INCAPACITATED_STR");
        object_str = PublicNameLink(viewing_empire_id, object_id);

    } else {    // ships or other to-be-determined objects...
        template_str = UserString("ENC_COMBAT_DESTROYED_STR");
        object_str = PublicNameLink(viewing_empire_id, object_id);
    }

    std::string owner_string = " ";
    if (const Empire* owner = GetEmpire(owner_id))
        owner_string += owner->Name() + " ";

    std::string object_link = FighterOrPublicNameLink(viewing_empire_id, object_id, object_owner_id);

    return str(FlexibleFormat(template_str) % owner_string % object_link);
}
예제 #5
0
std::string WeaponFireEvent::CombatLogDetails(int viewing_empire_id) const {
    const std::string& template_str = UserString("ENC_COMBAT_ATTACK_DETAILS");

    if (shield >= 0)
        return str(FlexibleFormat(template_str)
                   % ShipPartLink(weapon_name)
                   % power
                   % shield
                   % damage);
    else
        return str(FlexibleFormat(template_str)
                   % ShipPartLink(weapon_name)
                   % power
                   % UserString("ENC_COMBAT_SHIELD_PIERCED")
                   % damage);
}
예제 #6
0
bool SpecialsPanel::EventFilter(GG::Wnd* w, const GG::WndEvent& event) {
    if (event.Type() != GG::WndEvent::RClick)
        return false;
    const GG::Pt& pt = event.Point();

    for (const std::map<std::string, StatisticIcon*>::value_type& entry : m_icons)
    {
        if (entry.second != w)
            continue;

        bool retval = false;
        auto zoom_action = [&entry, &retval]() {
            retval = true;
            ClientUI::GetClientUI()->ZoomToSpecial(entry.first);
        };

        CUIPopupMenu popup(pt.x, pt.y);
        std::string popup_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % UserString(entry.first));

        popup.AddMenuItem(GG::MenuItem(popup_label, false, false, zoom_action));

        popup.Run();
        return retval;
    }
    return false;
}
예제 #7
0
bool PopulationPanel::EventFilter(GG::Wnd* w, const GG::WndEvent& event) {
    if (event.Type() != GG::WndEvent::RClick)
        return false;
    const GG::Pt& pt = event.Point();

    TemporaryPtr<const PopCenter> pc = GetPopCenter();
    if (!pc)
        return false;

    const std::string& species_name = pc->SpeciesName();
    if (species_name.empty())
        return false;

    if (m_meter_stats[0].second != w)
        return false;

    GG::MenuItem menu_contents;

    std::string popup_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % UserString(species_name));
    menu_contents.next_level.push_back(GG::MenuItem(popup_label, 1, false, false));
    CUIPopupMenu popup(pt.x, pt.y, menu_contents);

    if (!popup.Run() || popup.MenuID() != 1)
        return false;

    ClientUI::GetClientUI()->ZoomToSpecies(species_name);
    return true;
}
예제 #8
0
boost::statechart::result PlayingGame::react(const EndGame& msg) {
    if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.EndGame";
    Message::EndGameReason reason;
    std::string reason_player_name;
    ExtractMessageData(msg.m_message, reason, reason_player_name);
    std::string reason_message;
    bool error = false;
    switch (reason) {
    case Message::LOCAL_CLIENT_DISCONNECT:
        Client().EndGame(true);
        reason_message = UserString("SERVER_LOST");
        break;
    case Message::PLAYER_DISCONNECT:
        Client().EndGame(true);
        reason_message = boost::io::str(FlexibleFormat(UserString("PLAYER_DISCONNECTED")) % reason_player_name);
        error = true;
        break;
    case Message::YOU_ARE_ELIMINATED:
        Client().EndGame(true);
        reason_message = UserString("PLAYER_DEFEATED");
        break;
    }
    ClientUI::MessageBox(reason_message, error);
    Client().Remove(Client().GetClientUI()->GetMapWnd());
    Client().GetClientUI()->GetMapWnd()->RemoveWindows();
    Client().Networking().SetHostPlayerID(Networking::INVALID_PLAYER_ID);
    Client().Networking().SetPlayerID(Networking::INVALID_PLAYER_ID);
    return transit<IntroMenu>();
}
예제 #9
0
bool ResourcePanel::EventFilter(GG::Wnd* w, const GG::WndEvent& event) {
    if (event.Type() != GG::WndEvent::RClick)
        return false;
    const GG::Pt& pt = event.Point();

    MeterType meter_type = INVALID_METER_TYPE;
    for (const auto& meter_stat : m_meter_stats) {
        if (meter_stat.second.get() == w) {
            meter_type = meter_stat.first;
            break;
        }
    }

    if (meter_type == INVALID_METER_TYPE)
        return false;

    std::string meter_string = boost::lexical_cast<std::string>(meter_type);
    std::string meter_title;
    if (UserStringExists(meter_string))
        meter_title = UserString(meter_string);
    if (meter_title.empty())
        return false;

    bool retval = false;
    auto pedia_zoom_to_article_action = [&meter_string, &retval]() {
        retval = ClientUI::GetClientUI()->ZoomToMeterTypeArticle(meter_string); };

    auto popup = GG::Wnd::Create<CUIPopupMenu>(pt.x, pt.y);
    std::string popup_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % meter_title);
    popup->AddMenuItem(GG::MenuItem(popup_label, false, false, pedia_zoom_to_article_action));
    popup->Run();

    return retval;
}
예제 #10
0
////////////////////////////////////////////////////////////
// PlayingTurn
////////////////////////////////////////////////////////////
PlayingTurn::PlayingTurn(my_context ctx) :
    Base(ctx)
{
    if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) PlayingTurn";
    Client().Register(Client().m_ui->GetMapWnd());
    Client().m_ui->GetMapWnd()->InitTurn();
    // TODO: reselect last fleet if stored in save game ui data?
    Client().m_ui->GetMessageWnd()->HandleGameStatusUpdate(
        boost::io::str(FlexibleFormat(UserString("TURN_BEGIN")) % CurrentTurn()) + "\n");
    Client().m_ui->GetMessageWnd()->HandlePlayerStatusUpdate(Message::PLAYING_TURN, Client().PlayerID());
    Client().m_ui->GetPlayerListWnd()->Refresh();
    Client().m_ui->GetPlayerListWnd()->HandlePlayerStatusUpdate(Message::PLAYING_TURN, Client().PlayerID());
    Client().m_ui->GetMapWnd()->EnableOrderIssuing(Client().EmpireID() != ALL_EMPIRES);

    // if not controlling an empire, the player (observer) can't do anything
    // other than waiting for more turn updates.  Turn updates received when not
    // in WaitingForTurnData state will be ignored, and the Turn button is
    // disabled.  So, posting TurnEnded here has the effect of automatically
    // keeping observers in the WaitingForTurnData state so they can receive
    // updates from the server.
    if (Client().EmpireID() == ALL_EMPIRES)
        post_event(TurnEnded());

    else if (GetOptionsDB().Get<bool>("auto-advance-first-turn")) {
        static bool once = true;
        if (once) {
            post_event(AutoAdvanceFirstTurn());
            once = false;
        }
    }
}
예제 #11
0
boost::statechart::result PlayingGame::react(const EndGame& msg) {
    if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.EndGame";
    Message::EndGameReason reason;
    std::string reason_player_name;
    ExtractMessageData(msg.m_message, reason, reason_player_name);
    std::string reason_message;
    bool error = false;
    switch (reason) {
    case Message::LOCAL_CLIENT_DISCONNECT:
        Client().EndGame(true);
        reason_message = UserString("SERVER_LOST");
        break;
    case Message::PLAYER_DISCONNECT:
        Client().EndGame(true);
        reason_message = boost::io::str(FlexibleFormat(UserString("PLAYER_DISCONNECTED")) % reason_player_name);
        error = true;
        break;
    }
    //Note: Any transit<> transition must occur before the MessageBox().
    // MessageBox blocks and can allow other events to transit<> to a new state
    // which makes this transit fatal.
    boost::statechart::result retval = transit<IntroMenu>();
    ClientUI::MessageBox(reason_message, error);
    return retval;
}
예제 #12
0
파일: Fleet.cpp 프로젝트: adesst/freeorion
std::string Fleet::GenerateFleetName(const std::vector<int>& ship_ids, int new_fleet_id) {
    // TODO: Change returned name based on passed ship designs.  eg. return "colony fleet" if
    // ships are colony ships, or "battle fleet" if ships are armed.
    if (new_fleet_id == INVALID_OBJECT_ID)
        return UserString("NEW_FLEET_NAME_NO_NUMBER");

    return boost::io::str(FlexibleFormat(UserString("NEW_FLEET_NAME")) % boost::lexical_cast<std::string>(new_fleet_id));
}
예제 #13
0
std::string HullType::StatDescription() const {
    std::string retval = 
        str(FlexibleFormat(UserString("HULL_DESC"))
            % m_starlane_speed
            % m_fuel
            % m_battle_speed
            % m_structure);
    return retval;
}
예제 #14
0
std::string FighterAttackedEvent::CombatLogDescription(int viewing_empire_id) const {
    std::string attacked_by = FighterOrPublicNameLink(viewing_empire_id, attacked_by_object_id, attacker_owner_empire_id);
    std::string empire_coloured_attacked_fighter = EmpireColorWrappedText(attacked_owner_id, UserString("OBJ_FIGHTER"));

    const std::string& template_str = UserString("ENC_COMBAT_ATTACK_SIMPLE_STR");

    return str(FlexibleFormat(template_str)
                                % attacked_by
                                % empire_coloured_attacked_fighter);
}
예제 #15
0
bool PopulationPanel::EventFilter(GG::Wnd* w, const GG::WndEvent& event) {
    if (event.Type() != GG::WndEvent::RClick)
        return false;
    const GG::Pt& pt = event.Point();

    MeterType meter_type = INVALID_METER_TYPE;
    for (const std::pair<MeterType, StatisticIcon*>& meter_stat : m_meter_stats) {
        if (meter_stat.second == w) {
            meter_type = meter_stat.first;
            break;
        }
    }
    if (meter_type == INVALID_METER_TYPE)
        return false;

    std::string meter_string = boost::lexical_cast<std::string>(meter_type);
    std::string meter_title;
    if (UserStringExists(meter_string))
        meter_title = UserString(meter_string);

    std::string species_name;
    bool retval = false;

    CUIPopupMenu popup(pt.x, pt.y);
    std::shared_ptr<const PopCenter> pc = GetPopCenter();
    if (meter_type == METER_POPULATION && pc) {
        species_name = pc->SpeciesName();
        if (!species_name.empty()) {
            auto zoom_species_action = [&retval, &species_name]() { retval = ClientUI::GetClientUI()->ZoomToSpecies(species_name); };
            std::string species_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % UserString(species_name));
            popup.AddMenuItem(GG::MenuItem(species_label, false, false, zoom_species_action));
        }
    }

    if (!meter_title.empty()) {
        auto pedia_meter_type_action = [&retval, &meter_string]() { retval = ClientUI::GetClientUI()->ZoomToMeterTypeArticle(meter_string); };
        std::string popup_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % meter_title);
        popup.AddMenuItem(GG::MenuItem(popup_label, false, false, pedia_meter_type_action));
    }

    popup.Run();
    return retval;
}
예제 #16
0
void AIClientApp::HandlePythonAICrash() {
    // Note: If python crashed during initialization then the AI has not
    // been associated with a PlayerConnection so the server will not
    // know the AI's PlayerName.
    std::stringstream err_msg;
    err_msg << "AIClientApp failed due to error in python AI code for " << PlayerName() << ".  Exiting Soon.";
    ErrorLogger() << err_msg.str() << " id = " << PlayerID();
    Networking().SendMessage(
        ErrorMessage(str(FlexibleFormat(UserString("ERROR_PYTHON_AI_CRASHED")) % PlayerName()) , true));
}
예제 #17
0
void CombatLogWnd::CombatLogWndImpl::SetLog(int log_id) {
    if (!CombatLogAvailable(log_id)) {
        ErrorLogger() << "Couldn't find combat log with id: " << log_id;
        return;
    }

    m_wnd.DeleteChildren();
    GG::Layout* layout = new GG::Layout(m_wnd.UpperLeft().x, m_wnd.UpperLeft().y
                                        , m_wnd.Width(), m_wnd.Height()
                                        , 1, 1 ///< numrows, numcols
                                        , 0, 0 ///< wnd margin, cell margin
                                       );
    m_wnd.SetLayout(layout);

    const CombatLog& log = GetCombatLog(log_id);
    int client_empire_id = HumanClientApp::GetApp()->EmpireID();

    // Write Header text
    DebugLogger() << "Setting log with " << log.combat_events.size() << " events";

    TemporaryPtr<const System> system = GetSystem(log.system_id);
    const std::string& sys_name = (system ? system->PublicName(client_empire_id) : UserString("ERROR"));

    AddRow(DecorateLinkText(str(FlexibleFormat(UserString("ENC_COMBAT_LOG_DESCRIPTION_STR"))
                                % LinkTaggedIDText(VarText::SYSTEM_ID_TAG, log.system_id, sys_name)
                                % log.turn) + "\n"
                           ));
    AddRow(DecorateLinkText(UserString("COMBAT_INITIAL_FORCES")));
    AddRow(DecorateLinkText(CountsToText(CountByOwner(log.empire_ids, log.object_ids))));

    std::stringstream summary_text;
    summary_text << std::endl << UserString("COMBAT_SUMMARY_DESTROYED")
                 << std::endl << CountsToText(CountByOwner(log.empire_ids, log.destroyed_object_ids));
    AddRow(DecorateLinkText(summary_text.str()));

    // Write Logs
    for (std::vector<CombatEventPtr>::const_iterator it = log.combat_events.begin();
         it != log.combat_events.end(); ++it) {
        DebugLogger() << "event debug info: " << it->get()->DebugString();

        std::vector<GG::Wnd *> flat_logs =
            MakeCombatLogPanel(m_font->SpaceWidth()*10, client_empire_id, *it);
        for (std::vector<GG::Wnd *>::iterator log_it = flat_logs.begin();
             log_it != flat_logs.end(); ++log_it) {
            AddRow(*log_it);
        }
    }

    // Add a dummy row that the layout manager can use to add space.
    AddRow(DecorateLinkText(""));
    layout->SetRowStretch(layout->Rows() - 1, 1);

    HandleWndChanged();
}
예제 #18
0
std::string StealthChangeEvent::StealthChangeEventDetail::CombatLogDescription(int viewing_empire_id) const {

    std::string attacker_link = FighterOrPublicNameLink(viewing_empire_id, attacker_id, attacker_empire_id);
    std::string target_link = FighterOrPublicNameLink(viewing_empire_id, target_id, target_empire_id);
    std::string empire_link = EmpireLink(target_empire_id);
    const std::string& template_str = UserString("ENC_COMBAT_STEALTH_DECLOAK_ATTACK");

    return str(FlexibleFormat(template_str)
               % attacker_link
               % target_link
               % empire_link);
}
예제 #19
0
boost::statechart::result PlayingTurn::react(const SaveGameComplete& msg) {
    TraceLogger(FSM) << "(HumanClientFSM) PlayingTurn.SaveGameComplete";

    std::string save_filename;
    int bytes_written;
    ExtractServerSaveGameCompleteMessageData(msg.m_message, save_filename, bytes_written);

    Client().GetClientUI().GetMessageWnd()->HandleGameStatusUpdate(
        boost::io::str(FlexibleFormat(UserString("SERVER_SAVE_COMPLETE")) % save_filename % bytes_written) + "\n");

    Client().SaveGameCompleted();
    return discard_event();
}
예제 #20
0
std::string WeaponFireEvent::CombatLogDescription(int viewing_empire_id) const {
    std::string attacker_link = FighterOrPublicNameLink(viewing_empire_id, attacker_id, attacker_owner_id);
    std::string target_link = FighterOrPublicNameLink(viewing_empire_id, target_id, target_owner_id);

    const std::string& template_str = UserString("ENC_COMBAT_ATTACK_STR");

    return str(FlexibleFormat(template_str)
               % attacker_link
               % target_link
               % damage
               % bout
               % round);
}
예제 #21
0
std::string WeaponsPlatformEvent::CombatLogDescription(int viewing_empire_id) const {
    if (events.empty())
        return "";

    std::vector<std::string> damaged_target_links;
    std::vector<std::string> undamaged_target_links;

    for (const auto& target : events) {
        if (target.second.empty())
            continue;

        const auto& fire_event(*target.second.begin());
        std::string target_public_name(
            FighterOrPublicNameLink(viewing_empire_id, target.first,
                                    fire_event->target_owner_id));

        double damage = 0.0f;
        for (auto attack_it : target.second) {
            damage += attack_it->damage;
        }

        if (damage <= 0.0f) {
            undamaged_target_links.push_back(target_public_name);

        } else {
            damaged_target_links.push_back(
                str(FlexibleFormat(UserString("ENC_COMBAT_PLATFORM_TARGET_AND_DAMAGE"))
                    % target_public_name % damage));
        }
    }

    std::string desc = "";

    const std::vector<std::string> attacker_link(
        1, FighterOrPublicNameLink(viewing_empire_id, attacker_id, attacker_owner_id));

    if (!damaged_target_links.empty() ) {
        desc += FlexibleFormatList(attacker_link, damaged_target_links,
                                   UserString("ENC_COMBAT_PLATFORM_DAMAGE_MANY_EVENTS"),
                                   UserString("ENC_COMBAT_PLATFORM_DAMAGE_1_EVENTS")).str();

        if (!undamaged_target_links.empty())
            desc += "\n";
    }
    if (!undamaged_target_links.empty()) {
        desc += FlexibleFormatList(attacker_link, undamaged_target_links,
                                   UserString("ENC_COMBAT_PLATFORM_NO_DAMAGE_MANY_EVENTS"),
                                   UserString("ENC_COMBAT_PLATFORM_NO_DAMAGE_1_EVENTS")).str();
    }
    return desc;
}
예제 #22
0
std::string FighterLaunchEvent::CombatLogDescription(int viewing_empire_id) const {
    std::string launched_from_link = PublicNameLink(viewing_empire_id, launched_from_id);
    std::string empire_coloured_fighter = EmpireColorWrappedText(fighter_owner_empire_id, UserString("OBJ_FIGHTER"));

    // launching negative fighters indicates recovery of them by the ship
    const std::string& template_str = (number_launched >= 0 ?
                                       UserString("ENC_COMBAT_LAUNCH_STR") :
                                       UserString("ENC_COMBAT_RECOVER_STR"));

   return str(FlexibleFormat(template_str)
              % launched_from_link
              % empire_coloured_fighter
              % std::abs(number_launched));
}
예제 #23
0
boost::statechart::result WaitingForTurnData::react(const SaveGameComplete& msg) {
    if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) WaitingForTurnData.SaveGameComplete";

    std::string save_filename;
    int bytes_written;
    ExtractMessageData(msg.m_message, save_filename, bytes_written);


    Client().GetClientUI()->GetMessageWnd()->HandleGameStatusUpdate(
        boost::io::str(FlexibleFormat(UserString("SERVER_SAVE_COMPLETE")) % save_filename % bytes_written) + "\n");

    DebugLogger() << "Save Complete on Server";
    return discard_event();
}
예제 #24
0
void BuildingIndicator::Refresh() {
    if (!s_scanline_shader && GetOptionsDB().Get<bool>("UI.system-fog-of-war")) {
        boost::filesystem::path shader_path = GetRootDataDir() / "default" / "shaders" / "scanlines.frag";
        std::string shader_text;
        ReadFile(shader_path, shader_text);
        s_scanline_shader = boost::shared_ptr<ShaderProgram>(
            ShaderProgram::shaderProgramFactory("", shader_text));
    }

    SetBrowseModeTime(GetOptionsDB().Get<int>("UI.tooltip-delay"));

    TemporaryPtr<const Building> building = GetBuilding(m_building_id);
    if (!building)
        return;

    ClearBrowseInfoWnd();

    if (m_graphic) {
        delete m_graphic;
        m_graphic = 0;
    }
    if (m_scrap_indicator) {
        delete m_scrap_indicator;
        m_scrap_indicator = 0;
    }

    if (const BuildingType* type = GetBuildingType(building->BuildingTypeName())) {
        boost::shared_ptr<GG::Texture> texture = ClientUI::BuildingIcon(type->Name());
        m_graphic = new GG::StaticGraphic(texture, GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE);
        AttachChild(m_graphic);

        std::string desc = UserString(type->Description());
        if (building->GetMeter(METER_STEALTH))
            desc = UserString("METER_STEALTH") + boost::io::str(boost::format(": %3.1f\n\n") % building->GetMeter(METER_STEALTH)->Current()) + desc;
        if (GetOptionsDB().Get<bool>("UI.autogenerated-effects-descriptions") && !type->Effects().empty())
            desc += boost::io::str(FlexibleFormat(UserString("ENC_EFFECTS_STR")) % AutoGeneratedDescription(type->Effects()));

        SetBrowseInfoWnd(boost::shared_ptr<GG::BrowseInfoWnd>(
            new IconTextBrowseWnd(texture, UserString(type->Name()), desc)));
    }

    if (building && building->OrderedScrapped()) {
        boost::shared_ptr<GG::Texture> scrap_texture = ClientUI::GetTexture(ClientUI::ArtDir() / "misc" / "scrapped.png", true);
        m_scrap_indicator = new GG::StaticGraphic(scrap_texture, GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE);
        AttachChild(m_scrap_indicator);
    }

    DoLayout();
}
예제 #25
0
////////////////////////////////////////////////////////////
// PlayingTurn
////////////////////////////////////////////////////////////
PlayingTurn::PlayingTurn(my_context ctx) :
    Base(ctx)
{
    if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingTurn";
    Client().Register(Client().GetClientUI()->GetMapWnd());
    Client().GetClientUI()->GetMapWnd()->InitTurn();
    Client().GetClientUI()->GetMapWnd()->RegisterWindows(); // only useful at game start but InitTurn() takes a long time, don't want to display windows before content is ready.  could go in WaitingForGameStart dtor but what if it is given e.g. an error reaction?
    // TODO: reselect last fleet if stored in save game ui data?
    Client().GetClientUI()->GetMessageWnd()->HandleGameStatusUpdate(
        boost::io::str(FlexibleFormat(UserString("TURN_BEGIN")) % CurrentTurn()) + "\n");
    Client().GetClientUI()->GetMessageWnd()->HandlePlayerStatusUpdate(Message::PLAYING_TURN, Client().PlayerID());
    Client().GetClientUI()->GetPlayerListWnd()->Refresh();
    Client().GetClientUI()->GetPlayerListWnd()->HandlePlayerStatusUpdate(Message::PLAYING_TURN, Client().PlayerID());

    if (Client().GetApp()->GetClientType() != Networking::CLIENT_TYPE_HUMAN_OBSERVER)
        Client().GetClientUI()->GetMapWnd()->EnableOrderIssuing(true);

    if (Client().GetApp()->GetClientType() == Networking::CLIENT_TYPE_HUMAN_OBSERVER) {
        // observers can't do anything but wait for the next update, and need to
        // be back in WaitingForTurnData, so posting TurnEnded here has the effect
        // of keeping observers in the WaitingForTurnData state so they can receive
        // updates from the server.
        post_event(TurnEnded());

    } else if (Client().GetApp()->GetClientType() == Networking::CLIENT_TYPE_HUMAN_PLAYER) {
        if (Client().GetClientUI()->GetMapWnd()->AutoEndTurnEnabled()) {
            // if in-game-GUI auto turn advance enabled, set auto turn counter to 1
            Client().InitAutoTurns(1);
        }

        if (Client().AutoTurnsLeft() <= 0 &&
            GetOptionsDB().Get<bool>("auto-quit"))
        {
            // if no auto turns left, and supposed to quit after that, quit
            DebugLogger() << "auto-quit ending game.";
            std::cout << "auto-quit ending game." << std::endl;
            Client().EndGame(true);
            throw HumanClientApp::CleanQuit();
        }

        // if there are still auto turns left, advance the turn automatically,
        // and decrease the auto turn counter
        if (Client().AutoTurnsLeft() > 0) {
            post_event(AdvanceTurn());
            Client().DecAutoTurns();
        }
    }
}
예제 #26
0
std::string FightersAttackFightersEvent::CombatLogDescription(int viewing_empire_id) const {
    if (events.empty())
        return "";

    const auto& events_to_show = events;
    auto num_events_remaining = events.size();
    std::stringstream ss;

    // Use show_events_for_empire to show events in this order: viewing empire, ALL_EMPIRES and
    // then the remainder.
    auto show_events_for_empire =
        [&ss, &num_events_remaining, &events_to_show, &viewing_empire_id]
        (boost::optional<int> show_attacker) {
            int attacker_empire;
            int target_empire;
            for (const auto& index_and_event : events_to_show) {
                std::tie(attacker_empire, target_empire) = index_and_event.first;

                // Skip if this is not the particular attacker requested
                if (show_attacker && *show_attacker != attacker_empire)
                    continue;

                // Skip if no particular attacker was requested and this empire is the viewing
                // empire or ALL_EMPIRES
                if (!show_attacker && (attacker_empire == viewing_empire_id || attacker_empire == ALL_EMPIRES))
                    continue;

                auto count = std::to_string(index_and_event.second);
                const auto&& attacker_link = FighterOrPublicNameLink(
                    viewing_empire_id, INVALID_OBJECT_ID, attacker_empire);
                const auto&& target_link = FighterOrPublicNameLink(
                    viewing_empire_id, INVALID_OBJECT_ID, target_empire);
                const std::string& template_str = UserString("ENC_COMBAT_ATTACK_REPEATED_STR");

                ss << str(FlexibleFormat(template_str) % count % attacker_link % target_link);
                if (--num_events_remaining > 0)
                    ss << "\n";
            }
        };

    // Sort the events by viewing empire, then ALL_EMPIRES and then other empires.
    show_events_for_empire(viewing_empire_id);
    show_events_for_empire(ALL_EMPIRES);
    show_events_for_empire(boost::none);

    return ss.str();
}
예제 #27
0
boost::statechart::result PlayingTurn::react(const SaveGameComplete& msg) {
    TraceLogger(FSM) << "(HumanClientFSM) PlayingTurn.SaveGameComplete";

    std::string save_filename;
    int bytes_written;
    ExtractServerSaveGameCompleteMessageData(msg.m_message, save_filename, bytes_written);

    Client().GetClientUI().GetMessageWnd()->HandleGameStatusUpdate(
        boost::io::str(FlexibleFormat(UserString("SERVER_SAVE_COMPLETE")) % save_filename % bytes_written) + "\n");

    Client().SaveGameCompleted();

    // auto quit save has completed, close the app
    if (Client().GetApp()->GetClientType() == Networking::CLIENT_TYPE_HUMAN_PLAYER
        && Client().AutoTurnsLeft() <= 0
        && GetOptionsDB().Get<bool>("auto-quit"))
    {
        DebugLogger(FSM) << "auto-quit save completed, ending game.";
        Client().ExitApp(0);
    }

    return discard_event();
}
예제 #28
0
boost::statechart::result PlayingGame::react(const EndGame& msg) {
    TraceLogger(FSM) << "(HumanClientFSM) PlayingGame.EndGame";
    Message::EndGameReason reason;
    std::string reason_player_name;
    ExtractEndGameMessageData(msg.m_message, reason, reason_player_name);
    std::string reason_message;
    bool error = false;
    switch (reason) {
    case Message::LOCAL_CLIENT_DISCONNECT:
        reason_message = UserString("SERVER_LOST");
        break;
    case Message::PLAYER_DISCONNECT:
        reason_message = boost::io::str(FlexibleFormat(UserString("PLAYER_DISCONNECTED")) % reason_player_name);
        error = true;
        break;
    }

    // See reaction_transition_note.
    auto retval = discard_event();
    Client().ResetToIntro(true);
    ClientUI::MessageBox(reason_message, error);
    return retval;
}
예제 #29
0
void FieldIcon::RClick(const GG::Pt& pt, GG::Flags<GG::ModKey> mod_keys) {
    if (!Disabled())
        RightClickedSignal(m_field_id);

    GG::MenuItem menu_contents;

    TemporaryPtr<const Field> field = GetField(m_field_id);
    if (!field)
        return;
    const std::string& field_type_name = field->FieldTypeName();
    if (field_type_name.empty())
        return;

    std::string popup_label = boost::io::str(FlexibleFormat(UserString("ENC_LOOKUP")) % UserString(field_type_name));
    menu_contents.next_level.push_back(GG::MenuItem(popup_label, 1, false, false));
    GG::PopupMenu popup(pt.x, pt.y, ClientUI::GetFont(), menu_contents, ClientUI::TextColor(),
                        ClientUI::WndOuterBorderColor(), ClientUI::WndColor(), ClientUI::EditHiliteColor());

    if (!popup.Run() || popup.MenuID() != 1)
        return;

    ClientUI::GetClientUI()->ZoomToFieldType(field_type_name);
}
void SystemResourceSummaryBrowseWnd::UpdateAllocation(GG::Y& top) {
    // adds pairs of labels for allocation of resources in system, starting at vertical position \a top and
    // updates \a top to be the vertical position after the last entry
    for (unsigned int i = 0; i < m_allocation_labels_and_amounts.size(); ++i) {
        DeleteChild(m_allocation_labels_and_amounts[i].first);
        DeleteChild(m_allocation_labels_and_amounts[i].second);
    }
    m_allocation_labels_and_amounts.clear();

    TemporaryPtr<const System> system = GetSystem(m_system_id);
    if (!system || m_resource_type == INVALID_RESOURCE_TYPE)
        return;


    m_allocation = 0.0;


    // add label-value pair for each resource-consuming object in system to indicate amount of resource consumed
    std::vector<TemporaryPtr<const UniverseObject> > objects =
        Objects().FindObjects<const UniverseObject>(system->ContainedObjectIDs());

    for (std::vector<TemporaryPtr<const UniverseObject> >::const_iterator it = objects.begin();
         it != objects.end(); ++it)
    {
        TemporaryPtr<const UniverseObject> obj = *it;

        // display information only for the requested player
        if (m_empire_id != ALL_EMPIRES && !obj->OwnedBy(m_empire_id))
            continue;   // if m_empire_id == ALL_EMPIRES, display resource production for all empires.  otherwise, skip this resource production if it's not owned by the requested player


        std::string name = obj->Name();


        double allocation = ObjectResourceConsumption(obj, m_resource_type, m_empire_id);


        // don't add summary entries for objects that consume no resource.  (otherwise there would be a loooong pointless list of 0's
        if (allocation <= 0.0) {
            if (allocation < 0.0)
                ErrorLogger() << "object " << obj->Name() << " is reported having negative " << boost::lexical_cast<std::string>(m_resource_type) << " consumption";
            continue;
        }


        m_allocation += allocation;

        std::string amount_text = DoubleToString(allocation, 3, false);


        GG::Label* label = new CUILabel(name, GG::FORMAT_RIGHT);
        label->MoveTo(GG::Pt(GG::X0, top));
        label->Resize(GG::Pt(LabelWidth(), row_height));
        AttachChild(label);


        GG::Label* value = new CUILabel(amount_text);
        value->MoveTo(GG::Pt(LabelWidth(), top));
        value->Resize(GG::Pt(ValueWidth(), row_height));
        AttachChild(value);

        m_allocation_labels_and_amounts.push_back(std::pair<GG::Label*, GG::Label*>(label, value));

        top += row_height;
    }


    if (m_allocation_labels_and_amounts.empty()) {
        // add "blank" line to indicate no allocation
        GG::Label* label = new CUILabel(UserString("NOT_APPLICABLE"), GG::FORMAT_RIGHT);
        label->MoveTo(GG::Pt(GG::X0, top));
        label->Resize(GG::Pt(LabelWidth(), row_height));
        AttachChild(label);

        GG::Label* value = new CUILabel("");
        value->MoveTo(GG::Pt(LabelWidth(), top));
        value->Resize(GG::Pt(ValueWidth(), row_height));
        AttachChild(value);

        m_allocation_labels_and_amounts.push_back(std::pair<GG::Label*, GG::Label*>(label, value));

        top += row_height;
    }


    // set consumption / allocation label
    std::string resource_text = "";
    switch (m_resource_type) {
    case RE_INDUSTRY:
        resource_text = UserString("INDUSTRY_CONSUMPTION"); break;
    case RE_RESEARCH:
        resource_text = UserString("RESEARCH_CONSUMPTION"); break;
    case RE_TRADE:
        resource_text = UserString("TRADE_CONSUMPTION");    break;
    default:
        resource_text = UserString("UNKNOWN_VALUE_SYMBOL"); break;
    }

    std::string system_allocation_text = DoubleToString(m_allocation, 3, false);

    // for research only, local allocation makes no sense
    if (m_resource_type == RE_RESEARCH && m_allocation == 0.0)
        system_allocation_text = UserString("NOT_APPLICABLE");


    m_allocation_label->SetText(boost::io::str(FlexibleFormat(UserString("RESOURCE_ALLOCATION_TOOLTIP")) %
                                                              resource_text %
                                                              system_allocation_text));

    // height of label already added to top outside this function
}