예제 #1
0
bool BombardOrder::UndoImpl() const {
    TemporaryPtr<Planet> planet = GetPlanet(m_planet);
    if (!planet) {
        ErrorLogger() << "BombardOrder::UndoImpl couldn't get planet with id " << m_planet;
        return false;
    }

    TemporaryPtr<Ship> ship = GetShip(m_ship);
    if (!ship) {
        ErrorLogger() << "BombardOrder::UndoImpl couldn't get ship with id " << m_ship;
        return false;
    }
    if (ship->OrderedBombardPlanet() != m_planet) {
        ErrorLogger() << "BombardOrder::UndoImpl ship is not about to bombard planet";
        return false;
    }

    planet->SetIsAboutToBeBombarded(false);
    ship->ClearBombardPlanet();

    if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID()))
        fleet->StateChangedSignal();

    return true;
}
예제 #2
0
bool ColonizeOrder::UndoImpl() const {
    TemporaryPtr<Planet> planet = GetPlanet(m_planet);
    if (!planet) {
        ErrorLogger() << "ColonizeOrder::UndoImpl couldn't get planet with id " << m_planet;
        return false;
    }
    if (!planet->IsAboutToBeColonized()) {
        ErrorLogger() << "ColonizeOrder::UndoImpl planet is not about to be colonized...";
        return false;
    }

    TemporaryPtr<Ship> ship = GetShip(m_ship);
    if (!ship) {
        ErrorLogger() << "ColonizeOrder::UndoImpl couldn't get ship with id " << m_ship;
        return false;
    }
    if (ship->OrderedColonizePlanet() != m_planet) {
        ErrorLogger() << "ColonizeOrder::UndoImpl ship is not about to colonize planet";
        return false;
    }

    planet->SetIsAboutToBeColonized(false);
    ship->ClearColonizePlanet();

    if (TemporaryPtr<Fleet> fleet = GetFleet(ship->FleetID()))
        fleet->StateChangedSignal();

    return true;
}
예제 #3
0
파일: Fleet.cpp 프로젝트: adesst/freeorion
void Fleet::AddShip(int ship_id) {
    if (this->Contains(ship_id)) {
        Logger().debugStream() << "Fleet::AddShip this fleet '" << this->Name() << "' already contained ship '" << ship_id << "'";
        return;
    }

    Ship* ship = GetShip(ship_id);
    if (!ship) {
        Logger().errorStream() << "Fleet::AddShips() : Attempted to add an id (" << ship_id << ") of a non-ship object to a fleet.";
        return;
    }

    //Logger().debugStream() << "Fleet '" << this->Name() << "' adding ship: " << ship_id;

    // remove ship from old fleet
    if (Fleet* old_fleet = GetFleet(ship->FleetID()))
        old_fleet->RemoveShip(ship_id);

    // ensure ship is in same system as this fleet
    int ship_system_id = ship->SystemID();
    int this_fleet_system_id = this->SystemID();
    if (ship_system_id != this_fleet_system_id)
        if (System* system = GetSystem(this_fleet_system_id))
            system->Insert(ship);   // sets ship's system, remove from old system (if any) and moves ship to system's location (if necessary)

    // add ship to this fleet, and set its internal fleet record

    ship->SetFleetID(ID());
    m_ships.insert(ship_id);

    RecalculateFleetSpeed();
    StateChangedSignal();
}
예제 #4
0
파일: System.cpp 프로젝트: J-d-H/freeorion
void System::Remove(int id) {
    if (id == INVALID_OBJECT_ID)
        return;

    bool removed_fleet = false;

    std::set<int>::iterator it = m_fleets.find(id);
    if (it != m_fleets.end()) {
        m_fleets.erase(it);
        removed_fleet = true;
    }

    it = m_planets.find(id);
    if (it != m_planets.end()) {
        m_planets.erase(it);
        for (int i = 0; i < static_cast<int>(m_orbits.size()); ++i)
            if (m_orbits[i] == id)
                m_orbits[i] = INVALID_OBJECT_ID;
    }

    m_ships.erase(id);
    m_fields.erase(id);
    m_buildings.erase(id);
    m_objects.erase(id);

    if (removed_fleet) {
        if (TemporaryPtr<Fleet> fleet = GetFleet(id)) {
            std::vector<TemporaryPtr<Fleet> > fleets;
            fleets.push_back(fleet);
            FleetsRemovedSignal(fleets);
        }
    }
    StateChangedSignal();
}
예제 #5
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);
}
예제 #6
0
std::vector<Fleet> Game::Fleets() const {
	std::vector<Fleet> r;
	for (size_t i = 0; i < NumFleets(); ++i) {
		r.push_back(GetFleet(i));
	}
	return r;
}
예제 #7
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);
    }
}
예제 #8
0
std::vector<Fleet> Game::EnemyFleets() const {
	std::vector<Fleet> r;
	for (size_t i = 0; i < NumFleets(); ++i) {
		if (state.fleets[i].owner > 1)
			r.push_back(GetFleet(i));
	}
	return r;
}
예제 #9
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();
}
예제 #10
0
    int IssueColonizeOrder(int ship_id, int planet_id) {
        int empire_id = AIClientApp::GetApp()->EmpireID();

        // make sure ship_id is a ship...
        TemporaryPtr<const Ship> ship = GetShip(ship_id);
        if (!ship) {
            Logger().errorStream() << "AIInterface::IssueColonizeOrder : passed an invalid ship_id";
            return 0;
        }

        // get fleet of ship
        TemporaryPtr<const Fleet> fleet = GetFleet(ship->FleetID());
        if (!fleet) {
            Logger().errorStream() << "AIInterface::IssueColonizeOrder : ship with passed ship_id has invalid fleet_id";
            return 0;
        }

        // make sure player owns ship and its fleet
        if (!fleet->OwnedBy(empire_id)) {
            Logger().errorStream() << "AIInterface::IssueColonizeOrder : empire does not own fleet of passed ship";
            return 0;
        }
        if (!ship->OwnedBy(empire_id)) {
            Logger().errorStream() << "AIInterface::IssueColonizeOrder : empire does not own passed ship";
            return 0;
        }

        // verify that planet exists and is un-occupied.
        TemporaryPtr<const Planet> planet = GetPlanet(planet_id);
        if (!planet) {
            Logger().errorStream() << "AIInterface::IssueColonizeOrder : no planet with passed planet_id";
            return 0;
        }
        if ((!planet->Unowned()) && !( planet->OwnedBy(empire_id) && planet->CurrentMeterValue(METER_POPULATION)==0)) {
            Logger().errorStream() << "AIInterface::IssueColonizeOrder : planet with passed planet_id "<<planet_id<<" is already owned, or colonized by own empire";
            return 0;
        }

        // verify that planet is in same system as the fleet
        if (planet->SystemID() != fleet->SystemID()) {
            Logger().errorStream() << "AIInterface::IssueColonizeOrder : fleet and planet are not in the same system";
            return 0;
        }
        if (ship->SystemID() == INVALID_OBJECT_ID) {
            Logger().errorStream() << "AIInterface::IssueColonizeOrder : ship is not in a system";
            return 0;
        }

        AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new ColonizeOrder(empire_id, ship_id, planet_id)));

        return 1;
    }
