/// Looks for an appropriate fighting spot between the two soldiers /// Returns true if successful bool nofActiveSoldier::GetFightSpotNear(nofActiveSoldier* other, MapPoint * fight_spot) { // Calc middle between the two soldiers and use this as origin spot for the search of more fight spots MapPoint otherPos = gwg->GetNeighbour(other->GetPos(), other->GetCurMoveDir()); MapPoint middle( (pos.x + otherPos.x) / 2, (pos.y + otherPos.y) / 2 ); // Did we cross the borders ? ( horizontally) if(SafeDiff(middle.x, pos.x) > MEET_FOR_FIGHT_DISTANCE) { // In this case: distance = distance of soldier 1 to left border + distance of soldier 2 to right border MapCoord minx = std::min(pos.x, other->GetX()); MapCoord maxx = std::max(pos.x, other->GetX()); MapCoord diff = minx + (gwg->GetWidth() - maxx); middle.x += diff / 2; } // Did we cross the borders ? ( vertically) if(SafeDiff(middle.y, pos.y) > MEET_FOR_FIGHT_DISTANCE) { // In this case: distance = distance of soldier 1 to left border + distance of soldier 2 to right border MapCoord miny = std::min(pos.y, other->GetY()); MapCoord maxy = std::max(pos.y, other->GetY()); MapCoord diff = miny + (gwg->GetHeight() - maxy); middle.y += diff / 2; } // We could have crossed the border due to our interpolating across the borders middle = gwg->ConvertCoords(Point<int>(middle)); // Test Middle point first if(gwg->ValidPointForFighting(middle, true, NULL) && (GetPos() == middle || gwg->FindHumanPath(pos, middle, MEET_FOR_FIGHT_DISTANCE * 2, false, NULL) != 0xff) && (other->GetPos() == middle || gwg->FindHumanPath(other->GetPos(), middle, MEET_FOR_FIGHT_DISTANCE * 2, false, NULL) != 0xff)) { // Great, then let's take this one *fight_spot = middle; return true; } // Points around for(MapCoord tx = gwg->GetXA(middle.x, middle.y, 0), r = 1; r <= MEET_FOR_FIGHT_DISTANCE; tx = gwg->GetXA(tx, middle.y, 0), ++r) { // Wurde ein Punkt in diesem Radius gefunden? // bool found_in_radius = false; MapPoint t2(tx, middle.y); for(unsigned i = 2; i < 8; ++i) { for(MapCoord r2 = 0; r2 < r; t2 = gwg->GetNeighbour(t2, i % 6), ++r2) { // Did we find a good spot? if(gwg->ValidPointForFighting(t2, true, NULL) && gwg->FindHumanPath(pos, t2, MEET_FOR_FIGHT_DISTANCE * 2, false, NULL) != 0xff && gwg->FindHumanPath(other->GetPos(), t2, MEET_FOR_FIGHT_DISTANCE * 2, false, NULL) != 0xff) { // Great, then let's take this one *fight_spot = t2; return true; } } } } // No point found return false; }
/// Ist am Militärgebäude angekommen void nofAttacker::ReachedDestination() { // Sind wir direkt an der Flagge? if(pos == attacked_goal->GetFlag()->GetPos()) { // Building already captured? Continue capturing // This can only be a far away attacker if(attacked_goal->GetPlayer() == player) { state = STATE_ATTACKING_CAPTURINGNEXT; CapturingWalking(); static_cast<nobMilitary*>(attacked_goal)->FarAwayAttackerReachedGoal(this); return; } // Post schicken "Wir werden angegriffen" TODO evtl. unschön, da jeder Attacker das dann aufruft if(attacked_goal->GetPlayer() == GAMECLIENT.GetPlayerID()) GAMECLIENT.SendPostMessage( new ImagePostMsgWithLocation(_("We are under attack!"), PMC_MILITARY, pos, attacked_goal->GetBuildingType(), attacked_goal->GetNation())); // Dann Verteidiger rufen if(attacked_goal->CallDefender(this)) { // Verteidiger gefunden --> hinstellen und auf ihn warten SwitchStateAttackingWaitingForDefender(); } else { // kein Verteidiger gefunden --> ins Gebäude laufen und es erobern state = STATE_ATTACKING_CAPTURINGFIRST; StartWalking(1); // Normalen Militärgebäuden schonmal Bescheid sagen if(attacked_goal->GetGOT() == GOT_NOB_MILITARY) static_cast<nobMilitary*>(attacked_goal)->PrepareCapturing(); } } else { // dann hinstellen und warten, bis wir an die Reihe kommmen mit Kämpfen und außerdem diesen Platz // reservieren, damit sich kein anderer noch hier hinstellt state = STATE_ATTACKING_WAITINGAROUNDBUILDING; // zur Flagge hin ausrichten MapPoint attFlagPos = attacked_goal->GetFlag()->GetPos(); if(pos.y == attFlagPos.y && pos.x <= attFlagPos.x) dir = 3; else if(pos.y == attFlagPos.y && pos.x > attFlagPos.x) dir = 0; else if(pos.y < attFlagPos.y && pos.x < attFlagPos.x) dir = 4; else if(pos.y < attFlagPos.y && pos.x > attFlagPos.x) dir = 5; else if(pos.y > attFlagPos.y && pos.x < attFlagPos.x) dir = 2; else if(pos.y > attFlagPos.y && pos.x > attFlagPos.x) dir = 1; else if(pos.x == attFlagPos.x) { if(pos.y < attFlagPos.y && !(SafeDiff(pos.y, attFlagPos.y) & 1)) dir = 4; else if(pos.y < attFlagPos.y && (SafeDiff(pos.y, attFlagPos.y) & 1)) { if(pos.y & 1) dir = 5; else dir = 4; } else if(pos.y > attFlagPos.y && !(SafeDiff(pos.y, attFlagPos.y) & 1)) dir = 2; else if(pos.y > attFlagPos.y && (SafeDiff(pos.y, attFlagPos.y) & 1)) { if(pos.y & 1) dir = 1; else dir = 2; } } } }