/// A ware changed its route and doesn't want to use the ship anymore void nobHarborBuilding::WareDontWantToTravelByShip(Ware * ware) { // Maybe this building is already destroyed if(gwg->GetGOT(x,y) != GOT_NOB_HARBORBUILDING) return; // Ware aus unserer Liste streichen wares_for_ships.remove(ware); // Will die Ware jetzt vielleicht zu uns? if(ware->goal == this) { // Dann hier gleich einliefern AddWare(ware); // and dont forget to reduce our visual count - addware will increase both and the ware waiting for a ship added to the visual count! --goods.goods[ConvertShields(ware->type)]; } // Oder will sie wieder raus? else { waiting_wares.push_back(ware); AddLeavingEvent(); } }
void nobBaseWarehouse::AddWaitingWare(Ware*& ware) { waiting_wares.push_back(ware); ware->WaitInWarehouse(this); // Wenn gerade keiner rausgeht, muss neues Event angemeldet werden AddLeavingEvent(); // Die visuelle Warenanzahl wieder erhöhen inventory.visual.Add(ConvertShields(ware->type)); ware = NULL; // Take ownership }
/// A ware changed its route and doesn't want to use the ship anymore void nobHarborBuilding::WareDontWantToTravelByShip(Ware* ware) { // Maybe this building is already destroyed if(gwg->GetGOT(pos) != GOT_NOB_HARBORBUILDING) return; RTTR_Assert(helpers::contains(wares_for_ships, ware)); // Ware aus unserer Liste streichen wares_for_ships.remove(ware); // Carry out. If it would want to go back to this building, then this will be handled by the carrier waiting_wares.push_back(ware); ware->WaitInWarehouse(this); AddLeavingEvent(); }
bool nobBaseWarehouse::FreePlaceAtFlag() { if(!waiting_wares.empty()) { AddLeavingEvent(); return true; } else { // Evtl. war die Flagge voll und das Auslagern musste gestoppt werden // Weitere Waren/Figuren zum Auslagern und kein Event angemeldet? if(AreWaresToEmpty() && !empty_event) // --> Nächstes Event empty_event = em->AddEvent(this, empty_INTERVAL, 3); return false; } }
void nobBaseMilitary::AddLeavingFigure(noFigure* fig) { AddLeavingEvent(); leave_house.push_back(fig); }
/// Erhält die Waren von einem Schiff und nimmt diese in den Warenbestand auf void nobHarborBuilding::ReceiveGoodsFromShip(const std::list<noFigure*> figures, const std::list<Ware*> wares) { // Menschen zur Ausgehliste hinzufügen for(std::list<noFigure*>::const_iterator it = figures.begin();it!=figures.end();++it) { if((*it)->GetJobType() == JOB_BOATCARRIER) { ++goods.people[JOB_HELPER]; ++goods.goods[GD_BOAT]; } else ++goods.people[(*it)->GetJobType()]; // Wenn es kein Ziel mehr hat, sprich keinen weiteren Weg, kann es direkt hier gelagert // werden if ((*it)->HasNoGoal() || ((*it)->GetGoal() == this)) { AddFigure(*it, false); } else { Point<MapCoord> next_harbor = (*it)->ExamineRouteBeforeShipping(); unsigned char next_dir = (*it)->GetDir(); if (next_dir == 4) { AddLeavingFigure(*it); (*it)->ShipJourneyEnded(); } else if (next_dir == SHIP_DIR) { AddFigureForShip(*it, next_harbor); } else { AddFigure(*it, false); } } } // Waren zur Warteliste hinzufügen for(std::list<Ware*>::const_iterator it = wares.begin();it!=wares.end();++it) { // Optische Warenwerte entsprechend erhöhen ++goods.goods[ConvertShields((*it)->type)]; if((*it)->ShipJorneyEnded(this)) { // Ware will die weitere Reise antreten, also muss sie zur Liste der rausgetragenen Waren // hinzugefügt werden waiting_wares.push_back(*it); } else { // Ansonsten fügen wir die Ware einfach zu unserem Inventar dazu RemoveDependentWare(*it); ++real_goods.goods[ConvertShields((*it)->type)]; players->getElement(player)->RemoveWare(*it); delete *it; } } // Ggf. neues Rausgeh-Event anmelden, was notwendig ist, wenn z.B. nur Waren zur Liste hinzugefügt wurden AddLeavingEvent(); }
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 nobBaseWarehouse::HandleSendoutEvent() { // Fight or something in front of the house? Try again later! if(!gwg->IsRoadNodeForFigures(gwg->GetNeighbour(pos, 4), 4)) { empty_event = em->AddEvent(this, empty_INTERVAL, 3); return; } std::vector<unsigned> possibleIds; // Waren und Figuren zum Auslagern zusammensuchen // Wenn keine Platz an Flagge, dann keine Waren raus if(GetFlag()->IsSpaceForWare()) { for(unsigned i = 0; i < WARE_TYPES_COUNT; ++i) { if(GetInventorySetting(GoodType(i)).IsSet(EInventorySetting::SEND) && inventory[GoodType(i)]) possibleIds.push_back(i); } } for(unsigned i = 0; i < JOB_TYPES_COUNT; ++i) { // Figuren, die noch nicht implementiert sind, nicht nehmen! if(GetInventorySetting(Job(i)).IsSet(EInventorySetting::SEND) && inventory[Job(i)]) possibleIds.push_back(WARE_TYPES_COUNT + i); } // Gibts überhaupt welche? if(possibleIds.empty()) // ansonsten gleich tschüss return; // Eine ID zufällig auswählen unsigned selectedId = possibleIds[RANDOM.Rand(__FILE__, __LINE__, GetObjId(), possibleIds.size())]; if(selectedId < WARE_TYPES_COUNT) { // Ware Ware* ware = new Ware(GoodType(selectedId), NULL, this); noBaseBuilding* wareGoal = gwg->GetPlayer(player).FindClientForWare(ware); if(wareGoal != this) { ware->SetGoal(wareGoal); // Ware zur Liste hinzufügen, damit sie dann rausgetragen wird waiting_wares.push_back(ware); AddLeavingEvent(); // Ware aus Inventar entfernen inventory.real.Remove(GoodType(selectedId)); // Evtl. kein Schwert/Schild/Bier mehr da, sodass das Rekrutieren gestoppt werden muss TryStopRecruiting(); } else { gwg->GetPlayer(player).RemoveWare(ware); ware->Destroy(); deletePtr(ware); } } else { // Figur selectedId -= WARE_TYPES_COUNT; nobBaseWarehouse* wh = gwg->GetPlayer(player).FindWarehouse(*this, FW::AcceptsFigureButNoSend(Job(selectedId)), true, false); if(wh != this) { nofPassiveWorker* fig = new nofPassiveWorker(Job(selectedId), pos, player, NULL); if(wh) fig->GoHome(wh); else fig->StartWandering(); AddLeavingFigure(fig); // Person aus Inventar entfernen inventory.real.Remove(Job(selectedId)); // Evtl. kein Gehilfe mehr da, sodass das Rekrutieren gestoppt werden muss TryStopRecruiting(); } } // Weitere Waren/Figuren zum Auslagern? if(AreWaresToEmpty()) // --> Nächstes Event empty_event = em->AddEvent(this, empty_INTERVAL, 3); }