std::vector<unsigned short> GameWorldBase::GetFilteredSeaIDsForAttack(const MapPoint targetPt, const std::vector<unsigned short>& usableSeas, const unsigned char player_attacker) const { // Walk to the flag of the bld/harbor. Important to check because in some locations where the coast is north of the harbor this might be // blocked const MapPoint flagPt = GetNeighbour(targetPt, Direction::SOUTHEAST); std::vector<unsigned short> confirmedSeaIds; // Check each possible harbor for(unsigned curHbId = 1; curHbId <= GetNumHarborPoints(); ++curHbId) { const MapPoint harborPt = GetHarborPoint(curHbId); if(CalcDistance(harborPt, targetPt) > SEAATTACK_DISTANCE) continue; // Not attacking this harbor and harbors block? if(targetPt != harborPt && GetGGS().getSelection(AddonId::SEA_ATTACK) == 1) { // Does an enemy harbor exist at current harbor spot? -> Can't attack through this harbor spot const auto* hb = GetSpecObj<nobHarborBuilding>(harborPt); if(hb && GetPlayer(player_attacker).IsAttackable(hb->GetPlayer())) continue; } for(unsigned z = 0; z < 6; ++z) { const unsigned short seaId = GetSeaId(curHbId, Direction::fromInt(z)); if(!seaId) continue; // sea id is not in compare list or already confirmed? -> skip rest if(!helpers::contains(usableSeas, seaId) || helpers::contains(confirmedSeaIds, seaId)) continue; // checks previously tested sea ids to skip pathfinding bool previouslytested = false; for(unsigned k = 0; k < z; k++) { if(seaId == GetSeaId(curHbId, Direction::fromInt(k))) { previouslytested = true; break; } } if(previouslytested) continue; // Can figures reach flag from coast MapPoint coastalPt = GetCoastalPoint(curHbId, seaId); if((flagPt == coastalPt) || FindHumanPath(flagPt, coastalPt, SEAATTACK_DISTANCE) != INVALID_DIR) { confirmedSeaIds.push_back(seaId); // all sea ids confirmed? return without changes if(confirmedSeaIds.size() == usableSeas.size()) return confirmedSeaIds; } } } return confirmedSeaIds; }
std::vector<unsigned> GameWorldBase::GetUsableTargetHarborsForAttack(const MapPoint targetPt, std::vector<bool>& use_seas, const unsigned char player_attacker) const { // Walk to the flag of the bld/harbor. Important to check because in some locations where the coast is north of the harbor this might be // blocked const MapPoint flagPt = GetNeighbour(targetPt, Direction::SOUTHEAST); std::vector<unsigned> harbor_points; // Check each possible harbor for(unsigned curHbId = 1; curHbId <= GetNumHarborPoints(); ++curHbId) { const MapPoint harborPt = GetHarborPoint(curHbId); if(CalcDistance(harborPt, targetPt) > SEAATTACK_DISTANCE) continue; // Not attacking this harbor and harbors block? if(targetPt != harborPt && GetGGS().getSelection(AddonId::SEA_ATTACK) == 1) { // Does an enemy harbor exist at current harbor spot? -> Can't attack through this harbor spot const auto* hb = GetSpecObj<nobHarborBuilding>(harborPt); if(hb && GetPlayer(player_attacker).IsAttackable(hb->GetPlayer())) continue; } // add seaIds from which we can actually attack the harbor bool harborinlist = false; for(unsigned z = 0; z < 6; ++z) { const unsigned short seaId = GetSeaId(curHbId, Direction::fromInt(z)); if(!seaId) continue; // checks previously tested sea ids to skip pathfinding bool previouslytested = false; for(unsigned k = 0; k < z; k++) { if(seaId == GetSeaId(curHbId, Direction::fromInt(k))) { previouslytested = true; break; } } if(previouslytested) continue; // Can figures reach flag from coast const MapPoint coastalPt = GetCoastalPoint(curHbId, seaId); if((flagPt == coastalPt) || FindHumanPath(flagPt, coastalPt, SEAATTACK_DISTANCE) != INVALID_DIR) { use_seas.at(seaId - 1) = true; if(!harborinlist) { harbor_points.push_back(curHbId); harborinlist = true; } } } } return harbor_points; }
/// returns true when a harborpoint is in SEAATTACK_DISTANCE for figures! bool GameWorldBase::IsAHarborInSeaAttackDistance(const MapPoint pos) const { for(unsigned i = 1; i <= GetNumHarborPoints(); ++i) { if(CalcDistance(pos, GetHarborPoint(i)) < SEAATTACK_DISTANCE) { if(FindHumanPath(pos, GetHarborPoint(i), SEAATTACK_DISTANCE) != 0xff) return true; } } return false; }
/// returns true when a harborpoint is in SEAATTACK_DISTANCE for figures! bool GameWorldBase::IsAHarborInSeaAttackDistance(const Point<MapCoord> pos) const { for(unsigned i = 1;i<harbor_pos.size();++i) //poc: harbor dummy at spot 0 ask Oliverr why { if(CalcDistance(pos.x,pos.y,harbor_pos[i].x,harbor_pos[i].y)<SEAATTACK_DISTANCE) { if(FindHumanPath(pos.x,pos.y,harbor_pos[i].x,harbor_pos[i].y,SEAATTACK_DISTANCE!=0xff)) return true; } } return false; }
/// returns all sea_ids from which a given building can be attacked by sea void GameWorldBase::GetValidSeaIDsAroundMilitaryBuildingForAttack(const MapCoord x,const MapCoord y, std::vector<bool> * use_seas, const unsigned char player_attacker,std::vector<unsigned>*harbor_points) const { assert(use_seas); // Nach Hafenpunkten in der Nähe des angegriffenen Gebäudes suchen // Alle unsere Häfen durchgehen for(unsigned i = 1;i<harbor_pos.size();++i) { MapCoord harbor_x = harbor_pos[i].x, harbor_y = harbor_pos[i].y; if(CalcDistance(harbor_x,harbor_y,x,y) <= SEAATTACK_DISTANCE) { //target isnt the harbor pos AND there is an enemy harbor? -> done for this harbor pos const nobHarborBuilding *hb=GetSpecObj<nobHarborBuilding>(x,y); if(!(x == harbor_x && y == harbor_y) && hb && players->getElement(player_attacker)->IsPlayerAttackable(GetNode(x,y).owner-1)) { continue; } else { // Ist Ziel der Hafenspot? -> add sea_ids if(x == harbor_x && y == harbor_y) { harbor_points->push_back(i); unsigned short sea_ids[6]; GetSeaIDs(i,sea_ids); for(unsigned z = 0;z<6;++z) { if(sea_ids[z]) use_seas->at(sea_ids[z]) = true; } } //so our target building is in range of a free or allied harbor pos but not the harborspot - now lets see if we can findhumanpath else if(FindHumanPath(x,y,harbor_x,harbor_y,SEAATTACK_DISTANCE) != 0xff) { harbor_points->push_back(i); unsigned short sea_ids[6]; GetSeaIDs(i,sea_ids); for(unsigned z = 0;z<6;++z) { if(sea_ids[z]) use_seas->at(sea_ids[z]) = true; } } } } } }
/// Liefert Hafenpunkte im Umkreis von einem bestimmten Militärgebäude std::vector<unsigned> GameWorldBase::GetHarborPointsAroundMilitaryBuilding(const MapPoint pt) const { std::vector<unsigned> harbor_points; // Nach Hafenpunkten in der Nähe des angegriffenen Gebäudes suchen // Alle unsere Häfen durchgehen for(unsigned i = 1; i <= GetNumHarborPoints(); ++i) { const MapPoint harborPt = GetHarborPoint(i); if(CalcDistance(harborPt, pt) <= SEAATTACK_DISTANCE) { // Wird ein Weg vom Militärgebäude zum Hafen gefunden bzw. Ziel = Hafen? if(pt == harborPt) harbor_points.push_back(i); else if(FindHumanPath(pt, harborPt, SEAATTACK_DISTANCE) != 0xff) harbor_points.push_back(i); } } return harbor_points; }
/// Liefert Hafenpunkte im Umkreis von einem bestimmten Militärgebäude void GameWorldBase::GetHarborPointsAroundMilitaryBuilding(const MapCoord x, const MapCoord y, std::vector<unsigned> * harbor_points) const { assert(harbor_points); // Nach Hafenpunkten in der Nähe des angegriffenen Gebäudes suchen // Alle unsere Häfen durchgehen for(unsigned i = 1;i<harbor_pos.size();++i) { MapCoord harbor_x = harbor_pos[i].x, harbor_y = harbor_pos[i].y; if(CalcDistance(harbor_x,harbor_y,x,y) <= SEAATTACK_DISTANCE) { // Wird ein Weg vom Militärgebäude zum Hafen gefunden bzw. Ziel = Hafen? if(x == harbor_x && y == harbor_y) harbor_points->push_back(i); else if(FindHumanPath(x,y,harbor_x,harbor_y,SEAATTACK_DISTANCE) != 0xff) harbor_points->push_back(i); } } }