void nofAttacker::Walked() { ExpelEnemies(); // Was bestimmtes machen, je nachdem welchen Status wir gerade haben switch(state) { default: nofActiveSoldier::Walked(); break; case STATE_ATTACKING_WALKINGTOGOAL: { MissAttackingWalk(); } break; case STATE_ATTACKING_ATTACKINGFLAG: { // Ist evtl. das Zielgebäude zerstört? if(!attacked_goal) { // Nach Hause gehen ReturnHomeMissionAttacking(); return; } MapPoint goalFlagPos = attacked_goal->GetFlag()->GetPos(); // RTTR_Assert(enemy->GetGOT() == GOT_NOF_DEFENDER); // Are we at the flag? nofDefender* defender = nullptr; // Look for defenders at this position const std::list<noBase*>& figures = gwg->GetFigures(goalFlagPos); for(auto figure : figures) { if(figure->GetGOT() == GOT_NOF_DEFENDER) { // Is the defender waiting at the flag? // (could be wandering around or something) if(static_cast<nofDefender*>(figure)->IsWaitingAtFlag()) { defender = static_cast<nofDefender*>(figure); } } } if(pos == goalFlagPos) { if(defender) { // Start fight with the defender gwg->AddFigure(pos, new noFighting(this, defender)); // Set the appropriate states state = STATE_ATTACKING_FIGHTINGVSDEFENDER; defender->FightStarted(); } else // No defender at the flag? // -> Order new defenders or capture the building ContinueAtFlag(); } else { unsigned char dir = gwg->FindHumanPath(pos, goalFlagPos, 5, true); if(dir == 0xFF) { // es wurde kein Weg mehr gefunden --> neues Plätzchen suchen und warten state = STATE_ATTACKING_WALKINGTOGOAL; MissAttackingWalk(); // der Verteidiger muss darüber informiert werden if(defender) defender->AttackerArrested(); } else { // Hinlaufen StartWalking(Direction(dir)); } } } break; case STATE_ATTACKING_CAPTURINGFIRST: { // Ist evtl. das Zielgebäude zerstört? if(!attacked_goal) { // Nach Hause gehen ReturnHomeMissionAttacking(); return; } // Wenn schon welche drin sind, ist wieder ein feindlicher reingegangen if(attacked_goal->DefendersAvailable()) { // Wieder rausgehen, Platz reservieren if(attacked_goal->GetGOT() == GOT_NOB_MILITARY) static_cast<nobMilitary*>(attacked_goal)->StopCapturing(); state = STATE_ATTACKING_WALKINGTOGOAL; StartWalking(Direction::SOUTHEAST); return; } else { // Ist das Gebäude ein "normales Militärgebäude", das wir da erobert haben? if(BuildingProperties::IsMilitary(attacked_goal->GetBuildingType())) { RTTR_Assert(dynamic_cast<nobMilitary*>(attacked_goal)); // Meinem Heimatgebäude Bescheid sagen, dass ich nicht mehr komme (falls es noch eins gibt) if(building) building->SoldierLost(this); CancelAtHuntingDefender(); // Ggf. Schiff Bescheid sagen (Schiffs-Angreifer) if(ship_obj_id) CancelAtShip(); // Gebäude einnehmen auto* goal = static_cast<nobMilitary*>(attacked_goal); goal->Capture(player); // This is the new home building = attacked_goal; // mich zum Gebäude hinzufügen und von der Karte entfernen attacked_goal->AddActiveSoldier(this); RemoveFromAttackedGoal(); // Tell that we arrived and probably call other capturers goal->CapturingSoldierArrived(); gwg->RemoveFigure(pos, this); } // oder ein Hauptquartier oder Hafen? else { // Inform the owner of the building const std::string msg = (attacked_goal->GetGOT() == GOT_NOB_HQ) ? _("Our headquarters was destroyed!") : _("This harbor building was destroyed"); SendPostMessage(attacked_goal->GetPlayer(), new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), msg, PostCategory::Military, *attacked_goal)); // abreißen nobBaseMilitary* tmp_goal = attacked_goal; // attacked_goal wird evtl auf 0 gesetzt! tmp_goal->Destroy(); delete tmp_goal; attacked_goal = nullptr; ReturnHomeMissionAttacking(); } } } break; case STATE_ATTACKING_CAPTURINGNEXT: { CapturingWalking(); } break; case STATE_SEAATTACKING_GOTOHARBOR: // geht von seinem Heimatmilitärgebäude zum Starthafen { // Gucken, ob der Abflughafen auch noch steht und sich in unserer Hand befindet bool valid_harbor = true; noBase* hb = gwg->GetNO(harborPos); if(hb->GetGOT() != GOT_NOB_HARBORBUILDING) valid_harbor = false; else if(static_cast<nobHarborBuilding*>(hb)->GetPlayer() != player) valid_harbor = false; // Nicht mehr oder das angegriffene Gebäude kaputt? Dann müssen wir die ganze Aktion abbrechen if(!valid_harbor || !attacked_goal) { // Dann gehen wir halt wieder nach Hause ReturnHomeMissionAttacking(); return; } // Sind wir schon da? if(pos == harborPos) { // Uns zum Hafen hinzufügen state = STATE_SEAATTACKING_WAITINHARBOR; gwg->RemoveFigure(pos, this); gwg->GetSpecObj<nobHarborBuilding>(pos)->AddSeaAttacker(this); return; } // Erstmal Flagge ansteuern MapPoint harborFlagPos = gwg->GetNeighbour(harborPos, Direction::SOUTHEAST); // Wenn wir an der Flagge bereits sind, in den Hafen eintreten if(pos == harborFlagPos) StartWalking(Direction::NORTHWEST); else { // Weg zum Hafen suchen unsigned char dir = gwg->FindHumanPath(pos, harborFlagPos, MAX_ATTACKING_RUN_DISTANCE, false, nullptr); if(dir == 0xff) { // Kein Weg gefunden? Dann auch abbrechen! ReturnHomeMissionAttacking(); return; } // Und schön weiterlaufen StartWalking(Direction(dir)); } } break; case STATE_SEAATTACKING_WAITINHARBOR: // wartet im Hafen auf das ankommende Schiff { } break; case STATE_SEAATTACKING_ONSHIP: // befindet sich auf dem Schiff auf dem Weg zum Zielpunkt { // Auweia, das darf nicht passieren RTTR_Assert(false); } break; case STATE_SEAATTACKING_RETURNTOSHIP: // befindet sich an der Zielposition auf dem Weg zurück zum Schiff { HandleState_SeaAttack_ReturnToShip(); } break; } }
void nofAttacker::Walked() { ExpelEnemies(); // Was bestimmtes machen, je nachdem welchen Status wir gerade haben switch(state) { default: nofActiveSoldier::Walked(); break; case STATE_ATTACKING_WALKINGTOGOAL: { MissAttackingWalk(); } break; case STATE_ATTACKING_ATTACKINGFLAG: { // Ist evtl. das Zielgebäude zerstört? if(!attacked_goal) { // Nach Hause gehen ReturnHomeMissionAttacking(); return; } MapPoint flagPos = attacked_goal->GetFlag()->GetPos(); //assert(enemy->GetGOT() == GOT_NOF_DEFENDER); // Are we at the flag? nofDefender* defender = NULL; // Look for defenders at this position const std::list<noBase*>& figures = gwg->GetFigures(flagPos); for(std::list<noBase*>::const_iterator it = figures.begin(); it != figures.end(); ++it) { if((*it)->GetGOT() == GOT_NOF_DEFENDER) { // Is the defender waiting at the flag? // (could be wandering around or something) if(static_cast<nofDefender*>(*it)->IsWaitingAtFlag()) { defender = static_cast<nofDefender*>(*it); } } } if(pos == flagPos) { if(defender) { // Start fight with the defender gwg->AddFigure(new noFighting(this, defender), pos); // Set the appropriate states state = STATE_ATTACKING_FIGHTINGVSDEFENDER; defender->FightStarted(); } else // No defender at the flag? // -> Order new defenders or capture the building ContinueAtFlag(); } else { if( (dir = gwg->FindHumanPath(pos, flagPos, 5, true)) == 0xFF) { // es wurde kein Weg mehr gefunden --> neues Plätzchen suchen und warten state = STATE_ATTACKING_WALKINGTOGOAL; MissAttackingWalk(); // der Verteidiger muss darüber informiert werden if(defender) defender->AttackerArrested(); } else { // Hinlaufen StartWalking(dir); } } } break; case STATE_ATTACKING_CAPTURINGFIRST: { // Ist evtl. das Zielgebäude zerstört? if(!attacked_goal) { // Nach Hause gehen ReturnHomeMissionAttacking(); return; } // Wenn schon welche drin sind, ist wieder ein feindlicher reingegangen if(attacked_goal->DefendersAvailable()) { // Wieder rausgehen, Platz reservieren if(attacked_goal->GetGOT() == GOT_NOB_MILITARY) static_cast<nobMilitary*>(attacked_goal)->StopCapturing(); state = STATE_ATTACKING_WALKINGTOGOAL; StartWalking(4); return; } else { // Ist das Gebäude ein "normales Militärgebäude", das wir da erobert haben? if(attacked_goal->GetBuildingType() >= BLD_BARRACKS && attacked_goal->GetBuildingType() <= BLD_FORTRESS) { // Meinem Heimatgebäude Bescheid sagen, dass ich nicht mehr komme (falls es noch eins gibt) if(building) building->SoldierLost(this); // Ggf. Schiff Bescheid sagen (Schiffs-Angreifer) if(ship_obj_id) CancelAtShip(); // Gebäude einnehmen static_cast<nobMilitary*>(attacked_goal)->Capture(player); // Bin nun kein Angreifer mehr attacked_goal->UnlinkAggressor(this); // Das ist nun mein neues zu Hause building = attacked_goal; // mich zum Gebäude hinzufügen und von der Karte entfernen attacked_goal->AddActiveSoldier(this); gwg->RemoveFigure(this, pos); // ggf. weitere Soldaten rufen, damit das Gebäude voll wird static_cast<nobMilitary*>(attacked_goal)->NeedOccupyingTroops(player); } // oder ein Hauptquartier oder Hafen? else { // Inform the owner of the building if(GAMECLIENT.GetPlayerID() == attacked_goal->GetPlayer()) { if(attacked_goal->GetGOT() == GOT_NOB_HQ) GAMECLIENT.SendPostMessage(new ImagePostMsgWithLocation(_("Our headquarters was destroyed!"), PMC_MILITARY, pos, attacked_goal->GetBuildingType(), attacked_goal->GetNation())); else GAMECLIENT.SendPostMessage(new ImagePostMsgWithLocation(_("This harbor building was destroyed"), PMC_MILITARY, pos, attacked_goal->GetBuildingType(), attacked_goal->GetNation())); } // abreißen nobBaseMilitary* tmp_goal = attacked_goal; // attacked_goal wird evtl auf 0 gesetzt! tmp_goal->Destroy(); delete tmp_goal; attacked_goal = NULL; ReturnHomeMissionAttacking(); } } } break; case STATE_ATTACKING_CAPTURINGNEXT: { CapturingWalking(); } break; case STATE_SEAATTACKING_GOTOHARBOR: // geht von seinem Heimatmilitärgebäude zum Starthafen { // Gucken, ob der Abflughafen auch noch steht und sich in unserer Hand befindet bool valid_harbor = true; noBase* hb = gwg->GetNO(harborPos); if(hb->GetGOT() != GOT_NOB_HARBORBUILDING) valid_harbor = false; else if(static_cast<nobHarborBuilding*>(hb)->GetPlayer() != player) valid_harbor = false; // Nicht mehr oder das angegriffene Gebäude kaputt? Dann müssen wir die ganze Aktion abbrechen if(!valid_harbor || !attacked_goal) { // Dann gehen wir halt wieder nach Hause ReturnHomeMissionAttacking(); return; } // Sind wir schon da? if(pos == harborPos) { // Uns zum Hafen hinzufügen state = STATE_SEAATTACKING_WAITINHARBOR; gwg->RemoveFigure(this, pos); gwg->GetSpecObj<nobHarborBuilding>(pos)->AddSeaAttacker(this); return; } // Erstmal Flagge ansteuern MapPoint harborFlagPos = gwg->GetNeighbour(harborPos, 4); // Wenn wir an der Flagge bereits sind, in den Hafen eintreten if(pos == harborFlagPos) StartWalking(1); else { // Weg zum Hafen suchen unsigned char dir = gwg->FindHumanPath(pos, harborFlagPos, MAX_ATTACKING_RUN_DISTANCE, false, NULL); if(dir == 0xff) { // Kein Weg gefunden? Dann auch abbrechen! ReturnHomeMissionAttacking(); return; } // Und schön weiterlaufen StartWalking(dir); } } break; case STATE_SEAATTACKING_WAITINHARBOR: // wartet im Hafen auf das ankommende Schiff { } break; case STATE_SEAATTACKING_ONSHIP: // befindet sich auf dem Schiff auf dem Weg zum Zielpunkt { // Auweia, das darf nicht passieren assert(false); } break; case STATE_SEAATTACKING_RETURNTOSHIP: // befindet sich an der Zielposition auf dem Weg zurück zum Schiff { HandleState_SeaAttack_ReturnToShip(); } break; } }