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