/// Wenn ein Kampf gewonnen wurde
void nofAttacker::WonFighting()
{
    // addon BattlefieldPromotion active? -> increase rank!
    if(gwg->GetGGS().isEnabled(AddonId::BATTLEFIELD_PROMOTION))
        IncreaseRank();
    // Ist evtl. unser Heimatgebäude zerstört?
    if(!building && state != STATE_ATTACKING_FIGHTINGVSDEFENDER)
    {
        // Dann dem Ziel Bescheid sagen, falls es existiert (evtl. wurdes zufällig zur selben Zeit zerstört)
        InformTargetsAboutCancelling();

        // Ggf. Schiff Bescheid sagen (Schiffs-Angreifer)
        if(ship_obj_id)
            CancelAtShip();

        // Rumirren
        state = STATE_FIGUREWORK;
        StartWandering();
        Wander();
        return;
    }

    // Ist evtl. unser Ziel-Gebäude zerstört?
    if(!attacked_goal)
    {
        // Nach Hause gehen
        ReturnHomeMissionAttacking();
        return;
    }
    ContinueAtFlag();
}
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;
    }
}
Esempio n. 3
0
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;
    }
}