Exemplo n.º 1
0
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);
    }
}
Exemplo n.º 2
0
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();
    }
}
Exemplo n.º 3
0
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();
    }
}
Exemplo n.º 4
0
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));
}
Exemplo n.º 6
0
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));
    }
}
Exemplo n.º 7
0
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();
}