int UniverseObject::AgeInTurns() const {
    if (m_created_on_turn == BEFORE_FIRST_TURN)
        return SINCE_BEFORE_TIME_AGE;
    if ((m_created_on_turn == INVALID_GAME_TURN) || (CurrentTurn() == INVALID_GAME_TURN))
        return INVALID_OBJECT_AGE;
    return CurrentTurn() - m_created_on_turn;
}
void HearthstoneLogTracker::CardReturned( Player player, const string& cardId ) {
  DBG( "Card returned %s on turn %d: %s", PLAYER_NAMES[ player ], CurrentTurn(), cardId.c_str() );
  // Make sure we remove the "Choose One"-cards from the history
  // if we decide to withdraw them after a second of thought
  if( !mCardHistoryList.empty() &&
      mCardHistoryList.back().turn == CurrentTurn() &&
      mCardHistoryList.back().player == player &&
      mCardHistoryList.back().cardId == cardId )
  {
    mCardHistoryList.pop_back();
  }
}
Exemple #3
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;
        }
    }
}
Exemple #4
0
int SitRepPanel::NumVisibleSitrepsThisTurn() const {
    int count = 0;

    int client_empire_id = HumanClientApp::GetApp()->EmpireID();

    // which empires to count sitreps for?
    std::vector<int> empire_ids;
    if (HumanClientApp::GetApp()->Empires().Lookup(client_empire_id)) {
        empire_ids.push_back(client_empire_id);
    } else {
        for (EmpireManager::const_iterator it = Empires().begin(); it != Empires().end(); ++it)
            empire_ids.push_back(it->first);
    }

    for (std::vector<int>::const_iterator empire_it = empire_ids.begin();
         empire_it != empire_ids.end(); ++empire_it)
    {
        const Empire* empire = HumanClientApp::GetApp()->Empires().Lookup(*empire_it);
        if (!empire)
            continue;

        for (Empire::SitRepItr sitrep_it = empire->SitRepBegin(); sitrep_it != empire->SitRepEnd(); ++sitrep_it) {
            if (CurrentTurn() != sitrep_it->GetTurn())
                continue;
            if (m_hidden_sitrep_templates.find(sitrep_it->GetTemplateString()) != m_hidden_sitrep_templates.end())
                continue;
            ++count;
        }
    }
    return count;
}
    int IssueCreateShipDesignOrder(const std::string& name, const std::string& description,
                                   const std::string& hull, const std::vector<std::string> parts,
                                   const std::string& icon, const std::string& model, bool nameDescInStringTable)
    {
        if (name.empty() || description.empty() || hull.empty()) {
            Logger().errorStream() << "AIInterface::IssueCreateShipDesignOrderOrder : passed an empty name, description, or hull.";
            return 0;
        }
        if (!ShipDesign::ValidDesign(hull, parts)) {
            Logger().errorStream() << "AIInterface::IssueCreateShipDesignOrderOrder : pass a hull and parts that do not make a valid ShipDesign";
            return 0;
        }

        int empire_id = AIClientApp::GetApp()->EmpireID();
        int current_turn = CurrentTurn();

        // create design from stuff chosen in UI
        ShipDesign* design = new ShipDesign(name, description, current_turn, ClientApp::GetApp()->EmpireID(),
                                            hull, parts, icon, model, nameDescInStringTable);

        if (!design) {
            Logger().errorStream() << "AIInterface::IssueCreateShipDesignOrderOrder failed to create a new ShipDesign object";
            return 0;
        }

        int new_design_id = AIClientApp::GetApp()->GetNewDesignID();
        AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new ShipDesignOrder(empire_id, new_design_id, *design)));
        delete design;

        return 1;
    }
