void Grid::Print() { // Method to print the grid in the console std::cout << std::endl; // 1st row std::cout << GetNO().GetNO() << " " << GetNO().GetN() << " " << GetNO().GetNE() << " " << GetN().GetNO() << " " << GetN().GetN() << " " << GetN().GetNE() << " " << GetNE().GetNO() << " " << GetNE().GetN() << " " << GetNE().GetNE() << std::endl; // 2nd row std::cout << GetNO().GetO() << " " << GetNO().GetC() << " " << GetNO().GetE() << " " << GetN().GetO() << " " << GetN().GetC() << " " << GetN().GetE() << " " << GetNE().GetO() << " " << GetNE().GetC() << " " << GetNE().GetE() << std::endl; // 3rd row std::cout << GetNO().GetSO() << " " << GetNO().GetS() << " " << GetNO().GetSE() << " " << GetN().GetSO() << " " << GetN().GetS() << " " << GetN().GetSE() << " " << GetNE().GetSO() << " " << GetNE().GetS() << " " << GetNE().GetSE() << std::endl; // 4th row std::cout << GetO().GetNO() << " " << GetO().GetN() << " " << GetO().GetNE() << " " << GetC().GetNO() << " " << GetC().GetN() << " " << GetC().GetNE() << " " << GetE().GetNO() << " " << GetE().GetN() << " " << GetE().GetNE() << std::endl; // 5th row std::cout << GetO().GetO() << " " << GetO().GetC() << " " << GetO().GetE() << " " << GetC().GetO() << " " << GetC().GetC() << " " << GetC().GetE() << " " << GetE().GetO() << " " << GetE().GetC() << " " << GetE().GetE() << std::endl; // 6th row std::cout << GetO().GetSO() << " " << GetO().GetS() << " " << GetO().GetSE() << " " << GetC().GetSO() << " " << GetC().GetS() << " " << GetC().GetSE() << " " << GetE().GetSO() << " " << GetE().GetS() << " " << GetE().GetSE() << std::endl; // 7th row std::cout << GetSO().GetNO() << " " << GetSO().GetN() << " " << GetSO().GetNE() << " " << GetS().GetNO() << " " << GetS().GetN() << " " << GetS().GetNE() << " " << GetSE().GetNO() << " " << GetSE().GetN() << " " << GetSE().GetNE() << std::endl; // 8th row std::cout << GetSO().GetO() << " " << GetSO().GetC() << " " << GetSO().GetE() << " " << GetS().GetO() << " " << GetS().GetC() << " " << GetS().GetE() << " " << GetSE().GetO() << " " << GetSE().GetC() << " " << GetSE().GetE() << std::endl; // 9th row std::cout << GetSO().GetSO() << " " << GetSO().GetS() << " " << GetSO().GetSE() << " " << GetS().GetSO() << " " << GetS().GetS() << " " << GetS().GetSE() << " " << GetSE().GetSO() << " " << GetSE().GetS() << " " << GetSE().GetSE() << std::endl; std::cout << std::endl; }
bool GameWorldBase::IsMilitaryBuilding(const MapCoord x, const MapCoord y) const { if(GetNO(x,y)->GetType() == NOP_BUILDING || GetNO(x,y)->GetType() == NOP_BUILDINGSITE) { if( (GetSpecObj<noBaseBuilding>(x,y)->GetBuildingType() >= BLD_BARRACKS && GetSpecObj<noBaseBuilding>(x,y)->GetBuildingType() <= BLD_FORTRESS) || GetSpecObj<noBaseBuilding>(x,y)->GetBuildingType() == BLD_HEADQUARTERS || GetSpecObj<noBaseBuilding>(x,y)->GetBuildingType() == BLD_HARBORBUILDING) return true; } return false; }
bool Grid::isConsistent() { bool result = true; if(Col1().isConsistent()){result=false;} if(Col2().isConsistent()){result=false;} if(Col3().isConsistent()){result=false;} if(Col4().isConsistent()){result=false;} if(Col5().isConsistent()){result=false;} if(Col6().isConsistent()){result=false;} if(Col7().isConsistent()){result=false;} if(Col8().isConsistent()){result=false;} if(Col9().isConsistent()){result=false;} if(Row1().isConsistent()){result=false;} if(Row2().isConsistent()){result=false;} if(Row3().isConsistent()){result=false;} if(Row4().isConsistent()){result=false;} if(Row5().isConsistent()){result=false;} if(Row6().isConsistent()){result=false;} if(Row7().isConsistent()){result=false;} if(Row8().isConsistent()){result=false;} if(Row9().isConsistent()){result=false;} if(GetNO().isConsistent()){result=false;} if(GetN().isConsistent()){result=false;} if(GetNE().isConsistent()){result=false;} if(GetO().isConsistent()){result=false;} if(GetC().isConsistent()){result=false;} if(GetE().isConsistent()){result=false;} if(GetSO().isConsistent()){result=false;} if(GetS().isConsistent()){result=false;} if(GetSE().isConsistent()){result=false;} return result; }
noFlag * GameWorldBase::GetRoadFlag(int x, int y,unsigned char& dir,unsigned last_i) { unsigned char i = 0; while(true) { // suchen, wo der Weg weitergeht for(i = 0;i<6;++i) { if(GetPointRoad(x,y,i) && i != last_i) break; } if(i == 6) return 0; int tx = x,ty = y; x = GetXA(tx,ty,i); y = GetYA(tx,ty,i); // endlich am Ende des Weges und an einer Flagge angekommen? if(GetNO(x,y)->GetType() == NOP_FLAG) { dir = (i+3)%6; return GetSpecObj<noFlag>(x,y); } last_i = (i+3)%6; } }
const noFlag* GameWorldBase::GetRoadFlag(MapPoint pt, Direction& dir, unsigned prevDir) const { unsigned i = 0; while(true) { // suchen, wo der Weg weitergeht for(i = 0; i < Direction::COUNT; ++i) { if(i != prevDir && GetPointRoad(pt, Direction::fromInt(i))) break; } if(i == 6) return nullptr; pt = GetNeighbour(pt, Direction::fromInt(i)); // endlich am Ende des Weges und an einer Flagge angekommen? if(GetNO(pt)->GetType() == NOP_FLAG) { dir = Direction(i + 3); return GetSpecObj<noFlag>(pt); } prevDir = (i + 3) % 6; } }
/// Find a route for trade caravanes unsigned char GameWorldGame::FindTradePath(const MapPoint start, const MapPoint dest, const unsigned char player, const unsigned max_route, const bool random_route, std::vector<unsigned char>* route, unsigned* length, const bool record) const { //unsigned tt = GetTickCount(); //static unsigned cc = 0; //++cc; unsigned char pp = GetNode(dest).owner; if(!(pp == 0 || GetPlayer(player).IsAlly(pp - 1))) return 0xff; bool is_warehouse_at_goal = false; if(GetNO(dest)->GetType() == NOP_BUILDING) { if(GetSpecObj<noBuilding>(dest)->IsWarehouse()) is_warehouse_at_goal = true; } if(!IsNodeForFigures(dest) && !is_warehouse_at_goal ) return 0xff; unsigned char first_dir = 0xFF; FindFreePath(start, dest, random_route, max_route, route, length, &first_dir, IsPointOK_TradePath, IsPointToDestOK_TradePath, &player, record); //if(GetTickCount()-tt > 100) // printf("%u: %u ms; (%u, %u) to (%u, %u)\n", cc, GetTickCount()-tt, start.x, start.y, dest.x, dest.y); return first_dir; }
bool GameWorldBase::IsFlagAround(const MapPoint& pt) const { for(unsigned i = 0; i < 6; ++i) { if(GetNO(GetNeighbour(pt, Direction::fromInt(i)))->GetBM() == BlockingManner::Flag) return true; } return false; }
bool GameWorldBase::FlagNear(const int x, const int y) const { for(unsigned char i = 0;i<6;++i) { int ya = GetYA(x,y,i); int xa = GetXA(x,y,i); if(GetNO(xa,ya)->GetType() == NOP_FLAG) return 1; } return 0; }
bool GameWorldBase::IsMilitaryBuildingOnNode(const MapPoint pt, bool attackBldsOnly) const { const noBase* obj = GetNO(pt); if(obj->GetType() == NOP_BUILDING || obj->GetType() == NOP_BUILDINGSITE) { BuildingType buildingType = static_cast<const noBaseBuilding*>(obj)->GetBuildingType(); if(BuildingProperties::IsMilitary(buildingType)) return true; if(!attackBldsOnly && (buildingType == BLD_HEADQUARTERS || buildingType == BLD_HARBORBUILDING)) return true; } return false; }
bool GameWorldBase::IsRoadAvailable(const bool boat_road, const MapPoint pt) const { // Hindernisse if(GetNode(pt).obj) { BlockingManner bm = GetNode(pt).obj->GetBM(); if(bm != BlockingManner::None) return false; } // dont build on the border if(GetNode(pt).boundary_stones[0]) return false; for(unsigned z = 0; z < 6; ++z) { // Roads around charburner piles are not possible if(GetNO(GetNeighbour(pt, Direction::fromInt(z)))->GetBM() == BlockingManner::NothingAround) return false; // Other roads at this point? if(GetPointRoad(pt, Direction::fromInt(z))) return false; } // Terrain (unterscheiden, ob Wasser und Landweg) if(!boat_road) { bool flagPossible = false; for(unsigned char i = 0; i < 6; ++i) { TerrainBQ bq = GetDescription().get(GetRightTerrain(pt, Direction::fromInt(i))).GetBQ(); if(bq == TerrainBQ::DANGER) return false; else if(bq != TerrainBQ::NOTHING) flagPossible = true; } return flagPossible; } else { // Beim Wasserweg muss um den Punkt herum Wasser sein if(!IsWaterPoint(pt)) return false; } return true; }
/// Find a route for trade caravanes unsigned char GameWorldGame::FindTradePath(const MapPoint start, const MapPoint dest, unsigned char player, unsigned max_route, bool random_route, std::vector<unsigned char>* route, unsigned* length) const { unsigned char owner = GetNode(dest).owner; if(owner != 0 && !GetPlayer(player).IsAlly(owner -1)) return INVALID_DIR; RTTR_Assert(GetNO(dest)->GetType() == NOP_FLAG); // Goal should be the flag of a wh if(!IsNodeForFigures(dest)) return INVALID_DIR; unsigned char first_dir = INVALID_DIR; GetFreePathFinder().FindPath(start, dest, random_route, max_route, route, length, &first_dir, PathConditionTrade(*this, player)); return first_dir; }
Column Grid::Col1() { ColumnHolder sH = GetNO().LeftColumn(), sC = GetO().LeftColumn(), sB = GetSO().LeftColumn(); return Column(sH, sC, sB); }
bool GameWorldBase::RoadAvailable(const bool boat_road,const int x, const int y,unsigned char to_dir,const bool visual) const { // Hindernisse if(GetNode(x,y).obj) { noBase::BlockingManner bm = GetNode(x,y).obj->GetBM(); if(bm != noBase::BM_NOTBLOCKING) return false; } //dont build on the border if(GetNode(x,y).boundary_stones[0]) return false; for(unsigned char z = 0;z<6;++z) { // Roads around charburner piles are not possible if(GetNO(GetXA(x,y,z),GetYA(x,y,z))->GetBM() == noBase::BM_CHARBURNERPILE) return false; // Other roads at this point? if(GetPointRoad(x,y, z, visual)) { (void) GetPointRoad(x,y, z, visual); return false; } } for(unsigned char i = 3;i<6;++i) { if(GetNO(GetXA(x,y,i),GetYA(x,y,i))->GetBM() == noBase::BM_CASTLE) return false; } // Terrain (unterscheiden, ob Wasser und Landweg) if(!boat_road) { unsigned flag_hits = 0; unsigned char t; for(unsigned char i = 0;i<6;++i) { t = GetTerrainAround(x,y,i); if(TERRAIN_BQ[t] == BQ_CASTLE || TERRAIN_BQ[t] == BQ_CASTLE || TERRAIN_BQ[t] == BQ_MINE || TERRAIN_BQ[t] == BQ_FLAG) ++flag_hits; else if(TERRAIN_BQ[t] == BQ_DANGER) return 0; } if(!flag_hits) return false; // Richtung übergeben? Dann auch das zwischen den beiden Punkten beachten, damit // man nicht über ein Wasser oder so hüpft if(to_dir != 0xFF) { // Richtung genau entgegengesetzt, da das ja hier der Zielpunkt ist, wir müssen wieder zurück zum Quellpunkt to_dir = (to_dir+3)%6; //// Nicht über Wasser, Lava, Sümpfe gehen //if(!IsNodeToNodeForFigure(x,y,to_dir,boat_road)) // return false; } return true; } else { // Beim Wasserweg muss um den Punkt herum Wasser sein for(unsigned i = 0;i<6;++i) if(GetTerrainAround(x,y,i) != 14) return false; } return true; }
Column Grid::Col3() { ColumnHolder sH = GetNO().RightColumn(), sC = GetO().RightColumn(), sB = GetSO().RightColumn(); return Column(sH, sC, sB); }
Column Grid::Col2() { ColumnHolder sH = GetNO().MiddleColumn(), sC = GetO().MiddleColumn(), sB = GetSO().MiddleColumn(); return Column(sH, sC, sB); }
Row Grid::Row1() { RowHolder rH = GetNO().TopRow(), rC = GetN().TopRow(), rB = GetNE().TopRow(); return Row(rH, rC, rB); }
Row Grid::Row2() { RowHolder rH = GetNO().MiddleRow(), rC = GetN().MiddleRow(), rB = GetNE().MiddleRow(); return Row(rH, rC, rB); }
BuildingQuality GameWorldBase::CalcBQ(const MapCoord x, const MapCoord y,const unsigned char player,const bool flagonly,const bool visual, const bool ignore_player) const { /////////////////////// // 1. nach Terrain // Unser Land? if(!ignore_player && (GetNode(x,y).owner-1 != player || !IsPlayerTerritory(x,y))) return BQ_NOTHING; unsigned building_hits = 0; unsigned mine_hits = 0; unsigned flag_hits = 0; BuildingQuality val = BQ_CASTLE; unsigned char t; // bebaubar? for(unsigned char i = 0;i<6;++i) { t = GetTerrainAround(x,y,i); if(TERRAIN_BQ[t] == BQ_CASTLE) ++building_hits; else if(TERRAIN_BQ[t] == BQ_MINE) ++mine_hits; else if(TERRAIN_BQ[t] == BQ_FLAG) ++flag_hits; else if(TERRAIN_BQ[t] == BQ_DANGER) return BQ_NOTHING; } if(flag_hits) val = BQ_FLAG; else if(mine_hits == 6) val = BQ_MINE; else if(mine_hits) val = BQ_FLAG; else if(building_hits == 6) val = BQ_CASTLE; else if(building_hits) val = BQ_FLAG; else return BQ_NOTHING; ////////////////////////////////////// // 2. nach Terrain unsigned char ph = GetNode(x,y).altitude, th; // Bergwerke anders handhaben if(val == BQ_CASTLE && val != BQ_FLAG) { if((th=GetNodeAround(x,y,4).altitude) > ph) { if(th - ph > 1) val = BQ_FLAG; } // 2. Außenschale prüfen ( keine Hütten werden ab Steigung 3 ) for(unsigned i = 0;i<12;++i) { if( (th = GetNode(GetXA2(x,y,i),GetYA2(x,y,i)).altitude ) > ph) { if(th - ph > 2) { val = BQ_HUT; break; } } if( (th = GetNode(GetXA2(x,y,i), GetYA2(x,y,i)).altitude ) < ph) { if(ph - th > 2) { val = BQ_HUT; break; } } } // 1. Auäcnschale ( käcnen Flaggen werden ab Steigung 4) for(unsigned i = 0;i<6;++i) { if((th=GetNodeAround(x,y,i).altitude) > ph) { if(th - ph > 3) val = BQ_FLAG; } if((th=GetNodeAround(x,y,i).altitude) < ph) { if(ph - th > 3) val = BQ_FLAG; } } } else { for(unsigned i = 0;i<6;++i) { if(i > 3 && i!=5 && (th=GetNodeAround(x,y,i).altitude) > ph) { if(th - ph > 3) val = BQ_FLAG; } } } ////////////////////////////////////////// // 3. nach Objekten if(flagonly) if(FlagNear(x,y)) return BQ_NOTHING; // allgemein nix bauen auf folgenden Objekten: if(GetNO(x,y)->GetBM() != noBase::BM_NOTBLOCKING) return BQ_NOTHING; // Don't build anything around charburner piles for(unsigned i = 0;i<6;++i) { if(GetNO(GetXA(x,y,i),GetYA(x,y,i))->GetBM() == noBase::BM_CHARBURNERPILE) return BQ_NOTHING; } if(val > 2 && val != BQ_MINE) { for(unsigned i = 0;i<6;++i) { // Baum --> rundrum Hütte if(GetNO(GetXA(x,y,i),GetYA(x,y,i))->GetType() == NOP_TREE) { val = BQ_HUT; break; } /*// StaticObject --> rundrum Flagge/Hütte else if(GetNO(GetXA(x,y,i),GetYA(x,y,i))->GetType() == NOP_OBJECT) { const noStaticObject *obj = GetSpecObj<noStaticObject>(GetXA(x,y,i),GetYA(x,y,i)); if(obj->GetSize() == 2) val = BQ_FLAG; else val = BQ_HUT; break; }*/ } } // Stein, Feuer und Getreidefeld --> rundrum Flagge for(unsigned i = 0;i<6;++i) { const noBase * nob = GetNO(GetXA(x,y,i),GetYA(x,y,i)); if(nob->GetBM() == noBase::BM_GRANITE) { val = BQ_FLAG; break; } } // Flagge if(val == BQ_CASTLE) { for(unsigned char i = 0;i<3;++i) { if(GetNodeAround(x,y,i).obj) { if(GetNodeAround(x,y,i).obj->GetBM() == noBase::BM_FLAG) val = BQ_HOUSE; } } } if(GetNO(GetXA(x,y,3),GetYA(x,y,3))->GetBM() == noBase::BM_FLAG) return BQ_NOTHING; if(GetNO(GetXA(x,y,5),GetYA(x,y,5))->GetBM() == noBase::BM_FLAG) return BQ_NOTHING; if(val != BQ_FLAG) { if(GetNO(GetXA(x,y,5),GetYA(x,y,5))->GetBM() == noBase::BM_FLAG) val = BQ_FLAG; } // Gebäude if(val == BQ_CASTLE) { for(unsigned i = 0;i<12;++i) { noBase::BlockingManner bm = GetNO(GetXA2(x,y,i),GetYA2(x,y,i))->GetBM(); if(bm >= noBase::BM_HUT && bm <= noBase::BM_MINE) val = BQ_HOUSE; } } for(unsigned i = 0;i<3;++i) { if(val == BQ_CASTLE) { for(unsigned char c = 0;c<6;++c) { if(GetPointRoad(GetXA(x,y,i),GetYA(x,y,i), c, visual)) { val = BQ_HOUSE; break; } } } } for(unsigned char c = 0;c<6;++c) { if(GetPointRoad(x,y, c, visual)) { val = BQ_FLAG; break; } } if(val == BQ_FLAG) { for(unsigned char i = 0;i<6;++i) { if(GetNO(GetXA(x,y,i),GetYA(x,y,i))->GetBM() == noBase::BM_FLAG) return BQ_NOTHING; } } if(flagonly) return BQ_FLAG; if(val == BQ_FLAG) { for(unsigned char i = 0;i<3;++i) if(GetNO(GetXA(x,y,i),GetYA(x,y,i))->GetBM() == noBase::BM_FLAG) return BQ_NOTHING; } // Schloss bis hierhin und ist hier ein Hafenplatz? if(val == BQ_CASTLE && GetNode(x,y).harbor_id) // Dann machen wir einen Hafen draus val = BQ_HARBOR; if(val >= BQ_HUT && val <= BQ_HARBOR) { if(GetNO(GetXA(x,y,4),GetYA(x,y,4))->GetBM() == noBase::BM_FLAG) return val; if(CalcBQ(GetXA(x,y,4),GetYA(x,y,4),player,true,visual,ignore_player)) { return val; } else { for(unsigned char i = 0;i<3;++i) if(GetNO(GetXA(x,y,i),GetYA(x,y,i))->GetBM() == noBase::BM_FLAG) return BQ_NOTHING; return BQ_FLAG; } } return val; }
Row Grid::Row3() { RowHolder rH = GetNO().BottomRow(), rC = GetN().BottomRow(), rB = GetNE().BottomRow(); return Row(rH, rC, rB); }
/// Sucht verfügbare Soldaten, um dieses Militärgebäude mit einem Seeangriff anzugreifen void GameWorldBase::GetAvailableSoldiersForSeaAttack(const unsigned char player_attacker, const MapCoord x, const MapCoord y, std::list<GameWorldBase::PotentialSeaAttacker> * attackers) const { // Ist das Ziel auch ein richtiges Militärgebäude? if(GetNO(x,y)->GetGOT() != GOT_NOB_HARBORBUILDING && GetNO(x,y)->GetGOT() != GOT_NOB_HQ && GetNO(x,y)->GetGOT() != GOT_NOB_MILITARY) return; //bool use_seas[512]; //memset(use_seas,0,512); std::vector<bool>use_seas; use_seas.resize(seas.size()); // Mögliche Hafenpunkte in der Nähe des Gebäudes std::vector< unsigned > defender_harbors; GetValidSeaIDsAroundMilitaryBuildingForAttack(x,y,&use_seas,player_attacker,&defender_harbors); /* GetHarborPointsAroundMilitaryBuilding(x,y,&defender_harbors); // Nach Hafenpunkten in der Nähe des angegriffenen Gebäudes suchen // Alle unsere Häfen durchgehen for(unsigned i = 0;i<defender_harbors.size();++i) { unsigned harbor_id = defender_harbors[i]; // Steht an dieser Stelle ein Hafengeäude? Point<MapCoord> harbor_pos = GetHarborPoint(harbor_id); const noBase * hb = GetNO(harbor_pos.x,harbor_pos.y); if(hb->GetGOT() == GOT_NOB_HARBORBUILDING) { // Gehört dem Feind dieser Hafen und ist dieser Hafen nicht unser Ziel? if(players->getElement(player_attacker)->IsPlayerAttackable(static_cast<const nobHarborBuilding*>(hb)->GetPlayer()) && !(harbor_pos.x == x && harbor_pos.y == y)) { // Dann können wir hier nicht landen continue; } } unsigned short sea_ids[6]; GetSeaIDs(harbor_id,sea_ids); for(unsigned z = 0;z<6;++z) { if(sea_ids[z]) use_seas[sea_ids[z]] = true; } } */ // Liste alle Militärgebäude des Angreifers, die Soldaten liefern std::vector<nobHarborBuilding::SeaAttackerBuilding> buildings; // Angrenzende Häfen des Angreifers an den entsprechenden Meeren herausfinden for(std::list<nobHarborBuilding*>::const_iterator it = players->getElement(player_attacker)->GetHarbors() .begin();it!=players->getElement(player_attacker)->GetHarbors().end();++it) { // Bestimmen, ob Hafen an einem der Meere liegt, über die sich auch die gegnerischen // Hafenpunkte erreichen lassen bool is_at_sea = false; unsigned short sea_ids[6]; GetSeaIDs((*it)->GetHarborPosID(),sea_ids); for(unsigned i = 0;i<6;++i) { if(sea_ids[i] && use_seas[sea_ids[i]]) { is_at_sea = true; break; } } if(!is_at_sea) continue; (*it)->GetAttackerBuildingsForSeaAttack(&buildings,defender_harbors); } // Die Soldaten aus allen Militärgebäuden sammeln for(unsigned i = 0;i<buildings.size();++i) { // Soldaten holen std::vector<nofPassiveSoldier*> tmp_soldiers; buildings[i].building->GetSoldiersForAttack(buildings[i].harbor->GetX(),buildings[i].harbor->GetY(), player_attacker,&tmp_soldiers); // Überhaupt welche gefunden? if(!tmp_soldiers.size()) continue; // Soldaten hinzufügen for(unsigned j = 0;j<tmp_soldiers.size();++j) { PotentialSeaAttacker pa = { tmp_soldiers[j], buildings[i].harbor, buildings[i].distance }; attackers->push_back(pa); } } // Entsprechend nach Rang sortieren attackers->sort(); }