/// Eine Figur geht ins Lagerhaus void nobHarborBuilding::AddFigure(noFigure * figure, const bool increase_visual_counts) { // Brauchen wir einen Bauarbeiter für die Expedition? if(figure->GetJobType() == JOB_BUILDER && expedition.active && !expedition.builder) { nobBaseWarehouse::RemoveDependentFigure(figure); em->AddToKillList(figure); expedition.builder = true; // Ggf. ist jetzt alles benötigte da CheckExpeditionReady(); } // Brauchen wir einen Spähter für die Expedition? else if(figure->GetJobType() == JOB_SCOUT && exploration_expedition.active && !IsExplorationExpeditionReady()) { nobBaseWarehouse::RemoveDependentFigure(figure); em->AddToKillList(figure); ++exploration_expedition.scouts; ++goods.people[JOB_SCOUT]; // Ggf. ist jetzt alles benötigte da CheckExplorationExpeditionReady(); } else // ansonsten weiterdelegieren nobBaseWarehouse::AddFigure(figure,increase_visual_counts); }
/// Gibt die Wichtigkeit an, dass ein Schiff kommen muss (0 -> keine Bedürftigkeit) int nobHarborBuilding::GetNeedForShip(unsigned ships_coming) const { int points = 0; // Expedition -> 1 Schiff if(IsExpeditionReady()) { if(ships_coming == 0) points += 100; else --ships_coming; } if(IsExplorationExpeditionReady()) { if(ships_coming == 0) points += 100; else --ships_coming; } if ((figures_for_ships.size() > 0) || (wares_for_ships.size() > 0)) { if (ships_coming) { --ships_coming; } else { points += (figures_for_ships.size()+wares_for_ships.size())*5; } } if(soldiers_for_ships.size() > 0 && ships_coming == 0) points += (soldiers_for_ships.size()*10); return points; }
/// Prüft, ob eine Expedition von den Spähern her vollständig ist und ruft ggf. das Schiff void nobHarborBuilding::CheckExplorationExpeditionReady() { // Alles da? // Dann bestellen wir mal das Schiff if(IsExplorationExpeditionReady()) OrderShip(); }
/// Gibt Anzahl der Schiffe zurück, die noch für ausstehende Aufgaben benötigt werden unsigned nobHarborBuilding::GetNeededShipsCount() const { unsigned count = 0; // Expedition -> 1 Schiff if(IsExpeditionReady()) ++count; // Erkundungs-Expedition -> noch ein Schiff if(IsExplorationExpeditionReady()) ++count; // Evtl. Waren und Figuren -> noch ein Schiff pro Ziel if ((figures_for_ships.size() > 0) || (wares_for_ships.size() > 0)) { // Die verschiedenen Zielhäfen -> Für jeden Hafen ein Schiff ordern std::vector< Point<MapCoord> > destinations; for (std::list<FigureForShip>::const_iterator it = figures_for_ships.begin(); it != figures_for_ships.end(); ++it) { if (std::find(destinations.begin(), destinations.end(), it->dest) == destinations.end()) { destinations.push_back(it->dest); ++count; } } for (std::list<Ware*>::const_iterator it = wares_for_ships.begin(); it != wares_for_ships.end(); ++it) { if (std::find(destinations.begin(), destinations.end(), (*it)->GetNextHarbor()) == destinations.end()) { destinations.push_back((*it)->GetNextHarbor()); ++count; } } } // Evtl. Angreifer, die noch verschifft werden müssen if(soldiers_for_ships.size()) { // Die verschiedenen Zielhäfen -> Für jeden Hafen ein Schiff ordern std::vector< Point<MapCoord> > different_dests; for(std::list<SoldierForShip>::const_iterator it = soldiers_for_ships.begin(); it!=soldiers_for_ships.end();++it) { if(std::find(different_dests.begin(),different_dests.end(),it->dest) == different_dests.end()) { different_dests.push_back(it->dest); ++count; } } } return count; }
/// Prüft, ob eine Expedition von den Spähern her vollständig ist und ruft ggf. das Schiff void nobHarborBuilding::CheckExplorationExpeditionReady() { if ((exploration_expedition.scouts < SCOUTS_EXPLORATION_EXPEDITION) && (exploration_expedition.scouts + real_goods.people[JOB_SCOUT] >= SCOUTS_EXPLORATION_EXPEDITION)) { real_goods.people[JOB_SCOUT] -= SCOUTS_EXPLORATION_EXPEDITION - exploration_expedition.scouts; exploration_expedition.scouts = SCOUTS_EXPLORATION_EXPEDITION; } // Alles da? // Dann bestellen wir mal das Schiff if(IsExplorationExpeditionReady()) OrderShip(); }
/// Schiff ist angekommen void nobHarborBuilding::ShipArrived(noShip * ship) { // Verfügbare Aufgaben abklappern // Steht Expedition zum Start bereit? 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(); } // Oder auch eine Erkundungs-Expedition else if(IsExplorationExpeditionReady()) { // Aufräumen am Hafen exploration_expedition.active = false; // Expedition starten ship->StartExplorationExpedition(); assert(goods.people[JOB_SCOUT] >= exploration_expedition.scouts); goods.people[JOB_SCOUT] -= exploration_expedition.scouts; } // Gibt es Waren oder Figuren, die ein Schiff von hier aus nutzen wollen? else if(wares_for_ships.size() || figures_for_ships.size()) { // 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 Point<MapCoord> 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.x,it->dest.y); if(nb->GetGOT() == GOT_NOB_HARBORBUILDING) { 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().x,(*it)->GetNextHarbor().y); if(nb->GetGOT() == GOT_NOB_HARBORBUILDING) { 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[players->getElement(player)->nation];) { if(it->dest == dest) { figures.push_back(it->fig); it->fig->StartShipJourney(dest); --goods.people[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[players->getElement(player)->nation];) { if((*it)->GetNextHarbor() == dest) { wares.push_back(*it); (*it)->StartShipJourney(); --goods.goods[ConvertShields((*it)->type)]; it = wares_for_ships.erase(it); } else ++it; } // Und das Schiff starten lassen ship->PrepareTransport(dest,figures,wares); }// Oder vielleicht Schiffs-Angreifer? (copy paste of the last part) else if(soldiers_for_ships.size()) { // Ein Ziel (das des ersten Soldaten in der Liste) auswählen und alle übrigen // Soldaten mit dem gleichen Ziel mit auf das Schiff laden std::list<noFigure*> attackers; Point<MapCoord> 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) { --goods.people[it->attacker->GetJobType()]; attackers.push_back(it->attacker); it = soldiers_for_ships.erase(it); } else ++it; } ship->PrepareSeaAttack(ship_dest,attackers); } } // Oder vielleicht Schiffs-Angreifer? else if(soldiers_for_ships.size()) { // Ein Ziel (das des ersten Soldaten in der Liste) auswählen und alle übrigen // Soldaten mit dem gleichen Ziel mit auf das Schiff laden std::list<noFigure*> attackers; Point<MapCoord> 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) { --goods.people[it->attacker->GetJobType()]; attackers.push_back(it->attacker); it = soldiers_for_ships.erase(it); } else ++it; } ship->PrepareSeaAttack(ship_dest,attackers); } }
/// 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); } } }