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; } }
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; } }
bool GameWorldBase::RoadAlreadyBuilt(const bool /*boat_road*/, const MapPoint start, const std::vector<Direction>& route) { MapPoint tmp(start); for(unsigned i = 0; i < route.size() - 1; ++i) { // Richtiger Weg auf diesem Punkt? if(!GetPointRoad(tmp, route[i])) return false; tmp = GetNeighbour(tmp, route[i]); } return true; }
/// Baut eine (bisher noch visuell gebaute) Straße wieder zurück void GameWorldBase::RemoveVisualRoad(unsigned short start_x, unsigned short start_y, const std::vector<unsigned char>& route) { // Wieder zurückbauen for(unsigned z = 0;z<route.size();++z) { if (!GetPointRoad(start_x,start_y, route[z], false)) { SetPointVirtualRoad(start_x,start_y, route[z],0); CalcRoad(start_x,start_y,GAMECLIENT.GetPlayerID()); } GetPointA(start_x,start_y,route[z]); } }
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; }
bool GameWorldBase::RoadAlreadyBuilt(const bool boat_road, unsigned short start_x, unsigned short start_y, const std::vector<unsigned char>& route) { int tx = start_x; int ty = start_y; for(unsigned i = 0;i<route.size()-1;++i) { // Richtiger Weg auf diesem Punkt? if(!GetPointRoad(tx,ty, route[i])) return false; int tmpx = tx; tx = GetXA(tx,ty,route[i]); ty = GetYA(tmpx,ty,route[i]); } return true; }
bool GameWorldBase::IsNodeToNodeForFigure(const MapCoord x, const MapCoord y, const unsigned dir) const { // Nicht über Wasser, Lava, Sümpfe gehen // Als Boot dürfen wir das natürlich unsigned char t1 = GetWalkingTerrain1(x,y,dir), t2 = GetWalkingTerrain2(x,y,dir); // Wenn ein Weg da drüber geht, dürfen wir das sowieso, aber kein Wasserweg! unsigned char road = GetPointRoad(x,y,dir); if(road && road != RoadSegment::RT_BOAT+1) return true; if((t1 == TT_SNOW || t1 == TT_SWAMPLAND || t1 == TT_LAVA || (t1 == TT_WATER)) && (t2 == TT_SNOW || t2 == TT_SWAMPLAND || t2 == TT_LAVA || (t2 == TT_WATER ))) return false; else return true; }
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; }
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; }