void nofGeologist::GoToNextNode()
{
    // Wenn es keine Flagge mehr gibt, dann gleich rumirren
    if(!flag)
    {
        StartWandering();
        Wander();
        state = STATE_FIGUREWORK;
        return;
    }

    // ersten Punkt suchen
    unsigned char dir = GetNextNode();

    if(dir != INVALID_DIR)
    {
        // Wenn es einen Punkt gibt, dann hingehen
        state = STATE_GEOLOGIST_GOTONEXTNODE;
        StartWalking(Direction::fromInt(dir));
        --signs;
    } else if(node_goal == pos)
    {
        // Already there
        state = STATE_GEOLOGIST_GOTONEXTNODE;
        --signs;
        Walked();
    } else
    {
        // ansonsten zur Flagge zurückgehen
        state = STATE_GOTOFLAG;
        Walked();
    }
}
Example #2
0
void nofGeologist::GoToNextNode()
{
    // Wenn es keine Flagge mehr gibt, dann gleich rumirren
    if(!flag)
    {
        StartWandering();
        Wander();
        state = STATE_FIGUREWORK;
        return;
    }

    // ersten Punkt suchen
    unsigned char dir = GetNextNode();

    if(dir != 0xFF)
    {
        // Wenn es einen Punkt gibt, dann hingehen
        state = STATE_GEOLOGIST_GOTONEXTNODE;
        StartWalking(dir);
        --signs;
    }
    else
    {
        // ansonsten zur Flagge zurückgehen
        state = STATE_GOTOFLAG;
        Walked();
    }
}
Example #3
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);
        }

    }
}
Example #4
0
/**
 *
 *
 *  @author OLiver
 */
void nofCarrier::RoadSplitted(RoadSegment* rs1, RoadSegment* rs2)
{
    // Bin ich schon auf meinem Arbeitsplatz (=Straße) oder bin ich erst noch auf dem Weg dorthin?
    if(state == CARRS_FIGUREWORK)
    {
        // ich gehe erst noch hin, also gucken, welche Flagge ich anvisiert habe und das jeweilige Teilstück dann als Arbeitsstraße
        if(GetGoal() == rs1->GetF1())
            workplace = rs1;
        else
            workplace = rs2;
    }
    else if(state == CARRS_CARRYWARETOBUILDING || state == CARRS_LEAVEBUILDING)
    {
        // Wenn ich in ein Gebäude gehen oder rauskomme, auf den Weg gehen, der an dieses Gebäude grenzt
        if(cur_rs->GetF1() == rs1->GetF1() || cur_rs->GetF1() == rs1->GetF2())
            workplace = rs1;
        else
            workplace = rs2;
    }
    else
    {
        // sonst wurde es ja schon entschieden
        workplace = (cur_rs == rs1) ? rs1 : rs2;
    }

    // Sonstige Sachen für jeweilige States unternehmen
    switch(state)
    {
        default:
            break;
        case CARRS_WAITFORWARE:
        {
            // Wenn wir stehen, müssen wir in die Mitte laufen
            state = CARRS_GOTOMIDDLEOFROAD;
            Walked();
        } break;
        case CARRS_FETCHWARE:
        {
            // Wenn wir zur 2. Flagge vom 1. Wegstück gelaufen sind, können wir das nun vergessen
            if(!workplace->AreWareJobs(!rs_dir, ct, false))
                state = CARRS_GOTOMIDDLEOFROAD;
        } break;
    }

    // Mich als Träger für meinen neuen Arbeitsplatz zuweisen
    workplace->setCarrier(ct == CT_DONKEY ? 1 : 0, this);

    // Für andere Straße neuen Träger/Esel rufen
    RoadSegment* uc_road = ((rs1 == workplace) ? (rs2) : (rs1));
    uc_road->setCarrier(ct == CT_DONKEY ? 1 : 0, NULL);

    if(ct == CT_NORMAL)
        gwg->GetPlayer(player)->FindCarrierForRoad(uc_road);
    else if(ct == CT_DONKEY)
        uc_road->setCarrier(1, gwg->GetPlayer(player)->OrderDonkey(uc_road));
}
Example #5
0
void nofGeologist::Walked()
{
    if(state == STATE_GEOLOGIST_GOTONEXTNODE)
    {
        // Ist mein Zielpunkt überhaupt noch geeignet zum Graben (kann ja mittlerweile auch was drauf gebaut worden sein)
        if(!IsNodeGood(node_goal))
        {
            // alten Punkt wieder freigeben
            gwg->GetNode(node_goal).reserved = false;;
            // wenn nicht, dann zu einem neuen Punkt gehen
            GoToNextNode();
            return;
        }

        // Bin ich am Zielpunkt?
        if(pos == node_goal)
        {
            // anfangen zu graben
            current_ev = em->AddEvent(this, 100, 1);
            state = STATE_GEOLOGIST_DIG;
        }
        else
        {
            // Weg zum nächsten Punkt suchen
            unsigned char dir = gwg->FindHumanPath(pos, node_goal, 20);

            // Wenns keinen gibt
            if(dir == 0xFF)
            {
                // alten Punkt wieder freigeben
                gwg->GetNode(node_goal).reserved = false;
                // dann neuen Punkt suchen
                dir = GetNextNode();
                // falls es keinen gibt, dann zurück zur Flagge gehen und es übernimmt der andere "Walked"-Zweig
                if(dir == 0xFF)
                {
                    state = STATE_GOTOFLAG;
                    Walked();
                    return;
                }
            }
            
            StartWalking(dir);
        }
    }
    else if(state == STATE_GOTOFLAG)
    {
        GoToFlag();
    }
}
Example #6
0
void noAnimal::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
            Walked();
        } break;
        // Warte-Event
        case 1:
        {
            // wieder weiterlaufen
            StandardWalking();
            // state entsprechen setzen, wenn es nich gestorben ist
            if(state != STATE_DEAD)
                state = STATE_WALKING;

        } break;
        // Sterbe-Event
        case 2:
        {
            // nun verschwinden
            current_ev = em->AddEvent(this, 30, 3);
            state = STATE_DISAPPEARING;

            // Jäger ggf. Bescheid sagen (falls der es nicht mehr rechtzeitig schafft, bis ich verwest bin)
            if(hunter)
                hunter->AnimalLost();

        } break;
        // Verschwind-Event
        case 3:
        {
            // von der Karte tilgen
            current_ev = 0;
            gwg->RemoveFigure(this, pos);
            em->AddToKillList(this);
        } break;

    }

}
Example #7
0
/// Handle state "meet enemy" after each walking step
void nofActiveSoldier::MeetingEnemy()
{
    // Enemy vanished?
    if(!enemy)
    {
        FreeFightEnded();
        Walked();
        return;
    }

    // Reached the fighting place?
    if (GetPos() == fightSpot_)
    {
        // Enemy already there?
        if (enemy->GetPos() == fightSpot_ && enemy->GetState() == STATE_WAITINGFORFIGHT)
        {
            // Start fighting
            gwg->AddFigure(new noFighting(enemy, this), pos);

            enemy->FightingStarted();
            FightingStarted();

            return;
        }
        else
        {
            // Is the fighting point still valid (could be another fight there already e.g.)?
            // And the enemy still on the way?
            if (!gwg->ValidPointForFighting(pos, false,this) || enemy->GetState() != STATE_MEETENEMY)
            {
                // No
                // Abort the whole fighting fun with the enemy
                enemy->FreeFightEnded();

                FreeFightEnded();
                Walked();
            }
            // Spot is still ok, let's wait for the enemy
            else
            {
                RTTR_Assert(enemy->enemy == this);
                state = STATE_WAITINGFORFIGHT;
                return;
            }
        }
    }
    // Not at the fighting spot yet, continue walking there
    else
    {
        unsigned char dir = gwg->FindHumanPath(pos, fightSpot_, MAX_ATTACKING_RUN_DISTANCE);
        if (dir != 0xFF)
        {
            StartWalking(dir);
        }
        else
        {
            // qx: Couldnt find a way from current location to fighting spot -> cancel fight (Fix for #1189150)
            enemy->FreeFightEnded();
            FreeFightEnded();
            Walked();
        }
        return;
    }

}
Example #8
0
/**
 *
 *
 *  @author OLiver
 */
