void noFigure::StartWalking(const unsigned char newDir) { assert(!(GetGOT() == GOT_NOF_PASSIVESOLDIER && fs == FS_JOB)); assert(newDir <= 5); if(newDir > 5) { LOG.lprintf("Achtung: Bug im Spiel entdeckt! noFigure::StartWalking: dir = %d\n", unsigned(newDir)); return; } // Gehen wir in ein Gebäude? if(newDir == 1 && gwg->GetNO(gwg->GetNeighbour(pos, 1))->GetType() == NOP_BUILDING) gwg->GetSpecObj<noBuilding>(gwg->GetNeighbour(pos, 1))->OpenDoor(); // Dann die Tür aufmachen // oder aus einem raus? if(newDir == 4 && gwg->GetNO(pos)->GetType() == NOP_BUILDING) gwg->GetSpecObj<noBuilding>(pos)->OpenDoor(); // Dann die Tür aufmachen // Ist der Platz schon besetzt, wo wir hinlaufen wollen und laufen wir auf Straßen? if(!gwg->IsRoadNodeForFigures(gwg->GetNeighbour(pos, newDir), newDir) && cur_rs) { // Dann stehen bleiben! FaceDir(newDir); waiting_for_free_node = true; // Andere Figuren stoppen gwg->StopOnRoads(pos, newDir); } else { // Normal hinlaufen StartMoving(newDir, 20); } }
void nofBuildingWorker::TryToWork() { // Wurde die Produktion eingestellt? if(workplace->IsProductionDisabled()) { state = STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED; // Nun arbeite ich nich mehr StartNotWorking(); } // Falls man auf Waren wartet, kann man dann anfangen zu arbeiten // (bei Bergwerken müssen zusätzlich noch Rohstoffvorkommen vorhanden sein!) // (bei Brunnen muss ebenfalls auf Wasser geprüft werden!) // Spähturm-Erkunder arbeiten nie! // Charburner doesn't need wares for harvesting! // -> Wares are considered when calling GetPointQuality! else if( (workplace->WaresAvailable() || job == JOB_CHARBURNER) && (job != JOB_MINER || GetResources(workplace->GetBuildingType() - BLD_GRANITEMINE)) && (job != JOB_HELPER || GetResources(4)) && job != JOB_SCOUT) { state = STATE_WAITING1; current_ev = em->AddEvent(this, (GetGOT() == GOT_NOF_CATAPULTMAN) ? CATAPULT_WAIT1_LENGTH : JOB_CONSTS[job].wait1_length, 1); StopNotWorking(); } else { state = STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED; // Nun arbeite ich nich mehr StartNotWorking(); } }
void nofBuildingWorker::TryToWork() { // Wurde die Produktion eingestellt? if(workplace->IsProductionDisabled()) { state = STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED; // Nun arbeite ich nich mehr StartNotWorking(); } // Falls man auf Waren wartet, kann man dann anfangen zu arbeiten else if(AreWaresAvailable()) { if(ReadyForWork()) { state = STATE_WAITING1; current_ev = em->AddEvent(this, (GetGOT() == GOT_NOF_CATAPULTMAN) ? CATAPULT_WAIT1_LENGTH : JOB_CONSTS[job].wait1_length, 1); StopNotWorking(); }else { state = STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED; } } else { state = STATE_WAITINGFORWARES_OR_PRODUCTIONSTOPPED; // Nun arbeite ich nich mehr StartNotWorking(); } }
void noFigure::StopIfNecessary(const MapPoint pt) { // Lauf ich auf Wegen --> wenn man zum Ziel oder Weg läuft oder die Träger, die natürlich auch auf Wegen arbeiten if(fs == FS_GOHOME || fs == FS_GOTOGOAL || (fs == FS_JOB && GetGOT() == GOT_NOF_CARRIER)) { // Laufe ich zu diesem Punkt? if(current_ev) { if(!waiting_for_free_node && gwg->GetNeighbour(this->pos, GetCurMoveDir()) == pt) { // Dann stehenbleiben PauseWalking(); waiting_for_free_node = true; gwg->StopOnRoads(this->pos, GetCurMoveDir()); } } } }
void nobBaseWarehouse::HandleLeaveEvent() { #if RTTR_ENABLE_ASSERTS // Harbors have more queues. Ignore for now if(GetGOT() != GOT_NOB_HARBORBUILDING) { Inventory should = inventory.real; for(std::list<noFigure*>::iterator it = leave_house.begin(); it != leave_house.end(); ++it) { // Don't count warehouse workers if(!(*it)->MemberOfWarehouse()){ if((*it)->GetJobType() == JOB_BOATCARRIER) should.Add(JOB_HELPER); else should.Add((*it)->GetJobType()); } } for(unsigned i = 0; i < JOB_TYPES_COUNT; i++) RTTR_Assert(should.people[i] == inventory.visual.people[i]); } #endif // Falls eine Bestellung storniert wurde if(leave_house.empty() && waiting_wares.empty()) { go_out = false; return; } // Fight or something in front of the house and we are not defending? if(!gwg->IsRoadNodeForFigures(gwg->GetNeighbour(pos, 4), 4)) { // there's a fight bool found = false; // try to find a defender and make him leave the house first for(std::list<noFigure*>::iterator it = leave_house.begin(); it != leave_house.end(); ++it) { if(((*it)->GetGOT() == GOT_NOF_AGGRESSIVEDEFENDER) || ((*it)->GetGOT() == GOT_NOF_DEFENDER)) { // remove defender from list, insert him again in front of all others leave_house.push_front(*it); leave_house.erase(it); found = true; break; } } // no defender found? trigger next leaving event :) if(!found) { go_out = false; AddLeavingEvent(); return; } } // Figuren kommen zuerst raus if(!leave_house.empty()) { noFigure* fig = leave_house.front(); gwg->AddFigure(fig, pos); // Init road walking for figures walking on roads if(fig->IsWalkingOnRoad()) fig->InitializeRoadWalking(routes[4], 0, true); fig->ActAtFirst(); // Bei Lagerhausarbeitern das nicht abziehen! if(!fig->MemberOfWarehouse()) { // War das ein Boot-Träger? if(fig->GetJobType() == JOB_BOATCARRIER) { // Remove helper and boat separately inventory.visual.Remove(JOB_HELPER); inventory.visual.Remove(GD_BOAT); } else inventory.visual.Remove(fig->GetJobType()); if(fig->GetGOT() == GOT_NOF_TRADEDONKEY) { // Trade donkey carrying wares? GoodType carriedWare = static_cast<nofTradeDonkey*>(fig)->GetCarriedWare(); if(carriedWare != GD_NOTHING) inventory.visual.Remove(carriedWare); } } leave_house.pop_front(); } else { // Ist noch Platz an der Flagge? if(GetFlag()->GetWareCount() < 8) { // Dann Ware raustragen lassen Ware* ware = waiting_wares.front(); nofWarehouseWorker* worker = new nofWarehouseWorker(pos, player, ware, 0); gwg->AddFigure(worker, pos); inventory.visual.Remove(ConvertShields(ware->type)); worker->WalkToGoal(); ware->Carry(GetFlag()); waiting_wares.pop_front(); } else { // Kein Platz mehr für Waren --> keiner brauch mehr rauszukommen, und Figuren gibts ja auch keine mehr go_out = false; } } // Wenn keine Figuren und Waren mehr da sind (bzw die Flagge vorm Haus voll ist), brauch auch keiner mehr rauszukommen if(leave_house.empty() && waiting_wares.empty()) go_out = false; if(go_out) leaving_event = em->AddEvent(this, LEAVE_INTERVAL + RANDOM.Rand(__FILE__, __LINE__, GetObjId(), LEAVE_INTERVAL_RAND)); }
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)); } }
void noBaseBuilding::Destroy_noBaseBuilding() { DestroyAllRoads(); //notify the ai about this GAMECLIENT.SendAIEvent(new AIEvent::Building(AIEvent::BuildingDestroyed, x, y, type), player); gwg->GetGameInterface()->GI_UpdateMinimap(x, y); // evtl Anbauten wieder abreißen DestroyBuildingExtensions(); // ggf. Fenster schließen gwg->ImportantObjectDestroyed(x, y); // Baukosten zurückerstatten (nicht bei Baustellen) if( (GetGOT() != GOT_BUILDINGSITE) && ( GameClient::inst().GetGGS().isEnabled(ADDON_REFUND_MATERIALS) || GameClient::inst().GetGGS().isEnabled(ADDON_REFUND_ON_EMERGENCY) ) ) { // lebt unsere Flagge noch? noFlag *flag = GetFlag(); if(flag) { unsigned int percent_index = 0; // wenn Rückerstattung aktiv ist, entsprechende Prozentzahl wählen if(GameClient::inst().GetGGS().isEnabled(ADDON_REFUND_MATERIALS)) percent_index = GameClient::inst().GetGGS().getSelection(ADDON_REFUND_MATERIALS); // wenn Rückerstattung bei Notprogramm aktiv ist, 50% zurückerstatten else if(gwg->GetPlayer(player)->hasEmergency() && GameClient::inst().GetGGS().isEnabled(ADDON_REFUND_ON_EMERGENCY)) percent_index = 2; // wieviel kriegt man von jeder Ware wieder? const unsigned int percents[5] = { 0, 25, 50, 75, 100 }; const unsigned int percent = 10 * percents[percent_index]; // zurückgaben berechnen (abgerundet) unsigned int boards = (percent * BUILDING_COSTS[nation][type].boards) / 1000; unsigned int stones = (percent * BUILDING_COSTS[nation][type].stones) / 1000; GoodType goods[2] = {GD_BOARDS, GD_STONES}; bool which = 0; while(flag->IsSpaceForWare() && ( boards > 0 || stones > 0 )) { if( (!which && boards > 0) || (which && stones > 0)) { // Ware erzeugen Ware *ware = new Ware(goods[which], 0, flag); // Inventur anpassen gwg->GetPlayer(player)->IncreaseInventoryWare(goods[which], 1); // Abnehmer für Ware finden ware->goal = gwg->GetPlayer(player)->FindClientForWare(ware); // Ware soll ihren weiteren Weg berechnen ware->RecalcRoute(); // Ware ablegen flag->AddWare(ware); ware->LieAtFlag(flag); if(!which) --boards; else --stones; } which = !which; } } } Destroy_noRoadNode(); }