예제 #11
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);
    }
}
예제 #12
0
void Ship::Copy(TemporaryPtr<const UniverseObject> copied_object, int empire_id) {
    if (copied_object == this)
        return;
    TemporaryPtr<const Ship> copied_ship = boost::dynamic_pointer_cast<const Ship>(copied_object);
    if (!copied_ship) {
        Logger().errorStream() << "Ship::Copy passed an object that wasn't a Ship";
        return;
    }

    int copied_object_id = copied_object->ID();
    Visibility vis = GetUniverse().GetObjectVisibilityByEmpire(copied_object_id, empire_id);
    std::set<std::string> visible_specials = GetUniverse().GetObjectVisibleSpecialsByEmpire(copied_object_id, empire_id);

    UniverseObject::Copy(copied_object, vis, visible_specials);;

    if (vis >= VIS_BASIC_VISIBILITY) {
        if (this->m_fleet_id != copied_ship->m_fleet_id) {
            // as with other containers, removal from the old container is triggered by the contained Object; removal from System is handled by UniverseObject::Copy
            if (TemporaryPtr<Fleet> oldFleet = GetFleet(this->m_fleet_id)) 
                oldFleet->RemoveShip(this->ID());
            this->m_fleet_id =              copied_ship->m_fleet_id; // as with other containers (Systems), actual insertion into fleet ships set is handled by the fleet
        }

        if (vis >= VIS_PARTIAL_VISIBILITY) {
            if (this->Unowned())
                this->m_name =              copied_ship->m_name;

            this->m_design_id =             copied_ship->m_design_id;
            this->m_fighters =              copied_ship->m_fighters;
            this->m_missiles =              copied_ship->m_missiles;
            for (PartMeterMap::const_iterator it = copied_ship->m_part_meters.begin();
                 it != copied_ship->m_part_meters.end(); ++it)
            { this->m_part_meters[it->first]; }
            this->m_species_name =          copied_ship->m_species_name;

            if (vis >= VIS_FULL_VISIBILITY) {
                this->m_ordered_scrapped =          copied_ship->m_ordered_scrapped;
                this->m_ordered_colonize_planet_id= copied_ship->m_ordered_colonize_planet_id;
                this->m_ordered_invade_planet_id  = copied_ship->m_ordered_invade_planet_id;
                this->m_ordered_bombard_planet_id = copied_ship->m_ordered_bombard_planet_id;
                this->m_last_turn_active_in_combat= copied_ship->m_last_turn_active_in_combat;
                this->m_part_meters =               copied_ship->m_part_meters;
                this->m_produced_by_empire_id =     copied_ship->m_produced_by_empire_id;
            }
        }
    }
}
예제 #13
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;
}
예제 #14
0
    int IssueAggressionOrder(int object_id, bool aggressive) {
        int empire_id = AIClientApp::GetApp()->EmpireID();

        TemporaryPtr<const Fleet> fleet = GetFleet(object_id);
        if (!fleet) {
            Logger().errorStream() << "AIInterface::IssueAggressionOrder : no fleet with passed id";
            return 0;
        }
        if (!fleet->OwnedBy(empire_id)) {
            Logger().errorStream() << "AIInterface::IssueAggressionOrder : passed object_id of object not owned by player";
            return 0;
        }

        AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(
            new AggressiveOrder(empire_id, object_id, aggressive)));

        return 1;
    }
예제 #15
0
    int IssueFleetTransferOrder(int ship_id, int new_fleet_id) {
        int empire_id = AIClientApp::GetApp()->EmpireID();

        TemporaryPtr<const Ship> ship = GetShip(ship_id);
        if (!ship) {
            Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : passed an invalid ship_id " << ship_id;
            return 0;
        }
        int ship_sys_id = ship->SystemID();
        if (ship_sys_id == INVALID_OBJECT_ID) {
            Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : ship is not in a system";
            return 0;
        }
        if (!ship->OwnedBy(empire_id)) {
            Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : passed ship_id of ship not owned by player";
            return 0;
        }

        TemporaryPtr<const Fleet> fleet = GetFleet(new_fleet_id);
        if (!fleet) {
            Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : passed an invalid new_fleet_id " << new_fleet_id;
            return 0;
        }
        int fleet_sys_id = fleet->SystemID();
        if (fleet_sys_id == INVALID_OBJECT_ID) {
            Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : new fleet is not in a system";
            return 0;
        }
        if (!fleet->OwnedBy(empire_id)) {
            Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : passed fleet_id "<< new_fleet_id << " of fleet not owned by player";
            return 0;
        }

        if (fleet_sys_id != ship_sys_id) {
            Logger().errorStream() << "AIInterface::IssueFleetTransferOrder : new fleet in system " << fleet_sys_id << " and ship in system "<< ship_sys_id <<  " are not in the same system";
            return 0;
        }

        std::vector<int> ship_ids;
        ship_ids.push_back(ship_id);
        AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new FleetTransferOrder(empire_id, new_fleet_id, ship_ids)));

        return 1;
    }
