Пример #1
0
/// Gibt eine Liste mit möglichen Verbindungen zurück
void nobHarborBuilding::GetShipConnections(std::vector<ShipConnection>& connections) const
{
	// Is there any harbor building at all? (could be destroyed)?
	if(gwg->GetGOT(this->x,this->y) !=GOT_NOB_HARBORBUILDING)
		// Then good-bye
		return;

	// Is the harbor being destroyed right now?
	if (IsBeingDestroyedNow())
		return;

	std::vector<nobHarborBuilding*> harbor_buildings;
	for(unsigned short sea_id = 0;sea_id<6;++sea_id)
	{
		if(sea_ids[sea_id] != 0)
			players->getElement(player)->GetHarborBuildings(harbor_buildings,sea_ids[sea_id]);
	}

	for(unsigned i = 0;i<harbor_buildings.size();++i)
	{
		ShipConnection sc;
		sc.dest = harbor_buildings[i];
		// Als Kantengewicht nehmen wir die doppelte Entfernung (evtl muss ja das Schiff erst kommen)
		// plus einer Kopfpauschale (Ein/Ausladen usw. dauert ja alles)
		sc.way_costs = 2*gwg->CalcHarborDistance(GetHarborPosID(),harbor_buildings[i]->GetHarborPosID()) + 10; 
		connections.push_back(sc);
	}
}
Пример #2
0
/// Gibt eine Liste mit möglichen Verbindungen zurück
std::vector<nobHarborBuilding::ShipConnection> nobHarborBuilding::GetShipConnections() const
{
    std::vector<ShipConnection> connections;

    // Is the harbor being destroyed right now? Could happen due to pathfinding for wares that get notified about this buildings destruction
    if (IsBeingDestroyedNow())
        return connections;

    // Should already be handled by the above check, but keep the runtime check for now (TODO: remove runtime check)
    RTTR_Assert(gwg->GetGOT(pos) == GOT_NOB_HARBORBUILDING);

    // Is there any harbor building at all? (could be destroyed)?
    if(gwg->GetGOT(pos) != GOT_NOB_HARBORBUILDING)
        return connections;

    std::vector<nobHarborBuilding*> harbor_buildings;
    for(unsigned short sea_id = 0; sea_id < 6; ++sea_id)
    {
        if(sea_ids[sea_id] != 0)
            gwg->GetPlayer(player).GetHarborBuildings(harbor_buildings, sea_ids[sea_id]);
    }

    for(unsigned i = 0; i < harbor_buildings.size(); ++i)
    {
        ShipConnection sc;
        sc.dest = harbor_buildings[i];
        // Als Kantengewicht nehmen wir die doppelte Entfernung (evtl muss ja das Schiff erst kommen)
        // plus einer Kopfpauschale (Ein/Ausladen usw. dauert ja alles)
        sc.way_costs = 2 * gwg->CalcHarborDistance(GetHarborPosID(), harbor_buildings[i]->GetHarborPosID()) + 10;
        connections.push_back(sc);
    }
    return connections;
}
Пример #3
0
/// Gibt die Angreifergebäude zurück, die dieser Hafen für einen Seeangriff zur Verfügung stellen kann
void nobHarborBuilding::GetAttackerBuildingsForSeaAttack(std::vector<SeaAttackerBuilding> * buildings,
											const std::vector<unsigned>& defender_harbors)
{
	std::list<nobBaseMilitary*> all_buildings;
	gwg->LookForMilitaryBuildings(all_buildings,x,y,3);

	// Und zählen
	for(std::list<nobBaseMilitary*>::iterator it = all_buildings.begin();it!=all_buildings.end();++it)
	{
		if((*it)->GetGOT() != GOT_NOB_MILITARY)
			continue;
			
		// Liegt er auch im groben Raster und handelt es sich um den gleichen Besitzer?
		if((*it)->GetPlayer() != player || gwg->CalcDistance((*it)->GetX(),(*it)->GetY(),x,y) > BASE_ATTACKING_DISTANCE)
			continue;

		// Weg vom Hafen zum Militärgebäude berechnen
		if(!gwg->FindFreePath((*it)->GetX(),(*it)->GetY(),x,y,false,MAX_ATTACKING_RUN_DISTANCE,NULL,NULL,NULL,NULL,NULL,NULL,false))
			continue;

		// Entfernung zwischen Hafen und möglichen Zielhafenpunkt ausrechnen
		unsigned min_distance = 0xffffffff;
		for(unsigned i = 0;i<defender_harbors.size();++i)
		{
			min_distance = min(min_distance, gwg->CalcHarborDistance(GetHarborPosID(),defender_harbors.at(i)));
		}
		
		// Gebäude suchen, vielleicht schon vorhanden?
		std::vector<SeaAttackerBuilding>::iterator it2 = std::find(buildings->begin(), buildings->end(), 
		static_cast<nobMilitary*>(*it));
		// Noch nicht vorhanden? 
		if(it2 == buildings->end())
		{
			// Dann neu hinzufügen
			SeaAttackerBuilding sab = { static_cast<nobMilitary*>(*it), this, min_distance };
			buildings->push_back(sab);
		}
		// Oder vorhanden und jetzige Distanz ist kleiner?
		else if(min_distance < it2->distance)
		{
			// Dann Distanz und betreffenden Hafen aktualisieren
			it2->distance = min_distance;
			it2->harbor = this;
		}
	}
}
Пример #4
0
/// Schiff ist angekommen
void nobHarborBuilding::ShipArrived(noShip* ship)
{
    // get a new job - priority is given according to this list: attack,expedition,exploration,transport
    // any attackers ready?
    if(!soldiers_for_ships.empty())
    {
        // load all soldiers that share the same target as the first soldier in the list
        std::list<noFigure*> attackers;
        MapPoint ship_dest = soldiers_for_ships.begin()->dest;

        for(std::list<SoldierForShip>::iterator it = soldiers_for_ships.begin(); it != soldiers_for_ships.end();)
        {
            if(it->dest == ship_dest)
            {
                inventory.visual.Remove(it->attacker->GetJobType());
                attackers.push_back(it->attacker);
                it = soldiers_for_ships.erase(it);
            }
            else
                ++it;
        }

        ship->PrepareSeaAttack(GetHarborPosID(), ship_dest, attackers);
        return;
    }
    //Expedition ready?
    if(expedition.active && expedition.builder
            && expedition.boards == BUILDING_COSTS[nation][BLD_HARBORBUILDING].boards
            && expedition.stones == BUILDING_COSTS[nation][BLD_HARBORBUILDING].stones)
    {
        // Aufräumen am Hafen
        expedition.active = false;
        // Expedition starten
        ship->StartExpedition(GetHarborPosID());
        return;
    }
    // Exploration-Expedition ready?
    if(IsExplorationExpeditionReady())
    {
        // Aufräumen am Hafen
        exploration_expedition.active = false;
        // Expedition starten
        ship->StartExplorationExpedition(GetHarborPosID());
        inventory.visual.Remove(JOB_SCOUT, exploration_expedition.scouts);
        return;
    }

    // Gibt es Waren oder Figuren, die ein Schiff von hier aus nutzen wollen?
    if(!wares_for_ships.empty() || !figures_for_ships.empty())
    {
        // Das Ziel wird nach der ersten Figur bzw. ersten Ware gewählt
        // actually since the wares might not yet have informed the harbor that their target harbor was destroyed we pick the first figure/ware with a valid target instead
        MapPoint dest;
        bool gotdest = false;
        for(std::list<FigureForShip>::iterator it = figures_for_ships.begin(); it != figures_for_ships.end(); ++it)
        {
            noBase* nb = gwg->GetNO(it->dest);
            if(nb->GetGOT() == GOT_NOB_HARBORBUILDING && gwg->GetNode(it->dest).owner == player + 1) //target is a harbor and owned by the same player
            {
                dest = it->dest;
                gotdest = true;
                break;
            }
        }
        for(std::list<Ware*>::iterator it = wares_for_ships.begin(); !gotdest && it != wares_for_ships.end(); ++it)
        {
            noBase* nb = gwg->GetNO((*it)->GetNextHarbor());
            if(nb->GetGOT() == GOT_NOB_HARBORBUILDING && gwg->GetNode((*it)->GetNextHarbor()).owner == player + 1)
            {
                dest = (*it)->GetNextHarbor();
                gotdest = true;
                break;
            }
        }
        if(gotdest)
        {
            std::list<noFigure*> figures;

            // Figuren auswählen, die zu diesem Ziel wollen
            for(std::list<FigureForShip>::iterator it = figures_for_ships.begin(); it != figures_for_ships.end() && figures.size() < SHIP_CAPACITY;)
            {
                if(it->dest == dest)
                {
                    figures.push_back(it->fig);
                    it->fig->StartShipJourney();
                    inventory.visual.Remove(it->fig->GetJobType());
                    it = figures_for_ships.erase(it);
                }
                else
                    ++it;
            }

            // Und noch die Waren auswählen
            std::list<Ware*> wares;
            for(std::list<Ware*>::iterator it = wares_for_ships.begin(); it != wares_for_ships.end() && figures.size() + wares.size() < SHIP_CAPACITY;)
            {
                if((*it)->GetNextHarbor() == dest)
                {
                    wares.push_back(*it);
                    (*it)->StartShipJourney();
                    inventory.visual.Remove(ConvertShields((*it)->type));
                    it = wares_for_ships.erase(it);
                }
                else
                    ++it;
            }

            // Und das Schiff starten lassen
            ship->PrepareTransport(GetHarborPosID(), dest, figures, wares);
        }
    }
}