void nofHunter::AnimalLost() { animal = 0; switch(state) { default: return; case STATE_HUNTER_CHASING: case STATE_HUNTER_FINDINGSHOOTINGPOINT: case STATE_HUNTER_WALKINGTOCADAVER: { // nach Haue laufen StartWalkingHome(); } break; case STATE_HUNTER_SHOOTING: case STATE_HUNTER_EVISCERATING: { // Arbeits-Event abmelden em->RemoveEvent(current_ev); // Nach Hause laufen StartWalkingHome(); WalkHome(); } break; } }
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); } }
void nofHunter::HandleStateWalkingToCadaver() { // Sind wir schon da? if(animal->GetX() == x && animal->GetY() == y) { // dann ausnehmen state = STATE_HUNTER_EVISCERATING; current_ev = em->AddEvent(this,80,1); } else { // Weg dorthin suchen if((dir=gwg->FindHumanPath(x,y,animal->GetX(),animal->GetY(),6)) != 0xFF) { // Weg gefunden, dann hinlaufen StartWalking(dir); } else { // kein Weg gefunden --> nach Hause laufen StartWalkingHome(); WalkHome(); } } }
void nofHunter::HandleStateFindingShootingPoint() { // Sind wir schon da und steht das Tier schon? if(shooting_x == x && shooting_y == y && animal->IsReadyForShooting()) { // dann schießen state = STATE_HUNTER_SHOOTING; current_ev = em->AddEvent(this,16,1); } else { // Weg dorthin suchen if((dir=gwg->FindHumanPath(x,y,shooting_x,shooting_y,6)) != 0xFF) { // Weg gefunden, dann hinlaufen StartWalking(dir); } else { // kein Weg gefunden --> nach Hause laufen StartWalkingHome(); WalkHome(); } } }
void nofShipWright::WalkToWorkpoint() { // Sind wir am Ziel angekommen? if(pos == dest) { // Anfangen zu arbeiten state = STATE_WORK; current_ev = GetEvMgr().AddEvent(this, WORKING_TIME_SHIPS, 1); return; } unsigned char dir = gwg->FindHumanPath(pos, dest, 20); // Weg suchen und gucken ob der Punkt noch in Ordnung ist if(dir == 0xFF || (!IsPointGood(dest) && gwg->GetGOT(dest) != GOT_SHIPBUILDINGSITE)) { // Punkt freigeben gwg->SetReserved(dest, 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); } }
void nofHunter::HandleStateEviscerating() { // Tier verschwinden lassen gwg->RemoveFigure(animal,x,y); // Tier vernichten animal->Eviscerated(); animal->Destroy(); delete animal; animal = 0; // Fleisch in die Hand nehmen ware = GD_MEAT; // und zurück zur Hütte StartWalkingHome(); WalkHome(); }
void nofShipWright::WalkToWorkpoint() { // Sind wir am Ziel angekommen? if(x == dest_x && y == dest_y) { // Anfangen zu arbeiten state = STATE_WORK; current_ev = em->AddEvent(this,WORKING_TIME_SHIPS,1); } // Weg suchen und gucken ob der Punkt noch in Ordnung ist else if((dir = gwg->FindHumanPath(x,y,dest_x,dest_y,20)) == 0xFF || (!IsPointGood(dest_x,dest_y) && gwg->GetGOT(dest_x,dest_y) != GOT_SHIPBUILDINGSITE)) { // Punkt freigeben gwg->GetNode(dest_x,dest_y).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); } }
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; } }
void nofHunter::HandleStateChasing() { // Sind wir in der Nähe des Tieres? if(gwg->CalcDistance(x,y,animal->GetX(),animal->GetY()) < 7) { unsigned short animal_x, animal_y; // Dann bitten wir es mal, schonmal anzuhalten und bekommen seine Koordinaten, wo es dann steht animal->HunterIsNear(&animal_x,&animal_y); // Nun müssen wir drumherum einen Punkt suchen, von dem wir schießen, der natürlich direkt dem Standort // des Tieres gegenüberliegen muss (mit zufälliger Richtung beginnen) unsigned char doffset = RANDOM.Rand(__FILE__,__LINE__,obj_id,6); shooting_x = 0xFFFF; shooting_y = 0xFFFF; unsigned char d; for(d = 0;d<6;++d) { switch((d+doffset)%6) { case 0: { if(animal_x >= 4) { if(IsShootingPointGood(animal_x - 4,animal_y)) { shooting_x = animal_x - 4; shooting_y = animal_y; } } } break; case 1: { if(animal_x >= 2 && animal_y >= 4) { if(IsShootingPointGood(animal_x - 2,animal_y - 4)) { shooting_x = animal_x - 2; shooting_y = animal_y - 4; } } } break; case 2: { if(animal_x + 2 < gwg->GetWidth() && animal_y >= 4) { if(IsShootingPointGood(animal_x + 2,animal_y - 4)) { shooting_x = animal_x + 2; shooting_y = animal_y - 4; } } } break; case 3: { if(animal_x + 4 < gwg->GetWidth()) { if(IsShootingPointGood(animal_x + 4,animal_y)) { shooting_x = animal_x + 4; shooting_y = animal_y; } } } break; case 4: { if(animal_x + 2 < gwg->GetWidth() && animal_y + 4 < gwg->GetHeight()) { if(IsShootingPointGood(animal_x + 2,animal_y + 4)) { shooting_x = animal_x + 2; shooting_y = animal_y + 4; } } } break; case 5: { if(animal_x >= 2 && animal_y + 4 < gwg->GetHeight()) { if(IsShootingPointGood(animal_x - 2,animal_y + 4)) { shooting_x = animal_x - 2; shooting_y = animal_y + 4; } } } break; } // Wurde ein Punkt gefunden --> raus if(shooting_x != 0xFFFF) break; } // Wurde ein Punkt gefunden? if(shooting_x != 0xFFFF) { // Richtung, in die geschossen wird, bestimmen (natürlich die entgegengesetzte nehmen) shooting_dir = (d+doffset+3)%6; // dorthingehen state = STATE_HUNTER_FINDINGSHOOTINGPOINT; HandleStateFindingShootingPoint(); } else { // kein Punkt gefunden --> nach Hause gehen StartWalkingHome(); WalkHome(); } } else { // Weg dorthin suchen if((dir=gwg->FindHumanPath(x,y,animal->GetX(),animal->GetY(),MAX_HUNTING_DISTANCE)) != 0xFF) { // Weg gefunden, dann hinlaufen StartWalking(dir); } else { // kein Weg gefunden --> nach Hause laufen StartWalkingHome(); WalkHome(); } } }
void nofShipWright::HandleDerivedEvent(const unsigned int id) { switch(state) { case STATE_WAITING1: { // Herausfinden, was der Schiffsbauer als nächstes bauen soll if(dynamic_cast<nobShipYard*>(workplace)->GetMode() == nobShipYard::BOATS) // in Handwerksmanier Boote herstellen nofWorkman::HandleStateWaiting1(); else { // Verfügbare Punkte, die geeignete Plätze darstellen würden std::vector<ShipPoint> available_points; // Wege müssen immer von der Flagge aus berechnet werden MapPoint flagPos = gwg->GetNeighbour(pos, 4); for(MapCoord tx = gwg->GetXA(pos, 0), r = 1; r <= SHIPWRIGHT_RADIUS; tx = gwg->GetXA(tx, pos.y, 0), ++r) { 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) { // Besitze ich noch ein Schiff, was gebaut werden muss? noBase* obj = gwg->GetNode(t2).obj; if(!obj) continue; // Schiff? if(obj->GetGOT() == GOT_SHIPBUILDINGSITE) { // Platz noch nicht reserviert und gehört das Schiff auch mir? unsigned char first_dir = 0xFF; if(!gwg->GetNode(pos).reserved && static_cast<noShipBuildingSite*>(obj)->GetPlayer() == player && (first_dir = gwg->FindHumanPath(flagPos, t2, SHIPWRIGHT_WALKING_DISTANCE)) != 0xFF) { available_points.push_back(ShipPoint(t2, first_dir)); } } } } } // Kein Schiff im Bau gefunden? Dann Plätzchen für ein neues Schiff suchen if(available_points.empty()) { for(MapCoord tx = gwg->GetXA(pos, 0), r = 1; r <= SHIPWRIGHT_RADIUS; tx = gwg->GetXA(tx, pos.y, 0), ++r) { 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) { // Dieser Punkt geeignet? if(IsPointGood(t2)) { // Weg dorthin finden unsigned char first_dir = gwg->FindHumanPath(flagPos, t2, SHIPWRIGHT_WALKING_DISTANCE); if(first_dir != 0xFF) { available_points.push_back(ShipPoint(t2, first_dir)); } } } } } } // Punkte gefunden? if(!available_points.empty()) { // Einen Punkt zufällig auswählen und dorthin laufen ShipPoint p = available_points[RANDOM.Rand(__FILE__, __LINE__, obj_id, available_points.size())]; dest = p.pos; StartWalkingToShip(p.first_dir); } else { // Nichts zu arbeiten gefunden StartNotWorking(); // Weiter warten, vielleicht gibts ja später wieder mal was current_ev = em->AddEvent(this, JOB_CONSTS[job].wait1_length, 1); } } } break; case STATE_WORK: { // Sind wir an unserem Arbeitsplatz (dem Gebäude), wenn wir die Arbeit beendet haben, bauen wir nur Boote, // ansonsten sind wir an unserem Schiff und bauen große Schiffe if(workplace->GetPos() == pos) // Boote bauen nofWorkman::HandleStateWork(); else { // 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_WAITING2: { // Hier ist die Sache klar, dieser State kann nur bei Handwerkern vorkommen nofWorkman::HandleStateWaiting2(); } break; default: break; } }