void nofCarrier::Walked()
{
    // Bootssounds ggf. löschen
    if(ct == CT_BOAT && state != CARRS_FIGUREWORK)
        SOUNDMANAGER.WorkingFinished(this);

    switch(state)
    {
        default:
            break;
        case CARRS_GOTOMIDDLEOFROAD:
        {
            // Gibts an der Flagge in der entgegengesetzten Richtung, in die ich laufe, evtl Waren zu tragen
            // (da wir darüber nicht unmittelbar informiert werden!)
            if(workplace->AreWareJobs(rs_dir, ct, false))
            {
                // Dann umdrehen und holen
                rs_dir = !rs_dir;
                rs_pos = workplace->GetLength() - rs_pos;
                state = CARRS_FETCHWARE;

                StartWalking(cur_rs->GetDir(rs_dir, rs_pos));
            }
            else if(rs_pos == cur_rs->GetLength() / 2 || rs_pos == cur_rs->GetLength() / 2 + cur_rs->GetLength() % 2)
            {
                // Wir sind in der Mitte angekommen
                state = CARRS_WAITFORWARE;
                if(GetCurMoveDir() == 0 || GetCurMoveDir() == 1 || GetCurMoveDir() == 5)
                    FaceDir(5);
                else
                    FaceDir(4);

                current_ev = 0;

                // Jetzt wird wieder nur rumgegammelt, dann kriegen wir aber evtl keinen schönen IH-AH!
                StopWorking();

                // Animation auf später verschieben, damit die nicht mittendrin startet
                SetNewAnimationMoment();
            }
            else
            {
                // Eventuell laufen wir in die falsche Richtung?
                if(rs_pos > cur_rs->GetLength() / 2)
                {
                    rs_dir = !rs_dir;
                    rs_pos = cur_rs->GetLength() - rs_pos;
                }

                StartWalking(cur_rs->GetDir(rs_dir, rs_pos));
            }
        } break;
        case CARRS_FETCHWARE:
        {
            // Zur Flagge laufen, um die Ware zu holen

            // Sind wir schon da?
            if(rs_pos == cur_rs->GetLength())
                // Dann Ware aufnehmnen
                FetchWare(false);
            else
                StartWalking(cur_rs->GetDir(rs_dir, rs_pos));


        } break;
        case CARRS_CARRYWARE:
        {
            // Sind wir schon da?
            if(rs_pos == cur_rs->GetLength())
            {

                // Flagge, an der wir gerade stehen
                noFlag* this_flag  = static_cast<noFlag*>(((rs_dir) ? workplace->GetF1() : workplace->GetF2()));

                bool calculated = false;

                // Will die Waren jetzt gleich zur Baustelle neben der Flagge?
                if(WantInBuilding(&calculated))
                {
                    // Erst noch zur Baustelle bzw Gebäude laufen
                    state = CARRS_CARRYWARETOBUILDING;
                    StartWalking(1);
                    cur_rs = this_flag->routes[1];
                    // location wird immer auf nächste Flagge gesetzt --> in dem Fall aktualisieren
                    carried_ware->Carry((cur_rs->GetF1() == this_flag) ? cur_rs->GetF2() : cur_rs->GetF1());
                }
                else
                {
                    // Ist an der Flagge noch genügend Platz (wenn wir wieder eine Ware mitnehmen, kann sie auch voll sein)
                    if(this_flag->IsSpaceForWare())
                    {
                        carried_ware->LieAtFlag(this_flag);

                        // Ware soll ihren weiteren Weg berechnen
                        if (!calculated)
                        {
                            carried_ware->RecalcRoute();
                        }

                        // Ware ablegen
                        this_flag->AddWare(carried_ware);
                        // Wir tragen erstmal keine Ware mehr
                        carried_ware = 0;
                        // Gibts an den Flaggen etwas, was ich tragen muss, ansonsten wieder in die Mitte gehen und warten
                        LookForWares();
                    }
                    else if(workplace->AreWareJobs(!rs_dir, ct, true))
                    {
                        // die Flagge ist voll, aber wir können eine Ware mitnehmen, daher erst Ware nehmen und dann erst ablegen

                        // Ware "merken"
                        Ware* tmp_ware = carried_ware;
                        // neue Ware aufnehmen
                        FetchWare(true);

                        // alte Ware ablegen
                        tmp_ware->LieAtFlag(this_flag);

                        if (!calculated)
                        {
                            tmp_ware->RecalcRoute();
                        }
                        this_flag->AddWare(tmp_ware);
                    }
                    else
                    {
                        // wenn kein Platz mehr ist --> wieder umdrehen und zurückgehen
                        state = CARRS_GOBACKFROMFLAG;
                        rs_dir = !rs_dir;
                        rs_pos = cur_rs->GetLength() - rs_pos;
                        StartWalking((GetCurMoveDir() + 3) % 6);
                    }
                }
            }
            else if(rs_pos == cur_rs->GetLength() - 1)
            {
                // Wenn wir fast da sind, gucken, ob an der Flagge noch ein freier Platz ist
                noFlag* this_flag  = static_cast<noFlag*>(((rs_dir) ? workplace->GetF1() : workplace->GetF2()));

                if(this_flag->IsSpaceForWare() || WantInBuilding(NULL) || cur_rs->AreWareJobs(!rs_dir, ct, true))
                {
                    // Es ist Platz, dann zur Flagge laufen
                    StartWalking(cur_rs->GetDir(rs_dir, rs_pos));
                }
                else
                {
                    // Wenn kein Platz ist, stehenbleiben und warten!
                    state = CARRS_WAITFORWARESPACE;
                    FaceDir(cur_rs->GetDir(rs_dir, rs_pos));
                }
            }
            else
            {
                StartWalking(cur_rs->GetDir(rs_dir, rs_pos));
            }

        } break;
        case CARRS_CARRYWARETOBUILDING:
        {
            // Ware ablegen
            gwg->GetSpecObj<noRoadNode>(pos)->AddWare(carried_ware);
            // Ich trag' keine Ware mehr
            carried_ware = 0;
            // Wieder zurück zu meinem Weg laufen
            state = CARRS_LEAVEBUILDING;
            StartWalking(4);
        } break;
        case CARRS_LEAVEBUILDING:
        {
            // So tun, als ob der Träger gerade vom anderen Ende des Weges kommt, damit alles korrekt funktioniert
            cur_rs = workplace;
            FaceDir(workplace->GetDir(rs_dir, workplace->GetLength() - 1));
            LookForWares();
        } break;
        case CARRS_GOBACKFROMFLAG:
        {
            // Wieder umdrehen und so tun, als wären wir gerade normal angekommen
            rs_dir = !rs_dir;
            rs_pos = cur_rs->GetLength() - rs_pos;
            state = CARRS_CARRYWARE;
            Walked();
        } break;
        case CARRS_BOATCARRIER_WANDERONWATER:
        {
            WanderOnWater();
        } break;
    }
}