int ResourceCenter::TurnsSinceFocusChange() const {
    if (m_last_turn_focus_changed == INVALID_GAME_TURN)
        return 0;
    int current_turn = CurrentTurn();
    if (current_turn == INVALID_GAME_TURN)
        return 0;
    return current_turn - m_last_turn_focus_changed;
}
Exemple #7
0
double Planet::NextTurnCurrentMeterValue(MeterType type) const
{
    MeterType max_meter_type = INVALID_METER_TYPE;
    switch (type) {
    case METER_TARGET_POPULATION:
    case METER_TARGET_HEALTH:
    case METER_POPULATION:
    case METER_HEALTH:
    case METER_FOOD_CONSUMPTION:
        return PopCenterNextTurnMeterValue(type);
        break;
    case METER_TARGET_FARMING:
    case METER_TARGET_INDUSTRY:
    case METER_TARGET_RESEARCH:
    case METER_TARGET_TRADE:
    case METER_TARGET_MINING:
    case METER_TARGET_CONSTRUCTION:
    case METER_FARMING:
    case METER_INDUSTRY:
    case METER_RESEARCH:
    case METER_TRADE:
    case METER_MINING:
    case METER_CONSTRUCTION:
        return ResourceCenterNextTurnMeterValue(type);
        break;
    case METER_SHIELD:  max_meter_type = METER_MAX_SHIELD;  break;
    case METER_TROOPS:  max_meter_type = METER_MAX_TROOPS;  break;
    case METER_DEFENSE: max_meter_type = METER_MAX_DEFENSE; break;
        break;
    default:
        return UniverseObject::NextTurnCurrentMeterValue(type);
    }

    const Meter* meter = GetMeter(type);
    if (!meter) {
        throw std::invalid_argument("Planet::NextTurnCurrentMeterValue passed meter type that the Planet does not have, but should.");
    }
    double current_meter_value = meter->Current();

    const Meter* max_meter = GetMeter(max_meter_type);
    if (!max_meter) {
        throw std::runtime_error("Planet::NextTurnCurrentMeterValue dealing with invalid meter type");
    }
    double max_meter_value = max_meter->Current();

    // being attacked prevents meter growth
    if (LastTurnAttackedByShip() >= CurrentTurn()) {
        return std::min(current_meter_value, max_meter_value);
    }

    // currently meter growth is one per turn.
    return std::min(current_meter_value + 1.0, max_meter_value);
}
UniverseObject::UniverseObject(const std::string name, double x, double y) :
    StateChangedSignal(blocking_combiner<boost::signals2::optional_last_value<void> >(GetUniverse().UniverseObjectSignalsInhibited())),
    m_name(name),
    m_id(INVALID_OBJECT_ID),
    m_x(x),
    m_y(y),
    m_owner_empire_id(ALL_EMPIRES),
    m_system_id(INVALID_OBJECT_ID),
    m_meters(),
    m_created_on_turn(INVALID_GAME_TURN)
{
    m_created_on_turn = CurrentTurn();
}
Exemple #9
0
UniverseObject::UniverseObject() :
    StateChangedSignal(GetUniverse().UniverseObjectSignalsInhibited()),
    m_name(""),
    m_id(INVALID_OBJECT_ID),
    m_x(INVALID_POSITION),
    m_y(INVALID_POSITION),
    m_owner_empire_id(ALL_EMPIRES),
    m_system_id(INVALID_OBJECT_ID),
    m_meters(),
    m_created_on_turn(-1)
{
    //Logger().debugStream() << "UniverseObject::UniverseObject()";
    m_created_on_turn = CurrentTurn();
}
Exemple #10
0
float Ship::NextTurnCurrentMeterValue(MeterType type) const {
    const Meter* meter = UniverseObject::GetMeter(type);
    if (!meter)
        throw std::invalid_argument("Ship::NextTurnCurrentMeterValue passed meter type that the Ship does not have: " + boost::lexical_cast<std::string>(type));
    float current_meter_value = meter->Current();

    //if (type == METER_FUEL) {
    //    // todo: consider fleet movement or being stationary, which may partly replenish fuel
    //    // todo: consider fleet passing through or being in a supplied system, which replenishes fuel
    //}

    if (type == METER_SHIELD) {
        if (m_last_turn_active_in_combat >= CurrentTurn())
            return std::max(0.0f,   // battle just happened. shields limited to max shield, but don't regen
                            std::min(current_meter_value,
                                     UniverseObject::GetMeter(METER_MAX_SHIELD)->Current()));
        else                        // shields regneerate to max shield
            return UniverseObject::GetMeter(METER_MAX_SHIELD)->Current();
    }


    // ResourceCenter-like resource meter growth...

    MeterType target_meter_type = INVALID_METER_TYPE;
    switch (type) {
    case METER_TARGET_INDUSTRY:
    case METER_TARGET_RESEARCH:
    case METER_TARGET_TRADE:
        return current_meter_value;
        break;
    case METER_INDUSTRY:    target_meter_type = METER_TARGET_INDUSTRY;      break;
    case METER_RESEARCH:    target_meter_type = METER_TARGET_RESEARCH;      break;
    case METER_TRADE:       target_meter_type = METER_TARGET_TRADE;         break;
    default:
        return UniverseObject::NextTurnCurrentMeterValue(type);
    }

    const Meter* target_meter = UniverseObject::GetMeter(target_meter_type);
    if (!target_meter)
        throw std::runtime_error("Ship::NextTurnCurrentMeterValue dealing with invalid meter type: " + boost::lexical_cast<std::string>(type));
    float target_meter_value = target_meter->Current();

    // meter growth or decay towards target is one per turn.
    if (target_meter_value > current_meter_value)
        return std::min(current_meter_value + 1.0f, target_meter_value);
    else if (target_meter_value < current_meter_value)
        return std::max(target_meter_value, current_meter_value - 1.0f);
    else
        return current_meter_value;
}
Exemple #11
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();
        }
    }
}
Exemple #12
0
float Planet::NextTurnCurrentMeterValue(MeterType type) const {
    MeterType max_meter_type = INVALID_METER_TYPE;
    switch (type) {
    case METER_TARGET_POPULATION:
    case METER_POPULATION:
    case METER_TARGET_HAPPINESS:
    case METER_HAPPINESS:
        return PopCenterNextTurnMeterValue(type);
        break;
    case METER_TARGET_INDUSTRY:
    case METER_TARGET_RESEARCH:
    case METER_TARGET_TRADE:
    case METER_TARGET_CONSTRUCTION:
    case METER_INDUSTRY:
    case METER_RESEARCH:
    case METER_TRADE:
    case METER_CONSTRUCTION:
        return ResourceCenterNextTurnMeterValue(type);
        break;
    case METER_SHIELD:      max_meter_type = METER_MAX_SHIELD;          break;
    case METER_TROOPS:      max_meter_type = METER_MAX_TROOPS;          break;
    case METER_DEFENSE:     max_meter_type = METER_MAX_DEFENSE;         break;
    case METER_SUPPLY:      max_meter_type = METER_MAX_SUPPLY;          break;
        break;
    default:
        return UniverseObject::NextTurnCurrentMeterValue(type);
    }

    const Meter* meter = GetMeter(type);
    if (!meter) {
        throw std::invalid_argument("Planet::NextTurnCurrentMeterValue passed meter type that the Planet does not have, but should: " + boost::lexical_cast<std::string>(type));
    }
    float current_meter_value = meter->Current();

    const Meter* max_meter = GetMeter(max_meter_type);
    if (!max_meter) {
        throw std::runtime_error("Planet::NextTurnCurrentMeterValue dealing with invalid meter type: " + boost::lexical_cast<std::string>(type));
    }
    float max_meter_value = max_meter->Current();

    // being attacked prevents meter growth
    if (LastTurnAttackedByShip() >= CurrentTurn())
        return std::min(current_meter_value, max_meter_value);

    // currently meter growth is one per turn.
    return std::min(current_meter_value + 1.0f, max_meter_value);
}
Exemple #13
0
UniverseObject::UniverseObject(const std::string name, double x, double y,
                               const std::set<int>& owners/* = std::set<int>()*/) :
    StateChangedSignal(GetUniverse().UniverseObjectSignalsInhibited()),
    m_name(name),
    m_id(INVALID_OBJECT_ID),
    m_x(x),
    m_y(y),
    m_owner_empire_id(ALL_EMPIRES),
    m_system_id(INVALID_OBJECT_ID),
    m_meters(),
    m_created_on_turn(-1)
{
    //Logger().debugStream() << "UniverseObject::UniverseObject(" << name << ", " << x << ", " << y << ")";
    //if (m_x < 0.0 || GetUniverse().UniverseWidth() < m_x || m_y < 0.0 || GetUniverse().UniverseWidth() < m_y)
    //    throw std::invalid_argument("UniverseObject::UniverseObject : Attempted to create an object \"" + m_name + "\" off the map area.");
    m_created_on_turn = CurrentTurn();
}
Exemple #14
0
float Ship::NextTurnCurrentMeterValue(MeterType type) const {
    //if (type == METER_FUEL) {
    //    // todo: consider fleet movement or being stationary, which may partly replenish fuel
    //    // todo: consider fleet passing through or being in a supplied system, which replenishes fuel
    //} else if (type == METER_SUPPLY) {
    //    // todo: consider fleet passing through or being in a supplied system, which replenishes supplies
    //}
    if (type == METER_SHIELD) {
        if (m_last_turn_active_in_combat >= CurrentTurn())
            return std::max(0.0f,
                            std::min(UniverseObject::GetMeter(METER_SHIELD)->Current(),
                                     UniverseObject::GetMeter(METER_MAX_SHIELD)->Current()));
        else
            return UniverseObject::GetMeter(METER_MAX_SHIELD)->Current();
    }

    return UniverseObject::NextTurnCurrentMeterValue(type);
}
void ResourceCenter::SetFocus(const std::string& focus) {
    if (focus == m_focus)
        return;
    if (focus.empty()) {
        ClearFocus();
        return;
    }
    std::vector<std::string> avail_foci = AvailableFoci();
    if (std::find(avail_foci.begin(), avail_foci.end(), focus) != avail_foci.end()) {
        m_focus = focus;
        if (m_focus == m_focus_turn_initial)
            m_last_turn_focus_changed = m_last_turn_focus_changed_turn_initial;
        else
            m_last_turn_focus_changed = CurrentTurn();
        ResourceCenterChangedSignal();
        return;
    }
    ErrorLogger() << "ResourceCenter::SetFocus Exploiter!-- unavailable focus " << focus << " attempted to be set for object w/ dump string: " << Dump();
}
void HumanClientApp::StartTurn() {
    DebugLogger() << "HumanClientApp::StartTurn";

    const Empire *empire = GetEmpire(EmpireID());
    if (empire) {
        double RP = empire->ResourceOutput(RE_RESEARCH);
        double PP = empire->ResourceOutput(RE_INDUSTRY);
        int turn_number = CurrentTurn();
        float ratio = (RP/(PP+0.0001));
        const GG::Clr color = empire->Color();
        DebugLogger() << "Current Output (turn " << turn_number << ") RP/PP: " << ratio << " (" << RP << "/" << PP << ")";
        DebugLogger() << "EmpireColors: " << static_cast<int>(color.r)
                                          << " " << static_cast<int>(color.g)
                                          << " " << static_cast<int>(color.b)
                                          << " " << static_cast<int>(color.a);
    }

    ClientApp::StartTurn();
    m_fsm->process_event(TurnEnded());
}
Exemple #17
0
void UniverseObject::AddSpecial(const std::string& name, float capacity)
{ m_specials[name] = std::make_pair(CurrentTurn(), capacity); }
Exemple #18
0
void SitRepPanel::NextClicked() {
    m_showing_turn = std::min(CurrentTurn(), std::max(1, m_showing_turn + 1));
    Update();
}
Exemple #19
0
void SitRepPanel::Update() {
    Logger().debugStream() << "SitRepPanel::Update()";
    m_sitreps_lb->Clear();

    if (m_showing_turn == INVALID_GAME_TURN)
        this->SetName(UserString("SITREP_PANEL_TITLE"));
    else
        this->SetName(boost::io::str(FlexibleFormat(UserString("SITREP_PANEL_TITLE_TURN")) % m_showing_turn));


    // get sitrep entries for this client's player empire, or for all empires
    // if this client is an observer or moderator.
    // todo: double check that no-empire players are actually moderator or
    //       observers, instead of just passing the client empire id.
    std::list<SitRepEntry> currentTurnSitreps;
    GetTurnSitrepsFromEmpire(currentTurnSitreps, HumanClientApp::GetApp()->EmpireID());


    // order sitreps for display
    std::vector<SitRepEntry> orderedSitreps;
    std::vector<std::string> ordered_templates = OrderedSitrepTemplateStrings();
    for (std::vector<std::string>::const_iterator template_it = ordered_templates.begin();
         template_it != ordered_templates.end(); ++template_it)
    {
        for (std::list<SitRepEntry>::iterator sitrep_it = currentTurnSitreps.begin();
             sitrep_it != currentTurnSitreps.end(); sitrep_it++)
        {
            if (sitrep_it->GetTemplateString() == *template_it) {
                //Logger().debugStream() << "saving into orderedSitreps -  sitrep of template "<<*template_it<<" with full string "<< sitrep_it->GetText();
                orderedSitreps.push_back(*sitrep_it);
                //Logger().debugStream()<< "deleting above sitrep from currentTurnSitreps";
                sitrep_it = --currentTurnSitreps.erase(sitrep_it);
            }
        }
    }

    // copy remaining unordered sitreps
    for (std::list<SitRepEntry>::iterator sitrep_it = currentTurnSitreps.begin();
         sitrep_it != currentTurnSitreps.end(); sitrep_it++)
    { orderedSitreps.push_back(*sitrep_it); }

    // create UI rows for all sitrps
    GG::X width = m_sitreps_lb->Width() - 8;
    for (std::vector<SitRepEntry>::iterator sitrep_it = orderedSitreps.begin();
         sitrep_it != orderedSitreps.end(); sitrep_it++)
    { m_sitreps_lb->Insert(new SitRepRow(width, GG::Y(ClientUI::Pts()*2), *sitrep_it)); }

    // if at first turn, disable back button
    if (CurrentTurn() >= 1 && m_showing_turn > 1) {
        m_prev_turn_button->Disable(false);
    } else {
        m_prev_turn_button->Disable();
    }

    // if at current turn, disable forward button
    if (CurrentTurn() >= 1 && m_showing_turn < CurrentTurn()) {
        m_next_turn_button->Disable(false);
        m_last_turn_button->Disable(false);
    } else {
        m_next_turn_button->Disable();
        m_last_turn_button->Disable();
    }
}
void HumanClientApp::Autosave() {
    // autosave only on appropriate turn numbers, and when enabled for current
    // game type (single vs. multiplayer)
    int autosave_turns = GetOptionsDB().Get<int>("autosave.turns");
    if (autosave_turns < 1)
        return;     // avoid divide by zero
    if (CurrentTurn() % autosave_turns != 0 && CurrentTurn() != 1)
        return;     // turns divisible by autosave_turns, and first turn, have autosaves done
    if (m_single_player_game && !GetOptionsDB().Get<bool>("autosave.single-player"))
        return;
    if (!m_single_player_game && !GetOptionsDB().Get<bool>("autosave.multiplayer"))
        return;

    const char* legal_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-";

    // get empire name, filtered for filename acceptability
    int client_empire_id = EmpireID();
    const Empire* empire = GetEmpire(client_empire_id);
    std::string empire_name;
    if (empire)
        empire_name = empire->Name();
    else
        empire_name = UserString("OBSERVER");
    std::string::size_type first_good_empire_char = empire_name.find_first_of(legal_chars);
    if (first_good_empire_char == std::string::npos) {
        empire_name.clear();
    } else {
        std::string::size_type first_bad_empire_char = empire_name.find_first_not_of(legal_chars, first_good_empire_char);
        empire_name = empire_name.substr(first_good_empire_char, first_bad_empire_char - first_good_empire_char);
    }

    // get player name, also filtered
    std::string player_name;
    if (empire)
        player_name = empire->PlayerName();
    std::string::size_type first_good_player_char = player_name.find_first_of(legal_chars);
    if (first_good_player_char == std::string::npos) {
        player_name.clear();
    } else {
        std::string::size_type first_bad_player_char = player_name.find_first_not_of(legal_chars, first_good_player_char);
        player_name = player_name.substr(first_good_player_char, first_bad_player_char - first_good_player_char);
    }

    // select filename extension
    std::string extension;
    if (m_single_player_game)
        extension = SP_SAVE_FILE_EXTENSION;
    else
        extension = MP_SAVE_FILE_EXTENSION;

    // Add timestamp to autosave generated files
    std::string datetime_str = FilenameTimestamp();

    boost::filesystem::path autosave_dir_path(GetSaveDir() / "auto");

    std::string save_filename = boost::io::str(boost::format("FreeOrion_%s_%s_%04d_%s%s") % player_name % empire_name % CurrentTurn() % datetime_str % extension);
    boost::filesystem::path save_path(autosave_dir_path / save_filename);
    std::string path_string = PathString(save_path);

    try {
        // ensure autosave directory exists
        if (!exists(autosave_dir_path))
            boost::filesystem::create_directories(autosave_dir_path);
    } catch (const std::exception& e) {
        ErrorLogger() << "Autosave unable to check / create autosave directory: " << e.what();
        std::cerr << "Autosave unable to check / create autosave directory: " << e.what() << std::endl;
    }

    // check for and remove excess oldest autosaves
    int max_autosaves = GetOptionsDB().Get<int>("autosave.limit");
    RemoveOldestFiles(max_autosaves, autosave_dir_path);

    // create new save
    DebugLogger() << "Autosaving to: " << path_string;
    try {
        SaveGame(path_string);
    } catch (const std::exception& e) {
        ErrorLogger() << "Autosave failed: " << e.what();
        std::cerr << "Autosave failed: " << e.what() << std::endl;
    }
}
Exemple #21
0
Ship::Ship(int empire_id, int design_id, const std::string& species_name,
           int produced_by_empire_id/* = ALL_EMPIRES*/) :
    UniverseObject(),
    m_design_id(design_id),
    m_fleet_id(INVALID_OBJECT_ID),
    m_ordered_scrapped(false),
    m_ordered_colonize_planet_id(INVALID_OBJECT_ID),
    m_ordered_invade_planet_id(INVALID_OBJECT_ID),
    m_ordered_bombard_planet_id(INVALID_OBJECT_ID),
    m_last_turn_active_in_combat(INVALID_GAME_TURN),
    m_species_name(species_name),
    m_produced_by_empire_id(produced_by_empire_id),
    m_arrived_on_turn(CurrentTurn())
{
    if (!GetShipDesign(design_id))
        throw std::invalid_argument("Attempted to construct a Ship with an invalid design id");

    if (!m_species_name.empty() && !GetSpecies(m_species_name))
        DebugLogger() << "Ship created with invalid species name: " << m_species_name;

    SetOwner(empire_id);

    UniverseObject::Init();

    AddMeter(METER_FUEL);
    AddMeter(METER_MAX_FUEL);
    AddMeter(METER_SHIELD);
    AddMeter(METER_MAX_SHIELD);
    AddMeter(METER_DETECTION);
    AddMeter(METER_STRUCTURE);
    AddMeter(METER_MAX_STRUCTURE);
    AddMeter(METER_SPEED);
    AddMeter(METER_TARGET_INDUSTRY);
    AddMeter(METER_INDUSTRY);
    AddMeter(METER_TARGET_RESEARCH);
    AddMeter(METER_RESEARCH);
    AddMeter(METER_TARGET_TRADE);
    AddMeter(METER_TRADE);

    const std::vector<std::string>& part_names = Design()->Parts();
    for (std::size_t i = 0; i < part_names.size(); ++i) {
        if (part_names[i] != "") {
            const PartType* part = GetPartType(part_names[i]);
            if (!part) {
                ErrorLogger() << "Ship::Ship couldn't get part with name " << part_names[i];
                continue;
            }

            switch (part->Class()) {
            case PC_COLONY:
            case PC_TROOPS: {
                m_part_meters[std::make_pair(METER_CAPACITY, part->Name())];
                break;
            }
            case PC_DIRECT_WEAPON:      // capacity is damage, secondary stat is shots per attack
            case PC_FIGHTER_HANGAR: {   // capacity is how many fighters contained, secondary stat is damage per fighter attack
                m_part_meters[std::make_pair(METER_SECONDARY_STAT,      part->Name())];
                m_part_meters[std::make_pair(METER_MAX_SECONDARY_STAT,  part->Name())];
                // intentionally no break here
            }
            case PC_FIGHTER_BAY: {      // capacity is how many fighters launched per combat round
                m_part_meters[std::make_pair(METER_CAPACITY,            part->Name())];
                m_part_meters[std::make_pair(METER_MAX_CAPACITY,        part->Name())];
                break;
            }
            default:
                break;
            }
        }
    }
}
Exemple #22
0
int SitRepPanel::NumVisibleSitrepsThisTurn() const {
    std::map<int, std::list<SitRepEntry> > turns = GetSitRepsSortedByTurn(HumanClientApp::GetApp()->EmpireID(), m_hidden_sitrep_templates);
    return turns[CurrentTurn()].size();
}
void HearthstoneLogTracker::CardPlayed( Player player, const string& cardId, int internalId ) {
  DBG( "%s played card %s on turn %d", PLAYER_NAMES[ player ], cardId.c_str(), CurrentTurn() );
  mCardHistoryList.push_back( CardHistoryItem( CurrentTurn(), player, cardId, internalId ) );
}
Exemple #24
0
void AutoResolveCombat(CombatInfo& combat_info) {
    if (combat_info.objects.Empty())
        return;

    const System* system = combat_info.objects.Object<System>(combat_info.system_id);
    if (!system)
        Logger().errorStream() << "AutoResolveCombat couldn't get system with id " << combat_info.system_id;
    else
        Logger().debugStream() << "AutoResolveCombat at " << system->Name();

    if (GetOptionsDB().Get<bool>("verbose-logging")) {
        Logger().debugStream() << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%";
        Logger().debugStream() << "AutoResolveCombat objects before resolution: " << combat_info.objects.Dump();
    }

    // reasonably unpredictable but reproducible random seeding
    const int base_seed = combat_info.objects.begin()->first + CurrentTurn();


    // compile list of valid objects to attack or be attacked in this combat
    std::set<int> valid_target_object_ids;                          // all objects that can be attacked
    std::set<int> valid_attacker_object_ids;                        // all objects that can attack
    std::map<int, std::set<int> > empire_valid_attacker_object_ids; // objects that can attack that each empire owns
    float monster_detection = 0.0;

    for (ObjectMap::iterator it = combat_info.objects.begin(); it != combat_info.objects.end(); ++it) {
        const UniverseObject* obj = it->second;
        //Logger().debugStream() << "Considerting object " << obj->Name() << " owned by " << obj->Owner();
        if (ObjectCanAttack(obj)) {
            //Logger().debugStream() << "... can attack";
            valid_attacker_object_ids.insert(it->first);
            empire_valid_attacker_object_ids[obj->Owner()].insert(it->first);
        }
        if (ObjectCanBeAttacked(obj)) {
            //Logger().debugStream() << "... can be attacked";
            valid_target_object_ids.insert(it->first);
        }
        if (obj->Unowned() && obj->ObjectType() == OBJ_SHIP)
            monster_detection = std::max(monster_detection, obj->CurrentMeterValue(METER_DETECTION));
    }


    // map from empire to set of IDs of objects that empire's objects
    // could potentially target.
    std::map<int, std::set<int> > empire_valid_target_object_ids;   // objects that each empire can attack
    for (std::set<int>::const_iterator target_it = valid_target_object_ids.begin();
         target_it != valid_target_object_ids.end(); ++target_it)
    {
        int object_id = *target_it;
        const UniverseObject* obj = combat_info.objects.Object(object_id);
        //Logger().debugStream() << "Considering attackability of object " << obj->Name() << " owned by " << obj->Owner();

        // for all empires, can they attack this object?
        for (std::set<int>::const_iterator empire_it = combat_info.empire_ids.begin();
             empire_it != combat_info.empire_ids.end(); ++empire_it)
        {
            int attacking_empire_id = *empire_it;
            if (attacking_empire_id == ALL_EMPIRES) {
                if (ObjectAttackableByMonsters(obj, monster_detection)) {
                    //Logger().debugStream() << "object: " << obj->Name() << " attackable by monsters";
                    empire_valid_target_object_ids[ALL_EMPIRES].insert(object_id);
                }

            } else {
                // call function to find if empires can attack objects...
                if (ObjectAttackableByEmpire(obj, attacking_empire_id)) {
                    //Logger().debugStream() << "object: " << obj->Name() << " attackable by empire " << attacking_empire_id;
                    empire_valid_target_object_ids[attacking_empire_id].insert(object_id);
                }
            }
        }
    }


    // Each combat "round" a randomly-selected object in the battle attacks
    // something, if it is able to do so.  The number of rounds scales with the
    // number of objects, so the total actions per object is independent of
    // number of objects in the battle
    const int NUM_COMBAT_ROUNDS = 3*valid_attacker_object_ids.size();

    for (int round = 1; round <= NUM_COMBAT_ROUNDS; ++round) {
        Seed(base_seed + round);    // ensure each combat round produces different results

        // ensure something can attack and something can be attacked
        if (valid_attacker_object_ids.empty()) {
            Logger().debugStream() << "Nothing left can attack; combat over";
            break;
        }
        if (empire_valid_target_object_ids.empty()) {
            Logger().debugStream() << "Nothing left can be attacked; combat over";
            break;
        }
        // empires may have valid targets, but nothing to attack with.  If all
        // empires have no attackers or no valid targers, combat is over
        bool someone_can_attack_something = false;
        for (std::map<int, std::set<int> >::const_iterator attacker_it = empire_valid_attacker_object_ids.begin();
             attacker_it != empire_valid_attacker_object_ids.end(); ++attacker_it)
        {
            if (empire_valid_target_object_ids.find(attacker_it->first) != empire_valid_target_object_ids.end()) {
                someone_can_attack_something = true;
                break;
            }
        }
        if (!someone_can_attack_something) {
            Logger().debugStream() << "No empire has valid targets and something to attack with; combat over.";
            break;
        }

        Logger().debugStream() << "Combat at " << system->Name() << " (" << combat_info.system_id << ") Round " << round;

        // select attacking object in battle
        SmallIntDistType attacker_id_num_dist = SmallIntDist(0, valid_attacker_object_ids.size() - 1);
        std::set<int>::const_iterator attacker_it = valid_attacker_object_ids.begin();
        std::advance(attacker_it, attacker_id_num_dist());
        assert(attacker_it != valid_attacker_object_ids.end());
        int attacker_id = *attacker_it;

        UniverseObject* attacker = combat_info.objects.Object(attacker_id);
        if (!attacker) {
            Logger().errorStream() << "AutoResolveCombat couldn't get object with id " << attacker_id;
            continue;
        }
        Logger().debugStream() << "Attacker: " << attacker->Name();


        Ship* attack_ship = universe_object_cast<Ship*>(attacker);
        Planet* attack_planet = universe_object_cast<Planet*>(attacker);

        // loop over weapons of attacking object.  each gets a shot at a
        // randomly selected target object
        std::vector<PartAttackInfo> weapons;

        if (attack_ship) {
            weapons = ShipWeaponsStrengths(attack_ship);
            for (std::vector<PartAttackInfo>::const_iterator part_it = weapons.begin();
                 part_it != weapons.end(); ++part_it)
            {
                Logger().debugStream() << "weapon: " << part_it->part_type_name <<
                                          " attack: " << part_it->part_attack;
            }
        } else if (attack_planet) { // treat planet defenses as short range
            weapons.push_back(PartAttackInfo(PC_SHORT_RANGE, "", attack_planet->CurrentMeterValue(METER_DEFENSE)));
        }

        if (weapons.empty()) {
            Logger().debugStream() << "no weapons' can't attack";
            continue;   // no ability to attack!
        }

        for (std::vector<PartAttackInfo>::const_iterator weapon_it = weapons.begin();
             weapon_it != weapons.end(); ++weapon_it)
        {
            // select object from valid targets for this object's owner   TODO: with this weapon...
            Logger().debugStream() << "Attacking with weapon " << weapon_it->part_type_name << " with power " << weapon_it->part_attack;

            // get valid targets set for attacker owner.  need to do this for
            // each weapon that is attacking, as the previous shot might have
            // destroyed something
            int attacker_owner_id = attacker->Owner();

            std::map<int, std::set<int> >::iterator target_vec_it = empire_valid_target_object_ids.find(attacker_owner_id);
            if (target_vec_it == empire_valid_target_object_ids.end()) {
                Logger().debugStream() << "No targets for attacker with id: " << attacker_owner_id;
                break;
            }

            const std::set<int>& valid_target_ids = target_vec_it->second;
            if (valid_target_ids.empty())
                break; // should be redundant with this entry being erased when emptied


            // select target object
            SmallIntDistType target_id_num_dist = SmallIntDist(0, valid_target_ids.size() - 1);
            std::set<int>::const_iterator target_it = valid_target_ids.begin();
            std::advance(target_it, target_id_num_dist());
            assert(target_it != valid_target_ids.end());
            int target_id = *target_it;

            UniverseObject* target = combat_info.objects.Object(target_id);
            if (!target) {
                Logger().errorStream() << "AutoResolveCombat couldn't get target object with id " << target_id;
                continue;
            }
            Logger().debugStream() << "Target: " << target->Name();


            // do actual attacks, and mark attackers as valid targets for attacked object's owners
            if (attack_ship) {
                if (Ship* target_ship = universe_object_cast<Ship*>(target)) {
                    AttackShipShip(attack_ship, weapon_it->part_attack, target_ship, combat_info.damaged_object_ids);
                    empire_valid_target_object_ids[target_ship->Owner()].insert(attacker_id);
                } else if (Planet* target_planet = universe_object_cast<Planet*>(target)) {
                    AttackShipPlanet(attack_ship, weapon_it->part_attack,  target_planet, combat_info.damaged_object_ids);
                    empire_valid_target_object_ids[target_planet->Owner()].insert(attacker_id);
                }
            } else if (attack_planet) {
                if (Ship* target_ship = universe_object_cast<Ship*>(target)) {
                    AttackPlanetShip(attack_planet, target_ship, combat_info.damaged_object_ids);
                    empire_valid_target_object_ids[target_ship->Owner()].insert(attacker_id);
                } else if (Planet* target_planet = universe_object_cast<Planet*>(target)) {
                    AttackPlanetPlanet(attack_planet, target_planet, combat_info.damaged_object_ids);
                    empire_valid_target_object_ids[target_planet->Owner()].insert(attacker_id);
                }
            }


            // check for destruction of target object
            if (target->ObjectType() == OBJ_SHIP) {
                if (target->CurrentMeterValue(METER_STRUCTURE) <= 0.0) {
                    Logger().debugStream() << "!! Target Ship is destroyed!";
                    // object id destroyed
                    combat_info.destroyed_object_ids.insert(target_id);
                    // all empires in battle know object was destroyed
                    for (std::set<int>::const_iterator it = combat_info.empire_ids.begin();
                         it != combat_info.empire_ids.end(); ++it)
                    {
                        int empire_id = *it;
                        if (empire_id != ALL_EMPIRES)
                            combat_info.destroyed_object_knowers[empire_id].insert(target_id);
                    }

                    // remove destroyed ship's ID from lists of valid attackers and targets
                    valid_attacker_object_ids.erase(target_id);
                    valid_target_object_ids.erase(target_id);   // probably not necessary as this set isn't used in this loop

                    for (target_vec_it = empire_valid_target_object_ids.begin();
                         target_vec_it != empire_valid_target_object_ids.end(); ++target_vec_it)
                    { target_vec_it->second.erase(target_id); }

                    for (target_vec_it = empire_valid_attacker_object_ids.begin();
                         target_vec_it != empire_valid_attacker_object_ids.end(); ++target_vec_it)
                    { target_vec_it->second.erase(target_id); } // TODO: only erase from owner's entry in this list
                }

            } else if (target->ObjectType() == OBJ_PLANET) {
                if (target->CurrentMeterValue(METER_SHIELD) <= 0.0 &&
                    target->CurrentMeterValue(METER_DEFENSE) <= 0.0 &&
                    target->CurrentMeterValue(METER_CONSTRUCTION) <= 0.0)
                {
                    Logger().debugStream() << "!! Target Planet is knocked out of battle";

                    // remove disabled planet's ID from lists of valid attackers and targets
                    valid_attacker_object_ids.erase(target_id);
                    valid_target_object_ids.erase(target_id);   // probably not necessary as this set isn't used in this loop

                    for (target_vec_it = empire_valid_target_object_ids.begin();
                         target_vec_it != empire_valid_target_object_ids.end(); ++target_vec_it)
                    { target_vec_it->second.erase(target_id); }

                    for (target_vec_it = empire_valid_attacker_object_ids.begin();
                         target_vec_it != empire_valid_attacker_object_ids.end(); ++target_vec_it)
                    { target_vec_it->second.erase(target_id); } // TODO: only erase from owner's entry in this list
                }
            }

            // check if any empire has no remaining target or attacker objects.
            // If so, remove that empire's entry
            std::map<int, std::set<int> > temp = empire_valid_target_object_ids;
            for (target_vec_it = empire_valid_target_object_ids.begin();
                 target_vec_it != empire_valid_target_object_ids.end(); ++target_vec_it)
            {
                if (target_vec_it->second.empty()) {
                    temp.erase(target_vec_it->first);
                    Logger().debugStream() << "No valid targets left for empire with id: " << target_vec_it->first;
                }
            }
            empire_valid_target_object_ids = temp;

            temp = empire_valid_attacker_object_ids;
            for (target_vec_it = empire_valid_attacker_object_ids.begin();
                 target_vec_it != empire_valid_attacker_object_ids.end(); ++target_vec_it)
            {
                if (target_vec_it->second.empty()) {
                    temp.erase(target_vec_it->first);
                    Logger().debugStream() << "No valid attacking objects left for empire with id: " << target_vec_it->first;
                }
            }
            empire_valid_attacker_object_ids = temp;
        } // end for over weapons
    } // end for over combat arounds

    // ensure every participant knows what happened.
    // TODO: assemble list of objects to copy for each empire.  this should
    //       include objects the empire already knows about with standard
    //       visibility system, and also any objects the empire knows are
    //       destroyed or
    for (std::map<int, ObjectMap>::iterator it = combat_info.empire_known_objects.begin();
         it != combat_info.empire_known_objects.end(); ++it)
    { it->second.Copy(combat_info.objects); }

    if (GetOptionsDB().Get<bool>("verbose-logging"))
        Logger().debugStream() << "AutoResolveCombat objects after resolution: " << combat_info.objects.Dump();
}
Exemple #25
0
    int Variable<int>::Eval(const ScriptingContext& context) const
    {
        const adobe::name_t& property_name = m_property_name.back();

        IF_CURRENT_VALUE(int)

        if (m_ref_type == ValueRef::NON_OBJECT_REFERENCE) {
            if (property_name == CurrentTurn_name)
                return CurrentTurn();

            // add more non-object reference int functions here
            Logger().errorStream() << "Variable<int>::Eval unrecognized non-object property: " << ReconstructName(m_property_name, m_ref_type);
            return 0;
        }

        const UniverseObject* object = FollowReference(m_property_name.begin(), m_property_name.end(),
                                                       m_ref_type, context);
        if (!object) {
            Logger().errorStream() << "Variable<int>::Eval unable to follow reference: " << ReconstructName(m_property_name, m_ref_type);
            return 0;
        }

        if (property_name == Owner_name) {
            return object->Owner();
        } else if (property_name == ID_name) {
            return object->ID();
        } else if (property_name == CreationTurn_name) {
            return object->CreationTurn();
        } else if (property_name == Age_name) {
            return object->AgeInTurns();
        } else if (property_name == ProducedByEmpireID_name) {
            if (const Ship* ship = universe_object_cast<const Ship*>(object))
                return ship->ProducedByEmpireID();
            else if (const Building* building = universe_object_cast<const Building*>(object))
                return building->ProducedByEmpireID();
            else
                return ALL_EMPIRES;
        } else if (property_name == DesignID_name) {
            if (const Ship* ship = universe_object_cast<const Ship*>(object))
                return ship->DesignID();
            else
                return ShipDesign::INVALID_DESIGN_ID;
        } else if (property_name == Species_name) {
            if (const Planet* planet = universe_object_cast<const Planet*>(object))
                return GetSpeciesManager().GetSpeciesID(planet->SpeciesName());
            else if (const Ship* ship = universe_object_cast<const Ship*>(object))
                return GetSpeciesManager().GetSpeciesID(ship->SpeciesName());
            else
                return -1;
        } else if (property_name == FleetID_name) {
            if (const Ship* ship = universe_object_cast<const Ship*>(object))
                return ship->FleetID();
            else if (const Fleet* fleet = universe_object_cast<const Fleet*>(object))
                return fleet->ID();
            else
                return INVALID_OBJECT_ID;
        } else if (property_name == PlanetID_name) {
            if (const Building* building = universe_object_cast<const Building*>(object))
                return building->PlanetID();
            else if (const Planet* planet = universe_object_cast<const Planet*>(object))
                return planet->ID();
            else
                return INVALID_OBJECT_ID;
        } else if (property_name == SystemID_name) {
            return object->SystemID();
        } else if (property_name == FinalDestinationID_name) {
            if (const Fleet* fleet = universe_object_cast<const Fleet*>(object))
                return fleet->FinalDestinationID();
            else
                return INVALID_OBJECT_ID;
        } else if (property_name == NextSystemID_name) {
            if (const Fleet* fleet = universe_object_cast<const Fleet*>(object))
                return fleet->NextSystemID();
            else
                return INVALID_OBJECT_ID;
        } else if (property_name == PreviousSystemID_name) {
            if (const Fleet* fleet = universe_object_cast<const Fleet*>(object))
                return fleet->PreviousSystemID();
            else
                return INVALID_OBJECT_ID;
        } else if (property_name == NumShips_name) {
            if (const Fleet* fleet = universe_object_cast<const Fleet*>(object))
                return fleet->NumShips();
            else
                return 0;
        } else if (property_name == LastTurnBattleHere_name) {
            if (const System* system = universe_object_cast<const System*>(object))
                return system->LastTurnBattleHere();
            else
                return INVALID_GAME_TURN;
        } else if (property_name == Orbit_name) {
            if (const System* system = GetSystem(object->SystemID()))
                return system->OrbitOfObjectID(object->ID());
            return -1;
        }

        Logger().errorStream() << "Variable<int>::Eval unrecognized object property: " << ReconstructName(m_property_name, m_ref_type);
        return 0;
    }
