const noFlag* GameWorldBase::GetRoadFlag(MapPoint pt, Direction& dir, unsigned prevDir) const
{
    unsigned i = 0;

    while(true)
    {
        // suchen, wo der Weg weitergeht
        for(i = 0; i < Direction::COUNT; ++i)
        {
            if(i != prevDir && GetPointRoad(pt, Direction::fromInt(i)))
                break;
        }

        if(i == 6)
            return nullptr;

        pt = GetNeighbour(pt, Direction::fromInt(i));

        // endlich am Ende des Weges und an einer Flagge angekommen?
        if(GetNO(pt)->GetType() == NOP_FLAG)
        {
            dir = Direction(i + 3);
            return GetSpecObj<noFlag>(pt);
        }
        prevDir = (i + 3) % 6;
    }
}
void GameWorldBase::RecalcBQForRoad(const MapPoint pt)
{
    RecalcBQ(pt);

    for(unsigned i = 3; i < 6; ++i)
        RecalcBQ(GetNeighbour(pt, Direction::fromInt(i)));
}
unsigned GameWorldBase::GetHarborInDir(const MapPoint pt, const unsigned origin_harborId, const ShipDirection& dir,
                                       T_IsHarborOk isHarborOk) const
{
    RTTR_Assert(origin_harborId);

    // Herausfinden, in welcher Richtung sich dieser Punkt vom Ausgangspunkt unterscheidet
    unsigned char coastal_point_dir = 0xFF;
    const MapPoint hbPt = GetHarborPoint(origin_harborId);

    for(unsigned char i = 0; i < 6; ++i)
    {
        if(GetNeighbour(hbPt, Direction::fromInt(i)) == pt)
        {
            coastal_point_dir = i;
            break;
        }
    }

    RTTR_Assert(coastal_point_dir != 0xff);

    unsigned short seaId = GetSeaId(origin_harborId, Direction::fromInt(coastal_point_dir));
    const std::vector<HarborPos::Neighbor>& neighbors = GetHarborNeighbors(origin_harborId, dir);

    for(auto neighbor : neighbors)
    {
        if(IsHarborAtSea(neighbor.id, seaId) && isHarborOk(neighbor.id))
            return neighbor.id;
    }

    // Nichts gefunden
    return 0;
}
std::vector<unsigned short> GameWorldBase::GetFilteredSeaIDsForAttack(const MapPoint targetPt,
                                                                      const std::vector<unsigned short>& usableSeas,
                                                                      const unsigned char player_attacker) const
{
    // Walk to the flag of the bld/harbor. Important to check because in some locations where the coast is north of the harbor this might be
    // blocked
    const MapPoint flagPt = GetNeighbour(targetPt, Direction::SOUTHEAST);
    std::vector<unsigned short> confirmedSeaIds;
    // Check each possible harbor
    for(unsigned curHbId = 1; curHbId <= GetNumHarborPoints(); ++curHbId)
    {
        const MapPoint harborPt = GetHarborPoint(curHbId);

        if(CalcDistance(harborPt, targetPt) > SEAATTACK_DISTANCE)
            continue;

        // Not attacking this harbor and harbors block?
        if(targetPt != harborPt && GetGGS().getSelection(AddonId::SEA_ATTACK) == 1)
        {
            // Does an enemy harbor exist at current harbor spot? -> Can't attack through this harbor spot
            const auto* hb = GetSpecObj<nobHarborBuilding>(harborPt);
            if(hb && GetPlayer(player_attacker).IsAttackable(hb->GetPlayer()))
                continue;
        }

        for(unsigned z = 0; z < 6; ++z)
        {
            const unsigned short seaId = GetSeaId(curHbId, Direction::fromInt(z));
            if(!seaId)
                continue;
            // sea id is not in compare list or already confirmed? -> skip rest
            if(!helpers::contains(usableSeas, seaId) || helpers::contains(confirmedSeaIds, seaId))
                continue;

            // checks previously tested sea ids to skip pathfinding
            bool previouslytested = false;
            for(unsigned k = 0; k < z; k++)
            {
                if(seaId == GetSeaId(curHbId, Direction::fromInt(k)))
                {
                    previouslytested = true;
                    break;
                }
            }
            if(previouslytested)
                continue;

            // Can figures reach flag from coast
            MapPoint coastalPt = GetCoastalPoint(curHbId, seaId);
            if((flagPt == coastalPt) || FindHumanPath(flagPt, coastalPt, SEAATTACK_DISTANCE) != INVALID_DIR)
            {
                confirmedSeaIds.push_back(seaId);
                // all sea ids confirmed? return without changes
                if(confirmedSeaIds.size() == usableSeas.size())
                    return confirmedSeaIds;
            }
        }
    }
    return confirmedSeaIds;
}
std::vector<unsigned> GameWorldBase::GetUsableTargetHarborsForAttack(const MapPoint targetPt, std::vector<bool>& use_seas,
                                                                     const unsigned char player_attacker) const
{
    // Walk to the flag of the bld/harbor. Important to check because in some locations where the coast is north of the harbor this might be
    // blocked
    const MapPoint flagPt = GetNeighbour(targetPt, Direction::SOUTHEAST);
    std::vector<unsigned> harbor_points;
    // Check each possible harbor
    for(unsigned curHbId = 1; curHbId <= GetNumHarborPoints(); ++curHbId)
    {
        const MapPoint harborPt = GetHarborPoint(curHbId);

        if(CalcDistance(harborPt, targetPt) > SEAATTACK_DISTANCE)
            continue;

        // Not attacking this harbor and harbors block?
        if(targetPt != harborPt && GetGGS().getSelection(AddonId::SEA_ATTACK) == 1)
        {
            // Does an enemy harbor exist at current harbor spot? -> Can't attack through this harbor spot
            const auto* hb = GetSpecObj<nobHarborBuilding>(harborPt);
            if(hb && GetPlayer(player_attacker).IsAttackable(hb->GetPlayer()))
                continue;
        }

        // add seaIds from which we can actually attack the harbor
        bool harborinlist = false;
        for(unsigned z = 0; z < 6; ++z)
        {
            const unsigned short seaId = GetSeaId(curHbId, Direction::fromInt(z));
            if(!seaId)
                continue;
            // checks previously tested sea ids to skip pathfinding
            bool previouslytested = false;
            for(unsigned k = 0; k < z; k++)
            {
                if(seaId == GetSeaId(curHbId, Direction::fromInt(k)))
                {
                    previouslytested = true;
                    break;
                }
            }
            if(previouslytested)
                continue;

            // Can figures reach flag from coast
            const MapPoint coastalPt = GetCoastalPoint(curHbId, seaId);
            if((flagPt == coastalPt) || FindHumanPath(flagPt, coastalPt, SEAATTACK_DISTANCE) != INVALID_DIR)
            {
                use_seas.at(seaId - 1) = true;
                if(!harborinlist)
                {
                    harbor_points.push_back(curHbId);
                    harborinlist = true;
                }
            }
        }
    }
    return harbor_points;
}
bool GameWorldBase::IsFlagAround(const MapPoint& pt) const
{
    for(unsigned i = 0; i < 6; ++i)
    {
        if(GetNO(GetNeighbour(pt, Direction::fromInt(i)))->GetBM() == BlockingManner::Flag)
            return true;
    }
    return false;
}
bool GameWorldBase::IsOnRoad(const MapPoint& pt) const
{
    for(unsigned roadDir = 0; roadDir < 3; ++roadDir)
        if(GetRoad(pt, roadDir))
            return true;
    for(unsigned roadDir = 0; roadDir < 3; ++roadDir)
        if(GetRoad(GetNeighbour(pt, Direction::fromInt(roadDir)), roadDir))
            return true;
    return false;
}
unsigned char PreviewMinimap::CalcShading(const MapPoint pt, const std::vector<unsigned char>& altitudes) const
{
    int altitude = altitudes[GetMMIdx(pt)];
    MapPoint tmp = MakeMapPoint(GetNeighbour(Point<int>(pt), Direction::NORTHEAST), map_width, map_height);
    int A = altitudes[GetMMIdx(tmp)] - altitude;
    tmp = MakeMapPoint(GetNeighbour2(Point<int>(pt), 0), map_width, map_height);
    int B = altitudes[GetMMIdx(tmp)] - altitude;
    tmp = MakeMapPoint(GetNeighbour(Point<int>(pt), Direction::WEST), map_width, map_height);
    int C = altitudes[GetMMIdx(tmp)] - altitude;
    tmp = MakeMapPoint(GetNeighbour2(Point<int>(pt), 7), map_width, map_height);
    int D = altitudes[GetMMIdx(tmp)] - altitude;

    int shadingS2 = 64 + 9 * A - 3 * B - 6 * C - 9 * D;
    if(shadingS2 > 128)
        shadingS2 = 128;
    else if(shadingS2 < 0)
        shadingS2 = 0;

    return shadingS2;
}
bool GameWorldBase::RoadAlreadyBuilt(const bool /*boat_road*/, const MapPoint start, const std::vector<Direction>& route)
{
    MapPoint tmp(start);
    for(unsigned i = 0; i < route.size() - 1; ++i)
    {
        // Richtiger Weg auf diesem Punkt?
        if(!GetPointRoad(tmp, route[i]))
            return false;

        tmp = GetNeighbour(tmp, route[i]);
    }
    return true;
}
bool GameWorldBase::IsRoadAvailable(const bool boat_road, const MapPoint pt) const
{
    // Hindernisse
    if(GetNode(pt).obj)
    {
        BlockingManner bm = GetNode(pt).obj->GetBM();
        if(bm != BlockingManner::None)
            return false;
    }

    // dont build on the border
    if(GetNode(pt).boundary_stones[0])
        return false;

    for(unsigned z = 0; z < 6; ++z)
    {
        // Roads around charburner piles are not possible
        if(GetNO(GetNeighbour(pt, Direction::fromInt(z)))->GetBM() == BlockingManner::NothingAround)
            return false;

        // Other roads at this point?
        if(GetPointRoad(pt, Direction::fromInt(z)))
            return false;
    }

    // Terrain (unterscheiden, ob Wasser und Landweg)
    if(!boat_road)
    {
        bool flagPossible = false;

        for(unsigned char i = 0; i < 6; ++i)
        {
            TerrainBQ bq = GetDescription().get(GetRightTerrain(pt, Direction::fromInt(i))).GetBQ();
            if(bq == TerrainBQ::DANGER)
                return false;
            else if(bq != TerrainBQ::NOTHING)
                flagPossible = true;
        }

        return flagPossible;
    } else
    {
        // Beim Wasserweg muss um den Punkt herum Wasser sein
        if(!IsWaterPoint(pt))
            return false;
    }

    return true;
}
/// Ist es an dieser Stelle für einen Spieler möglich einen Hafen zu bauen
bool GameWorldBase::IsHarborPointFree(const unsigned harborId, const unsigned char player) const
{
    MapPoint hbPos(GetHarborPoint(harborId));

    // Überprüfen, ob das Gebiet in einem bestimmten Radius entweder vom Spieler oder gar nicht besetzt ist außer wenn der Hafen und die
    // Flagge im Spielergebiet liegen
    MapPoint flagPos = GetNeighbour(hbPos, Direction::SOUTHEAST);
    if(GetNode(hbPos).owner != player + 1 || GetNode(flagPos).owner != player + 1)
    {
        if(CheckPointsInRadius(hbPos, 4, IsPointOwnerDifferent(*this, player), false))
            return false;
    }

    return GetNode(hbPos).bq == BQ_HARBOR;
}
Example #12
0
/// Vermisst ein neues Weltmeer von einem Punkt aus, indem es alle mit diesem Punkt verbundenen
/// Wasserpunkte mit der gleichen ID belegt und die Anzahl zurückgibt
unsigned GameWorld::MeasureSea(const MapPoint pt, const unsigned short sea_id)
{
    // Breitensuche von diesem Punkt aus durchführen
    std::vector<bool> visited(width_ * height_, false);
    std::queue< MapPoint > todo;

    MapPoint start(pt);
    todo.push(start);

    // Knoten zählen (Startknoten schon mit inbegriffen)
    unsigned count = 0;

    while(!todo.empty())
    {
        MapPoint p = todo.front();
        todo.pop();

        if(visited[GetIdx(p)])
            continue;

        GetNode(p).sea_id = sea_id;

        for(unsigned i = 0; i < 6; ++i)
        {
            MapPoint pa = GetNeighbour(p, i);

            // Ist das dort auch ein Meerespunkt?
            if(!IsSeaPoint(pa))
                continue;

            if(!visited[GetIdx(pa)])
            {
                todo.push(pa);
            }
        }

        visited[GetIdx(p)] = true;
        ++count;
    }

    return count;

}
Example #13
0
/**
This function rebuilds the frame according to datas decoded from the VLD for a P AVC slice.
*/
void Decode_I_avc( const SPS *Sps, const PPS *Pps, const SLICE *ai_pstSlice, const unsigned char *SliceTable, 
				  RESIDU *picture_residu, const STRUCT_PF *ai_struct_pf, 
				  const W_TABLES *quantif, NAL *Nal, unsigned char *Y, unsigned char *U, unsigned char *V)
{

	if (!Nal -> NalToSkip){
		const short PicSizeInMbs = Sps -> PicSizeInMbs ;
		const short PicWiInMbs = Sps -> pic_width_in_mbs;
		const short PicWidthInMbs = Sps -> pic_width_in_mbs + 2;
		const short offset_L = (PicWidthInMbs << 8) + 16;
		const short offset_C = (PicWidthInMbs << 6) + 8;  

		short iCurrMbAddr = ai_pstSlice -> first_mb_in_slice ;

		short iMb_x;
		short iMb_y;
		
		//initialize macroblock position
		GetMbPosition(iCurrMbAddr, PicWiInMbs, &iMb_x, &iMb_y);

		Y += offset_L;
		U += offset_C;
		V += offset_C;

		//Loop on all macroblocks
		for ( ; iCurrMbAddr < PicSizeInMbs ;) {

			//Initialization of the macroblock neighbourhood
			GetNeighbour(iCurrMbAddr, iMb_x, PicWiInMbs, PicSizeInMbs, SliceTable, picture_residu, Pps -> constrained_intra_pred_flag);

			//Construction process for one macroblock
			decode_MB_I(&Y[(iMb_x + (iMb_y * PicWidthInMbs << 4)) << 4], &U[(iMb_x + (iMb_y * PicWidthInMbs << 3)) << 3], 
				&V[(iMb_x + (iMb_y * PicWidthInMbs << 3)) << 3], Pps, &picture_residu[iCurrMbAddr], PicWidthInMbs << 4, quantif, ai_struct_pf);

			//Updating the macroblock address
			iCurrMbAddr = Next_MbAddress(iCurrMbAddr, PicSizeInMbs, PicWiInMbs, SliceTable, &iMb_x, &iMb_y);
			if ( SliceTable [iCurrMbAddr] == 255 ) {
				iCurrMbAddr = PicSizeInMbs ;
			}
		}
	}
}
Example #14
0
/// Return a ship at this position owned by the given player. Prefers ships that need instructions.
noShip* GameWorldViewer::GetShip(const MapPoint pt, const unsigned char player) const
{
    noShip* ship = NULL;

    for (unsigned i = 0; i < 7; ++i)
    {
        MapPoint pa;

        if (i == 6)
        {
            pa = pt;
        }
        else
        {
            pa = GetNeighbour(pt, i);
        }

        const std::list<noBase*>& figures = GetFigures(pa);
        for(std::list<noBase*>::const_iterator it = figures.begin(); it != figures.end(); ++it)
        {
            if((*it)->GetGOT() == GOT_SHIP)
            {
                noShip* tmp = static_cast<noShip*>(*it);

                if (tmp->GetPlayer() == player)
                {
                    if ((tmp->GetPos() == pt) || (tmp->GetDestinationForCurrentMove() == pt))
                    {
                        if (tmp->IsWaitingForExpeditionInstructions())
                        {
                            return(tmp);
                        }

                        ship = tmp;
                    }
                }
            }
        }
    }

    return(ship);
}
Example #15
0
/// Ermittelt,  ob eine freie Route noch passierbar ist und gibt den Endpunkt der Route zurück
bool GameWorldBase::CheckFreeRoute(const MapPoint start,  const std::vector<unsigned char>& route,  const unsigned pos, 
                                   FP_Node_OK_Callback IsNodeOK,  FP_Node_OK_Callback IsNodeToDestOk,  MapPoint* dest,  const void* const param) const
{
    MapPoint pt(start);

    assert(pos < route.size());

    for(unsigned i = pos; i < route.size(); ++i)
    {
        pt = GetNeighbour(pt,  route[i]);
        if(!IsNodeToDestOk(*this,  pt,  route[i],  param))
            return false;
        if(i < route.size() - 1 && !IsNodeOK(*this,  pt,  route[i],  param))
            return false;
    }

    if(dest)
        *dest = pt;

    return true;
}
Example #16
0
// Find the position of first neighbour with given type
// and whole quantity of such neighbours
void GridManager::FindNeighbour(Vector2i p, sep::CellType type,
  sep::Axis&axis,
  sep::NeighborType &neighbor,
  int& quant) {
  int tmp_quant = 0;
  sep::CellType e_type;
  for (int ax = 0; ax <= sep::Y; ax++) {
    for (int neighb = 0; neighb <= sep::NEXT; neighb++) {
      if (GetNeighbour(p, (sep::Axis)ax, (sep::NeighborType)neighb, e_type)) {
        if (e_type == type) {
          if (!tmp_quant) {
            neighbor = (sep::NeighborType)neighb;
            axis = (sep::Axis)ax;
          }
          tmp_quant++;
        }
      }
    }
  }
  quant = tmp_quant;
}
Example #17
0
bool GridManager::FindNeighbourWithIndex(Vector2i p, sep::CellType type,
  int index, sep::Axis&axis,
  sep::NeighborType &neighbor) {
  int quant = 0;
  sep::CellType tmp_type;
  for (int ax = 0; ax <= sep::Y; ax++) {
    for (int neighb = 0; neighb <= sep::NEXT; neighb++) {
      if (GetNeighbour(p, (sep::Axis)ax, (sep::NeighborType)neighb, tmp_type)) {
        if (tmp_type == type) {
          if (quant == index) {
            neighbor = (sep::NeighborType)neighb;
            axis = (sep::Axis)ax;
            return true;
          }
          quant++;
        }
      }
    }
  }
  return false;
}
Example #18
0
/// Wegfinden ( A* ),  O(v lg v) --> Wegfindung auf allgemeinen Terrain (ohne Straßen),  für Wegbau und frei herumlaufende Berufe
bool GameWorldBase::FindFreePath(const MapPoint start, 
                                 const MapPoint dest,  const bool random_route, 
                                 const unsigned max_route,  std::vector<unsigned char>* route,  unsigned* length, 
                                 unsigned char* first_dir,   FP_Node_OK_Callback IsNodeOK,  FP_Node_OK_Callback IsNodeToDestOk,  const void* param,  const bool record) const
{
    // increase currentVisit,  so we don't have to clear the visited-states at every run
    currentVisit++;

    // if the counter reaches its maxium,  tidy up
    if (currentVisit == std::numeric_limits<unsigned>::max() - 1)
    {
        for (unsigned i = 0; i < (maxMapSize * maxMapSize); ++i)
        {
            pf_nodes[i].lastVisited = 0;
			pf_nodes[i].lastVisitedEven = 0;
        }
        currentVisit = 1;
    }

    std::set<PathfindingPoint> todo;
    PathfindingPoint::Init(dest,  this);

    // Anfangsknoten einfügen
    unsigned start_id = MakeCoordID(start);
    std::pair< std::set<PathfindingPoint>::iterator,  bool > ret = todo.insert(PathfindingPoint(start,  start_id));
    // Und mit entsprechenden Werten füllen
    pf_nodes[start_id].it_p = ret.first;
    pf_nodes[start_id].prev = INVALID_PREV;
    pf_nodes[start_id].lastVisited = currentVisit;
    pf_nodes[start_id].way = 0;
    pf_nodes[start_id].dir = 0;

    // TODO confirm random
    unsigned rand = (GetIdx(start)) * GAMECLIENT.GetGFNumber() % 6; //RANDOM.Rand(__FILE__,  __LINE__,  y_start * GetWidth() + x_start,  6);

    while(!todo.empty())
    {
        // Knoten mit den geringsten Wegkosten auswählen
        PathfindingPoint best = *todo.begin();
        // Knoten behandelt --> raus aus der todo Liste
        todo.erase(todo.begin());

        //printf("x: %u y: %u\n", best.x, best.y);

        // ID des besten Punktes ausrechnen

        unsigned best_id = best.id;

        // Dieser Knoten wurde aus dem set entfernt,  daher wird der entsprechende Iterator
        // auf das Ende (also nicht definiert) gesetzt,  quasi als "NULL"-Ersatz
        pf_nodes[best_id].it_p = todo.end();

        // Ziel schon erreicht? Allerdings Null-Weg,  wenn Start=Ende ist,  verbieten
        if(dest == best.pt && pf_nodes[best_id].way)
        {
            // Ziel erreicht!
            // Jeweils die einzelnen Angaben zurückgeben,  falls gewünscht (Pointer übergeben)
            if(length)
                *length = pf_nodes[best_id].way;
            if(route)
                route->resize(pf_nodes[best_id].way);

            // Route rekonstruieren und ggf. die erste Richtung speichern,  falls gewünscht
            for(unsigned z = pf_nodes[best_id].way - 1; best_id != start_id; --z,  best_id = pf_nodes[best_id].prev)
            {
                if(route)
                    (*route)[z] = pf_nodes[best_id].dir;
                if(first_dir && z == 0)
                    *first_dir = pf_nodes[best_id].dir;
            }

            // Fertig,  es wurde ein Pfad gefunden
            return true;
        }

        // Maximaler Weg schon erreicht? In dem Fall brauchen wir keine weiteren Knoten von diesem aus bilden
        if(pf_nodes[best_id].way == max_route)
            continue;

        // Bei Zufälliger Richtung anfangen (damit man nicht immer denselben Weg geht,  besonders für die Soldaten wichtig)
        unsigned start = random_route ? rand : 0;

        // Knoten in alle 6 Richtungen bilden
        for(unsigned z = start + 3; z < start + 9; ++z)
        {
            unsigned i = z % 6;

            // Koordinaten des entsprechenden umliegenden Punktes bilden
            MapPoint na = GetNeighbour(best.pt,  i);

            // ID des umliegenden Knotens bilden
            unsigned xaid = MakeCoordID(na);

            // Knoten schon auf dem Feld gebildet?
            if (pf_nodes[xaid].lastVisited == currentVisit)
            {
                // Dann nur ggf. Weg und Vorgänger korrigieren,  falls der Weg kürzer ist
                if(pf_nodes[xaid].it_p != todo.end() && pf_nodes[best_id].way + 1 < pf_nodes[xaid].way)
                {
                    pf_nodes[xaid].way  = pf_nodes[best_id].way + 1;
                    pf_nodes[xaid].prev = best_id;
                    todo.erase(pf_nodes[xaid].it_p);
                    ret = todo.insert(PathfindingPoint(na,  xaid));
                    pf_nodes[xaid].it_p = ret.first;
                    pf_nodes[xaid].dir = i;
                }
                // Wir wollen nicht denselben Knoten noch einmal einfügen,  daher Abbruch
                continue;
            }

            // Das Ziel wollen wir auf jedenfall erreichen lassen,  daher nur diese zusätzlichen
            // Bedingungen,  wenn es nicht das Ziel ist
            if(na != dest && IsNodeOK)
            {
                if(!IsNodeOK(*this,  na,  i,  param))
                    continue;
            }

            // Zusätzliche Bedingungen,  auch die das letzte Stück zum Ziel betreffen
            if(IsNodeToDestOk)
            {
                if(!IsNodeToDestOk(*this,  na,  i,  param))
                    continue;
            }

            // Alles in Ordnung,  Knoten kann gebildet werden
            pf_nodes[xaid].lastVisited = currentVisit;
            pf_nodes[xaid].way = pf_nodes[best_id].way + 1;
            pf_nodes[xaid].dir = i;
            pf_nodes[xaid].prev = best_id;

            ret = todo.insert(PathfindingPoint(na,  xaid));
            pf_nodes[xaid].it_p = ret.first;
        }
    }

    // Liste leer und kein Ziel erreicht --> kein Weg
    return false;
}
Example #19
0
/// Wegfinden ( A* ),  O(v lg v) --> Wegfindung auf allgemeinen Terrain (ohne Straßen),  für Wegbau und frei herumlaufende Berufe
bool GameWorldBase::FindFreePathAlternatingConditions(const MapPoint start, 
                                 const MapPoint dest,  const bool random_route, 
                                 const unsigned max_route,  std::vector<unsigned char>* route,  unsigned* length, 
                                 unsigned char* first_dir,   FP_Node_OK_Callback IsNodeOK,  FP_Node_OK_Callback IsNodeOKAlternate,  FP_Node_OK_Callback IsNodeToDestOk,  const void* param,  const bool record) const
{
    // increase currentVisit,  so we don't have to clear the visited-states at every run
    currentVisit++;
	//currentVisitEven++;

    // if the counter reaches its maxium,  tidy up
    if (currentVisit == std::numeric_limits<unsigned>::max() - 1)
    {
        for (unsigned i = 0; i < (maxMapSize * maxMapSize); ++i)
        {
            pf_nodes[i].lastVisited = 0;
			pf_nodes[i].lastVisitedEven = 0;
        }
        currentVisit = 1;
		//currentVisitEven = 1;
    }

    std::list<PathfindingPoint> todo;
	bool prevstepEven=true; //flips between even and odd 
	unsigned stepsTilSwitch=1;
    PathfindingPoint::Init(dest,  this);

    // Anfangsknoten einfügen
    unsigned start_id = MakeCoordID(start);
	todo.push_back(PathfindingPoint(start,  start_id));
    // Und mit entsprechenden Werten füllen
    //pf_nodes[start_id].it_p = ret.first;
    pf_nodes[start_id].prevEven = INVALID_PREV;
    pf_nodes[start_id].lastVisitedEven = currentVisit;
    pf_nodes[start_id].wayEven = 0;
    pf_nodes[start_id].dirEven = 0;
	//LOG.lprintf("pf: from %i, %i to %i, %i \n", x_start, y_start, x_dest, y_dest);
    // TODO confirm random
    unsigned rand = GetIdx(start) * GAMECLIENT.GetGFNumber() % 6; //RANDOM.Rand(__FILE__,  __LINE__,  y_start * GetWidth() + x_start,  6);

	while(!todo.empty())
    {		
		if(!stepsTilSwitch) //counter for next step and switch condition
		{			
			prevstepEven=!prevstepEven;
			stepsTilSwitch=todo.size();
			//prevstepEven? LOG.lprintf("pf: even,  to switch %i listsize %i ", stepsTilSwitch, todo.size()) : LOG.lprintf("pf: odd,  to switch %i listsize %i ", stepsTilSwitch, todo.size());
		}
		//else
			//prevstepEven? LOG.lprintf("pf: even,  to switch %i listsize %i ", stepsTilSwitch, todo.size()) : LOG.lprintf("pf: odd,  to switch %i listsize %i ", stepsTilSwitch, todo.size());
		stepsTilSwitch--;

        // Knoten mit den geringsten Wegkosten auswählen
        PathfindingPoint best = *todo.begin();
        // Knoten behandelt --> raus aus der todo Liste
        todo.erase(todo.begin());

        //printf("x: %u y: %u\n", best.x, best.y);

        // ID des besten Punktes ausrechnen

        unsigned best_id = best.id;
		//LOG.lprintf(" now %i, %i id: %i \n", best.x, best.y, best_id);
        // Dieser Knoten wurde aus dem set entfernt,  daher wird der entsprechende Iterator
        // auf das Ende (also nicht definiert) gesetzt,  quasi als "NULL"-Ersatz
        //pf_nodes[best_id].it_p = todo.end();

        // Ziel schon erreicht? Allerdings Null-Weg,  wenn Start=Ende ist,  verbieten
        if(dest == best.pt && ((prevstepEven && pf_nodes[best_id].wayEven) || (!prevstepEven && pf_nodes[best_id].way)))
        {
            // Ziel erreicht!
            // Jeweils die einzelnen Angaben zurückgeben,  falls gewünscht (Pointer übergeben)
            if(length)
				*length = prevstepEven ? pf_nodes[best_id].wayEven : pf_nodes[best_id].way;
            if(route)
                prevstepEven? route->resize(pf_nodes[best_id].wayEven) : route->resize(pf_nodes[best_id].way);

            // Route rekonstruieren und ggf. die erste Richtung speichern,  falls gewünscht
			bool alternate=prevstepEven;
            for(unsigned z = prevstepEven? pf_nodes[best_id].wayEven - 1 : pf_nodes[best_id].way - 1; best_id != start_id; --z,  best_id = alternate? pf_nodes[best_id].prevEven : pf_nodes[best_id].prev,  alternate=!alternate)
            {
                if(route)
                    (*route)[z] = alternate? pf_nodes[best_id].dirEven : pf_nodes[best_id].dir;
                if(first_dir && z == 0)
                    *first_dir = pf_nodes[best_id].dirEven;				
            }

            // Fertig,  es wurde ein Pfad gefunden
            return true;
        }

        // Maximaler Weg schon erreicht? In dem Fall brauchen wir keine weiteren Knoten von diesem aus bilden
        if((prevstepEven && pf_nodes[best_id].wayEven)==max_route || (!prevstepEven && pf_nodes[best_id].way == max_route))
            continue;

        // Bei Zufälliger Richtung anfangen (damit man nicht immer denselben Weg geht,  besonders für die Soldaten wichtig)
        unsigned startDir = random_route ? rand : 0;
		//LOG.lprintf("pf get neighbor nodes %i, %i id: %i \n", best.x, best.y, best_id);
        // Knoten in alle 6 Richtungen bilden
        for(unsigned z = startDir + 3; z < startDir + 9; ++z)
        {
            unsigned i = z % 6;

            // Koordinaten des entsprechenden umliegenden Punktes bilden
            MapPoint na = GetNeighbour(best.pt,  i);

            // ID des umliegenden Knotens bilden
            unsigned xaid = MakeCoordID(na);

            // Knoten schon auf dem Feld gebildet?
            if ((prevstepEven && pf_nodes[xaid].lastVisited == currentVisit) || (!prevstepEven && pf_nodes[xaid].lastVisitedEven == currentVisit))
            {
                continue;
            }

            // Das Ziel wollen wir auf jedenfall erreichen lassen,  daher nur diese zusätzlichen
            // Bedingungen,  wenn es nicht das Ziel ist
            if(na != dest && ((prevstepEven && IsNodeOK) || (!prevstepEven && IsNodeOKAlternate)))
            {
                if(prevstepEven)
				{
					if(!IsNodeOK(*this,  na,  i,  param))
						continue;
				}
				else
				{
					if (!IsNodeOKAlternate(*this,  na,  i,  param))
						continue;
					MapPoint p = best.pt;

					std::vector<MapPoint>evenlocationsonroute;
					bool alternate=prevstepEven;
					unsigned back_id=best_id;
					for(unsigned i=pf_nodes[best_id].way-1; i>1; i--, back_id = alternate? pf_nodes[back_id].prevEven : pf_nodes[back_id].prev,  alternate=!alternate) // backtrack the plannend route and check if another "even" position is too close
					{
						unsigned char pdir = alternate? pf_nodes[back_id].dirEven : pf_nodes[back_id].dir;
						p = GetNeighbour(p,  (pdir+3)%6);
						if(i%2==0) //even step
						{	
							evenlocationsonroute.push_back(p);
						}
					}
					bool tooclose=false;
					//LOG.lprintf("pf from %i, %i to %i, %i now %i, %i ", x_start, y_start, x_dest, y_dest, xa, ya);//\n
					for(std::vector<MapPoint>::const_iterator it=evenlocationsonroute.begin();it!=evenlocationsonroute.end(); ++it)
					{
						//LOG.lprintf("dist to %i, %i ", temp, *it);
						if(CalcDistance(na,  (*it))<2)
						{
							tooclose=true;
							break;
						}
					}
					//LOG.lprintf("\n");
					if(CalcDistance(na,  start)<2)
						continue;
					if(CalcDistance(na,  dest)<2)
						continue;
					if(tooclose)
						continue;
				}
            }

            // Zusätzliche Bedingungen,  auch die das letzte Stück zum Ziel betreffen
            if(IsNodeToDestOk)
            {
                if(!IsNodeToDestOk(*this,  na,  i,  param))
                    continue;
            }

            // Alles in Ordnung,  Knoten kann gebildet werden
            prevstepEven? pf_nodes[xaid].lastVisited = currentVisit			: pf_nodes[xaid].lastVisitedEven = currentVisit;
            prevstepEven? pf_nodes[xaid].way = pf_nodes[best_id].wayEven + 1: pf_nodes[xaid].wayEven = pf_nodes[best_id].way + 1;
            prevstepEven? pf_nodes[xaid].dir = i							: pf_nodes[xaid].dirEven = i;
            prevstepEven? pf_nodes[xaid].prev = best_id						: pf_nodes[xaid].prevEven = best_id	;

            todo.push_back(PathfindingPoint(na,  xaid));
            //pf_nodes[xaid].it_p = ret.first;
        }
    }

    // Liste leer und kein Ziel erreicht --> kein Weg
    return false;
}
void GameWorldBase::RecalcBQAroundPoint(const MapPoint pt)
{
    RecalcBQ(pt);
    for(unsigned char i = 0; i < 6; ++i)
        RecalcBQ(GetNeighbour(pt, Direction::fromInt(i)));
}
Example #21
0
void
phgNSBuildPc(NSSolver *ns)
{
    GRID *g = ns->g;
    SIMPLEX *e;
    FLOAT *dt = ns->dt;
    int i, j, q, s, k, l;
    FLOAT Theta = _nsp->Theta, nu = _nsp->nu, Thet1, nu0 = 0;
    DOF *tmp_u1 = phgDofNew(g, _nsp->utype, Dim, "tmp u1", func_u);
    int viscosity_type = ns->viscosity_type;
    LTYPE ltype = ns->ltype;


#if STEADY_STATE
    assert(fabs(Theta - 1) < 1e-12);
    Thet1 = 0; Unused(Thet1);
    Unused(dt);
#else
    Thet1 = 1 - Theta;
#endif /* STEADY_STATE */


    ForAllElements(g, e) {
	int M = ns->u[1]->type->nbas;	/* num of bases of Velocity */
	int N = ns->p[1]->type->nbas;	/* num of bases of Pressure */
	int order = 2 * DofTypeOrder(ns->p[1], e) + 
	    DofTypeOrder(ns->u[1], e) - 1; 	/* highest order term (u \nabla p, psi)  */
	FLOAT Ap[N][N], Fp[N][N], Qp[N][N], bufp[N], rhs1 = 1;
	FLOAT F[M*Dim][M*Dim], B[N][M*Dim], Bt[M*Dim][N];
	INT Ip[N];
	QUAD *quad;
	FLOAT vol, det;
	const FLOAT *w, *p, *vw, *gu, *vTe;

	quad = phgQuadGetQuad3D(order);
	vw = phgQuadGetDofValues(e, ns->wind, quad);  /* value wind */
	gu = phgQuadGetDofValues(e, ns->gradu[1], quad);        /* grad u^{n+1} */
	if (ns_params->noniter_temp)
	    vTe = phgQuadGetDofValues(e, ns->T[1], quad);  /* value temp */
	else
	    vTe = phgQuadGetDofValues(e, ns->T[0], quad);  /* value temp */
	
	vol = 0;
	Bzero(Ap); Bzero(Fp); Bzero(Qp); 
	Bzero(F); Bzero(Bt); Bzero(B);
	Bzero(bufp); 

	p = quad->points;
	w = quad->weights;
	for (q = 0; q < quad->npoints; q++) {
	    phgGeomGetCurvedJacobianAtLambda(g, e, p, &det);
	    vol = fabs(det / 6.);

	    for (i = 0; i < N; i++) {
		const FLOAT *gi = phgQuadGetBasisValues(e, ns->p[1], i, quad) + q;       /* phi_i */
		const FLOAT *ggi = phgQuadGetBasisCurvedGradient(e, ns->p[1], i, quad, q);    /* grad phi_i */
		for (j = 0; j < N; j++) {
		    const FLOAT *gj = phgQuadGetBasisValues(e, ns->p[1], j, quad) + q;       /* phi_j */
		    const FLOAT *ggj = phgQuadGetBasisCurvedGradient(e, ns->p[1], j, quad, q);    /* grad phi_i */
		    
		    nu = get_effective_viscosity(gu, *vTe, 0, viscosity_type);
		    if (i == 0 && j == 0)
			nu0 += nu;
#if ICE_BENCH_TEST ||				\
    ESIMINT_TEST ||				\
    HEINO_TEST ||				\
    TEST_CASE == ICE_EXACT	||		\
    TEST_CASE == ICE_GREEN_LAND
		    Unused(dt);
		    /* Note: B Q^-1 Bt ~ Ap(nu=1),
		     *       Fp(nu varies) is very different to Ap */
		    Ap[i][j] += vol*(*w) * INNER_PRODUCT(ggj, ggi);
#  if USE_QP_ONLY

		    //Qp[i][j] += vol*(*w) * LEN_SCALING * PRES_SCALING /(nu) * (*gj) * (*gi);
		    Qp[i][j] += vol*(*w) * 1. /(EQU_SCALING * nu) * (*gj) * (*gi);
		    /* if (i < NVert && j < NVert) { */
		    /* 	Qp[i][j] += vol*(*w) * LEN_SCALING * PRES_SCALING / (nu) * (*gj) * (*gi); */
		    /* } else if (i == NVert && j == NVert) { */
		    /* 	Qp[i][j] += vol*(*w) * LEN_SCALING * PRES_SCALING / (nu) * (*gj) * (*gi); */
		    /* } */

#  else
		    Qp[i][j] += vol*(*w) * (*gj) * (*gi);
#  endif
		    Fp[i][j] += vol*(*w) * (EQU_SCALING * nu * INNER_PRODUCT(ggj, ggi)
					    );
#elif STEADY_STATE 
		    Ap[i][j] += vol*(*w) * INNER_PRODUCT(ggj, ggi);
		    Qp[i][j] += vol*(*w) * (*gj) * (*gi);
		    Fp[i][j] += vol*(*w) * (nu * INNER_PRODUCT(ggj, ggi) * EQU_SCALING
					    );
#elif TIME_DEP_NON
		    Ap[i][j] += vol*(*w) * INNER_PRODUCT(ggj, ggi);
		    Qp[i][j] += vol*(*w) * (*gj) * (*gi);
		    Fp[i][j] += vol*(*w) * ((*gj) * (*gi) / dt[0]
					    + Theta * (nu * INNER_PRODUCT(ggj, ggi)
						       )
					    );
#else
		    TIME_DEP_LINEAR_ENTRY; /* Unavailable */
#endif /* STEADY_STATE */
		}
	    }

	    vw += Dim; 
	    gu += DDim;
	    vTe++;
	    w++; p += Dim+1;
	}


	/* Map: Element -> system */
	for (i = 0; i < N; i++) 
	    Ip[i] = phgMapE2L(_pcd->matFp->cmap, 0, e, i);

	/*
	 * PCD boundary setup I:
	 * Automaticly decide inflow boundary condition using wind direction.
	 *
	 * NOT active.
	 * */
	if (FALSE && !_nsp->pin_node) {
	    for (i = 0; i < N; i++) {
		BOOLEAN flag_inflow = FALSE;
		for (s = 0; s < NFace; s++) {
		    SHORT bases[NbasFace(ns->p[1])];
		    FLOAT *coord, vw_[3]; 
		    const FLOAT *lam, *normal;

		    if (!(e->bound_type[s] & BDRY_MASK))
			//if (!(e->bound_type[s] & INFLOW))
			continue;	/* boundary face */

		    phgDofGetBasesOnFace(ns->p[1], e, s, bases);
		    for (j = 0; j < NbasFace(ns->p[1]); j++) 
			if (i == bases[j]) {
			    normal = phgGeomGetFaceOutNormal(g, e, s);
			    coord = phgDofGetElementCoordinates(ns->p[1], e, i);
			    lam = phgGeomXYZ2Lambda(g, e, coord[0], coord[1], coord[2]);
			    phgDofEval(tmp_u1, e, lam, vw_);
			    if (INNER_PRODUCT(vw_, normal) > 1e-8) 
				flag_inflow = TRUE;
			}
		}
		
		if (flag_inflow) {
		    Bzero(bufp); bufp[i] = 1.0;
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    //phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);
		}
		else {
		    /* interior node Or Neumann */
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, Ap[i]);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, Fp[i]);
		    //phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
		}
		phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
	    }
	} 
	/*
	 * PCD boundary setup II:
	 * Enclose flow: use pinnode boundary.
	 *
	 * Qp is pinned, this is different to open flow.
	 * 
	 * */
	else if (_nsp->pin_node) {

	    for (i = 0; i < N; i++) {
		if (phgDofDirichletBC(_pcd->pbc, e, i, NULL, bufp, NULL, DOF_PROJ_NONE)) {
#if PIN_AT_ROOT 
		    if (g->rank != 0)
		    	phgError(1, "Pinned node only on rank 0!\n");
		    if (e->verts[i] != ns->pinned_node_id)
			phgError(1, "pinned node [%d] & [%d] doesn't coincide when build pc!\n",
				 e->verts[i], ns->pinned_node_id);
#else
		    if (GlobalVertex(g, e->verts[i]) != ns->pinned_node_id)
			phgError(1, "pinned node [%d] & [%d] doesn't coincide when build pc!\n",
				 e->verts[i], ns->pinned_node_id);
#endif /* PIN_AT_ROOT */

		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);
		} else {
		    /* interior node Or Neumann */
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, Ap[i]);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, Fp[i]);
		    phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
		}
	    }
	}
	/*
	 * PCD boundary setup III:
	 * Open flow: there could be varies kinds of combination on seting up
	 *   boundary conditon, but Inflow:Robin & Outflow:scaled Dirich is
	 *   prefered. See Ref[2].
	 * 
	 * */
	else {
	    for (i = 0; i < N; i++) {

		/*****************/
                /* Inflow	 */
                /*****************/
#warning PCD B.C.: Step 2.1. build mat, all neumann, add dirich entries
		if (FALSE && phgDofDirichletBC(_pcd->dof_inflow, e, i, NULL, bufp, NULL, DOF_PROJ_NONE)) {
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);
		} else if (FALSE && phgDofDirichletBC(_pcd->dof_outflow, e, i, NULL, bufp, NULL, DOF_PROJ_NONE)
			   && !(phgDofGetElementBoundaryType(ns->p[1], e, i) & INFLOW) ) {

		    ERROR_MSG("Fp, Qp");
		    nu = get_effective_viscosity(NULL, 0, 0, viscosity_type);
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    bufp[i] *= EQU_SCALING * nu;
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);

		    //phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		} else if (FALSE && phgDofDirichletBC(_pcd->pbc, e, i, NULL, bufp, NULL, DOF_PROJ_NONE)) {
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, bufp);
		    phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, bufp);
		    phgVecAddEntries(_pcd->rhsScale, 0, 1, Ip + i, &rhs1);
		}
		else if (FALSE) {
		    /* interior node Or Neumann */

		    ERROR_MSG("Fp, Qp");
		    phgMatAddEntries(_pcd->matAp, 1, Ip + i, N, Ip, Ap[i]);
		    phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, Fp[i]);
		    //phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
		}

		/******************/
                /* No bdry	  */
                /******************/
		//phgMatAddEntries(_pcd->matFp, 1, Ip + i, N, Ip, Fp[i]);
		phgMatAddEntries(_pcd->matQp, 1, Ip + i, N, Ip, Qp[i]);
	    }
	}


	if (0) {
	    /* Special term <[[p_i]], [[p_j]]> */
	    int face;
	    nu0 /= quad->npoints;
	    for (face = 0; face < NFace; face++) {
		FLOAT area =  phgGeomGetFaceArea(g, e, face);
		//FLOAT value = {area, -area};
		FLOAT values[2] = {vol * 1. /(EQU_SCALING * nu0),
				   -vol * 1. /(EQU_SCALING * nu0)};
		SIMPLEX *e_neigh;

		phgMatAddEntries(_pcd->matQp, 1, Ip+NVert, 1, Ip+NVert, values);
		if ((e_neigh = GetNeighbour(e, face)) != NULL) {
		    INT Ip_neigh = phgMapE2L(_pcd->matFp->cmap, 0, e_neigh, NVert);
		    phgMatAddEntries(_pcd->matQp, 1, Ip+NVert, 1, &Ip_neigh, values + 1);
		}
	    }
	}

    }	/* end element */
