Exemple #1
0
FleetMoveOrder::FleetMoveOrder(int empire, int fleet_id, int start_system_id, int dest_system_id, bool append) :
    Order(empire),
    m_fleet(fleet_id),
    m_start_system(start_system_id),
    m_dest_system(dest_system_id),
    m_append(append)
{
    // perform sanity checks
    TemporaryPtr<const Fleet> fleet = GetFleet(FleetID());
    if (!fleet) {
        ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet with id " << FleetID() << " to move, but no such fleet exists";
        return;
    }

    TemporaryPtr<const System> destination_system = GetSystem(DestinationSystemID());
    if (!destination_system) {
        ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet to move to system with id " << DestinationSystemID() << " but no such system exists / is known to exist";
        return;
    }

    // verify that empire specified in order owns specified fleet
    if (!fleet->OwnedBy(EmpireID()) ) {
        ErrorLogger() << "Empire with id " << EmpireID() << " order to move but does not own fleet with id " << FleetID();
        return;
    }

    std::pair<std::list<int>, double> short_path = GetUniverse().ShortestPath(m_start_system, m_dest_system, empire);

    m_route.clear();
    std::copy(short_path.first.begin(), short_path.first.end(), std::back_inserter(m_route));

    // ensure a zero-length (invalid) route is not requested / sent to a fleet
    if (m_route.empty())
        m_route.push_back(m_start_system);
}
Exemple #2
0
void ProductionQueueOrder::ExecuteImpl() const {
    ValidateEmpireID();

    Empire* empire = GetEmpire(EmpireID());
    try {
        if (m_item.build_type == BT_BUILDING || m_item.build_type == BT_SHIP) {
            empire->PlaceBuildInQueue(m_item, m_number, m_location, m_new_index);

        } else if (m_new_blocksize != INVALID_QUANTITY) {
            DebugLogger() << "ProductionQueueOrder quantity " << m_new_quantity << " Blocksize " << m_new_blocksize;
            empire->SetBuildQuantityAndBlocksize(m_index, m_new_quantity, m_new_blocksize);

        } else if (m_new_quantity != INVALID_QUANTITY) {
            empire->SetBuildQuantity(m_index, m_new_quantity);

        } else if (m_new_index != INVALID_INDEX) {
            empire->MoveBuildWithinQueue(m_index, m_new_index);

        } else if (m_rally_point_id != INVALID_OBJECT_ID) {
            DebugLogger() << "ProductionQueueOrder setting rally point to id: " << m_rally_point_id;
            empire->SetBuildRallyPoint(m_index, m_rally_point_id);

        } else if (m_index != INVALID_INDEX) {
            DebugLogger() << "ProductionQueueOrder removing build from index " << m_index;
            empire->RemoveBuildFromQueue(m_index);

        } else {
            ErrorLogger() << "Malformed ProductionQueueOrder.";
        }
    } catch (const std::exception& e) {
        ErrorLogger() << "Build order execution threw exception: " << e.what();
    }
}
Exemple #3
0
void ProductionQueueOrder::ExecuteImpl() const {
    ValidateEmpireID();

    Empire* empire = GetEmpire(EmpireID());
    try {
        if (m_build_type == BT_BUILDING)
            empire->PlaceBuildInQueue(BT_BUILDING, m_item_name, m_number, m_location);
        else if (m_build_type == BT_SHIP)
            empire->PlaceBuildInQueue(BT_SHIP, m_design_id, m_number, m_location);
        else if (m_new_blocksize != INVALID_QUANTITY) {
            DebugLogger() << "ProductionQueueOrder quantity " << m_new_quantity << " Blocksize " << m_new_blocksize;
            empire->SetBuildQuantityAndBlocksize(m_index, m_new_quantity, m_new_blocksize);
        }
        else if (m_new_quantity != INVALID_QUANTITY)
            empire->SetBuildQuantity(m_index, m_new_quantity);
        else if (m_new_index != INVALID_INDEX)
            empire->MoveBuildWithinQueue(m_index, m_new_index);
        else if (m_index != INVALID_INDEX) {
            DebugLogger() << "ProductionQueueOrder removing build from index " << m_index;
            empire->RemoveBuildFromQueue(m_index);
        }
        else
            ErrorLogger() << "Malformed ProductionQueueOrder.";
    } catch (const std::exception& e) {
        ErrorLogger() << "Build order execution threw exception: " << e.what();
    }
}
Exemple #4
0
void AggressiveOrder::ExecuteImpl() const {
    ValidateEmpireID();
    int empire_id = EmpireID();
    if (TemporaryPtr<Fleet> fleet = GetFleet(m_object_id)) {
        if (fleet->OwnedBy(empire_id))
            fleet->SetAggressive(m_aggression);
    }
}
Exemple #5
0
void BombardOrder::ExecuteImpl() const {
    ValidateEmpireID();
    int empire_id = EmpireID();

    TemporaryPtr<Ship> ship = GetShip(m_ship);
    if (!ship) {
        ErrorLogger() << "BombardOrder::ExecuteImpl couldn't get ship with id " << m_ship;
        return;
    }
    if (!ship->CanBombard()) {
        ErrorLogger() << "BombardOrder::ExecuteImpl got ship that can't bombard";
        return;
    }
    if (!ship->OwnedBy(empire_id)) {
        ErrorLogger() << "BombardOrder::ExecuteImpl got ship that isn't owned by the order-issuing empire";
        return;
    }

    TemporaryPtr<Planet> planet = GetPlanet(m_planet);
    if (!planet) {
        ErrorLogger() << "BombardOrder::ExecuteImpl couldn't get planet with id " << m_planet;
        return;
    }
    if (planet->OwnedBy(empire_id)) {
        ErrorLogger() << "BombardOrder::ExecuteImpl given planet that is already owned by the order-issuing empire";
        return;
    }
    if (!planet->Unowned() && Empires().GetDiplomaticStatus(planet->Owner(), empire_id) != DIPLO_WAR) {
        ErrorLogger() << "BombardOrder::ExecuteImpl given planet owned by an empire not at war with order-issuing empire";
        return;
    }
    if (GetUniverse().GetObjectVisibilityByEmpire(m_planet, empire_id) < VIS_BASIC_VISIBILITY) {
        ErrorLogger() << "BombardOrder::ExecuteImpl given planet that empire reportedly has insufficient visibility of, but will be allowed to proceed pending investigation";
        //return;
    }

    int ship_system_id = ship->SystemID();
    if (ship_system_id == INVALID_OBJECT_ID) {
        ErrorLogger() << "BombardOrder::ExecuteImpl given id of ship not in a system";
        return;
    }
    int planet_system_id = planet->SystemID();
    if (ship_system_id != planet_system_id) {
        ErrorLogger() << "BombardOrder::ExecuteImpl given ids of ship and planet not in the same system";
        return;
    }

    // note: multiple ships, from same or different empires, can invade the same planet on the same turn
    DebugLogger() << "BombardOrder::ExecuteImpl set for ship " << m_ship << " "
                           << ship->Name() << " to bombard planet " << m_planet << " " << planet->Name();
    planet->SetIsAboutToBeBombarded(true);
    ship->SetBombardPlanet(m_planet);

    if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID()))
        fleet->StateChangedSignal();
}
Exemple #6
0
void ResearchQueueOrder::ExecuteImpl() const {
    ValidateEmpireID();

    Empire* empire = GetEmpire(EmpireID());
    if (!empire) return;
    if (m_remove) {
        DebugLogger() << "ResearchQueueOrder::ExecuteImpl: removing from queue tech: " << m_tech_name;
        empire->RemoveTechFromQueue(m_tech_name);
    }
    else
        empire->PlaceTechInQueue(m_tech_name, m_position);
}
Exemple #7
0
void GiveObjectToEmpireOrder::ExecuteImpl() const {
    ValidateEmpireID();
    int empire_id = EmpireID();

    if (TemporaryPtr<Fleet> fleet = GetFleet(m_object_id)) {
        if (fleet->OwnedBy(empire_id))
            fleet->SetGiveToEmpire(m_recipient_empire_id);

    } else if (TemporaryPtr<Planet> planet = GetPlanet(m_object_id)) {
        if (planet->OwnedBy(empire_id))
            planet->SetGiveToEmpire(m_recipient_empire_id);
    }
}
Exemple #8
0
bool ScrapOrder::UndoImpl() const {
    ValidateEmpireID();
    int empire_id = EmpireID();

    if (TemporaryPtr<Ship> ship = GetShip(m_object_id)) {
        if (ship->OwnedBy(empire_id))
            ship->SetOrderedScrapped(false);
    } else if (TemporaryPtr<Building> building = GetBuilding(m_object_id)) {
        if (building->OwnedBy(empire_id))
            building->SetOrderedScrapped(false);
    } else {
        return false;
    }
    return true;
}
Exemple #9
0
void ChangeFocusOrder::ExecuteImpl() const {
    ValidateEmpireID();

    TemporaryPtr<Planet> planet = GetPlanet(PlanetID());

    if (!planet) {
        ErrorLogger() << "Illegal planet id specified in change planet focus order.";
        return;
    }

    if (!planet->OwnedBy(EmpireID())) {
        ErrorLogger() << "Empire attempted to issue change planet focus to another's planet.";
        return;
    }

    planet->SetFocus(m_focus);
}
Exemple #10
0
bool GiveObjectToEmpireOrder::UndoImpl() const {
    ValidateEmpireID();
    int empire_id = EmpireID();

    if (TemporaryPtr<Fleet> fleet = GetFleet(m_object_id)) {
        if (fleet->OwnedBy(empire_id)) {
            fleet->ClearGiveToEmpire();
            return true;
        }
    } else if (TemporaryPtr<Planet> planet = GetPlanet(m_object_id)) {
        if (planet->OwnedBy(empire_id)) {
            planet->ClearGiveToEmpire();
            return true;
        }
    }
    return false;
}
Exemple #11
0
void ScrapOrder::ExecuteImpl() const {
    ValidateEmpireID();
    int empire_id = EmpireID();

    if (TemporaryPtr<Ship> ship = GetShip(m_object_id)) {
        if (ship->SystemID() != INVALID_OBJECT_ID && ship->OwnedBy(empire_id)) {
            ship->SetOrderedScrapped(true);
            //DebugLogger() << "ScrapOrder::ExecuteImpl empire: " << empire_id
            //                       << " on ship: " << ship->ID() << " at system: " << ship->SystemID()
            //                       << " ... ordered scrapped?: " << ship->OrderedScrapped();
        }
    } else if (TemporaryPtr<Building> building = GetBuilding(m_object_id)) {
        int planet_id = building->PlanetID();
        if (TemporaryPtr<const Planet> planet = GetPlanet(planet_id)) {
            if (building->OwnedBy(empire_id) && planet->OwnedBy(empire_id))
                building->SetOrderedScrapped(true);
        }
    }
}
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 #13
0
void DeleteFleetOrder::ExecuteImpl() const {
    ValidateEmpireID();

    TemporaryPtr<Fleet> fleet = GetFleet(FleetID());

    if (!fleet) {
        ErrorLogger() << "Illegal fleet id specified in fleet delete order: " << FleetID();
        return;
    }

    if (!fleet->OwnedBy(EmpireID())) {
        ErrorLogger() << "Empire attempted to issue deletion order to another's fleet.";
        return;
    }

    if (!fleet->Empty())
        return; // should be no ships to delete

    TemporaryPtr<System> system = GetSystem(fleet->SystemID());
    if (system)
        system->Remove(fleet->ID());

    GetUniverse().Destroy(FleetID());
}
Exemple #14
0
void RenameOrder::ExecuteImpl() const {
    ValidateEmpireID();

    TemporaryPtr<UniverseObject> obj = GetUniverseObject(m_object);

    if (!obj) {
        ErrorLogger() << "Attempted to rename nonexistant object with id " << m_object;
        return;
    }

    // verify that empire specified in order owns specified object
    if (!obj->OwnedBy(EmpireID())) {
        ErrorLogger() << "Empire specified in rename order does not own specified object.";
        return;
    }

    // disallow the name "", since that denotes an unknown object
    if (m_name == "") {
        ErrorLogger() << "Name \"\" specified in rename order is invalid.";
        return;
    }

    obj->Rename(m_name);
}
Exemple #15
0
void FleetMoveOrder::ExecuteImpl() const {
    ValidateEmpireID();

    TemporaryPtr<Fleet> fleet = GetFleet(FleetID());
    if (!fleet) {
        ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet with id " << FleetID() << " to move, but no such fleet exists";
        return;
    }

    TemporaryPtr<const System> destination_system = GetEmpireKnownSystem(DestinationSystemID(), EmpireID());
    if (!destination_system) {
        ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet to move to system with id " << DestinationSystemID() << " but no such system is known to that empire";
        return;
    }

    // reject empty routes
    if (m_route.empty()) {
        ErrorLogger() << "Empire with id " << EmpireID() << " ordered fleet to move on empty route";
        return;
    }

    // verify that empire specified in order owns specified fleet
    if (!fleet->OwnedBy(EmpireID()) ) {
        ErrorLogger() << "Empire with id " << EmpireID() << " order to move but does not own fleet with id " << FleetID();
        return;
    }


    // verify fleet route first system
    int fleet_sys_id = fleet->SystemID();
    if (!m_append || fleet->TravelRoute().empty()) {
        if (fleet_sys_id != INVALID_OBJECT_ID) {
            // fleet is in a system.  Its move path should also start from that system.
            if (fleet_sys_id != m_start_system) {
                ErrorLogger() << "Empire with id " << EmpireID()
                              << " ordered a fleet to move from a system with id " << m_start_system
                              << " that it is not at.  Fleet is located at system with id " << fleet_sys_id;
                return;
            }
        } else {
            // fleet is not in a system.  Its move path should start from the next system it is moving to.
            int next_system = fleet->NextSystemID();
            if (next_system != m_start_system) {
                ErrorLogger() << "Empire with id " << EmpireID()
                              << " ordered a fleet to move starting from a system with id " << m_start_system
                              << ", but the fleet's next destination is system with id " << next_system;
                return;
            }
        }
    } else {
        // We should append and there is something to append to
        int last_system = fleet->TravelRoute().back();
        if (last_system != m_start_system) {
            ErrorLogger() << "Empire with id " << EmpireID()
                          << " ordered a fleet to continue from system with id " << m_start_system
                          << ", but the fleet's current route won't lead there, it leads to system " << last_system;
            return;
        }
    }


    // convert list of ids to list of System
    std::list<int> route_list;

    if(m_append && !fleet->TravelRoute().empty()){
        route_list = fleet->TravelRoute();
        route_list.erase(--route_list.end());// Remove the last one since it is the first one of the other
    }

    std::copy(m_route.begin(), m_route.end(), std::back_inserter(route_list));


    // validate route.  Only allow travel between systems connected in series by starlanes known to this fleet's owner.

    // check destination validity: disallow movement that's out of range
    std::pair<int, int> eta = fleet->ETA(fleet->MovePath(route_list));
    if (eta.first == Fleet::ETA_NEVER || eta.first == Fleet::ETA_OUT_OF_RANGE) {
        DebugLogger() << "FleetMoveOrder::ExecuteImpl rejected out of range move order";
        return;
    }

    std::string waypoints;
    for (std::list<int>::iterator it = route_list.begin(); it != route_list.end(); ++it) {
        waypoints += std::string(" ") + boost::lexical_cast<std::string>(*it);
    }
    DebugLogger() << "FleetMoveOrder::ExecuteImpl Setting route of fleet " << fleet->ID() << " to " << waypoints;

    fleet->SetRoute(route_list);
}
Exemple #16
0
void ColonizeOrder::ExecuteImpl() const {
    ValidateEmpireID();
    int empire_id = EmpireID();

    TemporaryPtr<Ship> ship = GetShip(m_ship);
    if (!ship) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl couldn't get ship with id " << m_ship;
        return;
    }
    if (!ship->CanColonize()) { // verifies that species exists and can colonize and that ship can colonize
        ErrorLogger() << "ColonizeOrder::ExecuteImpl got ship that can't colonize";
        return;
    }
    if (!ship->OwnedBy(empire_id)) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl got ship that isn't owned by the order-issuing empire";
        return;
    }

    float colonist_capacity = ship->ColonyCapacity();

    TemporaryPtr<Planet> planet = GetPlanet(m_planet);
    if (!planet) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl couldn't get planet with id " << m_planet;
        return;
    }
    if (planet->CurrentMeterValue(METER_POPULATION) > 0.0f) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that already has population";
        return;
    }
    if (!planet->Unowned() && planet->Owner() != empire_id) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that owned by another empire";
        return;
    }
    if (planet->OwnedBy(empire_id) && colonist_capacity == 0.0f) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that is already owned by empire and colony ship with zero capcity";
        return;
    }
    if (GetUniverse().GetObjectVisibilityByEmpire(m_planet, empire_id) < VIS_PARTIAL_VISIBILITY) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given planet that empire has insufficient visibility of";
        return;
    }
    if (colonist_capacity > 0.0f && planet->EnvironmentForSpecies(ship->SpeciesName()) < PE_HOSTILE) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl nonzero colonist capacity and planet that ship's species can't colonize";
        return;
    }

    int ship_system_id = ship->SystemID();
    if (ship_system_id == INVALID_OBJECT_ID) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given id of ship not in a system";
        return;
    }
    int planet_system_id = planet->SystemID();
    if (ship_system_id != planet_system_id) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given ids of ship and planet not in the same system";
        return;
    }
    if (planet->IsAboutToBeColonized()) {
        ErrorLogger() << "ColonizeOrder::ExecuteImpl given id planet that is already being colonized";
        return;
    }

    planet->SetIsAboutToBeColonized(true);
    ship->SetColonizePlanet(m_planet);

    if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID()))
        fleet->StateChangedSignal();
}
Exemple #17
0
void FleetTransferOrder::ExecuteImpl() const {
    ValidateEmpireID();

    // look up the destination fleet
    TemporaryPtr<Fleet> target_fleet = GetFleet(DestinationFleet());
    if (!target_fleet) {
        ErrorLogger() << "Empire attempted to move ships to a nonexistant fleet";
        return;
    }
    // check that destination fleet is owned by empire
    if (!target_fleet->OwnedBy(EmpireID())) {
        ErrorLogger() << "Empire attempted to move ships to a fleet it does not own";
        return;
    }
    // verify that fleet is in a system
    if (target_fleet->SystemID() == INVALID_OBJECT_ID) {
        ErrorLogger() << "Empire attempted to transfer ships to/from fleet(s) not in a system";
        return;
    }

    // check that all ships are in the same system
    std::vector<TemporaryPtr<Ship> > ships = Objects().FindObjects<Ship>(m_add_ships);

    std::vector<TemporaryPtr<Ship> > validated_ships;
    validated_ships.reserve(m_add_ships.size());
    std::vector<int>                 validated_ship_ids;
    validated_ship_ids.reserve(m_add_ships.size());

    for (std::vector<TemporaryPtr<Ship> >::const_iterator it = ships.begin();
         it != ships.end(); ++it)
    {
        TemporaryPtr<Ship> ship = *it;
        if (!ship->OwnedBy(EmpireID()))
            continue;
        if (ship->SystemID() != target_fleet->SystemID())
            continue;
        if (ship->FleetID() == target_fleet->ID())
            continue;
        validated_ships.push_back(ship);
        validated_ship_ids.push_back(ship->ID());
    }
    if (validated_ships.empty())
        return;

    GetUniverse().InhibitUniverseObjectSignals(true);

    // remove from old fleet(s)
    std::set<TemporaryPtr<Fleet> > modified_fleets;
    for (std::vector<TemporaryPtr<Ship> >::iterator it = validated_ships.begin();
         it != validated_ships.end(); ++it)
    {
        TemporaryPtr<Ship> ship = *it;
        if (TemporaryPtr<Fleet> source_fleet = GetFleet(ship->FleetID())) {
            source_fleet->RemoveShip(ship->ID());
            modified_fleets.insert(source_fleet);
        }
        ship->SetFleetID(target_fleet->ID());
    }

    // add to new fleet
    target_fleet->AddShips(validated_ship_ids);

    GetUniverse().InhibitUniverseObjectSignals(false);

    // signal change to fleet states
    modified_fleets.insert(target_fleet);

    for (std::set<TemporaryPtr<Fleet> >::iterator it = modified_fleets.begin();
         it != modified_fleets.end(); ++it)
    {
        TemporaryPtr<Fleet> modified_fleet = *it;
        if (!modified_fleet->Empty())
            modified_fleet->StateChangedSignal();
        // if modified fleet is empty, it should be immently destroyed, so that updating it now is redundant
    }
}
Exemple #18
0
void ShipDesignOrder::ExecuteImpl() const {
    ValidateEmpireID();

    Universe& universe = GetUniverse();

    Empire* empire = GetEmpire(EmpireID());
    if (m_delete_design_from_empire) {
        // player is ordering empire to forget about a particular design
        if (!empire->ShipDesignKept(m_design_id)) {
            ErrorLogger() << "Tried to remove a ShipDesign that the empire wasn't remembering";
            return;
        }
        empire->RemoveShipDesign(m_design_id);

    } else if (m_create_new_design) {
        // check if a design with this ID already exists
        if (universe.GetShipDesign(m_design_id)) {
            ErrorLogger() << "Tried to create a new ShipDesign with an id of an already-existing ShipDesign";
            return;
        }
        ShipDesign* new_ship_design = new ShipDesign(m_name, m_description,
                                                     m_designed_on_turn, EmpireID(), m_hull, m_parts,
                                                     m_icon, m_3D_model, m_name_desc_in_stringtable,
                                                     m_is_monster);

        universe.InsertShipDesignID(new_ship_design, m_design_id);
        universe.SetEmpireKnowledgeOfShipDesign(m_design_id, EmpireID());
        empire->AddShipDesign(m_design_id);

    } else if (m_update_name_or_description) {
        // player is ordering empire to rename a design
        const std::set<int>& empire_known_design_ids = universe.EmpireKnownShipDesignIDs(EmpireID());
        std::set<int>::iterator design_it = empire_known_design_ids.find(m_design_id);
        if (design_it == empire_known_design_ids.end()) {
            ErrorLogger() << "Tried to rename/redescribe a ShipDesign that this empire hasn't seen";
            return;
        }
        const ShipDesign* design = GetShipDesign(*design_it);
        if (!design) {
            ErrorLogger() << "Tried to rename/redescribe a ShipDesign that doesn't exist (but this empire has seen it)!";
            return;
        }
        if (design->DesignedByEmpire() != EmpireID()) {
            ErrorLogger() << "Tried to rename/redescribe a ShipDesign that isn't owned by this empire!";
            return;
        }
        GetUniverse().RenameShipDesign(m_design_id, m_name, m_description);

    } else if (m_move_design) {
        //Move an existing design from its current location to just before the after_design
        if (!empire->ShipDesignKept(m_design_id)) {
            ErrorLogger() << "Tried to move a ShipDesign that the empire wasn't remembering";
            return;
        }
        if (m_design_id == m_design_id_after)
            return;

        empire->RemoveShipDesign(m_design_id);
        empire->AddShipDesign(m_design_id, m_design_id_after);
        DebugLogger() << "Move Ship Design " << m_design_id << " to before " << m_design_id_after;
    } else {
        // player is ordering empire to retain a particular design, so that is can
        // be used to construct ships by that empire.

        // TODO: consider removing this order, so that an empire needs to use
        // espionage or trade to gain access to a ship design made by another
        // player

        // check if empire is already remembering the design
        if (empire->ShipDesignKept(m_design_id)) {
            ErrorLogger() << "Tried to remember a ShipDesign that was already being remembered";
            return;
        }

        // check if the empire can see any objects that have this design (thus enabling it to be copied)
        const std::set<int>& empire_known_design_ids = universe.EmpireKnownShipDesignIDs(EmpireID());
        if (empire_known_design_ids.find(m_design_id) != empire_known_design_ids.end()) {
            empire->AddShipDesign(m_design_id);
        } else {
            ErrorLogger() << "Tried to remember a ShipDesign that this empire hasn't seen";
            return;
        }

    }
}
Exemple #19
0
void NewFleetOrder::ExecuteImpl() const {
    ValidateEmpireID();

    if (m_system_id == INVALID_OBJECT_ID) {
        ErrorLogger() << "Empire attempted to create a new fleet outside a system";
        return;
    }
    TemporaryPtr<System> system = GetSystem(m_system_id);
    if (!system) {
        ErrorLogger() << "Empire attempted to create a new fleet in a nonexistant system";
        return;
    }

    if (m_fleet_names.empty())
        return;
    if (m_fleet_names.size() != m_fleet_ids.size()
        || m_fleet_names.size() != m_ship_id_groups.size()
        || m_fleet_names.size() != m_aggressives.size())
    {
        ErrorLogger() << "NewFleetOrder has inconsistent data container sizes...";
        return;
    }

    GetUniverse().InhibitUniverseObjectSignals(true);
    std::vector<TemporaryPtr<Fleet> > created_fleets;
    created_fleets.reserve(m_fleet_names.size());


    // create fleet for each group of ships
    for (int i = 0; i < static_cast<int>(m_fleet_names.size()); ++i) {
        const std::string&      fleet_name =    m_fleet_names[i];
        int                     fleet_id =      m_fleet_ids[i];
        const std::vector<int>& ship_ids =      m_ship_id_groups[i];
        bool                    aggressive =    m_aggressives[i];

        if (ship_ids.empty())
            continue;   // nothing to do...

        // validate specified ships
        std::vector<TemporaryPtr<Ship> >    validated_ships;
        std::vector<int>                    validated_ships_ids;
        for (unsigned int i = 0; i < ship_ids.size(); ++i) {
            // verify that empire is not trying to take ships from somebody else's fleet
            TemporaryPtr<Ship> ship = GetShip(ship_ids[i]);
            if (!ship) {
                ErrorLogger() << "Empire attempted to create a new fleet with an invalid ship";
                continue;
            }
            if (!ship->OwnedBy(EmpireID())) {
                ErrorLogger() << "Empire attempted to create a new fleet with ships from another's fleet.";
                continue;
            }
            if (ship->SystemID() != m_system_id) {
                ErrorLogger() << "Empire attempted to make a new fleet from ship in the wrong system";
                continue;
            }
            validated_ships.push_back(ship);
            validated_ships_ids.push_back(ship->ID());
        }
        if (validated_ships.empty())
            continue;

        // create fleet
        TemporaryPtr<Fleet> fleet = GetUniverse().CreateFleet(fleet_name, system->X(), system->Y(),
                                                              EmpireID(), fleet_id);
        fleet->GetMeter(METER_STEALTH)->SetCurrent(Meter::LARGE_VALUE);
        fleet->SetAggressive(aggressive);

        // an ID is provided to ensure consistancy between server and client universes
        GetUniverse().SetEmpireObjectVisibility(EmpireID(), fleet->ID(), VIS_FULL_VISIBILITY);

        system->Insert(fleet);

        // new fleet will get same m_arrival_starlane as fleet of the first ship in the list.
        TemporaryPtr<Ship> firstShip = validated_ships[0];
        TemporaryPtr<Fleet> firstFleet = GetFleet(firstShip->FleetID());
        if (firstFleet)
            fleet->SetArrivalStarlane(firstFleet->ArrivalStarlane());

        // remove ships from old fleet(s) and add to new
        for (std::vector<TemporaryPtr<Ship> >::iterator ship_it = validated_ships.begin();
             ship_it != validated_ships.end(); ++ship_it)
        {
            TemporaryPtr<Ship> ship = *ship_it;
            if (TemporaryPtr<Fleet> old_fleet = GetFleet(ship->FleetID()))
                old_fleet->RemoveShip(ship->ID());
            ship->SetFleetID(fleet->ID());
        }
        fleet->AddShips(validated_ships_ids);

        created_fleets.push_back(fleet);
    }

    GetUniverse().InhibitUniverseObjectSignals(false);

    system->FleetsInsertedSignal(created_fleets);
    system->StateChangedSignal();
}
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
void Order::ValidateEmpireID() const {
    if (!(GetEmpire(EmpireID())))
        throw std::runtime_error("Invalid empire ID specified for order.");
}