예제 #1
0
void nobUsual::OnOutOfResources()
{
    // Post verschicken, keine Rohstoffe mehr da
    if(outOfRessourcesMsgSent)
        return;
    outOfRessourcesMsgSent = true;
    productivity = 0;
    std::fill(last_productivities.begin(), last_productivities.end(), 0);

    const char* error;
    if(GetBuildingType() == BLD_WELL)
        error = _("This well has dried out");
    else if(BuildingProperties::IsMine(GetBuildingType()))
        error = _("This mine is exhausted");
    else if(GetBuildingType() == BLD_QUARRY)
        error = _("No more stones in range");
    else if(GetBuildingType() == BLD_FISHERY)
        error = _("No more fishes in range");
    else
        return;

    SendPostMessage(player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), error, PostCategory::Economy, *this));
    gwg->GetNotifications().publish(BuildingNote(BuildingNote::NoRessources, player, GetPos(), GetBuildingType()));

    if(GAMECLIENT.GetPlayerId() == player && gwg->GetGGS().isEnabled(AddonId::DEMOLISH_BLD_WO_RES))
    {
        GAMECLIENT.DestroyBuilding(GetPos());
    }
}
예제 #2
0
void nobMilitary::Destroy_nobMilitary()
{
    // Remove from military square and buildings first, to avoid e.g. sending canceled soldiers back to this building
    gwg->GetPlayer(player).RemoveMilitaryBuilding(this);
    gwg->GetMilitarySquares().Remove(this);

    // Bestellungen stornieren
    CancelOrders();

    // Soldaten rausschicken
    for(SortedTroops::iterator it = troops.begin(); it != troops.end(); ++it)
        (*it)->InBuildingDestroyed();
    troops.clear();

    // Inform far-away capturers
    for(std::list<nofAttacker*>::iterator it = far_away_capturers.begin(); it != far_away_capturers.end(); ++it)
        (*it)->AttackedGoalDestroyed();
    far_away_capturers.clear();

    // Events ggf. entfernen
    GetEvMgr().RemoveEvent(goldorder_event);
    GetEvMgr().RemoveEvent(upgrade_event);

    // übriggebliebene Goldmünzen in der Inventur abmelden
    gwg->GetPlayer(player).DecreaseInventoryWare(GD_COINS, coins);

    Destroy_nobBaseMilitary();

    // Land drumherum neu berechnen (nur wenn es schon besetzt wurde!)
    // Nach dem BaseDestroy erst, da in diesem erst das Feuer gesetzt, die Straße gelöscht wird usw.
    if(!new_built)
        gwg->RecalcTerritory(*this, true, false);

    gwg->GetNotifications().publish(BuildingNote(BuildingNote::Lost, player, pos, type_));
}
예제 #3
0
void nobMilitary::AddPassiveSoldier(nofPassiveSoldier* soldier)
{
    RTTR_Assert(soldier->GetPlayer() == player);
    RTTR_Assert(troops.size() < unsigned(TROOPS_COUNT[nation][size]));

    troops.insert(soldier);

    // und aus den bestllten Truppen raushauen, da er ja jetzt hier ist
    ordered_troops.erase(soldier);

    // Wurde dieses Gebäude zum ersten Mal besetzt?
    if(new_built)
    {
        SendPostMessage(player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), _("Military building occupied"), PMC_MILITARY, *this));
        // Ist nun besetzt
        new_built = false;
        // Landgrenzen verschieben
        gwg->RecalcTerritory(*this, false, true);
        // Tür zumachen
        CloseDoor();
        // Fanfarensound abspieln, falls das Militärgebäude im Sichtbereich ist und unseres ist
        gwg->MilitaryBuildingCaptured(pos, player);
        gwg->GetNotifications().publish(BuildingNote(BuildingNote::Captured, player, pos, type_));
    }
    else
    {
        // Evtl. Soldaten befördern
        PrepareUpgrading();
    }

    if( mAutoTrain )
        RegulateTroops();

    // Goldmünzen suchen, evtl sinds ja neue Soldaten
    SearchCoins();
}
예제 #4
0
void nobMilitary::Capture(const unsigned char new_owner)
{
    RTTR_Assert(IsCaptured());

    captured_not_built = true;
    mAutoTrain = false;
    mAutoTrainVirtual = false;

    // Goldmünzen in der Inventur vom alten Spieler abziehen und dem neuen hinzufügen
    gwg->GetPlayer(player).DecreaseInventoryWare(GD_COINS, coins);
    gwg->GetPlayer(new_owner).IncreaseInventoryWare(GD_COINS, coins);

    // Soldaten, die auf Mission sind, Bescheid sagen
    for(std::list<nofActiveSoldier*>::iterator it = troops_on_mission.begin(); it != troops_on_mission.end(); ++it)
        (*it)->HomeDestroyed();

    // Bestellungen die hierher unterwegs sind canceln
    CancelOrders();

    // Aggressiv-Verteidigenden Soldaten Bescheid sagen, dass sie nach Hause gehen können
    for(std::list<nofAggressiveDefender*>::iterator it = aggressive_defenders.begin(); it != aggressive_defenders.end(); ++it)
        (*it)->AttackedGoalDestroyed();

    troops_on_mission.clear();
    aggressive_defenders.clear();

    // In der Wirtschaftsverwaltung dieses Gebäude jetzt zum neuen Spieler zählen und beim alten raushauen
    gwg->GetPlayer(player).RemoveMilitaryBuilding(this);
    gwg->GetPlayer(new_owner).AddMilitaryBuilding(this);

    // Alten Besitzer merken
    unsigned char old_player = player;

    // neuer Spieler
    player = new_owner;

    // Flagge davor auch übernehmen
    GetFlag()->Capture(new_owner);

    // Territorium neu berechnen
    gwg->RecalcTerritory(*this, false, false);

    // Sichtbarkeiten berechnen für alten Spieler
    gwg->RecalcVisibilitiesAroundPoint(pos, GetMilitaryRadius() + VISUALRANGE_MILITARY + 1, old_player, NULL);

    // Grenzflagge entsprechend neu setzen von den Feinden
    LookForEnemyBuildings();
    // und von den Verbündeten (da ja ein Feindgebäude weg ist)!
    sortedMilitaryBlds buildings = gwg->LookForMilitaryBuildings(pos, 4);
    for(sortedMilitaryBlds::iterator it = buildings.begin(); it != buildings.end(); ++it)
    {
        // verbündetes Gebäude?
        if(gwg->GetPlayer((*it)->GetPlayer()).IsPlayerAttackable(old_player)
                && (*it)->GetBuildingType() >= BLD_BARRACKS && (*it)->GetBuildingType() <= BLD_FORTRESS)
            // Grenzflaggen von dem neu berechnen
            static_cast<nobMilitary*>(*it)->LookForEnemyBuildings();
    }

    // ehemalige Leute dieses Gebäudes nach Hause schicken, die ggf. grad auf dem Weg rein/raus waren
    MapPoint coords[2] = {pos, MapPoint(gwg->GetNeighbour(pos, 4))};
    for(unsigned short i = 0; i < 2; ++i)
    {
        const std::list<noBase*>& figures = gwg->GetFigures(coords[i]);
        for(std::list<noBase*>::const_iterator it = figures.begin(); it != figures.end(); ++it)
        {
            if((*it)->GetType() == NOP_FIGURE)
            {
                if(static_cast<noFigure*>(*it)->GetCurrentRoad() == routes[4] && static_cast<noFigure*>(*it)->GetPlayer() != new_owner)
                {
                    static_cast<noFigure*>(*it)->Abrogate();
                    static_cast<noFigure*>(*it)->StartWandering();
                }
            }
        }
    }

    // Send all allied aggressors home (we own the building now!)
    for(std::list<nofAttacker*>::iterator it = aggressors.begin(); it != aggressors.end();)
    {
        nofAttacker* attacker = *it;
        // dont remove attackers owned by players not allied with the new owner!
        unsigned char attPlayer = attacker->GetPlayer();
        if(attPlayer != player && !gwg->GetPlayer(attPlayer).IsPlayerAttackable(player))
        {
            it = aggressors.erase(it);
            attacker->CapturedBuildingFull();
        }else
            ++it;
    }

    // Fanfarensound abspieln, falls das Militärgebäude im Sichtbereich ist und unseres ist
    gwg->MilitaryBuildingCaptured(pos, player);

    // Post verschicken, an den alten Besitzer und an den neuen Besitzer
    SendPostMessage(old_player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), _("Military building lost"), PMC_MILITARY, *this));
    SendPostMessage(player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), _("Military building captured"), PMC_MILITARY, *this));

    // ggf. Fenster schließen vom alten Spieler
    gwg->ImportantObjectDestroyed(pos);
    gwg->GetNotifications().publish(BuildingNote(BuildingNote::Captured, player, pos, type_));
    gwg->GetNotifications().publish(BuildingNote(BuildingNote::Lost, old_player, pos, type_));
}