void nofFarmhand::WalkToWorkpoint() { // Sind wir am Ziel angekommen? if(pos == dest) { // Anfangen zu arbeiten state = STATE_WORK; current_ev = em->AddEvent(this, JOB_CONSTS[job_].work_length, 1); WorkStarted(); return; } // Weg suchen und gucken ob der Punkt noch in Ordnung ist unsigned char dir = gwg->FindHumanPath(pos, dest, 20); if(dir == 0xFF || GetPointQuality(dest) == PQ_NOTPOSSIBLE) { // Punkt freigeben gwg->GetNode(dest).reserved = false; // Kein Weg führt mehr zum Ziel oder Punkt ist nich mehr in Ordnung --> wieder nach Hause gehen StartWalkingHome(); } else { // Alles ok, wir können hinlaufen StartWalking(dir); } }
bool nofFarmhand::IsPointAvailable(const MapPoint pt) { // Gibts an diesen Punkt überhaupt die nötigen Vorraussetzungen für den Beruf? if(GetPointQuality(pt) != PQ_NOTPOSSIBLE) { // Gucken, ob ein Weg hinführt if(gwg->FindHumanPath(this->pos, pt, 20) != 0xFF) return 1; else return 0; } else return 0; }
bool nofFarmhand::IsPointAvailable(const unsigned short x, const unsigned short y) { // Gibts an diesen Punkt überhaupt die nötigen Vorraussetzungen für den Beruf? if(GetPointQuality(x, y) != PQ_NOTPOSSIBLE) { // Gucken, ob ein Weg hinführt if(gwg->FindHumanPath(this->x, this->y, x, y, 20) != 0xFF) return 1; else return 0; } else return 0; }
/// Abgeleitete Klasse informieren, wenn fertig ist mit Arbeiten void nofCharburner::WorkFinished() { noBase* no = gwg->GetNO(x, y); // Is a charburner pile is already there? if(no->GetGOT() == GOT_CHARBURNERPILE) { // Is Pile already in the normal "coal harvest mode"? if(static_cast<noCharburnerPile*>(no)->GetState() == noCharburnerPile::STATE_HARVEST) // Then let's bring a coal to our house ware = GD_COAL; // One step further static_cast<noCharburnerPile*>(no)->NextStep(); return; } // Point still good? if(GetPointQuality(x, y) != PQ_NOTPOSSIBLE) { // Delete previous elements // Only environt objects and signs are allowed to be removed by the worker! // Otherwise just do nothing NodalObjectType nop = no->GetType(); if(nop == NOP_ENVIRONMENT || nop == NOP_NOTHING) { no = gwg->GetSpecObj<noBase>(x, y); if(no) { no->Destroy(); delete no; } // Plant charburner pile gwg->SetNO(new noCharburnerPile(x, y), x, y); // BQ drumrum neu berechnen gwg->RecalcBQAroundPointBig(x, y); } } }
void nofFarmhand::HandleDerivedEvent(const unsigned int id) { switch(state) { case STATE_WORK: { // fertig mit Arbeiten --> dann müssen die "Folgen des Arbeitens" ausgeführt werden WorkFinished(); // Objekt wieder freigeben gwg->GetNode(pos).reserved = false; // Wieder nach Hause gehen StartWalkingHome(); // Evtl. Sounds löschen if(was_sounding) { SOUNDMANAGER.WorkingFinished(this); was_sounding = false; } } break; case STATE_WAITING1: { // Fertig mit warten --> anfangen zu arbeiten // Die Arbeitsradien der Berufe wie in JobConst.h (ab JOB_WOODCUTTER!) const unsigned char RADIUS[7] = { 6, 7, 6, 0, 8, 2, 2 }; // Additional radius delta r which is used when a point in radius r was found // I.e. looks till radius r + delta r const unsigned ADD_RADIUS_WHEN_FOUND[7] = { 1, 1, 1, 1, 0, 1, 1}; // Anzahl der Radien, wo wir gültige Punkte gefunden haben unsigned radius_count = 0; // Available points: 1st class and 2st class std::vector< MapPoint > available_points[3]; unsigned max_radius = (job_ == JOB_CHARBURNER) ? 3 : RADIUS[job_ - JOB_WOODCUTTER]; unsigned add_radius_when_found = (job_ == JOB_CHARBURNER) ? 1 : ADD_RADIUS_WHEN_FOUND[job_ - JOB_WOODCUTTER]; bool points_found = false; bool wait = false; for(MapCoord tx = gwg->GetXA(pos, 0), r = 1; r <= max_radius; tx = gwg->GetXA(tx, pos.y, 0), ++r) { // Wurde ein Punkt in diesem Radius gefunden? bool found_in_radius = false; MapPoint t2(tx, pos.y); for(unsigned i = 2; i < 8; ++i) { for(MapCoord r2 = 0; r2 < r; t2 = gwg->GetNeighbour(t2, i % 6), ++r2) { if(IsPointAvailable(t2)) { if (!gwg->GetNode(t2).reserved) { available_points[GetPointQuality(t2) - PQ_CLASS1].push_back(MapPoint(t2)); found_in_radius = true; points_found = true; } else if (job_ == JOB_STONEMASON) { // just wait a little bit longer wait = true; } } } } // Nur die zwei ADD_RADIUS_WHEN_FOUND Radien erst einmal nehmen if(found_in_radius) { if( radius_count++ == add_radius_when_found) break; } } // Are there any objects at all? if(points_found) { // Prefer 1st class objects and use only 2nd class objects if there are no more other objects anymore MapPoint p(0, 0); for(unsigned i = 0; i < 3; ++i) { if(!available_points[i].empty()) { p = available_points[i][RANDOM.Rand(__FILE__, __LINE__, GetObjId(), available_points[i].size())]; break; } } // Als neues Ziel nehmen dest = p; state = STATE_WALKTOWORKPOINT; // Wir arbeiten jetzt workplace->is_working = true; // Punkt für uns reservieren gwg->GetNode(dest).reserved = true;; // Anfangen zu laufen (erstmal aus dem Haus raus!) StartWalking(4); StopNotWorking(); WalkingStarted(); } else if (wait) { // We have to wait, since we do not know whether there are any unreachable or reserved points where there's more to get current_ev = em->AddEvent(this, JOB_CONSTS[job_].wait1_length, 1); StartNotWorking(); } else { if(GAMECLIENT.GetPlayerID() == this->player) { if (!OutOfRessourcesMsgSent) { switch(job_) { case JOB_STONEMASON: GAMECLIENT.SendPostMessage( new ImagePostMsgWithLocation(_("No more stones in range"), PMC_GENERAL, pos, workplace->GetBuildingType(), workplace->GetNation())); OutOfRessourcesMsgSent = true; // Produktivitätsanzeige auf 0 setzen workplace->SetProductivityToZero(); break; case JOB_FISHER: GAMECLIENT.SendPostMessage( new ImagePostMsgWithLocation(_("No more fishes in range"), PMC_GENERAL, pos, workplace->GetBuildingType(), workplace->GetNation())); OutOfRessourcesMsgSent = true; // Produktivitätsanzeige auf 0 setzen workplace->SetProductivityToZero(); break; default: break; } } } // KI-Event erzeugen switch(workplace->GetBuildingType()) { case BLD_WOODCUTTER: case BLD_QUARRY: case BLD_FISHERY: GAMECLIENT.SendAIEvent(new AIEvent::Building(AIEvent::NoMoreResourcesReachable, workplace->GetPos(), workplace->GetBuildingType()), player); break; default: break; } // Weiter warten, vielleicht gibts ja später wieder mal was current_ev = em->AddEvent(this, JOB_CONSTS[job_].wait1_length, 1); StartNotWorking(); } } break; default: break; } }