Example #22
0
void GameWorld::Scan(glArchivItem_Map* map)
{
    width_ = map->getHeader().getWidth(); //-V807
    height_ = map->getHeader().getHeight();
    lt = LandscapeType(map->getHeader().getGfxSet());

    Init();

    // Dummy-Hafenpos für Index 0 einfügen // ask Oliverr why!
    // -> I just did, the dummy is so that the harbor "0" might be used for ships with no particular destination
    // poc: if you ever remove this dummy go to GameWorldBase::CalcDistanceToNearestHarbor and fix the loop to include the first harbor again (think Ive seen other instances of dummyadjusted loops as well...)
    GameWorldBase::HarborPos dummy(MapPoint(0, 0));
    
    harbor_pos.push_back(dummy);

    // Andere Sachen setzen
	MapPoint pt(0, 0);
	
    for(pt.y = 0; pt.y < height_; ++pt.y)
    {
        for(pt.x = 0; pt.x < width_; ++pt.x)
        {
        	MapNode& node = GetNode(pt);

            node.roads[2] = node.roads[1] = node.roads[0] = 0;
            node.roads_real[2] = node.roads_real[1] = node.roads_real[0] = false;
            node.altitude = map->GetMapDataAt(MAP_ALTITUDE, pt.x, pt.y);
            // Aufpassen, dass die Terrainindizes im Rahmen liegen, ansonsten 0 nehmen, unbekanntes Terrain (Bsp.
            // Karte "Drachenebene")
            unsigned char t1 = map->GetMapDataAt(MAP_TERRAIN1, pt.x, pt.y), t2 = map->GetMapDataAt(MAP_TERRAIN2, pt.x, pt.y);

            // Hafenplatz?
            if(TerrainData::IsHarborSpot(t1))
            {	
				GameWorldBase::HarborPos p(pt);
                node.harbor_id = harbor_pos.size();
                harbor_pos.push_back(p);
            }
            else
                node.harbor_id = 0;

            node.t1 = TerrainData::MapIdx2Terrain(t1);
            node.t2 = TerrainData::MapIdx2Terrain(t2);

            node.resources = map->GetMapDataAt(MAP_RESOURCES, pt.x, pt.y);

            // Wasser?
            if(node.resources == 0x20 || node.resources == 0x21)
            {
                // TODO: Berge hatten komische Wasserbeeinflussung
                // ggf 0-4 Wasser setzen
                if( (node.t1 == TT_DESERT || node.t2 == TT_DESERT) ||
                        TerrainData::IsWater(node.t1) || TerrainData::IsWater(node.t2) )
                    node.resources = 0; // Kein Wasser, in der Wüste, da isses trocken!
                else if( (node.t1 == TT_STEPPE || node.t2 == TT_STEPPE) )
                    node.resources = 0x23; // 2 Wasser
                else if( (node.t1 == TT_SAVANNAH || node.t2 == TT_SAVANNAH) )
                    node.resources = 0x25; // 4 Wasser
                else
                    node.resources = 0x27; // 7 Wasser
            }

            node.reserved = false;
            node.owner = 0;
            for(unsigned i = 0; i < 4; ++i)
                node.boundary_stones[i] = 0;
            node.sea_id = 0;

            // FOW-Zeug initialisieren
            for(unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i)
            {
                MapNode::FoWData& fow = node.fow[i];
                switch(GAMECLIENT.GetGGS().exploration)
                {
                    case GlobalGameSettings::EXP_DISABLED:
                    {
                        fow.visibility = VIS_VISIBLE;
                    } break;
                    case GlobalGameSettings::EXP_CLASSIC:
                    {
                        fow.visibility = VIS_INVISIBLE;
                    } break;
                    case GlobalGameSettings::EXP_FOGOFWAR:
                    {
                        fow.visibility = VIS_INVISIBLE;
                    } break;
                    case GlobalGameSettings::EXP_FOGOFWARE_EXPLORED:
                    {
                        fow.visibility = VIS_FOW;
                    } break;
                }

                fow.last_update_time = 0;
                fow.object = NULL;
                fow.roads[0] = fow.roads[1] =
                                           fow.roads[2] = 0;
                fow.owner = 0;
                for(unsigned z = 0; z < 4; ++z)
                    fow.boundary_stones[z] = 0;
            }
        }
    }

    std::vector< MapPoint > headquarter_positions;

    // Objekte auslesen
    for(pt.y = 0; pt.y < height_; ++pt.y)
    {
        for(pt.x = 0; pt.x < width_; ++pt.x)
        {
            unsigned int pos = GetIdx(pt);
            unsigned char lc = map->GetMapDataAt(MAP_LANDSCAPE, pt.x, pt.y);

            switch(map->GetMapDataAt(MAP_TYPE, pt.x, pt.y))
            {
                    // Player Startpos (provisorisch)
                case 0x80:
                {
                    headquarter_positions.push_back(pt);

                    if(lc < GAMECLIENT.GetPlayerCount())
                    {
                        GetPlayer(lc).hqPos = pt;
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Baum 1-4
                case 0xC4:
                {
                    if(lc >= 0x30 && lc <= 0x3D)
                        nodes[pos].obj = new noTree(pt, 0, 3);
                    else if(lc >= 0x70 && lc <= 0x7D)
                        nodes[pos].obj = new noTree(pt, 1, 3);
                    else if(lc >= 0xB0 && lc <= 0xBD)
                        nodes[pos].obj = new noTree(pt, 2, 3);
                    else if(lc >= 0xF0 && lc <= 0xFD)
                        nodes[pos].obj = new noTree(pt, 3, 3);
                    else
                    {
                        LOG.lprintf("Unbekannter Baum1-4 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Baum 5-8
                case 0xC5:
                {
                    if(lc >= 0x30 && lc <= 0x3D)
                        nodes[pos].obj = new noTree(pt, 4, 3);
                    else if(lc >= 0x70 && lc <= 0x7D)
                        nodes[pos].obj = new noTree(pt, 5, 3);
                    else if(lc >= 0xB0 && lc <= 0xBD)
                        nodes[pos].obj = new noTree(pt, 6, 3);
                    else if(lc >= 0xF0 && lc <= 0xFD)
                        nodes[pos].obj = new noTree(pt, 7, 3);
                    else
                    {
                        LOG.lprintf("Unbekannter Baum5-8 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Baum 9
                case 0xC6:
                {
                    if(lc >= 0x30 && lc <= 0x3D)
                        nodes[pos].obj = new noTree(pt, 8, 3);
                    else
                    {
                        LOG.lprintf("Unbekannter Baum9 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Sonstiges Naturzeug ohne Funktion, nur zur Dekoration
                case 0xC8:
                {
                    /// @todo mis0bobs unvollständig (dieses lagerzelt), 4 und 5 überhaupt nicht erwähnt
                    // mis1bobs, 2 und 3 sind vollständig eingebaut

                    // Objekte aus der map_?_z.lst
                    if(lc <= 0x0A)
                        nodes[pos].obj = new noEnvObject(pt, 500 + lc);

                    // "wasserstein" aus der map_?_z.lst
                    else if(lc == 0x0B)
                        nodes[pos].obj = new noStaticObject(pt, 500 + lc);

                    // Objekte aus der map_?_z.lst
                    else if(lc >= 0x0C && lc <= 0x0F)
                        nodes[pos].obj = new noEnvObject(pt, 500 + lc);

                    // Objekte aus der map.lst
                    else if(lc >= 0x10 && lc <= 0x14)
                        nodes[pos].obj = new noEnvObject(pt, 542 + lc - 0x10);

                    // gestrandetes Schiff (mis0bobs, unvollständig)
                    else if(lc == 0x15)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x15) * 2, 0, 1);

                    // das Tor aus der map_?_z.lst
                    else if(lc == 0x16)
                        nodes[pos].obj = new noStaticObject(pt, 560, 0xFFFF, 2);

                    // das geöffnete Tor aus map_?_z.lst
                    else if(lc == 0x17)
                        nodes[pos].obj = new noStaticObject(pt, 561, 0xFFFF, 2);

                    // Stalagmiten (mis1bobs)
                    else if(lc >= 0x18 && lc <= 0x1E)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x18) * 2, 1);

                    // toter Baum (mis1bobs)
                    else if(lc >= 0x1F && lc <= 0x20)
                        nodes[pos].obj = new noStaticObject(pt, 20 + (lc - 0x1F) * 2, 1);

                    // Gerippe (mis1bobs)
                    else if(lc == 0x21)
                        nodes[pos].obj = new noEnvObject(pt, 30, 1);

                    // Objekte aus der map.lst
                    else if(lc >= 0x22 && lc <= 0x27)
                        nodes[pos].obj = new noEnvObject(pt, 550 + lc - 0x22);

                    // Objekte aus der map.lst
                    else if(lc >= 0x28 && lc <= 0x2B)
                        nodes[pos].obj = new noEnvObject(pt, 556 + lc - 0x28);

                    // die "kaputten" Gebäuderuinen usw (mis2bobs)
                    else if(lc >= 0x2C && lc <= 0x2D)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x2C) * 2, 2);
                    else if(lc == 0x2E)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x2C) * 2, 2, 1);
                    else if(lc == 0x2F)
                        nodes[pos].obj = new noStaticObject(pt, (lc - 0x2C) * 2, 2, 2);
                    else if(lc == 0x30)
                        nodes[pos].obj = new noEnvObject(pt, (lc - 0x2C) * 2, 2);

                    // der Wikinger (mis3bobs)
                    else if(lc == 0x31)
                        nodes[pos].obj = new noStaticObject(pt, 0, 2);

                    else
                    {
                        LOG.lprintf("Unbekanntes Naturzeug auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }

                } break;

                // Granit Typ 1
                case 0xCC:
                {
                    if(lc >= 0x01 && lc <= 0x06)
                        nodes[pos].obj = new noGranite(GT_1, lc - 1);
                    else
                    {
                        LOG.lprintf("Unbekannter Granit1 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Granit Typ 2
                case 0xCD:
                {
                    if(lc >= 0x01 && lc <= 0x06)
                        nodes[pos].obj = new noGranite(GT_2, lc - 1);
                    else
                    {
                        LOG.lprintf("Unbekannter Granit2 auf x=%d, y=%d: id=%d (0x%0X)\n", pt.x, pt.y, lc, lc);
                        nodes[pos].obj = NULL;
                    }
                } break;

                // Nichts
                case 0:
                {
                    nodes[pos].obj = NULL;
                } break;

                default:
                {
                    /*LOG.lprintf("Unbekanntes Objekt %d (0x%0X) auf x=%d, y=%d: id=%d (0x%0X)\n", map->map_type[y*width+x], map->map_type[y*width+x], x, y, lc, lc);
                    */         nodes[pos].obj = NULL;
                } break;
            }
        }
    }

    // BQ mit nichts erstmal inititalisieren (HQ-Setzen berechnet diese neu und braucht sie)
    for(pt.y = 0; pt.y < height_; ++pt.y)
    {
        for(pt.x = 0; pt.x < width_; ++pt.x)
        {
            SetBQ(pt, BQ_NOTHING);
        }
    }

    //random locations? -> randomize them :)
    if (GAMECLIENT.GetGGS().random_location)
    {
        ptrdiff_t (*p_myrandom)(ptrdiff_t) = myRandom;
        std::random_shuffle(headquarter_positions.begin(), headquarter_positions.end(), p_myrandom);

        for (unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i)
        {
            GetPlayer(i).hqPos = headquarter_positions.at(i);
        }
    }

    // HQ setzen
    for(unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i)
    {
        // Existiert überhaupt ein HQ?
        if(GetPlayer(i).hqPos.x != 0xFFFF)
        {
            if(GetPlayer(i).ps == PS_OCCUPIED || GetPlayer(i).ps == PS_KI)
            {
                nobHQ* hq = new nobHQ(GetPlayer(i).hqPos, i, GetPlayer(i).nation);
                SetNO(hq, GetPlayer(i).hqPos);
                GetPlayer(i).AddWarehouse(reinterpret_cast<nobBaseWarehouse*>(hq));
            }
            /*else
                GetNode(GetPlayer(i).hqx,GetPlayer(i).hqy).obj = 0;*/
        }
    }

    // Tiere auslesen
    for(pt.y = 0; pt.y < height_; ++pt.y)
    {
        for(pt.x = 0; pt.x < width_; ++pt.x)
        {
            unsigned pos = GetIdx(pt);
            // Tiere setzen
            Species species;
            switch(map->GetMapDataAt(MAP_ANIMALS, pt.x, pt.y))
            {
                    // TODO: Welche ID ist Polarbär?
                case 1: species = Species(SPEC_RABBITWHITE+RANDOM.Rand(__FILE__, __LINE__, 0, 2)); break; // zufällige Hasenart nehmen
                case 2: species = SPEC_FOX; break;
                case 3: species = SPEC_STAG; break;
                case 4: species = SPEC_DEER; break;
                case 5: species = SPEC_DUCK; break;
                case 6: species = SPEC_SHEEP; break;
                default: species = SPEC_NOTHING; break;
            }

            if(species != SPEC_NOTHING)
            {
                noAnimal* animal = new noAnimal(species, pt);
                AddFigure(animal, pt);
                // Loslaufen
                animal->StartLiving();
            }

            /// 4 Fische setzen
            if(map->GetMapDataAt(MAP_RESOURCES, pos) > 0x80 && map->GetMapDataAt(MAP_RESOURCES, pos)  < 0x90)
                GetNode(pt).resources = 0x84;
        }
    }

    /// Weltmeere vermessen
    for(pt.y = 0; pt.y < height_; ++pt.y)
    {
        for(pt.x = 0; pt.x < width_; ++pt.x)
        {
            // Noch kein Meer an diesem Punkt?
            if(!GetNode(pt).sea_id)
            {
                // Aber trotzdem Teil eines noch nicht vermessenen Meeres?
                if(IsSeaPoint(pt))
                {
                    unsigned sea_size = MeasureSea(pt, seas.size());
                    seas.push_back(Sea(sea_size));
                }
            }
        }
    }

    /// Die Meere herausfinden, an die die Hafenpunkte grenzen
    for(unsigned i = 0; i < harbor_pos.size(); ++i)
    {
        for(unsigned z = 0; z < 6; ++z)
            harbor_pos[i].cps[z].sea_id = IsCoastalPoint(GetNeighbour(harbor_pos[i].pos, z));
    }

    // Nachbarn der einzelnen Hafenplätze ermitteln
    CalcHarborPosNeighbors();

    /// Schatten und BQ berechnen
    for(pt.y = 0; pt.y < height_; ++pt.y)
    {
        for(pt.x = 0; pt.x < width_; ++pt.x)
        {
            RecalcShadow(pt);
            SetBQ(pt, GAMECLIENT.GetPlayerID());
        }
    }

    /// Bei FoW und aufgedeckt müssen auch die ersten FoW-Objekte erstellt werden
    if(GAMECLIENT.GetGGS().exploration == GlobalGameSettings::EXP_FOGOFWARE_EXPLORED)
    {
        for(pt.y = 0; pt.y < height_; ++pt.y)
        {
            for(pt.x = 0; pt.x < width_; ++pt.x)
            {
                // Alle Spieler durchgehen
                for(unsigned i = 0; i < GAMECLIENT.GetPlayerCount(); ++i)
                {
                    // An der Stelle FOW für diesen Spieler?
                    if(GetNode(pt).fow[i].visibility == VIS_FOW)
                        SaveFOWNode(pt, i);
                }
            }
        }
    }

}