Exemple #26
0
void UniverseObject::AddSpecial(const std::string& name)
{ m_specials[name] = CurrentTurn(); }
void HearthstoneLogTracker::HandleLogLine( const QString& line ) {
  if( line.trimmed().isEmpty() || line.startsWith( "(Filename:" )  ) {
    return;
  }

  // CardPlayed / CardReturned / PlayerDied
  static QRegExp regex( "ProcessChanges.*\\[.*id=(\\d+).*cardId=(\\w+|).*\\].*zone from (.*) ->\\s?(.*)" );
  if( regex.indexIn(line) != -1 ) {
    QStringList captures = regex.capturedTexts();
    int id = captures[1].toInt();
    QString cardId = captures[2];
    QString from = captures[3];
    QString to = captures[4];

    bool draw = from.contains( "DECK" ) && to.contains( "HAND" );
    bool mulligan = from.contains( "HAND" ) && to.contains( "DECK" );

    // Discarded cards by playing Soulfire, Doomguard etc.
    bool discard = from.contains( "HAND" ) && to.contains( "GRAVEYARD" );

    if( !draw && !mulligan && !discard ) {
      if( from.contains( "FRIENDLY HAND" ) ) {
        CardPlayed( PLAYER_SELF, cardId.toStdString(), id );
      } else if( from.contains( "OPPOSING HAND" ) ) {
        CardPlayed( PLAYER_OPPONENT, cardId.toStdString(), id );
      } else if( from.contains( "OPPOSING SECRET" ) && to.contains( "OPPOSING GRAVEYARD" ) ) {
        SecretResolved( PLAYER_OPPONENT, cardId.toStdString(), id );
      }
    }

    if( from.contains( "FRIENDLY PLAY" ) && to.contains( "FRIENDLY HAND" ) ) {
      CardReturned( PLAYER_SELF, cardId.toStdString() );
    }

    DBG( "Card %s from %s -> %s. (draw: %d, mulligan %d, discard %d) [%d]", qt2cstr( cardId ), qt2cstr( from ), qt2cstr( to ), draw, mulligan, discard, id );
  }

  // Outcome
  static QRegExp regexOutcome( "name=(victory|defeat)_screen_start" );
  if( regexOutcome.indexIn(line) != -1 ) {
    QStringList captures = regexOutcome.capturedTexts();
    QString outcome = captures[1];

    if( outcome == "victory" ) {
      emit HandleOutcome( OUTCOME_VICTORY );
    } else if( outcome == "defeat" ) {
      emit HandleOutcome( OUTCOME_DEFEAT );
    }
    emit HandleMatchEnd( mCardHistoryList );
    Reset();
  }

  // Coin
  static QRegExp regexCoin( "ProcessChanges.*zonePos=5.*zone from  -> (.*)" );  // unique because from is nothing -> " "
  if( regexCoin.indexIn(line) != -1 ) {
    QStringList captures = regexCoin.capturedTexts();
    QString to = captures[1];

    if( to.contains( "FRIENDLY HAND" ) ) {
      // I go second because I get the coin
      emit HandleOrder( ORDER_SECOND );
    } else if( to.contains( "OPPOSING HAND" ) ) {
      // Opponent got coin, so I go first
      emit HandleOrder( ORDER_FIRST );
    }
  }

  // Turn Info
  static QRegExp regexTurn( "change=powerTask.*tag=NEXT_STEP value=MAIN_ACTION" );
  if( regexTurn.indexIn(line) != -1 ) {
    mTurnCounter++;

    emit HandleTurn( mTurnCounter );

    // reset hero power usage on turn change
    mHeroPowerUsed = false;
  }

  // Hero Power
  static QRegExp regexHeroPowerEquip( "player=(\\d+).*-> FRIENDLY PLAY \\(Hero Power\\)" );
  if( regexHeroPowerEquip.indexIn(line) != -1 ) {
    QStringList captures = regexHeroPowerEquip.capturedTexts();
    QString playerId = captures[1];

    mHeroPlayerId = playerId.toInt();
    DBG( "Hero Power Equip -> My Player Id: %d", mHeroPlayerId );
  }

  static QRegExp regexHeroPower( "PowerProcessor\\.DoTaskListForCard.*cardId=(\\w+).*player=(\\d+)" );
  if( regexHeroPower.indexIn(line) != -1 ) {
    QStringList captures = regexHeroPower.capturedTexts();
    QString cardId = captures[1];
    int playerId = captures[2].toInt();
    Player player = ( playerId == mHeroPlayerId ) ? PLAYER_SELF : PLAYER_OPPONENT;

    bool isHeroPower = false;
    for( int i = 0; i < NUM_HERO_POWER_CARDS; i++ ) {
      if( cardId == HERO_POWER_CARD_IDS[ i ] ) {
        isHeroPower = true;
        break;
      }
    }

    // Power log line is emitted multiple times
    // Make sure we only account for first occurrence
    // Plus line is emitted when match starts, so ignore turn 0
    if( isHeroPower && !mHeroPowerUsed && CurrentTurn() > 0 ) {
      CardPlayed( player, cardId.toStdString() );
      mHeroPowerUsed = true;
    }
  }

  // Hero Equip
  static QRegExp regexHeroEquip( "cardId=(\\w+).*-> (\\w+) PLAY \\(Hero\\)" );
  if( regexHeroEquip.indexIn(line) != -1 ) {
    QStringList captures = regexHeroEquip.capturedTexts();
    QString cardId = captures[1];
    QString type = captures[2];

    // This log line can be emitted when hero swaps (Lord Jaraxxus)
    // So make sure we only account for the "initial" playable heroes
    Class hero = CLASS_UNKNOWN;
    for( int i = 0; i < NUM_HEROES; i++ ) {
      // startsWith instead of exact match to support
      // the new reasonably priced hero skins
      // (e.g. HERO_01a instead of HERO_01)
      if( cardId.startsWith( HERO_IDS[ i ] ) ) {
        hero = ( Class )i;
      }
    }

    // Set solo mode when encountering naxxramas/blackrock mountain heroes
    if( hero == CLASS_UNKNOWN ) {
      if( cardId.startsWith("NAX") || cardId.startsWith("BRM") ) {
        HandleGameMode( MODE_SOLO_ADVENTURES );
      }
    }

    if( hero != CLASS_UNKNOWN ) {
      if( type == "FRIENDLY" ) {
        emit HandleMatchStart();
        emit HandleOwnClass( hero );
      } else {
        emit HandleOpponentClass( hero );
      }
    }
  }

  // Game Mode
  // Practice, Casual/Ranked, ScreenForge
  static QRegExp regexMode( "---(\\w+)---" );
  if( regexMode.indexIn(line) != -1 ) {
    QStringList captures = regexMode.capturedTexts();
    QString screen = captures[1];

    if( screen == "RegisterScreenPractice" ) {
      HandleGameMode( MODE_SOLO_ADVENTURES );
    } else if( screen == "RegisterScreenTourneys") {
      HandleGameMode( MODE_CASUAL ); // or ranked resp.
    } else if( screen == "RegisterScreenForge" ) {
      HandleGameMode( MODE_ARENA );
    } else if( screen == "RegisterScreenFriendly" ) {
      HandleGameMode( MODE_FRIENDLY );
    }
  }

  // Tavern Brawl
  static QRegExp regexTavernBrawl( "SAVE --> NetCacheTavernBrawlRecord" );
  if( regexTavernBrawl.indexIn(line) != -1 ) {
    HandleGameMode( MODE_TAVERN_BRAWL );
  }

  // Rank
  // Rank events via log are unreliable

  // Legend
  // Emitted at the end of the game twice, make sure we capture only the first time
  static QRegExp regexLegend( "legend rank (\\d+)" );
  if( !mLegendTracked && regexLegend.indexIn(line) != -1 ) {
    QStringList captures = regexLegend.capturedTexts();
    int legend = captures[1].toInt();
    if( legend > 0 ) {
      mLegendTracked = true;
      HandleLegend( legend );
    }
  }

  // Casual/Ranked distinction
  static QRegExp regexRanked( "name=rank_window" );
  if( regexRanked.indexIn(line) != -1 ) {
    HandleGameMode( MODE_RANKED );
  }

  // flag current GAME as spectated
  static QRegExp regexBeginSpectating( "Start Spectator Game" );
  if( regexBeginSpectating.indexIn(line) != -1 ) {
    DBG( "Begin spectator game" );
    emit HandleSpectating( true );
  }

  // disable spectating flag if we leave the spectator MODE
  static QRegExp regexEndSpectating( "End Spectator Mode" );
  if( regexEndSpectating.indexIn(line) != -1 ) {
    DBG( "End spectator mode" );
    emit HandleSpectating( false );
  }
}
Exemple #28
0
    double Variable<double>::Eval(const ScriptingContext& context) const
    {
        const adobe::name_t& property_name = m_property_name.back();

        IF_CURRENT_VALUE(float)

        if (m_ref_type == ValueRef::NON_OBJECT_REFERENCE) {
            if (property_name == CurrentTurn_name) {
                return CurrentTurn();
            } else if (property_name == UniverseCentreX_name |
                       property_name == UniverseCentreY_name)
            {
                return GetUniverse().UniverseWidth() / 2;
            }

            // add more non-object reference double functions here
            Logger().errorStream() << "Variable<double>::Eval unrecognized non-object property: " << ReconstructName(m_property_name, m_ref_type);
            return 0.0;
        }

        const UniverseObject* object = FollowReference(m_property_name.begin(), m_property_name.end(),
                                                       m_ref_type, context);
        if (!object) {
            Logger().errorStream() << "Variable<double>::Eval unable to follow reference: " << ReconstructName(m_property_name, m_ref_type);
            return 0.0;
        }

        MeterType meter_type = NameToMeter(property_name);
        if (object && meter_type != INVALID_METER_TYPE) {
            if (object->GetMeter(meter_type))
                return object->InitialMeterValue(meter_type);

        } else if (property_name == TradeStockpile_name) {
            if (const Empire* empire = Empires().Lookup(object->Owner()))
                return empire->ResourceStockpile(RE_TRADE);

        } else if (property_name == DistanceToSource_name) {
            if (!context.source) {
                Logger().errorStream() << "ValueRef::Variable<double>::Eval can't find distance to source because no source was passed";
                return 0.0;
            }
            double delta_x = object->X() - context.source->X();
            double delta_y = object->Y() - context.source->Y();
            return std::sqrt(delta_x * delta_x + delta_y * delta_y);

        } else if (property_name == X_name) {
            return object->X();

        } else if (property_name == Y_name) {
            return object->Y();

        } else if (property_name == SizeAsDouble_name) {
            if (const Planet* planet = universe_object_cast<const Planet*>(object))
                return planet->SizeAsInt();

        } else if (property_name == DistanceFromOriginalType_name) {
            if (const Planet* planet = universe_object_cast<const Planet*>(object))
                return planet->DistanceFromOriginalType();

        } else if (property_name == NextTurnPopGrowth_name) {
            if (const PopCenter* pop = dynamic_cast<const PopCenter*>(object))
                return pop->NextTurnPopGrowth();

        } else if (property_name == CurrentTurn_name) {
            return CurrentTurn();

        }

        Logger().errorStream() << "Variable<double>::Eval unrecognized object property: " << ReconstructName(m_property_name, m_ref_type);
        return 0.0;
    }
void ResourceCenter::ClearFocus() {
    m_focus.clear();
    m_last_turn_focus_changed = CurrentTurn();
    ResourceCenterChangedSignal();
}
Exemple #30
0
void SitRepPanel::LastClicked() {
    m_showing_turn = CurrentTurn();
    Update();
}