예제 #1
0
void noFigure::HandleEvent(const unsigned int id)
{
    // Bei ID = 0 ists ein Laufevent, bei allen anderen an abgeleitete Klassen weiterleiten
    if(id)
    {
        HandleDerivedEvent(id);
    }
    else
    {
        current_ev = NULL;
        WalkFigure();

        // Alte Richtung und Position für die Berechnung der Sichtbarkeiten merken
        unsigned char old_dir = GetCurMoveDir();

        MapPoint old_pos(pos);

        switch(fs)
        {
            case FS_GOHOME:
            case FS_GOTOGOAL:
            {
                WalkToGoal();
            } break;

            case FS_JOB:
            {
                Walked();
                break;
            }
            case FS_WANDER:
            {
                Wander();
                break;
            }
        }

        // Ggf. Sichtbereich testen
        if(GetVisualRange())
        {

            // Use old position (don't use this->x/y because it might be different now
            // Figure could be in a ship etc.)
            gwg->RecalcMovingVisibilities(old_pos, player, GetVisualRange(), old_dir, NULL);


            std::vector<noBase*> figures = gwg->GetDynamicObjectsFrom(old_pos);

            // Wenn Figur verschwunden ist, muss ihr ehemaliger gesamter Sichtbereich noch einmal
            // neue berechnet werden
            if(!helpers::contains(figures, this))
                CalcVisibilities(old_pos);
        }

    }
}
예제 #2
0
/// Geht wieder zurück zur Flagge und dann nach Hause
void nofFlagWorker::GoToFlag()
{
    // Zur Flagge zurücklaufen

    // Bin ich an der Fahne?
    if(pos == flag->GetPos())
    {
        // nach Hause gehen
        nobBaseWarehouse* wh = gwg->GetPlayer(player).FindWarehouse(*flag, FW::AcceptsFigure(job_), true, false);
        if(wh)
        {
            GoHome(wh);
            // Vorgaukeln, dass wir ein Stück Straße bereits geschafft haben
            // damit wir mit WalkToGoal weiter bis zum Ziel laufen können
            cur_rs = &emulated_wanderroad;
            rs_pos = 0;
            WalkToGoal();
        }
        else
        {
            // Weg führt nicht mehr zum Lagerhaus, dann rumirren
            StartWandering();
            Wander();
        }


        // Da wir quasi "freiwillig" nach Hause gegangen sind ohne das Abreißen der Flagge, auch manuell wieder
        // "abmelden"
        gwg->GetPlayer(player).RemoveFlagWorker(this);
        state = STATE_FIGUREWORK;
        flag = NULL;
    }
    else
    {
        // Weg suchen
        unsigned char dir = gwg->FindHumanPath(pos, flag->GetPos(), 40);

        // Wenns keinen gibt, rumirren, ansonsten hinlaufen
        if(dir == 0xFF)
        {
            Abrogate();
            StartWandering();
            Wander();
            state = STATE_FIGUREWORK;

            flag = NULL;
        }
        else
        {
            StartWalking(dir);
        }
    }
}
예제 #3
0
void noFigure::WanderToFlag()
{
    // Existiert die Flagge überhaupt noch?
    noBase* no = gwg->GetNO(flagPos_);
    if(no->GetObjId() != flag_obj_id)
    {
        // Wenn nicht, wieder normal weiter rumirren
        StartWandering();
        Wander();
        return;
    }

    // Sind wir schon da?
    if(pos == flagPos_)
    {
        // Gibts noch nen Weg zu einem Lagerhaus?

        if(nobBaseWarehouse* wh = gwg->GetPlayer(player).FindWarehouse(
                                      gwg->GetSpecObj<noRoadNode>(pos), FW::Condition_StoreFigure, 0, true, &job_, false))
        {
            // ja, dann können wir ja hingehen
            goal_ = wh;
            cur_rs = 0;
            rs_pos = 0;
            fs = FS_GOHOME;
            wh->AddDependentFigure(this);
            WalkToGoal();
            return;
        }
        else
        {
            // Wenn nicht, wieder normal weiter rumirren
            StartWandering();
            Wander();
            return;
        }
    }

    // Weiter zur Flagge gehen
    // Gibts noch nen Weg dahin bzw. existiert die Flagge noch?
    unsigned char dir = gwg->FindHumanPath(pos, flagPos_, 60, false);
    if(dir != 0xFF)
    {
        // weiter hinlaufen
        StartWalking(dir);
    }
    else
    {
        // Wenn nicht, wieder normal weiter rumirren
        StartWandering();
        Wander();
    }
}
예제 #4
0
void noFigure::ActAtFirst()
{
    // Je nach unserem Status bestimmte Dinge tun
    switch(fs)
    {
        default: break;
        case FS_GOTOGOAL: WalkToGoal(); break;
        case FS_JOB: StartWalking(4); break; // erstmal rauslaufen, darum kümmern sich dann die abgeleiteten Klassen
        case FS_GOHOME:
        {
            // Wenn ich gleich wieder nach Hause geschickt wurde und aus einem Lagerhaus rauskomme, gar nicht erst rausgehen!
            if(goal_->GetPos() == pos)
            {
                gwg->RemoveFigure(this, pos);
                static_cast<nobBaseWarehouse*>(goal_)->AddFigure(this);
            }
            else
                // ansonsten ganz normal rausgehen
                WalkToGoal();
        } break;
        case FS_WANDER: StartWalking(4); break; // erstmal rauslaufen, darum kümmern sich dann die Wander-Funktionen
    }
}
예제 #5
0
void noFigure::GoHome(noRoadNode* goal)
{
    if(on_ship)
    {
        // Wir befinden uns gerade an Deck, also einfach goal auf Null setzen und dann sehen wir, was so passiert
        this->goal_ = NULL;
        return;
    }
    // Nächstes Lagerhaus suchen
    else if(!goal)
    {
        // Wenn wir cur_rs == 0, dann hängen wir wahrscheinlich noch im Lagerhaus in der Warteschlange
        if(cur_rs == 0)
        {
            assert(gwg->GetNO(pos)->GetGOT() == GOT_NOB_HQ || //-V807
                   gwg->GetNO(pos)->GetGOT() == GOT_NOB_STOREHOUSE
                   || gwg->GetNO(pos)->GetGOT() == GOT_NOB_HARBORBUILDING);

            gwg->GetSpecObj<nobBaseWarehouse>(pos)->CancelFigure(this);
            return;
        }
        else
            this->goal_ = gwg->GetPlayer(player).FindWarehouse((rs_dir) ? cur_rs->GetF1() : cur_rs->GetF2(), FW::Condition_StoreFigure, 0, true, &job_, false);
    }
    else
        this->goal_ = goal;

    if(this->goal_)
    {
        fs = FS_GOHOME;
        // Lagerhaus Bescheid sagen
        static_cast<nobBaseWarehouse*>(this->goal_)->AddDependentFigure(this);

        // Wenn wir stehen, zusätzlich noch loslaufen!
        if(waiting_for_free_node)
        {
            waiting_for_free_node = false;
            WalkToGoal();
            // anderen Leuten noch ggf Bescheid sagen
            gwg->RoadNodeAvailable(this->pos);
        }
    }
    else
    {
        // Kein Lagerhaus gefunden --> Rumirren
        StartWandering();
        cur_rs = 0;
    }
}
예제 #6
0
void noFigure::WalkToGoal()
{
    // Kein Ziel mehr --> Rumirren
    if(!goal_)
    {
        StartWandering();
        Wander();
        return;
    }

    // Straße abgelaufen oder noch gar keine Straße vorhanden?
    if(((cur_rs) ? (rs_pos == cur_rs->GetLength()) : true))
    {
        // Ziel erreicht?
        // Bei dem Träger können das beide Flaggen sein!
        MapPoint goal1, goal2;
        if(GetGOT() == GOT_NOF_CARRIER && fs == FS_GOTOGOAL)
        {
            goal1 = static_cast<nofCarrier*>(this)->GetFirstFlag() ?
                static_cast<nofCarrier*>(this)->GetFirstFlag()->GetPos() : MapPoint(0xFFFF, 0xFFFF);
            goal2 = static_cast<nofCarrier*>(this)->GetSecondFlag() ?
                static_cast<nofCarrier*>(this)->GetSecondFlag()->GetPos() : MapPoint(0xFFFF, 0xFFFF);
        }
        else
        {
            goal1 = goal_->GetPos();
            goal2 = MapPoint(0xFFFF, 0xFFFF);
        }

        if(goal1 == pos || goal2 == pos)
        {
            if(fs == FS_GOHOME)
            {
                // Mann im Lagerhaus angekommen
                gwg->RemoveFigure(this, pos);
                static_cast<nobBaseWarehouse*>(goal_)->AddFigure(this);
            }
            else
            {
                // Zeug nullen
                cur_rs = NULL;
                rs_dir = 0;
                rs_pos = 0;
                goal_ = NULL;


                // abgeleiteter Klasse sagen, dass das Ziel erreicht wurde
                fs = FS_JOB;
                GoalReached();
            }

        }
        else
        {
            MapPoint next_harbor;
            // Neuen Weg berechnen
            unsigned char route = gwg->FindHumanPathOnRoads(gwg->GetSpecObj<noRoadNode>(pos), goal_, NULL, &next_harbor);
            // Kein Weg zum Ziel... nächstes Lagerhaus suchen
            if(route == 0xFF)
            {
                // Arbeisplatz oder Laghaus Bescheid sagen
                Abrogate();
                // Wir gehen jetzt nach Hause
                GoHome();
                // Evtl wurde kein Lagerhaus gefunden und wir sollen rumirren, dann tun wir das gleich
                if(fs == FS_WANDER)
                {
                    Wander();
                    return;
                }

                // Nach Hause laufen...
                WalkToGoal();
                return;
            }
            // Oder müssen wir das Schiff nehmen?
            else if(route == SHIP_DIR)
            {
                // Uns in den Hafen einquartieren
                noBase* nob;
                if((nob = gwg->GetNO(pos))->GetGOT() != GOT_NOB_HARBORBUILDING)
                {
                    // Es gibt keinen Hafen mehr -> nach Hause gehen

                    // Arbeisplatz oder Laghaus Bescheid sagen
                    Abrogate();
                    // Wir gehen jetzt nach Hause
                    GoHome();
                    // Evtl wurde kein Lagerhaus gefunden und wir sollen rumirren, dann tun wir das gleich
                    if(fs == FS_WANDER)
                    {
                        Wander();
                        return;
                    }

                    // Nach Hause laufen...
                    WalkToGoal();
                    return;
                }

                // Uns in den Hafen einquartieren
                cur_rs = NULL; // wir laufen nicht mehr auf einer Straße
                gwg->RemoveFigure(this, pos);
                static_cast<nobHarborBuilding*>(nob)->AddFigureForShip(this, next_harbor);

                return;
            }


            // Nächste Straße wollen, auf der man geht
            cur_rs = gwg->GetSpecObj<noRoadNode>(pos)->routes[route];
            StartWalking(route);
            rs_pos = 0;
            rs_dir = (gwg->GetSpecObj<noRoadNode>(pos) == cur_rs->GetF1()) ? false : true;
        }

    }
    else
    {
        StartWalking(cur_rs->GetDir(rs_dir, rs_pos));
    }
}