示例#1
0
GoodType nofMetalworker::GetOrderedTool()
{
    // qx:tools
    int prio = -1;
    int tool = -1;

    GameClientPlayer& owner = gwg->GetPlayer(player);
    for (unsigned i = 0; i < TOOL_COUNT; ++i)
    {
        if (owner.tools_ordered[i] > 0 && (owner.toolsSettings_[i] > prio) )
        {
            prio = owner.toolsSettings_[i];
            tool = i;
        }
    }

    if (tool != -1)
    {
        --owner.tools_ordered[tool];

        if (ToolsOrderedTotal() == 0)
            SendPostMessage(player, new PostMsg(GetEvMgr().GetCurrentGF(), _("Completed the ordered amount of tools."), PMC_GENERAL));

        gwg->GetNotifications().publish(ToolNote(ToolNote::OrderCompleted, player));
        return TOOLS_SETTINGS_IDS[tool];
    }
    return GD_NOTHING;
}
示例#2
0
/// Das Schiff wird um eine Stufe weitergebaut
void noShipBuildingSite::MakeBuildStep()
{
    ++progress;

    // Schiff fertiggestellt?
    if(progress > PROGRESS_PARTS[0] + PROGRESS_PARTS[1] + PROGRESS_PARTS[2])
    {
        // Replace me by ship
        GetEvMgr().AddToKillList(this);
        gwg->SetNO(pos, NULL);
        noShip* ship = new noShip(pos, player);
        gwg->AddFigure(ship, pos);

        // Schiff registrieren lassen
        gwg->GetPlayer(player).RegisterShip(ship);

        // BQ neu berechnen, da Schiff nicht mehr blockiert
        gwg->RecalcBQAroundPointBig(pos);

        // Spieler über Fertigstellung benachrichtigen
        SendPostMessage(player, new ShipPostMsg(GetEvMgr().GetCurrentGF(), _("A new ship is ready"), PostCategory::Economy, *ship));
        gwg->GetNotifications().publish(ShipNote(ShipNote::Constructed, player, pos));
    }

}
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());
    }
}
示例#4
0
void noShip::Driven()
{
    MapPoint enemy_territory_discovered(MapPoint::Invalid());
    gwg->RecalcMovingVisibilities(pos, player, GetVisualRange(), GetCurMoveDir(), &enemy_territory_discovered);

    // Feindliches Territorium entdeckt?
    if(enemy_territory_discovered.isValid())
    {
        // Send message if necessary
        if(gwg->GetPlayer(player).ShipDiscoveredHostileTerritory(enemy_territory_discovered))
            SendPostMessage(player, new PostMsg(GetEvMgr().GetCurrentGF(), _("A ship disovered an enemy territory"), PostCategory::Military, enemy_territory_discovered));
    }

    switch(state)
    {
        case STATE_GOTOHARBOR: HandleState_GoToHarbor(); break;
        case STATE_EXPEDITION_DRIVING: HandleState_ExpeditionDriving(); break;
        case STATE_EXPLORATIONEXPEDITION_DRIVING: HandleState_ExplorationExpeditionDriving(); break;
        case STATE_TRANSPORT_DRIVING: HandleState_TransportDriving(); break;
        case STATE_SEAATTACK_DRIVINGTODESTINATION: HandleState_SeaAttackDriving(); break;
        case STATE_SEAATTACK_RETURN_DRIVING: HandleState_SeaAttackReturn(); break;
        default:
            RTTR_Assert(false);
            break;
    }
}
示例#5
0
void noShip::HandleState_ExpeditionDriving()
{
    Result res;
    // Zum Heimathafen fahren?
    if(home_harbor == goal_harborId)
        res = DriveToHarbour();
    else
        res = DriveToHarbourPlace();

    switch(res)
    {
        case DRIVING: return;
        case GOAL_REACHED:
        {
            // Haben wir unsere Expedition beendet?
            if(home_harbor == goal_harborId)
            {
                // Sachen wieder in den Hafen verladen
                state = STATE_EXPEDITION_UNLOADING;
                current_ev = GetEvMgr().AddEvent(this, UNLOADING_TIME, 1);
            }
            else
            {
                // Warten auf weitere Anweisungen
                state = STATE_EXPEDITION_WAITING;

                // Spieler benachrichtigen
                SendPostMessage(player, new ShipPostMsg(GetEvMgr().GetCurrentGF(), _("A ship has reached the destination of its expedition."), PostCategory::Economy, *this));
                gwg->GetNotifications().publish(ExpeditionNote(ExpeditionNote::Waiting, player, pos));
            }
        } break;
        case NO_ROUTE_FOUND:
        case HARBOR_DOESNT_EXIST: //should only happen when an expedition is cancelled and the home harbor no longer exists
        {
            if(home_harbor != goal_harborId && home_harbor != 0)
            {
                // Try to go back
                goal_harborId = home_harbor;
                HandleState_ExpeditionDriving();
            }else
                FindUnloadGoal(STATE_EXPEDITION_DRIVING); // Unload anywhere!
        } break;
    }
}
void nofGeologist::SetSign(Resource resources)
{
    RTTR_Assert(resources.getType() != Resource::Fish); // Shall never happen

    // Bestimmte Objekte können gelöscht werden
    NodalObjectType noType = gwg->GetNO(pos)->GetType();
    if(noType != NOP_NOTHING && noType != NOP_ENVIRONMENT)
        return;
    gwg->DestroyNO(pos, false);

    // Schild setzen
    gwg->SetNO(pos, new noSign(pos, resources));

    // If nothing found, there is nothing left to do
    if(resources.getAmount() == 0u)
        return;

    if(!resAlreadyFound[resources.getType()] && !IsSignInArea(resources.getType()))
    {
        const char* msg;
        switch(resources.getType())
        {
            case Resource::Iron: msg = _("Found iron ore"); break;
            case Resource::Gold: msg = _("Found gold"); break;
            case Resource::Coal: msg = _("Found coal"); break;
            case Resource::Granite: msg = _("Found granite"); break;
            case Resource::Water: msg = _("Found water"); break;
            default: RTTR_Assert(false); return;
        }

        if(resources.getType() != Resource::Water || gwg->GetGGS().getSelection(AddonId::EXHAUSTIBLE_WATER) != 1)
        {
            SendPostMessage(player, new PostMsg(GetEvMgr().GetCurrentGF(), msg, PostCategory::Geologist, pos));
        }

        gwg->GetNotifications().publish(ResourceNote(player, pos, resources));
        if(gwg->HasLua())
            gwg->GetLua().EventResourceFound(this->player, pos, resources.getType(), resources.getAmount());
    }
    resAlreadyFound[resources.getType()] = true;
}
示例#7
0
void nobMilitary::HitOfCatapultStone()
{
    // Ein Soldat weniger, falls es noch welche gibt
    if(!troops.empty())
    {
        nofPassiveSoldier* soldier = *troops.begin();
        helpers::pop_front(troops);
        // Shortcut for Die(): No need to remove from world as it is inside and we can delete it right away
        soldier->RemoveFromInventory();
        soldier->LeftBuilding();
        soldier->Destroy();
        deletePtr(soldier);
    }

    // If there are troops left, order some more, else this will be destroyed
    if(!troops.empty())
        RegulateTroops();

    // Post verschicken
    SendPostMessage(player, new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), _("A catapult is firing upon us!"), PMC_MILITARY, *this));
}
GoodType nofMetalworker::GetOrderedTool()
{
    GamePlayer& owner = gwg->GetPlayer(player);
    std::vector<uint8_t> random_array;
    for(unsigned i = 0; i < NUM_TOOLS; ++i)
    {
        if(owner.GetToolsOrdered(i) == 0)
            continue;
        unsigned toolPriority = std::max(owner.GetToolPriority(i), 1u);
        random_array.insert(random_array.end(), toolPriority, i);
    }
    if(random_array.empty())
        return GD_NOTHING;

    unsigned toolIdx = random_array[RANDOM_RAND(GetObjId(), random_array.size())];

    owner.ToolOrderProcessed(toolIdx);

    if(!HasToolOrder())
        SendPostMessage(player, new PostMsg(GetEvMgr().GetCurrentGF(), _("Completed the ordered amount of tools."), PostCategory::Economy));

    return TOOLS[toolIdx];
}
示例#9
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();
}
/// 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;
            RTTR_Assert(dynamic_cast<nobMilitary*>(attacked_goal));
            auto* goal = static_cast<nobMilitary*>(attacked_goal);
            RTTR_Assert(goal->IsFarAwayCapturer(this));
            // Start walking first so the flag is free
            StartWalking(Direction::NORTHWEST);
            // Then tell the building
            goal->FarAwayCapturerReachedGoal(this);
            return;
        }

        // Post schicken "Wir werden angegriffen" TODO evtl. unschön, da jeder Attacker das dann aufruft
        SendPostMessage(attacked_goal->GetPlayer(), new PostMsgWithBuilding(GetEvMgr().GetCurrentGF(), _("We are under attack!"),
                                                                            PostCategory::Military, *attacked_goal));

        // 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(Direction::NORTHWEST);
            // 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
        Direction dir(Direction::WEST);
        MapPoint attFlagPos = attacked_goal->GetFlag()->GetPos();
        if(pos.y == attFlagPos.y && pos.x <= attFlagPos.x)
            dir = Direction::EAST;
        else if(pos.y == attFlagPos.y && pos.x > attFlagPos.x)
            dir = Direction::WEST;
        else if(pos.y < attFlagPos.y && pos.x < attFlagPos.x)
            dir = Direction::SOUTHEAST;
        else if(pos.y < attFlagPos.y && pos.x > attFlagPos.x)
            dir = Direction::SOUTHWEST;
        else if(pos.y > attFlagPos.y && pos.x < attFlagPos.x)
            dir = Direction::NORTHEAST;
        else if(pos.y > attFlagPos.y && pos.x > attFlagPos.x)
            dir = Direction::NORTHWEST;
        else /* (pos.x ==  attFlagPos.x)*/
        {
            if(pos.y < attFlagPos.y && !(safeDiff(pos.y, attFlagPos.y) & 1))
                dir = Direction::SOUTHEAST;
            else if(pos.y < attFlagPos.y && (safeDiff(pos.y, attFlagPos.y) & 1))
            {
                if(pos.y & 1)
                    dir = Direction::SOUTHWEST;
                else
                    dir = Direction::SOUTHEAST;
            } else if(pos.y > attFlagPos.y && !(safeDiff(pos.y, attFlagPos.y) & 1))
                dir = Direction::NORTHEAST;
            else /* (pos.y > attFlagPos.y && (safeDiff(pos.y, attFlagPos.y) & 1))*/
            {
                if(pos.y & 1)
                    dir = Direction::NORTHWEST;
                else
                    dir = Direction::NORTHEAST;
            }
        }
        FaceDir(dir);
        if(attacked_goal->GetPlayer() == player)
        {
            // Building already captured? -> Then we might be a far-away-capturer
            // -> Tell the building, that we are here
            RTTR_Assert(dynamic_cast<nobMilitary*>(attacked_goal));
            auto* goal = static_cast<nobMilitary*>(attacked_goal);
            if(goal->IsFarAwayCapturer(this))
                goal->FarAwayCapturerReachedGoal(this);
        }
    }
}
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;
    }
}
示例#12
0
void noShip::HandleEvent(const unsigned int id)
{
    RTTR_Assert(current_ev);
    RTTR_Assert(current_ev->id == id);
    current_ev = NULL;

    if(id == 0)
    {
        // Move event
        // neue Position einnehmen
        Walk();
        // entscheiden, was als nächstes zu tun ist
        Driven();
    }else
    {
        switch(state)
        {
        default: 
            RTTR_Assert(false);
            LOG.write("Bug detected: Invalid state in ship event");
            break;
        case STATE_EXPEDITION_LOADING:
            // Schiff ist nun bereit und Expedition kann beginnen
            state = STATE_EXPEDITION_WAITING;

            // Spieler benachrichtigen
            SendPostMessage(player, new ShipPostMsg(GetEvMgr().GetCurrentGF(), _("A ship is ready for an expedition."), PostCategory::Economy, *this));
            gwg->GetNotifications().publish(ExpeditionNote(ExpeditionNote::Waiting, player, pos));
            break;
        case STATE_EXPLORATIONEXPEDITION_LOADING:
        case STATE_EXPLORATIONEXPEDITION_WAITING:
            // Schiff ist nun bereit und Expedition kann beginnen
            ContinueExplorationExpedition();
            break;
        case STATE_EXPEDITION_UNLOADING:
        {
            // Hafen herausfinden
            noBase* hb = goal_harborId ? gwg->GetNO(gwg->GetHarborPoint(goal_harborId)) : NULL;

            if(hb && hb->GetGOT() == GOT_NOB_HARBORBUILDING)
            {
                Inventory goods;
                unsigned char nation = gwg->GetPlayer(player).nation;
                goods.goods[GD_BOARDS] = BUILDING_COSTS[nation][BLD_HARBORBUILDING].boards;
                goods.goods[GD_STONES] = BUILDING_COSTS[nation][BLD_HARBORBUILDING].stones;
                goods.people[JOB_BUILDER] = 1;
                static_cast<nobBaseWarehouse*>(hb)->AddGoods(goods, false);
                // Wieder idlen und ggf. neuen Job suchen
                StartIdling();
                gwg->GetPlayer(player).GetJobForShip(this);
            }
            else
            {
                // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state
                state = STATE_EXPEDITION_DRIVING;
                HandleState_ExpeditionDriving();
            }
            break;
        }
        case STATE_EXPLORATIONEXPEDITION_UNLOADING:
        {
            // Hafen herausfinden
            noBase* hb = goal_harborId ? gwg->GetNO(gwg->GetHarborPoint(goal_harborId)): NULL;

            unsigned old_visual_range = GetVisualRange();

            if(hb && hb->GetGOT() == GOT_NOB_HARBORBUILDING)
            {
                // Späher wieder entladen
                Inventory goods;
                goods.people[JOB_SCOUT] = gwg->GetGGS().GetNumScoutsExedition();
                static_cast<nobBaseWarehouse*>(hb)->AddGoods(goods, false);
                // Wieder idlen und ggf. neuen Job suchen
                StartIdling();
                gwg->GetPlayer(player).GetJobForShip(this);
            }
            else
            {
                // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state
                state = STATE_EXPLORATIONEXPEDITION_DRIVING;
                HandleState_ExplorationExpeditionDriving();
            }

            // Sichtbarkeiten neu berechnen
            gwg->RecalcVisibilitiesAroundPoint(pos, old_visual_range, player, NULL);

            break;
        }
        case STATE_TRANSPORT_LOADING:
            StartTransport();
            break;
        case STATE_TRANSPORT_UNLOADING:
        case STATE_SEAATTACK_UNLOADING:
        {
            // Hafen herausfinden
            RTTR_Assert(state == STATE_SEAATTACK_UNLOADING || remaining_sea_attackers == 0);
            noBase* hb = goal_harborId ? gwg->GetNO(gwg->GetHarborPoint(goal_harborId)): NULL;
            if(hb && hb->GetGOT() == GOT_NOB_HARBORBUILDING)
            {
                static_cast<nobHarborBuilding*>(hb)->ReceiveGoodsFromShip(figures, wares);
                figures.clear();
                wares.clear();

                state = STATE_TRANSPORT_UNLOADING;
                // Hafen bescheid sagen, dass er das Schiff nun nutzen kann
                static_cast<nobHarborBuilding*>(hb)->ShipArrived(this);

                // Hafen hat keinen Job für uns?
                if (state == STATE_TRANSPORT_UNLOADING)
                {
                    // Wieder idlen und ggf. neuen Job suchen
                    StartIdling();
                    gwg->GetPlayer(player).GetJobForShip(this);
                }
            }
            else
            {
                // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state
                if(state == STATE_TRANSPORT_UNLOADING)
                    FindUnloadGoal(STATE_TRANSPORT_DRIVING);
                else
                    FindUnloadGoal(STATE_SEAATTACK_RETURN_DRIVING);
            }
            break;
        }
        case STATE_SEAATTACK_LOADING:
            StartSeaAttack();
            break;
        case STATE_SEAATTACK_WAITING:
        {
            // Nächsten Soldaten nach draußen beordern
            if(figures.empty())
                break;

            nofAttacker* attacker = static_cast<nofAttacker*>(figures.front());
            // Evtl. ist ein Angreifer schon fertig und wieder an Board gegangen
            // der darf dann natürlich nicht noch einmal raus, sonst kann die schöne Reise
            // böse enden
            if(attacker->IsSeaAttackCompleted())
                break;

            figures.pop_front();
            gwg->AddFigure(attacker, pos);

            current_ev = GetEvMgr().AddEvent(this, 30, 1);
            attacker->StartAttackOnOtherIsland(pos, GetObjId());
            break;
        }
        }
    }
}
示例#13
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_));
}