예제 #16
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());
}
예제 #17
0
    int IssueFleetMoveOrder(int fleet_id, int destination_id) {
        TemporaryPtr<const Fleet> fleet = GetFleet(fleet_id);
        if (!fleet) {
            Logger().errorStream() << "AIInterface::IssueFleetMoveOrder : passed an invalid fleet_id";
            return 0;
        }

        int empire_id = AIClientApp::GetApp()->EmpireID();
        if (!fleet->OwnedBy(empire_id)) {
            Logger().errorStream() << "AIInterface::IssueFleetMoveOrder : passed fleet_id of fleet not owned by player";
            return 0;
        }

        int start_id = fleet->SystemID();
        if (start_id == INVALID_OBJECT_ID)
            start_id = fleet->NextSystemID();

        if (destination_id != INVALID_OBJECT_ID && destination_id == start_id)
            Logger().debugStream() << "AIInterface::IssueFleetMoveOrder : pass destination system id (" << destination_id << ") that fleet is already in";

        AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new FleetMoveOrder(empire_id, fleet_id, start_id, destination_id)));

        return 1;
    }
예제 #18
0
void FleetButton::Init(const std::vector<int>& fleet_IDs, SizeType size_type) {
    //std::cout << "FleetButton::Init" << std::endl;

    // get fleets
    std::vector<TemporaryPtr<const Fleet> > fleets;
    for (std::vector<int>::const_iterator it = fleet_IDs.begin(); it != fleet_IDs.end(); ++it) {
        TemporaryPtr<const Fleet> fleet = GetFleet(*it);
        if (!fleet) {
            ErrorLogger() << "FleetButton::FleetButton couldn't get fleet with id " << *it;
            continue;
        }
        m_fleets.push_back(*it);
        fleets.push_back(fleet);
    }

    // determine owner(s) of fleet(s).  Only care whether or not there is more than one owner, as owner
    // is used to determine colouration
    int owner_id = ALL_EMPIRES;
    int multiple_owners = false;
    if (fleets.empty()) {
        // leave as ALL_EMPIRES
    } else if (fleets.size() == 1) {
        owner_id = (*fleets.begin())->Owner();
    } else {
        owner_id = (*fleets.begin())->Owner();
        // use ALL_EMPIRES if there are multiple owners (including no owner and an owner)
        for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) {
            TemporaryPtr<const Fleet> fleet = *it;
            if (fleet->Owner() != owner_id) {
                owner_id = ALL_EMPIRES;
                multiple_owners = true;
                break;
            }
        }
    }


    // get fleet colour
    if (multiple_owners) {
        SetColor(GG::CLR_WHITE);
    } else if (owner_id == ALL_EMPIRES) {
        // all ships owned by now empire
        bool monsters = true;
        // find if any ship in fleets in button is not a monster
        for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) {
            TemporaryPtr<const Fleet> fleet = *it;
            for (std::set<int>::const_iterator ship_it = fleet->ShipIDs().begin();
                    ship_it != fleet->ShipIDs().end(); ++ship_it)
            {
                if (TemporaryPtr<const Ship> ship = GetShip(*ship_it)) {
                    if (!ship->IsMonster()) {
                        monsters = false;
                        break;
                    }
                }
            }
        }

        if (monsters)
            SetColor(GG::CLR_RED);
        else
            SetColor(GG::CLR_WHITE);
    } else {
        // single empire owner
        if (const Empire* empire = GetEmpire(owner_id))
            SetColor(empire->Color());
        else
            SetColor(GG::CLR_GRAY); // should never be necessary... but just in case
    }


    // determine direction button should be rotated to orient along a starlane
    GLfloat pointing_angle = 0.0f;

    TemporaryPtr<const Fleet> first_fleet;
    if (!m_fleets.empty())
        first_fleet = *fleets.begin();
    if (first_fleet && first_fleet->SystemID() == INVALID_OBJECT_ID && first_fleet->NextSystemID() != INVALID_OBJECT_ID) {
        int next_sys_id = first_fleet->NextSystemID();
        if (TemporaryPtr<const UniverseObject> obj = GetUniverseObject(next_sys_id)) {
            // fleet is not in a system and has a valid next destination, so can orient it in that direction
            // fleet icons might not appear on the screen in the exact place corresponding to their
            // actual universe position, but if they're moving along a starlane, this code will assume
            // their apparent position will only be different from their true position in a direction
            // parallel with the starlane, so the direction from their true position to their destination
            // position can be used to get a direction vector to orient the icon
            float dest_x = obj->X(), dest_y = obj->Y();
            float cur_x = first_fleet->X(), cur_y = first_fleet->Y();
            const MapWnd* map_wnd = ClientUI::GetClientUI()->GetMapWnd();
            GG::Pt dest = map_wnd->ScreenCoordsFromUniversePosition(dest_x, dest_y);
            GG::Pt cur = map_wnd->ScreenCoordsFromUniversePosition(cur_x, cur_y);
            GG::Pt direction_vector = dest - cur;

            if (direction_vector.x != GG::X0 || direction_vector.y != GG::Y0)
                pointing_angle = 360.0f / TWO_PI * std::atan2(static_cast<float>(Value(direction_vector.y)), static_cast<float>(Value(direction_vector.x))) + 90;
        }
    }


    // select icon(s) for fleet(s)
    int num_ships = 0;
    for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) {
        TemporaryPtr<const Fleet> fleet = *it;
        if (fleet)
            num_ships += fleet->NumShips();
    }
    boost::shared_ptr<GG::Texture> size_texture = FleetSizeIcon(num_ships, size_type);
    std::vector<boost::shared_ptr<GG::Texture> > head_textures = FleetHeadIcons(fleets, size_type);


    // add RotatingGraphics for all icons needed
    if (size_texture) {
        RotatingGraphic* icon = new RotatingGraphic(size_texture, GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE);
        icon->SetPhaseOffset(pointing_angle);
        icon->SetRPM(0.0f);
        icon->SetColor(this->Color());
        m_icons.push_back(icon);
        Resize(GG::Pt(size_texture->DefaultWidth(), size_texture->DefaultHeight()));
        AttachChild(icon);
    }

    for (std::vector<boost::shared_ptr<GG::Texture> >::const_iterator it = head_textures.begin();
            it != head_textures.end(); ++it)
    {
        RotatingGraphic* icon = new RotatingGraphic(*it, GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE);
        icon->SetPhaseOffset(pointing_angle);
        icon->SetRPM(0.0f);
        icon->SetColor(this->Color());
        m_icons.push_back(icon);
        if (Width() < (*it)->DefaultWidth())
            Resize(GG::Pt((*it)->DefaultWidth(), (*it)->DefaultHeight()));
        AttachChild(icon);
    }

    // set up selection indicator
    m_selection_indicator = new RotatingGraphic(FleetSelectionIndicatorIcon(), GG::GRAPHIC_FITGRAPHIC | GG::GRAPHIC_PROPSCALE);
    m_selection_indicator->SetRPM(ClientUI::SystemSelectionIndicatorRPM());

    LayoutIcons();

    // Scanlines for not currently-visible objects?
    int empire_id = HumanClientApp::GetApp()->EmpireID();
    if (empire_id == ALL_EMPIRES || !GetOptionsDB().Get<bool>("UI.system-fog-of-war"))
        return;

    bool at_least_one_fleet_visible = false;
    for (std::vector<int>::const_iterator it = m_fleets.begin(); it != m_fleets.end(); ++it) {
        if (GetUniverse().GetObjectVisibilityByEmpire(*it, empire_id) >= VIS_BASIC_VISIBILITY) {
            at_least_one_fleet_visible = true;
            break;
        }
    }

    // Create scanline renderer control
    m_scanline_control = new ScanlineControl(GG::X0, GG::Y0, Width(), Height());

    if (!at_least_one_fleet_visible)
        AttachChild(m_scanline_control);
}
예제 #19
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);
}
예제 #20
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();
}
예제 #21
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
    }
}
예제 #22
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();
}
예제 #23
0
void FleetButton::Init(const std::vector<int>& fleet_IDs, SizeType size_type) {
    if (!scanline_shader && GetOptionsDB().Get<bool>("UI.system-fog-of-war")) {
        boost::filesystem::path shader_path = GetRootDataDir() / "default" / "shaders" / "scanlines.frag";
        std::string shader_text;
        ReadFile(shader_path, shader_text);
        scanline_shader = boost::shared_ptr<ShaderProgram>(
            ShaderProgram::shaderProgramFactory("", shader_text));
    }

    // get fleets
    std::vector<TemporaryPtr<const Fleet> > fleets;
    for (std::vector<int>::const_iterator it = fleet_IDs.begin(); it != fleet_IDs.end(); ++it) {
        TemporaryPtr<const Fleet> fleet = GetFleet(*it);
        if (!fleet) {
            Logger().errorStream() << "FleetButton::FleetButton couldn't get fleet with id " << *it;
            continue;
        }
        m_fleets.push_back(*it);
        fleets.push_back(fleet);
    }

    // determine owner(s) of fleet(s).  Only care whether or not there is more than one owner, as owner
    // is used to determine colouration
    int owner_id = ALL_EMPIRES;
    int multiple_owners = false;
    if (fleets.empty()) {
        // leave as ALL_EMPIRES
    } else if (fleets.size() == 1) {
        owner_id = (*fleets.begin())->Owner();
    } else {
        owner_id = (*fleets.begin())->Owner();
        // use ALL_EMPIRES if there are multiple owners (including no owner and an owner)
        for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) {
            TemporaryPtr<const Fleet> fleet = *it;
            if (fleet->Owner() != owner_id) {
                owner_id = ALL_EMPIRES;
                multiple_owners = true;
                break;
            }
        }
    }


    // get fleet colour
    if (multiple_owners) {
        SetColor(GG::CLR_WHITE);
    } else if (owner_id == ALL_EMPIRES) {
        // all ships owned by now empire
        bool monsters = true;
        // find if any ship in fleets in button is not a monster
        for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) {
            TemporaryPtr<const Fleet> fleet = *it;
            for (std::set<int>::const_iterator ship_it = fleet->ShipIDs().begin();
                 ship_it != fleet->ShipIDs().end(); ++ship_it)
            {
                if (TemporaryPtr<const Ship> ship = GetShip(*ship_it)) {
                    if (!ship->IsMonster()) {
                        monsters = false;
                        break;
                    }
                }
            }
        }

        if (monsters)
            SetColor(GG::CLR_RED);
        else
            SetColor(GG::CLR_WHITE);

    } else {
        // single empire owner
        if (const Empire* empire = Empires().Lookup(owner_id))
            SetColor(empire->Color());
        else
            SetColor(GG::CLR_GRAY); // should never be necessary... but just in case
    }


    // select icon(s) for fleet(s)
    int num_ships = 0;
    for (std::vector<TemporaryPtr<const Fleet> >::const_iterator it = fleets.begin(); it != fleets.end(); ++it) {
        TemporaryPtr<const Fleet> fleet = *it;
        if (fleet)
            num_ships += fleet->NumShips();
    }
    m_size_icon = FleetSizeIcon(num_ships, size_type);
    m_head_icons = FleetHeadIcons(fleets, size_type);

    // resize to fit icon by first determining necessary size, and then resizing
    GG::X texture_width(0);
    GG::Y texture_height(0);

    if (!m_head_icons.empty()) {
        texture_width = m_head_icons.front()->DefaultWidth();
        texture_height = m_head_icons.front()->DefaultHeight();
    }
    if (m_size_icon) {
        texture_width = std::max(texture_width, m_size_icon->DefaultWidth());
        texture_height = std::max(texture_height, m_size_icon->DefaultHeight());
    }


    // determine if fleet icon should be rotated.  this should be done if the fleet is moving along
    // a starlane, which is the case if the fleet is not in a system and has a valid next system
    GG::Pt direction_vector(GG::X(0), GG::Y(1));    // default, unrotated button orientation

    TemporaryPtr<const Fleet> first_fleet;
    if (!m_fleets.empty())
        first_fleet = *fleets.begin();
    
    if (first_fleet && first_fleet->SystemID() == INVALID_OBJECT_ID) {
        int next_sys_id = first_fleet->NextSystemID();
        if (TemporaryPtr<const UniverseObject> obj = GetUniverseObject(next_sys_id)) {
            // fleet is not in a system and has a valid next destination, so can orient it in that direction
            // fleet icons might not appear on the screen in the exact place corresponding to their 
            // actual universe position, but if they're moving along a starlane, this code will assume
            // their apparent position will only be different from their true position in a direction
            // parallel with the starlane, so the direction from their true position to their destination
            // position can be used to get a direction vector to orient the icon
            double dest_x = obj->X(), dest_y = obj->Y();
            double cur_x = first_fleet->X(), cur_y = first_fleet->Y();
            const MapWnd* map_wnd = ClientUI::GetClientUI()->GetMapWnd();
            GG::Pt dest = map_wnd->ScreenCoordsFromUniversePosition(dest_x, dest_y);
            GG::Pt cur = map_wnd->ScreenCoordsFromUniversePosition(cur_x, cur_y);
            direction_vector = dest - cur;
        }
    }

    // check for unrotated texture
    if (Value(direction_vector.x) == 0) {
        // not rotated.  can do simple texture blits
        m_vertex_components.clear();
    } else {
        // texture is rotated, so need some extra math
        // get rotated corner vetex x and y components (x1, y1, x2, y2, x3, y3, x4, y4) for texture of appropriate size
        m_vertex_components = VectorAlignedQuadVertices(direction_vector, Value(texture_height), Value(texture_width));
    }

    // size icon according to texture size (average two dimensions)
    int diameter = static_cast<int>((Value(texture_width) + Value(texture_height)) / 2.0);
    Resize(GG::Pt(GG::X(diameter), GG::Y(diameter)));

    // get selection indicator texture
    m_selection_texture = ClientUI::GetTexture(ClientUI::ArtDir() / "icons" / "fleet" / "fleet_selection.png", true);
}
예제 #24
0
SitRepEntry CreateFleetArrivedAtDestinationSitRep(int system_id, int fleet_id, int recipient_empire_id) {
    TemporaryPtr<const Fleet> fleet = GetFleet(fleet_id);

    //bool system_contains_recipient_empire_planets = false;
    //if (const System* system = GetSystem(system_id)) {
    //    std::vector<int> system_planets = system->FindObjectIDs<Planet>();
    //    for (std::vector<int>::const_iterator planet_it = system_planets.begin();
    //         planet_it != system_planets.end(); ++planet_it)
    //    {
    //        const Planet* planet = GetPlanet(*planet_it);
    //        if (!planet || planet->Unowned())
    //            continue;
    //        if (planet->OwnedBy(recipient_empire_id)) {
    //            system_contains_recipient_empire_planets = true;
    //            break;
    //        }
    //    }
    //}

    //There are variants of this message for {monster, own, foreign} * {one ship, fleet}.
    // TODO: More variants for systems with / without recipient-owned planets
    //These should really be assembled from several pieces: a fleet description,
    //a system description, and a message template into which both are substituted.
    if (!fleet) {
        SitRepEntry sitrep(UserStringNop("SITREP_FLEET_ARRIVED_AT_SYSTEM"), "icons/sitrep/fleet_arrived.png");
        sitrep.AddVariable(VarText::SYSTEM_ID_TAG,  boost::lexical_cast<std::string>(system_id));
        sitrep.AddVariable(VarText::FLEET_ID_TAG,   boost::lexical_cast<std::string>(fleet_id));
        return sitrep;
    } else if (fleet->Unowned() && fleet->HasMonsters()) {
        if (fleet->NumShips() == 1) {
            SitRepEntry sitrep(UserStringNop("SITREP_MONSTER_SHIP_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png");
            sitrep.AddVariable(VarText::SYSTEM_ID_TAG,     boost::lexical_cast<std::string>(system_id));
            sitrep.AddVariable(VarText::FLEET_ID_TAG,      boost::lexical_cast<std::string>(fleet_id));
            int ship_id = *fleet->ShipIDs().begin();
            sitrep.AddVariable(VarText::SHIP_ID_TAG,       boost::lexical_cast<std::string>(ship_id));
            if (TemporaryPtr<const Ship> ship = GetShip(ship_id))
                sitrep.AddVariable(VarText::DESIGN_ID_TAG, boost::lexical_cast<std::string>(ship->DesignID()));
            return sitrep;
        } else {
            SitRepEntry sitrep(UserStringNop("SITREP_MONSTER_FLEET_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png");
            sitrep.AddVariable(VarText::SYSTEM_ID_TAG,  boost::lexical_cast<std::string>(system_id));
            sitrep.AddVariable(VarText::FLEET_ID_TAG,   boost::lexical_cast<std::string>(fleet_id));
            sitrep.AddVariable(VarText::RAW_TEXT_TAG,   boost::lexical_cast<std::string>(fleet->NumShips()));
            return sitrep;
        }
    } else if (fleet->Unowned()) {
        SitRepEntry sitrep(UserStringNop("SITREP_FLEET_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png");
        sitrep.AddVariable(VarText::SYSTEM_ID_TAG,  boost::lexical_cast<std::string>(system_id));
        sitrep.AddVariable(VarText::FLEET_ID_TAG,   boost::lexical_cast<std::string>(fleet_id));
        sitrep.AddVariable(VarText::RAW_TEXT_TAG,   boost::lexical_cast<std::string>(fleet->NumShips()));
        return sitrep;
    } else if (fleet->OwnedBy(recipient_empire_id)) {
        if (fleet->NumShips() == 1) {
            SitRepEntry sitrep(UserStringNop("SITREP_OWN_SHIP_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png");
            sitrep.AddVariable(VarText::SYSTEM_ID_TAG,     boost::lexical_cast<std::string>(system_id));
            sitrep.AddVariable(VarText::FLEET_ID_TAG,      boost::lexical_cast<std::string>(fleet_id));
            sitrep.AddVariable(VarText::EMPIRE_ID_TAG,     boost::lexical_cast<std::string>(fleet->Owner()));
            int ship_id = *fleet->ShipIDs().begin();
            sitrep.AddVariable(VarText::SHIP_ID_TAG,       boost::lexical_cast<std::string>(ship_id));
            if (TemporaryPtr<const Ship> ship = GetShip(ship_id))
                sitrep.AddVariable(VarText::DESIGN_ID_TAG, boost::lexical_cast<std::string>(ship->DesignID()));
            return sitrep;
        } else {
            SitRepEntry sitrep(UserStringNop("SITREP_OWN_FLEET_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png");
            sitrep.AddVariable(VarText::SYSTEM_ID_TAG,  boost::lexical_cast<std::string>(system_id));
            sitrep.AddVariable(VarText::FLEET_ID_TAG,   boost::lexical_cast<std::string>(fleet_id));
            sitrep.AddVariable(VarText::EMPIRE_ID_TAG,  boost::lexical_cast<std::string>(fleet->Owner()));
            sitrep.AddVariable(VarText::RAW_TEXT_TAG,   boost::lexical_cast<std::string>(fleet->NumShips()));
            return sitrep;
        }
    } else {
        if (fleet->NumShips() == 1) {
            SitRepEntry sitrep(UserStringNop("SITREP_FOREIGN_SHIP_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png");
            sitrep.AddVariable(VarText::SYSTEM_ID_TAG,     boost::lexical_cast<std::string>(system_id));
            sitrep.AddVariable(VarText::FLEET_ID_TAG,      boost::lexical_cast<std::string>(fleet_id));
            sitrep.AddVariable(VarText::EMPIRE_ID_TAG,     boost::lexical_cast<std::string>(fleet->Owner()));
            int ship_id = *fleet->ShipIDs().begin();
            sitrep.AddVariable(VarText::SHIP_ID_TAG,       boost::lexical_cast<std::string>(ship_id));
            if (TemporaryPtr<const Ship> ship = GetShip(ship_id))
                sitrep.AddVariable(VarText::DESIGN_ID_TAG, boost::lexical_cast<std::string>(ship->DesignID()));
            return sitrep;
        } else {
            SitRepEntry sitrep(UserStringNop("SITREP_FOREIGN_FLEET_ARRIVED_AT_DESTINATION"), "icons/sitrep/fleet_arrived.png");
            sitrep.AddVariable(VarText::SYSTEM_ID_TAG,  boost::lexical_cast<std::string>(system_id));
            sitrep.AddVariable(VarText::FLEET_ID_TAG,   boost::lexical_cast<std::string>(fleet_id));
            sitrep.AddVariable(VarText::EMPIRE_ID_TAG,  boost::lexical_cast<std::string>(fleet->Owner()));
            sitrep.AddVariable(VarText::RAW_TEXT_TAG,   boost::lexical_cast<std::string>(fleet->NumShips()));
            return sitrep;
        }
    }
}
예제 #25
0
    int IssueInvadeOrder(int ship_id, int planet_id) {
        int empire_id = AIClientApp::GetApp()->EmpireID();

        // make sure ship_id is a ship...
        TemporaryPtr<const Ship> ship = GetShip(ship_id);
        if (!ship) {
            Logger().errorStream() << "AIInterface::IssueInvadeOrder : passed an invalid ship_id";
            return 0;
        }

        // get fleet of ship
        TemporaryPtr<const Fleet> fleet = GetFleet(ship->FleetID());
        if (!fleet) {
            Logger().errorStream() << "AIInterface::IssueInvadeOrder : ship with passed ship_id has invalid fleet_id";
            return 0;
        }

        // make sure player owns ship and its fleet
        if (!fleet->OwnedBy(empire_id)) {
            Logger().errorStream() << "AIInterface::IssueInvadeOrder : empire does not own fleet of passed ship";
            return 0;
        }
        if (!ship->OwnedBy(empire_id)) {
            Logger().errorStream() << "AIInterface::IssueInvadeOrder : empire does not own passed ship";
            return 0;
        }

        // verify that planet exists and is occupied by another empire
        TemporaryPtr<const Planet> planet = GetPlanet(planet_id);
        if (!planet) {
            Logger().errorStream() << "AIInterface::IssueInvadeOrder : no planet with passed planet_id";
            return 0;
        }
        bool owned_by_invader = planet->OwnedBy(empire_id);
        bool unowned = planet->Unowned();
        bool populated = planet->CurrentMeterValue(METER_POPULATION) > 0.;
        bool visible = GetUniverse().GetObjectVisibilityByEmpire(planet_id, empire_id) >= VIS_PARTIAL_VISIBILITY;
        bool vulnerable = planet->CurrentMeterValue(METER_SHIELD) <= 0.;
        float shields = planet->CurrentMeterValue(METER_SHIELD);
        std::string thisSpecies = planet->SpeciesName();
        //bool being_invaded = planet->IsAboutToBeInvaded();
        bool invadable = !owned_by_invader && vulnerable && (populated || !unowned) && visible ;// && !being_invaded; a 'being_invaded' check prevents AI from invading with multiple ships at once, which is important
        if (!invadable) {
            Logger().errorStream() << "AIInterface::IssueInvadeOrder : planet with passed planet_id "<< planet_id <<" and species "<<thisSpecies<<" is  "
                                   << "not invadable due to one or more of: owned by invader empire, "
                                   << "not visible to invader empire, has shields above zero, "
                                   << "or is already being invaded.";
            if (!unowned) 
                Logger().errorStream() << "AIInterface::IssueInvadeOrder : planet (id " << planet_id << ") is not unowned";
            if (!visible)
                Logger().errorStream() << "AIInterface::IssueInvadeOrder : planet (id " << planet_id << ") is not visible";
            if (!vulnerable)
                Logger().errorStream() << "AIInterface::IssueInvadeOrder : planet (id " << planet_id << ") is not vulnerable, shields at "<<shields;
            return 0;
        }

        // verify that planet is in same system as the fleet
        if (planet->SystemID() != fleet->SystemID()) {
            Logger().errorStream() << "AIInterface::IssueInvadeOrder : fleet and planet are not in the same system";
            return 0;
        }
        if (ship->SystemID() == INVALID_OBJECT_ID) {
            Logger().errorStream() << "AIInterface::IssueInvadeOrder : ship is not in a system";
            return 0;
        }

        AIClientApp::GetApp()->Orders().IssueOrder(OrderPtr(new InvadeOrder(empire_id, ship_id, planet_id)));

        return 1;
    }
예제 #26
0
CombatInfo::CombatInfo(int system_id_) :
    system_id(system_id_)
{
    const Universe& universe = GetUniverse();
    const ObjectMap& universe_objects = universe.Objects();

    const System* system = universe_objects.Object<System>(system_id);
    if (!system) {
        Logger().errorStream() << "CombatInfo constructed with invalid system id: " << system_id;
        return;
    }

    // add copy of system to full / complete objects in combat
    System* copy_system = system->Clone();
    objects.Insert(system_id, copy_system);


    // find ships and their owners in system
    std::vector<int> ship_ids = system->FindObjectIDs<Ship>();
    for (std::vector<int>::const_iterator it = ship_ids.begin(); it != ship_ids.end(); ++it) {
        int ship_id = *it;
        const Ship* ship = GetShip(ship_id);
        if (!ship) {
            Logger().errorStream() << "CombatInfo::CombatInfo couldn't get ship with id " << ship_id << " in system " << system->Name() << " (" << system_id << ")";
            continue;
        }

        // add owner to empires that have assets in this battle
        empire_ids.insert(ship->Owner());

        // add copy of ship to full / complete copy of objects in system
        Ship* copy = ship->Clone();
        objects.Insert(ship_id, copy);
    }

    // find planets and their owners in system
    std::vector<int> planet_ids = system->FindObjectIDs<Planet>();
    for (std::vector<int>::const_iterator it = planet_ids.begin(); it != planet_ids.end(); ++it) {
        int planet_id = *it;
        const Planet* planet = GetPlanet(planet_id);
        if (!planet) {
            Logger().errorStream() << "CombatInfo::CombatInfo couldn't get planet with id " << planet_id << " in system " << system->Name() << " (" << system_id << ")";
            continue;
        }

        // if planet is populated, add owner to empires that have assets in this battle
        if (planet->CurrentMeterValue(METER_POPULATION) > 0.0)
            empire_ids.insert(planet->Owner());

        // add copy of ship to full / complete copy of objects in system
        Planet* copy = planet->Clone();
        objects.Insert(planet_id, copy);
    }

    // TODO: should buildings be considered separately?

    // now that all participants in the battle have been found, loop through
    // objects again to assemble each participant empire's latest
    // known information about all objects in this battle

    // system
    for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) {
        int empire_id = *empire_it;
        if (empire_id == ALL_EMPIRES)
            continue;
        System* visibility_limited_copy = system->Clone(empire_id);
        empire_known_objects[empire_id].Insert(system_id, visibility_limited_copy);
    }
    // ships
    for (std::vector<int>::const_iterator it = ship_ids.begin(); it != ship_ids.end(); ++it) {
        int ship_id = *it;
        const Ship* ship = GetShip(ship_id);
        if (!ship) {
            Logger().errorStream() << "CombatInfo::CombatInfo couldn't get ship with id " << ship_id << " in system " << system->Name() << " (" << system_id << ")";
            continue;
        }
        const Fleet* fleet = GetFleet(ship->FleetID());
        if (!fleet) {
            Logger().errorStream() << "CombatInfo::CombatInfo couldn't get fleet with id " << ship->FleetID() << " in system " << system->Name() << " (" << system_id << ")";
            continue;
        }

        for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) {
            int empire_id = *empire_it;
            if (empire_id == ALL_EMPIRES)
                continue;
            if (universe.GetObjectVisibilityByEmpire(ship_id, empire_id) >= VIS_BASIC_VISIBILITY ||
                   (fleet->Aggressive() &&
                       (empire_id == ALL_EMPIRES ||
                        fleet->Unowned() ||
                        Empires().GetDiplomaticStatus(empire_id, fleet->Owner()) == DIPLO_WAR)))
            {
                Ship* visibility_limited_copy = ship->Clone(empire_id);
                empire_known_objects[empire_id].Insert(ship_id, visibility_limited_copy);
            }
        }
    }
    // planets
    for (std::vector<int>::const_iterator it = planet_ids.begin(); it != planet_ids.end(); ++it) {
        int planet_id = *it;
        const Planet* planet = GetPlanet(planet_id);
        if (!planet) {
            Logger().errorStream() << "CombatInfo::CombatInfo couldn't get planet with id " << planet_id << " in system " << system->Name() << " (" << system_id << ")";
            continue;
        }

        for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) {
            int empire_id = *empire_it;
            if (empire_id == ALL_EMPIRES)
                continue;
            if (universe.GetObjectVisibilityByEmpire(planet_id, empire_id) >= VIS_BASIC_VISIBILITY) {
                Planet* visibility_limited_copy = planet->Clone(empire_id);
                empire_known_objects[empire_id].Insert(planet_id, visibility_limited_copy);
            }
        }
    }

    // after battle is simulated, any changes to latest known or actual objects
    // will be copied back to the main Universe's ObjectMap and the Universe's
    // empire latest known objects ObjectMap
}
예제 #27
0
CombatInfo::CombatInfo(int system_id_, int turn_) :
    turn(turn_),
    system_id(system_id_)
{
    TemporaryPtr<System> system = ::GetSystem(system_id);
    if (!system) {
        Logger().errorStream() << "CombatInfo constructed with invalid system id: " << system_id;
        return;
    }

    // add system to full / complete objects in combat - NOTE: changed from copy of system
    objects.Insert(system);


    // find ships and their owners in system
    std::vector<TemporaryPtr<Ship> > ships =
        Objects().FindObjects<Ship>(system->ShipIDs());

    for (std::vector<TemporaryPtr<Ship> >::const_iterator ship_it = ships.begin();
         ship_it != ships.end(); ++ship_it)
    {
        TemporaryPtr<Ship> ship = *ship_it;
        // add owner to empires that have assets in this battle
        empire_ids.insert(ship->Owner());

        objects.Insert(ship);
    }

    // find planets and their owners in system
    std::vector<TemporaryPtr<Planet> > planets =
        Objects().FindObjects<Planet>(system->PlanetIDs());

    for (std::vector<TemporaryPtr<Planet> >::const_iterator planet_it = planets.begin();
         planet_it != planets.end(); ++planet_it)
    {
        TemporaryPtr<Planet> planet = *planet_it;
        // if planet is populated, add owner to empires that have assets in this battle
        if (planet->CurrentMeterValue(METER_POPULATION) > 0.0)
            empire_ids.insert(planet->Owner());

        objects.Insert(planet);
    }

    // TODO: should buildings be considered separately?

    // now that all participants in the battle have been found, loop through
    // objects again to assemble each participant empire's latest
    // known information about all objects in this battle

    // system
    for (std::set<int>::const_iterator empire_it = empire_ids.begin();
         empire_it != empire_ids.end(); ++empire_it)
    {
        int empire_id = *empire_it;
        if (empire_id == ALL_EMPIRES)
            continue;
        empire_known_objects[empire_id].Insert(GetEmpireKnownSystem(system->ID(), empire_id));
    }

    // ships
    for (std::vector<TemporaryPtr<Ship> >::const_iterator it = ships.begin();
         it != ships.end(); ++it)
    {
        TemporaryPtr<Ship> ship = *it;
        int ship_id = ship->ID();
        TemporaryPtr<const Fleet> fleet = GetFleet(ship->FleetID());
        if (!fleet) {
            Logger().errorStream() << "CombatInfo::CombatInfo couldn't get fleet with id "
                                   << ship->FleetID() << " in system " << system->Name() << " (" << system_id << ")";
            continue;
        }

        for (std::set<int>::const_iterator empire_it = empire_ids.begin();
             empire_it != empire_ids.end(); ++empire_it)
        {
            int empire_id = *empire_it;
            if (empire_id == ALL_EMPIRES)
                continue;
            if (GetUniverse().GetObjectVisibilityByEmpire(ship_id, empire_id) >= VIS_BASIC_VISIBILITY ||
                   (fleet->Aggressive() &&
                       (empire_id == ALL_EMPIRES ||
                        fleet->Unowned() ||
                        Empires().GetDiplomaticStatus(empire_id, fleet->Owner()) == DIPLO_WAR)))
            { empire_known_objects[empire_id].Insert(GetEmpireKnownShip(ship->ID(), empire_id));}
        }
    }

    // planets
    for (std::vector<TemporaryPtr<Planet> >::const_iterator it = planets.begin();
         it != planets.end(); ++it)
    {
        TemporaryPtr<Planet> planet = *it;
        int planet_id = planet->ID();

        for (std::set<int>::const_iterator empire_it = empire_ids.begin(); empire_it != empire_ids.end(); ++empire_it) {
            int empire_id = *empire_it;
            if (empire_id == ALL_EMPIRES)
                continue;
            if (GetUniverse().GetObjectVisibilityByEmpire(planet_id, empire_id) >= VIS_BASIC_VISIBILITY) {
                empire_known_objects[empire_id].Insert(GetEmpireKnownPlanet(planet->ID(), empire_id));
            }
        }
    }

    // after battle is simulated, any changes to latest known or actual objects
    // will be copied back to the main Universe's ObjectMap and the Universe's
    // empire latest known objects ObjectMap - NOTE: Using the real thing now
}