예제 #1
0
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;
	}
}
예제 #2
0
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);
    }
}
예제 #3
0
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();
		}
	}
}
예제 #4
0
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();
		}
	}
}
예제 #5
0
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);
    }
}
예제 #6
0
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();
}
예제 #7
0
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);
	}
}
예제 #8
0
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;
    }
}
예제 #9
0
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();
		}
	}
}
예제 #10
0
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;
    }
}