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(); } }
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(); } }
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); } } }
/** * * * @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)); }
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(); } }
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; } }
/// 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; } }
/** * * * @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; } }