boost::statechart::result WaitingForTurnData::react(const GameStart& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) WaitingForTurnData.GameStart"; bool loaded_game_data; bool ui_data_available; SaveGameUIData ui_data; bool save_state_string_available; std::string save_state_string; // ignored - used by AI but not by human client OrderSet orders; ExtractMessageData(msg.m_message, Client().m_single_player_game, Client().EmpireIDRef(), Client().CurrentTurnRef(), Empires(), GetUniverse(), GetSpeciesManager(), Client().m_player_info, orders, loaded_game_data, ui_data_available, ui_data, save_state_string_available, save_state_string); Client().StartGame(); std::swap(Client().Orders(), orders); // bring back orders planned in the current turn, they will be applied later, after some basic turn initialization if (loaded_game_data && ui_data_available) Client().m_ui->RestoreFromSaveData(ui_data); // if I am the host on the first turn, do an autosave. on later turns, will // have just loaded save, so don't need to autosave. might also have just // loaded a turn 1 autosave, but not sure how to check for that here... if (Client().CurrentTurn() == 1 && Client().Networking().PlayerIsHost(Client().PlayerID())) Client().Autosave(); return transit<PlayingTurn>(); }
void MessageWndEdit::FindGameWords() { // add player and empire names for (std::map<int, Empire*>::value_type& entry : Empires()) { m_game_words.insert(entry.second->Name()); m_game_words.insert(entry.second->PlayerName()); } // add system names for (std::shared_ptr<System> system : GetUniverse().Objects().FindObjects<System>()) { if (system->Name() != "") m_game_words.insert(system->Name()); } // add ship names for (std::shared_ptr<Ship> ship : GetUniverse().Objects().FindObjects<Ship>()) { if (ship->Name() != "") m_game_words.insert(ship->Name()); } // add ship design names for (const auto& design : GetPredefinedShipDesignManager().GetOrderedShipDesigns()) { if (!design->Name().empty()) m_game_words.insert(UserString(design->Name())); } // add specials names for (const std::string& special_name : SpecialNames()) { if (special_name != "") m_game_words.insert(UserString(special_name)); } // add species names for (const std::map<std::string, Species*>::value_type& entry : GetSpeciesManager()) { if (entry.second->Name() != "") m_game_words.insert(UserString(entry.second->Name())); } // add techs names for (const std::string& tech_name : GetTechManager().TechNames()) { if (tech_name != "") m_game_words.insert(UserString(tech_name)); } // add building type names for (const auto& entry : GetBuildingTypeManager()) { if (entry.second->Name() != "") m_game_words.insert(UserString(entry.second->Name())); } // add ship hulls for (const auto& design : GetPredefinedShipDesignManager().GetOrderedShipDesigns()) { if (!design->Hull().empty()) m_game_words.insert(UserString(design->Hull())); } // add ship parts for (const auto& design : GetPredefinedShipDesignManager().GetOrderedShipDesigns()) { for (const std::string& part_name : design->Parts()) { if (part_name != "") m_game_words.insert(UserString(part_name)); } } }
bool SetEmpireHomeworld(Empire* empire, int planet_id, std::string species_name) { // get home planet and system, check if they exist TemporaryPtr<Planet> home_planet = GetPlanet(planet_id); TemporaryPtr<System> home_system; if (home_planet) home_system = GetSystem(home_planet->SystemID()); if (!home_planet || !home_system) { ErrorLogger() << "SetEmpireHomeworld: couldn't get homeworld or system for empire" << empire->EmpireID(); return false; } DebugLogger() << "SetEmpireHomeworld: setting system " << home_system->ID() << " (planet " << home_planet->ID() << ") to be home system for empire " << empire->EmpireID(); // get species, check if it exists Species* species = GetSpeciesManager().GetSpecies(species_name); if (!species) { ErrorLogger() << "SetEmpireHomeworld: couldn't get species \"" << species_name << "\" to set with homeworld id " << home_planet->ID(); return false; } // set homeword's planet type to the preferred type for this species const std::map<PlanetType, PlanetEnvironment>& spte = species->PlanetEnvironments(); if (!spte.empty()) { // invert map from planet type to environments to map from // environments to type, sorted by environment std::map<PlanetEnvironment, PlanetType> sept; for (std::map<PlanetType, PlanetEnvironment>::const_iterator it = spte.begin(); it != spte.end(); ++it) sept[it->second] = it->first; // assuming enum values are ordered in increasing goodness... PlanetType preferred_planet_type = sept.rbegin()->second; // both the current as well as the original type need to be set to the preferred type home_planet->SetType(preferred_planet_type); home_planet->SetOriginalType(preferred_planet_type); // set planet size according to planet type if (preferred_planet_type == PT_ASTEROIDS) home_planet->SetSize(SZ_ASTEROIDS); else if (preferred_planet_type == PT_GASGIANT) home_planet->SetSize(SZ_GASGIANT); else home_planet->SetSize(SZ_MEDIUM); } home_planet->Colonize(empire->EmpireID(), species_name, Meter::LARGE_VALUE); species->AddHomeworld(home_planet->ID()); empire->SetCapitalID(home_planet->ID()); empire->AddExploredSystem(home_planet->SystemID()); return true; }
boost::statechart::result WaitingForTurnData::react(const TurnUpdate& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) WaitingForTurnData.TurnUpdate"; ExtractMessageData(msg.m_message, Client().EmpireID(), Client().CurrentTurnRef(), Empires(), GetUniverse(), GetSpeciesManager(), Client().m_player_info); // if I am the host, do autosave if (Client().Networking().PlayerIsHost(Client().PlayerID())) Client().Autosave(); return transit<PlayingTurn>(); }
boost::statechart::result WaitingForTurnData::react(const TurnUpdate& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) WaitingForTurnData.TurnUpdate"; ExtractMessageData(msg.m_message, Client().EmpireID(), Client().CurrentTurnRef(), Empires(), GetUniverse(), GetSpeciesManager(), Client().m_player_info); // if I am the host, do autosave for (std::map<int, PlayerInfo>::const_iterator it = Client().m_player_info.begin(); it != Client().m_player_info.end(); ++it) if (it->second.host && it->first == Client().PlayerID()) Client().Autosave(); return transit<PlayingTurn>(); }
void IApp::StartBackgroundParsing() { const auto& rdir = GetResourceDir(); GetBuildingTypeManager().SetBuildingTypes(Pending::StartParsing(parse::buildings, rdir / "scripting/buildings")); GetEncyclopedia().SetArticles(Pending::StartParsing(parse::encyclopedia_articles, rdir / "scripting/encyclopedia")); GetFieldTypeManager().SetFieldTypes(Pending::StartParsing(parse::fields, rdir / "scripting/fields")); GetSpecialsManager().SetSpecialsTypes(Pending::StartParsing(parse::specials, rdir / "scripting/specials")); GetSpeciesManager().SetSpeciesTypes(Pending::StartParsing(parse::species, rdir / "scripting/species")); GetPartTypeManager().SetPartTypes(Pending::StartParsing(parse::ship_parts, rdir / "scripting/ship_parts")); GetHullTypeManager().SetHullTypes(Pending::StartParsing(parse::ship_hulls, rdir / "scripting/ship_hulls")); GetPredefinedShipDesignManager().SetShipDesignTypes( Pending::StartParsing(parse::ship_designs, rdir / "scripting/ship_designs")); GetPredefinedShipDesignManager().SetMonsterDesignTypes( Pending::StartParsing(parse::ship_designs, rdir / "scripting/monster_designs")); GetGameRules().Add(Pending::StartParsing(parse::game_rules, rdir / "scripting/game_rules.focs.txt")); GetTechManager().SetTechs(Pending::StartParsing(parse::techs<TechManager::TechParseTuple>, rdir / "scripting/techs")); InitEmpireColors(rdir / "empire_colors.xml"); }
boost::statechart::result WaitingForGameStart::react(const GameStart& msg) { TraceLogger(FSM) << "(HumanClientFSM) WaitingForGameStart.GameStart"; bool loaded_game_data; bool ui_data_available; SaveGameUIData ui_data; bool save_state_string_available; std::string save_state_string; // ignored - used by AI but not by human client OrderSet orders; bool single_player_game = false; int empire_id = ALL_EMPIRES; int current_turn = INVALID_GAME_TURN; Client().PlayerStatus().clear(); Client().Orders().Reset(); ExtractGameStartMessageData(msg.m_message, single_player_game, empire_id, current_turn, Empires(), GetUniverse(), GetSpeciesManager(), GetCombatLogManager(), GetSupplyManager(), Client().Players(), Client().Orders(), loaded_game_data, ui_data_available, ui_data, save_state_string_available, save_state_string, Client().GetGalaxySetupData()); DebugLogger(FSM) << "Extracted GameStart message for turn: " << current_turn << " with empire: " << empire_id; Client().SetSinglePlayerGame(single_player_game); Client().SetEmpireID(empire_id); Client().SetCurrentTurn(current_turn); GetGameRules().SetFromStrings(Client().GetGalaxySetupData().GetGameRules()); bool is_new_game = !(loaded_game_data && ui_data_available); Client().StartGame(is_new_game); if (!is_new_game) Client().GetClientUI().RestoreFromSaveData(ui_data); // if I am the host on the first turn, do an autosave. if (is_new_game && Client().Networking().PlayerIsHost(Client().PlayerID())) Client().Autosave(); return transit<PlayingTurn>(); }
boost::statechart::result WaitingForGameStart::react(const GameStart& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) WaitingForGameStart.GameStart"; bool loaded_game_data; bool ui_data_available; SaveGameUIData ui_data; bool save_state_string_available; std::string save_state_string; // ignored - used by AI but not by human client OrderSet orders; bool single_player_game = false; int empire_id = ALL_EMPIRES; int current_turn = INVALID_GAME_TURN; Client().PlayerStatus().clear(); ExtractMessageData(msg.m_message, single_player_game, empire_id, current_turn, Empires(), GetUniverse(), GetSpeciesManager(), GetCombatLogManager(), Client().Players(), orders, loaded_game_data, ui_data_available, ui_data, save_state_string_available, save_state_string, Client().GetGalaxySetupData()); DebugLogger() << "Extracted GameStart message for turn: " << current_turn << " with empire: " << empire_id; Client().SetSinglePlayerGame(single_player_game); Client().SetEmpireID(empire_id); Client().SetCurrentTurn(current_turn); Client().StartGame(); std::swap(Client().Orders(), orders); // bring back orders planned in the current turn, they will be applied later, after some basic turn initialization if (loaded_game_data && ui_data_available) Client().GetClientUI()->RestoreFromSaveData(ui_data); // if I am the host on the first turn, do an autosave. on later turns, will // have just loaded save, so don't need to autosave. might also have just // loaded a turn 1 autosave, but not sure how to check for that here... if (Client().CurrentTurn() == 1 && Client().Networking().PlayerIsHost(Client().PlayerID())) Client().Autosave(); return transit<PlayingTurn>(); }
boost::statechart::result WaitingForTurnData::react(const TurnUpdate& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.TurnUpdate"; int current_turn = INVALID_GAME_TURN; try { ExtractMessageData(msg.m_message, Client().EmpireID(), current_turn, Empires(), GetUniverse(), GetSpeciesManager(), GetCombatLogManager(), Client().Players()); } catch (...) { Client().GetClientUI()->GetMessageWnd()->HandleLogMessage(UserString("ERROR_PROCESSING_SERVER_MESSAGE") + "\n"); return discard_event(); } DebugLogger() << "Extracted TurnUpdate message for turn: " << current_turn; Client().SetCurrentTurn(current_turn); // if I am the host, do autosave if (Client().Networking().PlayerIsHost(Client().PlayerID())) Client().Autosave(); return transit<PlayingTurn>(); }
void HumanClientApp::NewSinglePlayerGame(bool quickstart) { if (!GetOptionsDB().Get<bool>("force-external-server")) { try { StartServer(); } catch (const std::runtime_error& err) { ErrorLogger() << "HumanClientApp::NewSinglePlayerGame : Couldn't start server. Got error message: " << err.what(); ClientUI::MessageBox(UserString("SERVER_WONT_START"), true); return; } } bool ended_with_ok = false; if (!quickstart) { GalaxySetupWnd galaxy_wnd; galaxy_wnd.Run(); ended_with_ok = galaxy_wnd.EndedWithOk(); } bool failed = false; unsigned int start_time = Ticks(); while (!m_networking.ConnectToLocalHostServer(boost::posix_time::seconds(2))) { if (SERVER_CONNECT_TIMEOUT < Ticks() - start_time) { ClientUI::MessageBox(UserString("ERR_CONNECT_TIMED_OUT"), true); failed = true; break; } } m_connected = !failed; if (!failed && (quickstart || ended_with_ok)) { DebugLogger() << "HumanClientApp::NewSinglePlayerGame : Connected to server"; SinglePlayerSetupData setup_data; setup_data.m_new_game = true; setup_data.m_filename.clear(); // not used for new game // get values stored in options from previous time game was run or // from just having run GalaxySetupWnd // GalaxySetupData setup_data.m_seed = GetOptionsDB().Get<std::string>("GameSetup.seed"); setup_data.m_size = GetOptionsDB().Get<int>("GameSetup.stars"); setup_data.m_shape = GetOptionsDB().Get<Shape>("GameSetup.galaxy-shape"); setup_data.m_age = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.galaxy-age"); setup_data.m_starlane_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.starlane-frequency"); setup_data.m_planet_density = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.planet-density"); setup_data.m_specials_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.specials-frequency"); setup_data.m_monster_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.monster-frequency"); setup_data.m_native_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.native-frequency"); setup_data.m_ai_aggr = GetOptionsDB().Get<Aggression>("GameSetup.ai-aggression"); // SinglePlayerSetupData contains a map of PlayerSetupData, for // the human and AI players. Need to compile this information // from the specified human options and number of requested AIs // Human player setup data first PlayerSetupData human_player_setup_data; human_player_setup_data.m_player_name = GetOptionsDB().Get<std::string>("GameSetup.player-name"); human_player_setup_data.m_empire_name = GetOptionsDB().Get<std::string>("GameSetup.empire-name"); // DB stores index into array of available colours, so need to get that array to look up value of index. // if stored value is invalid, use a default colour const std::vector<GG::Clr>& empire_colours = EmpireColors(); int colour_index = GetOptionsDB().Get<int>("GameSetup.empire-color"); if (colour_index >= 0 && colour_index < static_cast<int>(empire_colours.size())) human_player_setup_data.m_empire_color = empire_colours[colour_index]; else human_player_setup_data.m_empire_color = GG::CLR_GREEN; human_player_setup_data.m_starting_species_name = GetOptionsDB().Get<std::string>("GameSetup.starting-species"); if (human_player_setup_data.m_starting_species_name == "1") human_player_setup_data.m_starting_species_name = "SP_HUMAN"; // kludge / bug workaround for bug with options storage and retreival. Empty-string options are stored, but read in as "true" boolean, and converted to string equal to "1" if (!GetSpecies(human_player_setup_data.m_starting_species_name)) { const SpeciesManager& sm = GetSpeciesManager(); if (sm.NumPlayableSpecies() < 1) human_player_setup_data.m_starting_species_name.clear(); else human_player_setup_data.m_starting_species_name = sm.playable_begin()->first; } human_player_setup_data.m_save_game_empire_id = ALL_EMPIRES; // not used for new games human_player_setup_data.m_client_type = Networking::CLIENT_TYPE_HUMAN_PLAYER; // add to setup data players setup_data.m_players.push_back(human_player_setup_data); // AI player setup data. One entry for each requested AI int num_AIs = GetOptionsDB().Get<int>("GameSetup.ai-players"); for (int ai_i = 1; ai_i <= num_AIs; ++ai_i) { PlayerSetupData ai_setup_data; ai_setup_data.m_player_name = "AI_" + boost::lexical_cast<std::string>(ai_i); ai_setup_data.m_empire_name.clear(); // leave blank, to be set by server in Universe::GenerateEmpires ai_setup_data.m_empire_color = GG::CLR_ZERO; // to be set by server ai_setup_data.m_starting_species_name.clear(); // leave blank, to be set by server ai_setup_data.m_save_game_empire_id = ALL_EMPIRES; // not used for new games ai_setup_data.m_client_type = Networking::CLIENT_TYPE_AI_PLAYER; setup_data.m_players.push_back(ai_setup_data); } m_networking.SendMessage(HostSPGameMessage(setup_data)); m_fsm->process_event(HostSPGameRequested()); } else { DebugLogger() << "HumanClientApp::NewSinglePlayerGame killing server due to canceled game or server connection failure"; if (m_networking.Connected()) { DebugLogger() << "HumanClientApp::NewSinglePlayerGame Sending server shutdown message."; m_networking.SendMessage(ShutdownServerMessage(m_networking.PlayerID())); boost::this_thread::sleep(boost::posix_time::seconds(1)); m_networking.DisconnectFromServer(); if (!m_networking.Connected()) DebugLogger() << "HumanClientApp::NewSinglePlayerGame Disconnected from server."; else ErrorLogger() << "HumanClientApp::NewSinglePlayerGame Unexpectedly still connected to server...?"; } KillServer(); } }
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; }
const Species* GetSpecies(const std::string& name) { return GetSpeciesManager().GetSpecies(name); }
void MessageWndEdit::FindGameWords() { // add player and empire names for (EmpireManager::const_iterator it = Empires().begin(); it != Empires().end(); ++it) { m_gameWords.insert(it->second->Name()); m_gameWords.insert(it->second->PlayerName()); } // add system names std::vector<TemporaryPtr<System> > systems = GetUniverse().Objects().FindObjects<System>(); for (unsigned int i = 0; i < systems.size(); ++i) { if (systems[i]->Name() != "") m_gameWords.insert(systems[i]->Name()); } // add ship names std::vector<TemporaryPtr<Ship> > ships = GetUniverse().Objects().FindObjects<Ship>(); for (unsigned int i = 0; i < ships.size(); ++i) { if (ships[i]->Name() != "") m_gameWords.insert(ships[i]->Name()); } // add ship design names for (PredefinedShipDesignManager::iterator it = GetPredefinedShipDesignManager().begin(); it != GetPredefinedShipDesignManager().end(); ++it) { if (it->second->Name() != "") m_gameWords.insert(UserString(it->second->Name())); } // add specials names std::vector<std::string> specials = SpecialNames(); for (unsigned int i = 0; i < specials.size(); ++i) { if (specials[i] != "") m_gameWords.insert(UserString(specials[i])); } // add species names for (SpeciesManager::iterator it = GetSpeciesManager().begin(); it != GetSpeciesManager().end(); ++it) { if (it->second->Name() != "") m_gameWords.insert(UserString(it->second->Name())); } // add techs names std::vector<std::string> techs = GetTechManager().TechNames(); for (unsigned int i = 0; i < techs.size(); ++i) { if (techs[i] != "") m_gameWords.insert(UserString(techs[i])); } // add building type names for (BuildingTypeManager::iterator it = GetBuildingTypeManager().begin(); it != GetBuildingTypeManager().end(); ++it) { if (it->second->Name() != "") m_gameWords.insert(UserString(it->second->Name())); } // add ship hulls for (PredefinedShipDesignManager::iterator it = GetPredefinedShipDesignManager().begin(); it != GetPredefinedShipDesignManager().end(); ++it) { if (it->second->Hull() != "") m_gameWords.insert(UserString(it->second->Hull())); } // add ship parts for (PredefinedShipDesignManager::iterator it = GetPredefinedShipDesignManager().begin(); it != GetPredefinedShipDesignManager().end(); ++it) { const std::vector<std::string>& parts = it->second->Parts(); for (std::vector<std::string>::const_iterator it1 = parts.begin(); it1 != parts.end(); ++it1) { if (*it1 != "") m_gameWords.insert(UserString(*it1)); } } }
void AIClientApp::HandleMessage(const Message& msg) { //DebugLogger() << "AIClientApp::HandleMessage " << msg.Type(); switch (msg.Type()) { case Message::ERROR_MSG: { ErrorLogger() << "AIClientApp::HandleMessage : Received ERROR message from server: " << msg.Text(); break; } case Message::HOST_ID: { const std::string& text = msg.Text(); int host_id = Networking::INVALID_PLAYER_ID; if (text.empty()) { ErrorLogger() << "AIClientApp::HandleMessage for HOST_ID : Got empty message text?!"; } else { try { host_id = boost::lexical_cast<int>(text); } catch(const boost::bad_lexical_cast& ex) { ErrorLogger() << "AIClientApp::HandleMessage for HOST_ID : Couldn't parse message text \"" << text << "\": " << ex.what(); } } m_networking->SetHostPlayerID(host_id); break; } case Message::JOIN_GAME: { if (PlayerID() == Networking::INVALID_PLAYER_ID) { DebugLogger() << "AIClientApp::HandleMessage : Received JOIN_GAME acknowledgement"; try { int player_id; boost::uuids::uuid cookie; // ignore ExtractJoinAckMessageData(msg, player_id, cookie); m_networking->SetPlayerID(player_id); } catch(const boost::bad_lexical_cast& ex) { ErrorLogger() << "AIClientApp::HandleMessage for JOIN_GAME : Couldn't parse message text \"" << msg.Text() << "\": " << ex.what(); } } else { ErrorLogger() << "AIClientApp::HandleMessage : Received erroneous JOIN_GAME acknowledgement when already in a game"; } break; } case Message::GAME_START: { DebugLogger() << "AIClientApp::HandleMessage : Received GAME_START message; starting AI turn..."; bool single_player_game; // ignored bool loaded_game_data; bool ui_data_available; // ignored SaveGameUIData ui_data; // ignored bool state_string_available; // ignored, as save_state_string is sent even if not set by ExtractMessageData std::string save_state_string; m_empire_status.clear(); ExtractGameStartMessageData(msg, single_player_game, m_empire_id, m_current_turn, m_empires, m_universe, GetSpeciesManager(), GetCombatLogManager(), GetSupplyManager(), m_player_info, m_orders, loaded_game_data, ui_data_available, ui_data, state_string_available, save_state_string, m_galaxy_setup_data); DebugLogger() << "Extracted GameStart message for turn: " << m_current_turn << " with empire: " << m_empire_id; GetUniverse().InitializeSystemGraph(m_empire_id); DebugLogger() << "Message::GAME_START loaded_game_data: " << loaded_game_data; if (loaded_game_data) { TraceLogger() << "Message::GAME_START save_state_string: " << save_state_string; m_AI->ResumeLoadedGame(save_state_string); Orders().ApplyOrders(); } else { DebugLogger() << "Message::GAME_START Starting New Game!"; // % Distribution of aggression levels // Aggression : 0 1 2 3 4 5 (0=Beginner, 5=Maniacal) // __ __ __ __ __ __ //Max 0 :100 0 0 0 0 0 //Max 1 : 25 75 0 0 0 0 //Max 2 : 0 25 75 0 0 0 //Max 3 : 0 0 25 75 0 0 //Max 4 : 0 0 0 25 75 0 //Max 5 : 0 0 0 0 25 75 // Optional aggression table, possibly for 0.4.4+? // Aggression : 0 1 2 3 4 5 (0=Beginner, 5=Maniacal) // __ __ __ __ __ __ //Max 0 :100 0 0 0 0 0 //Max 1 : 25 75 0 0 0 0 //Max 2 : 8 17 75 0 0 0 //Max 3 : 0 8 17 75 0 0 //Max 4 : 0 0 8 17 75 0 //Max 5 : 0 0 0 8 17 75 const std::string g_seed = GetGalaxySetupData().m_seed; const std::string emp_name = GetEmpire(m_empire_id)->Name(); unsigned int my_seed = 0; try { // generate consistent my_seed values from galaxy seed & empire name. boost::hash<std::string> string_hash; std::size_t h = string_hash(g_seed); my_seed = 3 * static_cast<unsigned int>(h) * static_cast<unsigned int>(string_hash(emp_name)); DebugLogger() << "Message::GAME_START getting " << emp_name << " AI aggression, RNG Seed: " << my_seed; } catch (...) { DebugLogger() << "Message::GAME_START getting " << emp_name << " AI aggression, could not initialise RNG."; } int rand_num = 0; int this_aggr = m_max_aggression; if (this_aggr > 0 && my_seed > 0) { Seed(my_seed); rand_num = RandSmallInt(0, 99); // if it's in the top 25% then decrease aggression. if (rand_num > 74) this_aggr--; // Leaving the following as commented out code for now. Possibly for 0.4.4+? // in the top 8% ? decrease aggression again, unless it's already as low as it gets. // if (rand_num > 91 && this_aggr > 0) this_aggr--; } DebugLogger() << "Message::GAME_START setting AI aggression as " << this_aggr << " (from rnd " << rand_num << "; max aggression " << m_max_aggression << ")"; m_AI->SetAggression(this_aggr); m_AI->StartNewGame(); } m_AI->GenerateOrders(); break; } case Message::SAVE_GAME_COMPLETE: break; case Message::TURN_UPDATE: { //DebugLogger() << "AIClientApp::HandleMessage : extracting turn update message data"; ExtractTurnUpdateMessageData(msg, m_empire_id, m_current_turn, m_empires, m_universe, GetSpeciesManager(), GetCombatLogManager(), GetSupplyManager(), m_player_info); //DebugLogger() << "AIClientApp::HandleMessage : generating orders"; GetUniverse().InitializeSystemGraph(m_empire_id); m_AI->GenerateOrders(); //DebugLogger() << "AIClientApp::HandleMessage : done handling turn update message"; break; } case Message::TURN_PARTIAL_UPDATE: ExtractTurnPartialUpdateMessageData(msg, m_empire_id, m_universe); break; case Message::TURN_PROGRESS: { Message::TurnProgressPhase phase_id; ExtractTurnProgressMessageData(msg, phase_id); ClientApp::HandleTurnPhaseUpdate(phase_id); break; } case Message::PLAYER_STATUS: break; case Message::END_GAME: { DebugLogger() << "Message::END_GAME : Exiting"; DebugLogger() << "Acknowledge server shutdown message."; Networking().SendMessage(AIEndGameAcknowledgeMessage()); ExitApp(0); break; } case Message::PLAYER_CHAT: { std::string data; int player_id; boost::posix_time::ptime timestamp; ExtractServerPlayerChatMessageData(msg, player_id, timestamp, data); m_AI->HandleChatMessage(player_id, data); break; } case Message::DIPLOMACY: { DiplomaticMessage diplo_message; ExtractDiplomacyMessageData(msg, diplo_message); m_AI->HandleDiplomaticMessage(diplo_message); break; } case Message::DIPLOMATIC_STATUS: { DiplomaticStatusUpdateInfo diplo_update; ExtractDiplomaticStatusMessageData(msg, diplo_update); m_AI->HandleDiplomaticStatusUpdate(diplo_update); break; } case Message::LOGGER_CONFIG: { std::set<std::tuple<std::string, std::string, LogLevel>> options; ExtractLoggerConfigMessageData(msg, options); SetLoggerThresholds(options); break; } case Message::CHECKSUM: { TraceLogger() << "(AIClientApp) CheckSum."; VerifyCheckSum(msg); break; } default: { ErrorLogger() << "AIClientApp::HandleMessage : Received unknown Message type code " << msg.Type(); break; } } //DebugLogger() << "AIClientApp::HandleMessage done"; }