Beispiel #1
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();
}