Ejemplo n.º 1
0
/// Sagt Bescheid, dass ein Schiffsangreifer nicht mehr mit nach Hause fahren will
void noShip::SeaAttackerWishesNoReturn()
{
    RTTR_Assert(remaining_sea_attackers);
    RTTR_Assert(state == STATE_SEAATTACK_WAITING);

    --remaining_sea_attackers;
    // Alle Soldaten an Bord
    if(remaining_sea_attackers == 0)
    {
        // Andere Events ggf. erstmal abmelden
        GetEvMgr().RemoveEvent(current_ev);
        if(!figures.empty())
        {
            // Go back home. Note: home_harbor can be 0 if it was destroyed, allow this and let the state handlers handle that case later
            goal_harborId = home_harbor;
            state = STATE_SEAATTACK_RETURN_DRIVING;
            StartDrivingToHarborPlace();
            HandleState_SeaAttackReturn();
        }
        else
        {
            // Wenn keine Soldaten mehr da sind können wir auch erstmal idlen
            StartIdling();
            gwg->GetPlayer(player).GetJobForShip(this);
        }
    }

}
Ejemplo n.º 2
0
void noShip::HandleState_SeaAttackReturn()
{
    Result res = DriveToHarbour();
    switch(res)
    {
        default: return;
        case GOAL_REACHED:
        {
            // Entladen
            state = STATE_SEAATTACK_UNLOADING;
            this->current_ev = em->AddEvent(this, UNLOADING_TIME, 1);
        } break;
        case HARBOR_DOESNT_EXIST:
        {
            // Kein Hafen mehr?
            // Dann müssen alle Angreifer ihren Heimatgebäuden Bescheid geben, dass sie
            // nun nicht mehr kommen
            // Das Schiff muss einen Notlandeplatz ansteuern
            for(std::list<noFigure*>::iterator it = figures.begin(); it != figures.end(); ++it)
                static_cast<nofAttacker*>(*it)->CancelAtHomeMilitaryBuilding();

            state = STATE_TRANSPORT_DRIVING;
            HandleState_TransportDriving();

        } break;
        case NO_ROUTE_FOUND:
        {
            MapPoint goal(gwg->GetHarborPoint(goal_harbor_id));
            // Nichts machen und idlen
            StartIdling();
        } break;
    }
}
Ejemplo n.º 3
0
/// Sagt Bescheid, dass ein Schiffsangreifer nicht mehr mit nach Hause fahren will
void noShip::SeaAttackerWishesNoReturn()
{
    assert(remaining_sea_attackers);
    --remaining_sea_attackers;
    // Alle Soldaten an Bord
    if(remaining_sea_attackers == 0)
    {
        // Andere Events ggf. erstmal abmelden
        em->RemoveEvent(current_ev);
        if(!figures.empty())
        {
            //set it to 1 so we "know" that we are driving back not any transport but a group of sea attackers (reset @ handleevent unload transport, used when target harbor dies to set the soldiers goal to 0)
            remaining_sea_attackers = 1;
            // Wieder nach Hause fahren
            goal_harbor_id = home_harbor;
            StartDrivingToHarborPlace();
            state = STATE_TRANSPORT_DRIVING;
            HandleState_TransportDriving();
            for(std::list<noFigure*>::iterator it = figures.begin(); it != figures.end(); ++it)
                (*it)->StartShipJourney(gwg->GetHarborPoint(goal_harbor_id));
        }
        else
        {
            // Wenn keine Soldaten mehr da sind können wir auch erstmal idlen
            StartIdling();
            players->getElement(player)->GetJobForShip(this);
        }
    }

}
Ejemplo n.º 4
0
void noShip::HandleState_ExpeditionDriving()
{
    Result res;
    // Zum Heimathafen fahren?
    if(home_harbor == goal_harbor_id)
        res = DriveToHarbour();
    else
        res = DriveToHarbourPlace();

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

                // Spieler benachrichtigen
                if(GAMECLIENT.GetPlayerID() == this->player)
                    GAMECLIENT.SendPostMessage(new ShipPostMsg(_("A ship has reached the destination of its expedition."), PMC_GENERAL, GAMECLIENT.GetPlayer(player).nation, pos));

                // KI Event senden
                GAMECLIENT.SendAIEvent(new AIEvent::Location(AIEvent::ExpeditionWaiting, pos), player);
            }
        } break;
        case NO_ROUTE_FOUND:
        {
            MapPoint goal(gwg->GetHarborPoint(goal_harbor_id));
            // Nichts machen und idlen
            StartIdling();
        } break;
        case HARBOR_DOESNT_EXIST: //should only happen when an expedition is cancelled and the home harbor no longer exists
        {
            // Kein Heimathafen mehr?
            // Das Schiff muss einen Notlandeplatz ansteuern
            if(players->getElement(player)->FindHarborForUnloading(this, pos, &goal_harbor_id, &route_, NULL))
            {
                curRouteIdx = 0;
                home_harbor = goal_harbor_id; //set new home=goal so we will actually unload once we reach the goal
                HandleState_ExpeditionDriving();
            }
            else
            {
                // Ansonsten als verloren markieren, damit uns später Bescheid gesagt wird
                // wenn es einen neuen Hafen gibt
                lost = true;
            }
        } break;
    }
}
Ejemplo n.º 5
0
void noShip::HandleState_TransportDriving()
{
    Result res = DriveToHarbour();
    switch(res)
    {
        default: return;
        case GOAL_REACHED:
        {
            // Waren abladen, dafür wieder kurze Zeit hier ankern
            state = STATE_TRANSPORT_UNLOADING;
            current_ev = em->AddEvent(this, UNLOADING_TIME, 1);

        } break;
        case NO_ROUTE_FOUND:
        {
            // Nichts machen und idlen
            StartIdling();
        } break;
        case HARBOR_DOESNT_EXIST:
        {
            // Kein Hafen mehr?
            // Dann müssen alle Leute ihren Heimatgebäuden Bescheid geben, dass sie
            // nun nicht mehr kommen
            // Das Schiff muss einen Notlandeplatz ansteuern
            //LOG.lprintf("transport goal harbor doesnt exist player %i state %i pos %u,%u \n",player,state,x,y);
            for(std::list<noFigure*>::iterator it = figures.begin(); it != figures.end(); ++it)
            {
                (*it)->Abrogate();
                (*it)->SetGoalToNULL();
            }

            if(remaining_sea_attackers)
            {
                remaining_sea_attackers = 0;
                for(std::list<noFigure*>::iterator it = figures.begin(); it != figures.end(); ++it)
                    static_cast<nofAttacker*>(*it)->HomeHarborLost();
            }
            for(std::list<Ware*>::iterator it = wares.begin(); it != wares.end(); ++it)
            {
                (*it)->NotifyGoalAboutLostWare();
                (*it)->goal = NULL;
            }

            // Neuen Hafen suchen
            if(players->getElement(player)->FindHarborForUnloading(this, pos, &goal_harbor_id, &route_, NULL))
            {
                curRouteIdx = 0;
                HandleState_TransportDriving();
            }
            else
            {
                // Ansonsten als verloren markieren, damit uns später Bescheid gesagt wird
                // wenn es einen neuen Hafen gibt
                lost = true;
            }
        } break;
    }
}
Ejemplo n.º 6
0
void noShip::HandleState_ExplorationExpeditionDriving()
{
    Result res;
    // Zum Heimathafen fahren?
    if(home_harbor == goal_harbor_id && covered_distance >= MAX_EXPLORATION_EXPEDITION_DISTANCE)
        res = DriveToHarbour();
    else
        res = DriveToHarbourPlace();

    switch(res)
    {
        default: return;
        case GOAL_REACHED:
        {
            // Haben wir unsere Expedition beendet?
            if(home_harbor == goal_harbor_id && covered_distance >= MAX_EXPLORATION_EXPEDITION_DISTANCE)
            {
                // Dann sind wir fertig -> wieder entladen
                state = STATE_EXPLORATIONEXPEDITION_UNLOADING;
                current_ev = em->AddEvent(this, UNLOADING_TIME, 1);
            }
            else
            {
                // Strecke, die wir gefahren sind, draufaddieren
                covered_distance += route_.size();
                // Erstmal kurz ausruhen an diesem Punkt und das Rohr ausfahren, um ein bisschen
                // auf der Insel zu gucken
                state = STATE_EXPLORATIONEXPEDITION_WAITING;
                current_ev = em->AddEvent(this, EXPLORATION_EXPEDITION_WAITING_TIME, 1);
            }

        } break;
        case NO_ROUTE_FOUND:
        {
            MapPoint goal(gwg->GetHarborPoint(goal_harbor_id));
            unsigned old_visual_range = GetVisualRange();
            // Nichts machen und idlen
            StartIdling();
            // Sichtbarkeiten neu berechnen
            gwg->RecalcVisibilitiesAroundPoint(pos, old_visual_range, player, NULL);
        } break;
        case HARBOR_DOESNT_EXIST:
        {
            // Neuen Hafen suchen
            if(players->getElement(player)->FindHarborForUnloading
                    (this, pos, &goal_harbor_id, &route_, NULL))
                HandleState_TransportDriving();
            else
                // Ansonsten als verloren markieren, damit uns später Bescheid gesagt wird
                // wenn es einen neuen Hafen gibt
                lost = true;

        } break;
    }
}
Ejemplo n.º 7
0
void noShip::HandleState_GoToHarbor()
{
    // Hafen schon zerstört?
    if(goal_harbor_id == 0)
    {
        StartIdling();
    }
    else
    {
        Result res = DriveToHarbour();
        switch(res)
        {
            default: return;
            case GOAL_REACHED:
            {

                MapPoint goal(gwg->GetHarborPoint(goal_harbor_id));
                // Erstmal nichts machen und idlen
                StartIdling();
                // Hafen Bescheid sagen, dass wir da sind (falls er überhaupt noch existiert)
                noBase* nb = gwg->GetNO(goal);
                if(nb->GetGOT() == GOT_NOB_HARBORBUILDING)
                    static_cast<nobHarborBuilding*>(nb)->ShipArrived(this);
            } break;
            case NO_ROUTE_FOUND:
            {
                MapPoint goal(gwg->GetHarborPoint(goal_harbor_id));
                // Dem Hafen Bescheid sagen
                gwg->GetSpecObj<nobHarborBuilding>(goal)->ShipLost(this);
                // Ziel aktualisieren
                goal_harbor_id = 0;
                // Nichts machen und idlen
                StartIdling();
            } break;
            case HARBOR_DOESNT_EXIST:
            {
                // Nichts machen und idlen
                StartIdling();
            } break;
        }
    }
}
Ejemplo n.º 8
0
void noShip::HandleState_GoToHarbor()
{
    // Hafen schon zerstört?
    if(goal_harborId == 0)
    {
        StartIdling();
        return;
    }

    Result res = DriveToHarbour();
    switch(res)
    {
    case DRIVING:
        return; // Continue
    case GOAL_REACHED:
        {
            MapPoint goal(gwg->GetHarborPoint(goal_harborId));
            RTTR_Assert(goal.isValid());
            // Go idle here (if harbor does not need it)
            StartIdling();
            // Hafen Bescheid sagen, dass wir da sind (falls er überhaupt noch existiert)
            noBase* hb = goal.isValid() ? gwg->GetNO(goal) : NULL;
            if(hb && hb->GetGOT() == GOT_NOB_HARBORBUILDING)
                static_cast<nobHarborBuilding*>(hb)->ShipArrived(this);
        } break;
    case NO_ROUTE_FOUND:
        {
            MapPoint goal(gwg->GetHarborPoint(goal_harborId));
            RTTR_Assert(goal.isValid());
            // Dem Hafen Bescheid sagen
            gwg->GetSpecObj<nobHarborBuilding>(goal)->ShipLost(this);
            StartIdling();
        } break;
    case HARBOR_DOESNT_EXIST:
        StartIdling();
        break;
    }
}
Ejemplo n.º 9
0
/// Weist das Schiff an, an der aktuellen Position einen Hafen zu gründen
void noShip::FoundColony()
{
    if(state != STATE_EXPEDITION_WAITING)
        return;

    // Kolonie gründen
    if(gwg->FoundColony(goal_harborId, player, seaId_))
    {
        // Dann idlen wir wieder
        StartIdling();
        // Neue Arbeit suchen
        gwg->GetPlayer(player).GetJobForShip(this);
    }
    else //colony founding FAILED
        gwg->GetNotifications().publish(ExpeditionNote(ExpeditionNote::Waiting, player, pos));
}
Ejemplo n.º 10
0
/// Weist das Schiff an, an der aktuellen Position einen Hafen zu gründen
void noShip::FoundColony()
{
    if(state != STATE_EXPEDITION_WAITING)
        return;

    // Kolonie gründen
    if(gwg->FoundColony(goal_harbor_id, player, seaId_))
    {
        // Dann idlen wir wieder
        StartIdling();
        // Neue Arbeit suchen
        players->getElement(player)->GetJobForShip(this);
    }
    else //colony founding FAILED - notify ai
        GAMECLIENT.SendAIEvent(new AIEvent::Location(AIEvent::ExpeditionWaiting, pos), player);

}
Ejemplo n.º 11
0
CControlPanel::CControlPanel()
{
	_totalMem = 0;
	_renderingMode = 0;
	
	_floatWindow = LWindow::CreateWindow(PPob_ControlWindow, this);
	if (_floatWindow) {
	
	
		// Get the main multi panel view and load up all the panels
		LMultiPanelView*	mainMPV = dynamic_cast<LMultiPanelView*> (_floatWindow->FindPaneByID(item_ControlMainPanelView));
		ThrowIfNil_(mainMPV);
		mainMPV->CreateAllPanels();
		LPageController*	thePage = dynamic_cast<LPageController*> (_floatWindow->FindPaneByID(item_ControlPageController));
		ThrowIfNil_(thePage);
		thePage->AddListener(mainMPV);
		
		LView*	theRenderingView = dynamic_cast<LView*> (_floatWindow->FindPaneByID(kRenderingView));
		LView*	thePositionView = dynamic_cast<LView*> (_floatWindow->FindPaneByID(kPositionView));
		LView*	theAnimationView = dynamic_cast<LView*> (_floatWindow->FindPaneByID(kAnimationView));

		UReanimator::LinkListenerToControls(this, theRenderingView, PPob_RenderingView);
		UReanimator::LinkListenerToControls(this, thePositionView, PPob_PositionView);
		UReanimator::LinkListenerToControls(this, theAnimationView, PPob_AnimationView);
		
		UpdateValues(true);
		StartIdling();
		_lastDraw = 0;
		_drawInterval = 60; // in Ticks

		// position
		GDHandle dominantDevice = ::GetMainDevice();
		Rect screenRect = (**dominantDevice).gdRect;
		Rect windowBounds;
		_floatWindow->GetGlobalBounds(windowBounds);
		_floatWindow->MoveWindowTo(screenRect.right - (windowBounds.right - windowBounds.left + 13), ::GetMBarHeight() + 23 );
		

		_floatWindow->Show();
	}
}
Ejemplo n.º 12
0
void noShip::HandleState_ExplorationExpeditionDriving()
{
    Result res;
    // Zum Heimathafen fahren?
    if(home_harbor == goal_harborId && covered_distance >= MAX_EXPLORATION_EXPEDITION_DISTANCE)
        res = DriveToHarbour();
    else
        res = DriveToHarbourPlace();

    switch(res)
    {
        case DRIVING: return;
        case GOAL_REACHED:
        {
            // Haben wir unsere Expedition beendet?
            if(home_harbor == goal_harborId && covered_distance >= MAX_EXPLORATION_EXPEDITION_DISTANCE)
            {
                // Dann sind wir fertig -> wieder entladen
                state = STATE_EXPLORATIONEXPEDITION_UNLOADING;
                current_ev = GetEvMgr().AddEvent(this, UNLOADING_TIME, 1);
            }
            else
            {
                // Strecke, die wir gefahren sind, draufaddieren
                covered_distance += route_.size();
                // Erstmal kurz ausruhen an diesem Punkt und das Rohr ausfahren, um ein bisschen
                // auf der Insel zu gucken
                state = STATE_EXPLORATIONEXPEDITION_WAITING;
                current_ev = GetEvMgr().AddEvent(this, EXPLORATION_EXPEDITION_WAITING_TIME, 1);
            }

        } break;
        case NO_ROUTE_FOUND:
        case HARBOR_DOESNT_EXIST:
            gwg->RecalcVisibilitiesAroundPoint(pos, GetVisualRange(), player, NULL);
            StartIdling();
            break;
    }
}
Ejemplo n.º 13
0
void noShip::HandleState_SeaAttackDriving()
{
    Result res = DriveToHarbourPlace();
    switch(res)
    {
        default: return;
        case GOAL_REACHED:
        {
            // Ziel erreicht, dann stellen wir das Schiff hier hin und die Soldaten laufen nacheinander
            // raus zum Ziel
            state = STATE_SEAATTACK_WAITING;
            current_ev = em->AddEvent(this, 15, 1);
            remaining_sea_attackers = figures.size();

        } break;
        case NO_ROUTE_FOUND:
        {
            MapPoint goal(gwg->GetHarborPoint(goal_harbor_id));
            // Nichts machen und idlen
            StartIdling();
        } break;
    }
}
Ejemplo n.º 14
0
void noShip::HandleEvent(const unsigned int id)
{
    current_ev = 0;

    switch(id)
    {
            // Laufevent
        case 0:
        {
            // neue Position einnehmen
            Walk();

            // entscheiden, was als nächstes zu tun ist
            Driven();
        } break;
        default:
        {
            switch(state)
            {
                default: break;
                case STATE_EXPEDITION_LOADING:
                {
                    // Schiff ist nun bereit und Expedition kann beginnen
                    state = STATE_EXPEDITION_WAITING;

                    // Spieler benachrichtigen
                    if(GAMECLIENT.GetPlayerID() == this->player)
                        GAMECLIENT.SendPostMessage(new ShipPostMsg(_("A ship is ready for an expedition."), PMC_GENERAL, GAMECLIENT.GetPlayer(player).nation, pos));

                    // KI Event senden
                    GAMECLIENT.SendAIEvent(new AIEvent::Location(AIEvent::ExpeditionWaiting, pos), player);
                } break;
                case STATE_EXPLORATIONEXPEDITION_LOADING:
                {
                    // Schiff ist nun bereit und Expedition kann beginnen
                    ContinueExplorationExpedition();
                } break;
                case STATE_EXPLORATIONEXPEDITION_WAITING:
                {
                    // Schiff ist nun bereit und Expedition kann beginnen
                    ContinueExplorationExpedition();
                } break;

                case STATE_EXPEDITION_UNLOADING:
                {
                    // Hafen herausfinden
                    MapPoint goal_pos(gwg->GetHarborPoint(goal_harbor_id));
                    noBase* hb = gwg->GetNO(goal_pos);

                    if(hb->GetGOT() == GOT_NOB_HARBORBUILDING)
                    {
                        Goods goods;
                        memset(&goods, 0, sizeof(Goods));
                        unsigned char nation = players->getElement(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);
                        // Wieder idlen und ggf. neuen Job suchen
                        StartIdling();
                        players->getElement(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
                    MapPoint goal_pos(gwg->GetHarborPoint(goal_harbor_id));
                    noBase* hb = gwg->GetNO(goal_pos);

                    unsigned old_visual_range = GetVisualRange();

                    if(hb->GetGOT() == GOT_NOB_HARBORBUILDING)
                    {
                        // Späher wieder entladen
                        Goods goods;
                        memset(&goods, 0, sizeof(Goods));
                        goods.people[JOB_SCOUT] = SCOUTS_EXPLORATION_EXPEDITION;
                        static_cast<nobBaseWarehouse*>(hb)->AddGoods(goods);
                        // Wieder idlen und ggf. neuen Job suchen
                        StartIdling();
                        players->getElement(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:
                {
                    // Hafen herausfinden
                    remaining_sea_attackers = 0; //can be 1 in case we had sea attackers on board - set to 1 for a special check when the return harbor is destroyed to set the returning attackers goal to 0
                    MapPoint goal_pos(gwg->GetHarborPoint(goal_harbor_id));
                    noBase* hb = gwg->GetNO(goal_pos);
                    if(hb->GetGOT() == GOT_NOB_HARBORBUILDING)
                    {
                        static_cast<nobHarborBuilding*>(hb)->ReceiveGoodsFromShip(figures, wares);
                        figures.clear();
                        wares.clear();

                        // 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();
                            players->getElement(player)->GetJobForShip(this);
                        }
                    }
                    else
                    {
                        // target harbor for unloading doesnt exist anymore -> set state to driving and handle the new state
                        state = STATE_TRANSPORT_DRIVING;
                        HandleState_TransportDriving();
                    }


                } 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.begin());
                    // 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 = em->AddEvent(this, 30, 1);
                    attacker->StartAttackOnOtherIsland(pos, GetObjId());
                    ;
                };
                case STATE_SEAATTACK_UNLOADING:
                {
                } break;
            }
        } break;

    }

}
Ejemplo n.º 15
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;
        }
        }
    }
}