/// 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
}
Esempio n. 3
0
/// 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;
    }
}
Esempio n. 5
0
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);
}