Пример #1
0
/**
 * Output just a single tile
 */
void Game::drawtile(CoordinateSet p) {
	Tile *t = getTile(p);
	chtype output = t->output();
	wmove(window, getOutputRow(p), getOutputColumn(p));
	waddch(window, output);
}
Пример #2
0
Tile*
TileGrid::getTile(vicoord virt) noexcept {
    return getTile(virt2phys(virt));
}
Пример #3
0
bool checkTurn(turn inTurn, int field[8][8], bool isPlayer1)
{
    int pr1, pr2, pr3, pr4, pr5;        //Создаем 5 промежуточных переменных
    pr1 = inTurn.fromX - inTurn.toX;    //Записываем разницу между координатами
    pr2 = inTurn.fromY - inTurn.toY;    //Тоже самое
    pr3 = getTile(field, inTurn.fromX, inTurn.fromY);   //Получаем фигуру
    pr4 = getTile(field, inTurn.toX, inTurn.toY);       //Тоже самое
    std::cout << pr1 << " " << pr2 << " " << pr3 << " " << pr4 << "\n"; //Выводим отладочную информацию
    if(isPlayer1)   //Если ходит первый игрок
    {
        if((pr2 == 0) && ((pr1 == 1) || (pr1 == -1)) && (pr3 == 1) && (pr4 == 0))   //Если ход вверх/вниз верен
        {
            return 1;
        }
        if((pr1 == 0) && ((pr2 == 1) || (pr2 == -1)) && (pr3 == 1) && (pr4 == 0))   //Если ход влево/вправо верен
        {
            return 1;
        }
        if((pr2 == 0) && ((pr1 == 2) || (pr1 == -2)) && (pr3 == 1) && (pr4 == 0))   //Если прыжок вверх/вниз верен
        {
            if(pr2 == 2)    //Если вверх
            {
                pr5 = getTile(field, inTurn.fromX - 1, inTurn.fromY);
            }
            else            //Вниз
            {
                pr5 = getTile(field, inTurn.fromX + 1, inTurn.fromY);
            }
            if(pr5 != 0)
            {
                return 1;
            }
        }
        if((pr1 == 0) && ((pr2 == 2) || (pr2 == -2)) && (pr3 == 1) && (pr4 == 0))
        {
            if(pr1 == 2)
            {
                pr5 = getTile(field, inTurn.fromX, inTurn.fromY - 1);
            }
            else
            {
                pr5 = getTile(field, inTurn.fromX, inTurn.fromY + 1);
            }
            if(pr1 != 0)
            {
                return 1;
            }
        }
    }
    else
    {
        if((pr2 == 0) && ((pr1 == 1) || (pr1 == -1)) && (pr3 == 2) && (pr4 == 0))
        {
            return 1;
        }
        if((pr1 == 0) && ((pr2 == 1) || (pr2 == -1)) && (pr3 == 2) && (pr4 == 0))
        {
            return 1;
        }
        if((pr2 == 0) && ((pr1 == 2) || (pr1 == -2)) && (pr3 == 2) && (pr4 == 0))
        {
            if(pr2 == 2)
            {
                pr5 = getTile(field, inTurn.fromX - 1, inTurn.fromY);
            }
            else
            {
                pr5 = getTile(field, inTurn.fromX + 1, inTurn.fromY);
            }
            if(pr5 != 0)
            {
                return 1;
            }
        }
        if((pr1 == 0) && ((pr2 == 2) || (pr2 == -2)) && (pr3 == 2) && (pr4 == 0))
        {
            if(pr1 == 2)
            {
                pr5 = getTile(field, inTurn.fromX, inTurn.fromY - 1);
            }
            else
            {
                pr5 = getTile(field, inTurn.fromX, inTurn.fromY + 1);
            }
            if(pr1 != 0)
            {
                return 1;
            }
        }
    }
    return 0;
}
void AnnotationManager::addTileMonitor(AnnotationTileMonitor& monitor) {
    monitors.insert(&monitor);
    monitor.update(getTile(monitor.tileID));
}
Пример #5
0
void PtexReader::TiledFaceBase::reduce(FaceData*& face, PtexReader* r,
                                       Res newres, PtexUtils::ReduceFn reducefn)
{
    // get reduce lock and make sure we still need to reduce
    AutoMutex rlocker(r->reducelock);
    if (face) {
        // another thread must have generated it while we were waiting
        AutoLockCache clocker(_cache->cachelock);
        // make sure it's still there now that we have the lock
        if (face) {
            face->ref();
            return;
        }
    }

    /* Tiled reductions should generally only be anisotropic (just u
       or v, not both) since isotropic reductions are precomputed and
       stored on disk.  (This function should still work for isotropic
       reductions though.)

       In the anisotropic case, the number of tiles should be kept the
       same along the direction not being reduced in order to preserve
       the laziness of the file access.  In contrast, if reductions
       were not tiled, then any reduction would read all the tiles and
       defeat the purpose of tiling.
    */

    // keep new face local until fully initialized
    FaceData* volatile newface = 0;

    // don't tile if either dimension is 1 (rare, would complicate blendFaces too much)
    // also, don't tile triangle reductions (too complicated)
    Res newtileres;
    bool isTriangle = r->_header.meshtype == mt_triangle;
    if (newres.ulog2 == 1 || newres.vlog2 == 1 || isTriangle) {
        newtileres = newres;
    }
    else {
        // propagate the tile res to the reduction
        newtileres = _tileres;
        // but make sure tile isn't larger than the new face!
        if (newtileres.ulog2 > newres.ulog2) newtileres.ulog2 = newres.ulog2;
        if (newtileres.vlog2 > newres.vlog2) newtileres.vlog2 = newres.vlog2;
    }


    // determine how many tiles we will have on the reduction
    int newntiles = newres.ntiles(newtileres);

    if (newntiles == 1) {
        // no need to keep tiling, reduce tiles into a single face
        // first, get all tiles and check if they are constant (with the same value)
        PtexFaceData** tiles = (PtexFaceData**) alloca(_ntiles * sizeof(PtexFaceData*));
        bool allConstant = true;
        for (int i = 0; i < _ntiles; i++) {
            PtexFaceData* tile = tiles[i] = getTile(i);
            allConstant = (allConstant && tile->isConstant() &&
                           (i == 0 || (0 == memcmp(tiles[0]->getData(), tile->getData(),
                                                   _pixelsize))));
        }
        if (allConstant) {
            // allocate a new constant face
            newface = new ConstantFace((void**)&face, _cache, _pixelsize);
            memcpy(newface->getData(), tiles[0]->getData(), _pixelsize);
        }
        else if (isTriangle) {
            // reassemble all tiles into temporary contiguous image
            // (triangle reduction doesn't work on tiles)
            int tileures = _tileres.u();
            int tilevres = _tileres.v();
            int sstride = _pixelsize * tileures;
            int dstride = sstride * _ntilesu;
            int dstepv = dstride * tilevres - sstride*(_ntilesu-1);

            char* tmp = (char*) malloc(_ntiles * _tileres.size() * _pixelsize);
            char* tmpptr = tmp;
            for (int i = 0; i < _ntiles;) {
                PtexFaceData* tile = tiles[i];
                if (tile->isConstant())
                    PtexUtils::fill(tile->getData(), tmpptr, dstride,
                                    tileures, tilevres, _pixelsize);
                else
                    PtexUtils::copy(tile->getData(), sstride, tmpptr, dstride, tilevres, sstride);
                i++;
                tmpptr += i%_ntilesu ? sstride : dstepv;
            }

            // allocate a new packed face
            newface = new PackedFace((void**)&face, _cache, newres,
                                     _pixelsize, _pixelsize * newres.size());
            // reduce and copy into new face
            reducefn(tmp, _pixelsize * _res.u(), _res.u(), _res.v(),
                     newface->getData(), _pixelsize * newres.u(), _dt, _nchan);

            free(tmp);
        }
        else {
            // allocate a new packed face
            newface = new PackedFace((void**)&face, _cache, newres,
                                     _pixelsize, _pixelsize*newres.size());

            int tileures = _tileres.u();
            int tilevres = _tileres.v();
            int sstride = _pixelsize * tileures;
            int dstride = _pixelsize * newres.u();
            int dstepu = dstride/_ntilesu;
            int dstepv = dstride*newres.v()/_ntilesv - dstepu*(_ntilesu-1);

            char* dst = (char*) newface->getData();
            for (int i = 0; i < _ntiles;) {
                PtexFaceData* tile = tiles[i];
                if (tile->isConstant())
                    PtexUtils::fill(tile->getData(), dst, dstride,
                                    newres.u()/_ntilesu, newres.v()/_ntilesv,
                                    _pixelsize);
                else
                    reducefn(tile->getData(), sstride, tileures, tilevres,
                             dst, dstride, _dt, _nchan);
                i++;
                dst += i%_ntilesu ? dstepu : dstepv;
            }
        }
        // release the tiles
        for (int i = 0; i < _ntiles; i++) tiles[i]->release();
    }
    else {
        // otherwise, tile the reduced face
        newface = new TiledReducedFace((void**)&face, _cache, newres, newtileres,
                                       _dt, _nchan, this, reducefn);
    }
    AutoLockCache clocker(_cache->cachelock);
    face = newface;

    // clean up unused data
    _cache->purgeData();
}
Пример #6
0
bool SceneMgr::save(xs::DataChunk* pDataChunk,bool writeOccupants)
{
	int nGridWidth = GRID_WIDTH;
	int nGridHeight = GRID_HEIGHT;

	if(!isValid())
	{
		return false;
	}

	int nGridRow = Ceil(m_nMapHeight, nGridHeight);
	int nGridCol = Ceil(m_nMapWidth, nGridWidth);

	uint *pOffsetsData = 0;
	xs::Stream *pDataStream = 0;

    //  地图版本信息;
    pDataChunk->beginChunk('MVER',&pDataStream);
    m_nMapVersion = SUPPORT_EFFECT_SCALE_AND_ANGLE_ADJUST_MAP_VERSION;
    pDataStream->write(&m_nMapVersion, sizeof(m_nMapVersion));
    pDataChunk->endChunk();

	pDataChunk->beginChunk('MINF',&pDataStream);
	pDataStream->write(&m_nMapWidth,sizeof(m_nMapWidth));
	pDataStream->write(&m_nMapHeight,sizeof(m_nMapHeight));
	pDataChunk->endChunk();

	xs::DataChunk::stChunk *pIdxChunk = pDataChunk->beginChunk('MIDX',&pDataStream);
	for(int row = 0;row < nGridRow;row++)
	for(int col = 0;col < nGridCol;col++)
	{
		uint offset = 0;
		pDataStream->write(&offset,sizeof(offset));
	}
	pDataChunk->endChunk();
	pOffsetsData = (uint*)pIdxChunk->m_pData;

	m_bWriteOccupants = writeOccupants;
	int nTileRow = nGridHeight / 32;
	int nTileCol = nGridWidth / (64 / 2);
	xs::Point ptTileLeftTop;
	xs::Point ptLeftTop;
	for(int row = 0;row < nGridRow;row++)
	for(int col = 0;col < nGridCol;col++)
	{
		pDataChunk->beginChunk('MDAT',&pDataStream);
			pOffsetsData[row * nGridCol + col] = pDataChunk->getOffset();

			ptLeftTop.x = col * nGridWidth;
			ptLeftTop.y = row * nGridHeight;

			m_SceneCo.pixel2Tile(ptLeftTop, ptTileLeftTop);
			_SaveBlock(pDataStream,ptTileLeftTop,nTileRow,nTileCol);

		pDataChunk->endChunk();
	}
	m_bWriteOccupants = false;

	m_pGround->save(pDataChunk);

	SceneBlock	mb;
	int nTileWidth = m_SceneCo.getMatrixWidth();
	int nTileHeight = m_SceneCo.getMatrixHeight();

	mb.SetMapSize(nTileWidth, nTileHeight);

	for (int row = 0; row < nTileHeight; ++row)
	{
		for (int col = 0; col < nTileWidth; ++col)
		{
			xs::Point ptTile (col, row);
			Tile *pTile = &getTile(ptTile);
			if (!pTile->isValid())
			{
				mb.SetBlock(col, row, true);
			}
			else
			{
				mb.SetBlock(col, row, pTile->isBlock() ? true: false);
			}

		}
	}			

	pDataChunk->beginChunk('MWPT',&pDataStream);
	mb.Save(pDataStream);
	pDataChunk->endChunk();

	return true;
}
Пример #7
0
/**
 * Check if a Tile at position (row,col) has a widget.
 * @param row :: The row to check.
 * @param col :: The column to check.
 */
bool TiledWindow::hasWidget(int row, int col) const {
  Tile *tile = getTile(row, col);
  return tile->widget() != NULL;
}
Пример #8
0
void HeightMipmap::buildResiduals(int level)
{
    int nTiles = max(1, (baseLevelSize / this->tileSize) >> (maxLevel - level));
    int nTilesPerFile = min(nTiles, 16);
    int tileSize = min(topLevelSize << level, this->tileSize);

    printf("Build residuals level %d...\n", level);

    currentLevel = level;
    reset(baseLevelSize >> (maxLevel - currentLevel), baseLevelSize >> (maxLevel - currentLevel), min(topLevelSize << currentLevel, this->tileSize));

    float *parentTile = new float[(this->tileSize + 5) * (this->tileSize + 5)];
    float *currentTile = new float[(this->tileSize + 5) * (this->tileSize + 5)];
    float *residualTile = new float[(this->tileSize + 5) * (this->tileSize + 5)];
    unsigned char *encodedResidual = new unsigned char[(this->tileSize + 5) * (this->tileSize + 5) * 2];

    float maxRR = 0.0;
    float maxEE = 0.0;
    for (int dy = 0; dy < nTiles / nTilesPerFile; ++dy) {
        for (int dx = 0; dx < nTiles / nTilesPerFile; ++dx) {
            char buf[256];
            sprintf(buf, "%s/residual-%.2d-%.4d-%.4d.tiff", cache.c_str(), level, dx, dy);

            if (flog(buf)) {
                TIFF* f = TIFFOpen(buf, "wb");
                for (int ny = 0; ny < nTilesPerFile; ++ny) {
                    for (int nx = 0; nx < nTilesPerFile; ++nx) {
                        int tx = nx + dx * nTilesPerFile;
                        int ty = ny + dy * nTilesPerFile;
                        float maxR, meanR, maxErr;

                        getApproxTile(level - 1, tx / 2, ty / 2, parentTile);
                        getTile(level, tx, ty, currentTile);
                        computeResidual(parentTile, currentTile, level, tx, ty, residualTile, maxR, meanR);
                        encodeResidual(level, residualTile, encodedResidual);
                        computeApproxTile(parentTile, residualTile, level, tx, ty, currentTile, maxErr);
                        if (level < maxLevel) {
                            saveApproxTile(level, tx, ty, currentTile);
                        }

                        TIFFSetField(f, TIFFTAG_IMAGEWIDTH, tileSize + 5);
                        TIFFSetField(f, TIFFTAG_IMAGELENGTH, tileSize + 5);
                        TIFFSetField(f, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
                        TIFFSetField(f, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
                        TIFFSetField(f, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
                        TIFFSetField(f, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
                        /*TIFFSetField(f, TIFFTAG_SAMPLESPERPIXEL, 1);
                        TIFFSetField(f, TIFFTAG_BITSPERSAMPLE, 16);*/
                        TIFFSetField(f, TIFFTAG_SAMPLESPERPIXEL, 2);
                        TIFFSetField(f, TIFFTAG_BITSPERSAMPLE, 8);
                        TIFFWriteEncodedStrip(f, 0, encodedResidual, (tileSize + 5) * (tileSize + 5) * 2);
                        TIFFWriteDirectory(f);

                        maxRR = max(maxR, maxRR);
                        maxEE = max(maxErr, maxEE);
                    }
                }

                TIFFClose(f);
                printf("%f max residual, %f max err\n", maxRR, maxEE);
            }
        }
    }

    delete[] parentTile;
    delete[] currentTile;
    delete[] residualTile;
    delete[] encodedResidual;
}
MLErrorCode FuzzyConnectedness::calculate(PagedImg *inputData, PagedImg *inputMarker)
{
  // Clear former data.
  clearData();
  // Get the images' extents. 
  Vector extent = inputData->getImgExt();
  // Create image box for internal images.
  // The input image extents  
  SubImgBox box(Vector(-1,-1,-1,0,0,0),Vector(extent.x, extent.y, extent.z, 0, 0,0)); 
  //Set extends of internal images
  _connectivityMapOutImg.setBox(box);
  _labelMapOutImg.setBox(box);
  _inputTmpImg.setBox(box);
  _pointerTmpImg.setBox(box);
  // Copy input image

  MLErrorCode status =getTile(inputData->getBaseOp(),inputData->getOutIndex(),_inputTmpImg);
  if(status==ML_RESULT_OK)
  { 
    // Copy seed points
    status = getTile(inputMarker->getBaseOp(),inputMarker->getOutIndex(),_labelMapOutImg);
    if(status==ML_RESULT_OK)
    {  
      // Allocate memory for the connectivity map.
      _connectivityMapOutImg.allocate(ML_RETURN_NULL);

      if(_connectivityMapOutImg.getData()!=NULL)
      {
        // Allocate memory for the temporary image used internally.
        _pointerTmpImg.allocate(ML_RETURN_NULL);
        if( _pointerTmpImg.getData() != NULL )
        {
          SubImgBox box(extent);
          // Calculate the minimum and maximum intensity values in the image.
          // The original SubImgBox has to be used, as the padding voxels have not been
          // initialised. (As they are never read in the algorithm it is not necessary!!)
          _inputTmpImg.calcMinMax(_minValue,_maxValue,&box);
          // initialise the allocated data.
          _connectivityMapOutImg.fillSubImg(_minValue);
          _pointerTmpImg.fillSubImg(0);
          // initialise the segmentation module.
          _segmentCore.setProperty(extent.x+2,extent.y+2,extent.z+2, _minValue);
          //Start calculation. Resulting connectivity map will be stored in _outputImageData, the color map in _markerData
          _segmentCore.startShortestPathSearchAsFloat(_inputTmpImg.getData(),_connectivityMapOutImg.getData(),
            _labelMapOutImg.getData(),_pointerTmpImg.getData());

          // Free temporary data. 
          _inputTmpImg.free();
          _pointerTmpImg.free();
        }
        else
        {
          // If memory allocation failed MLErrorCode
          status=ML_NO_MEMORY;
        }
      }
      else
      {
        // If memory allocation failed MLErrorCode
        status = ML_NO_MEMORY;
      }
    }
  }
  if(status != ML_RESULT_OK)
  {
    // If an error occured clear image data.
    clearData();
  }
  return status;
}
void Level::randomizeLevel(int minRoomSize, int roomVariance) {
	int freeTiles = height * width;
	
	// Generate a random room
	int roomWidth = (rand() % roomVariance) + minRoomSize;
	int roomHeight = (rand() % roomVariance) + minRoomSize;
	int cornerX = (rand() % ((width - 3) - roomWidth)) + 1;
	int cornerY = (rand() % ((height - 3) - roomHeight)) + 1;

	// Generate the first room
	for(int i = cornerX; i < cornerX + roomWidth - 1; i++) {
		for(int j = cornerY; j < cornerY + roomHeight - 1; j++) {
			this->getTile(i, j)->setPassable(true);
		}
	}
	freeTiles -= roomWidth * roomHeight;
	
	// Generate more rooms branching off until all freeTiles are used up (kind of...
	// the amount subtracted from freeTiles includes the room's walls, so some
	// overlap between rooms will occur. Practically, this means freeTiles is very
	// likely to drop under 0 before the level is actually full)
	int generatedRooms = 0;
	int failedAttempts = 0; // Keep a counter of failed attempts and abort if it gets too high
	while(freeTiles > 0
		&& failedAttempts < 200) 
	{
		int numNeighbouringPassable = 0;
		int randX = rand() % width;
		int randY = rand() % height;
		int generateDir;

		if(getTile(randX, randY)->passable()) {
			failedAttempts++;
			continue;
		}

		// Never base a new room on a tile directly adjoining the edge of the level
		if(getTile(randX + 1, randY) == NULL
			|| getTile(randX - 1, randY) == NULL
			|| getTile(randX, randY + 1) == NULL
			|| getTile(randX, randY - 1) == NULL) 
		{
			failedAttempts++;
			continue;
		}

		// Check the number of neighbours, and store the relative direction the room should be generated
		// in
		if(getTile(randX + 1, randY)->passable()) {
			numNeighbouringPassable++;
			generateDir = DIR_WEST;
		} else if(getTile(randX - 1, randY)->passable()) {
			numNeighbouringPassable++;
			generateDir = DIR_EAST;
		} else if(getTile(randX, randY + 1)->passable()) {
			numNeighbouringPassable++;
			generateDir = DIR_NORTH;
		} else if(getTile(randX, randY - 1)->passable()) {
			numNeighbouringPassable++;
			generateDir = DIR_SOUTH;
		}

		if(numNeighbouringPassable != 1) {
			continue;
			failedAttempts++;
		}

		// Found a wall with one open neighbour, see if there's room to generate a room on the
		// opposite side of the free space.
		roomWidth = (rand() % roomVariance) + minRoomSize;
		roomHeight = (rand() % roomVariance) + minRoomSize;
		int topLeftX, topLeftY;

		if(generateDir == DIR_WEST) {
			topLeftX = randX - (roomWidth - 1);
			topLeftY = randY - (roomHeight / 2);
		} else if(generateDir == DIR_EAST) {
			topLeftX = randX;
			topLeftY = randY - (roomHeight / 2);
		} else if(generateDir == DIR_NORTH) {
			topLeftX = randX - (roomWidth / 2);
			topLeftY = randY - (roomHeight - 1);
		} else if(generateDir == DIR_SOUTH) {
			topLeftX = randX - (roomWidth / 2);
			topLeftY = randY;
		}

		if(isRectEmpty(topLeftX, topLeftY, roomWidth, roomHeight)) {
			// Space is available, generate the room and add a door
			getTile(randX, randY)->setDoor(true);

			// 50% chance the door is open
			getTile(randX, randY)->setPassable(rand() % 2 == 0);
			
			for(int i = topLeftX + 1; i < topLeftX + roomWidth - 1; i++) {
				for(int j = topLeftY + 1; j < topLeftY + roomHeight - 1; j++) {
					getTile(i, j)->setPassable(true);
				}
			}
			
			generatedRooms++;
			failedAttempts = 0;
			freeTiles -= (roomWidth * roomHeight);
		}
	}
}
Пример #11
0
void House::_tryUpdate_1_to_11_lvl( int level4grow, int startSmallPic, int startBigPic, const char desirability )
{       
  if( getSize() == 1 )
  {
    Tilemap& tmap = _getCity()->getTilemap();
    TilemapTiles area = tmap.getFilledRectangle( getTile().getIJ(), Size(2) );
    bool mayGrow = true;

    foreach( Tile* tile, area )
    {
      if( tile == NULL )
      {
        mayGrow = false;   //some broken, can't grow
        break;
      }

      HousePtr house = tile->getOverlay().as<House>();
      if( house != NULL && house->getLevelSpec().getHouseLevel() == level4grow )
      {
        if( house->getSize().getWidth() > 1 )  //bigger house near, can't grow
        {
          mayGrow = false;
          break;
        }            
      }
      else
      {
        mayGrow = false; //no house near, can't grow
        break;
      }
    }

    if( mayGrow )
    {
      int sumHabitants = getNbHabitants();
      int sumFreeWorkers = _d->freeWorkersCount;
      TilemapTiles::iterator delIt=area.begin();
      HousePtr selfHouse = (*delIt)->getOverlay().as<House>();

      delIt++; //don't remove himself
      for( ; delIt != area.end(); delIt++ )
      {
        HousePtr house = (*delIt)->getOverlay().as<House>();
        if( house.isValid() )
        {
          house->deleteLater();
          house->_d->currentHabitants = 0;

          sumHabitants += house->getNbHabitants();
          sumFreeWorkers += house->_d->freeWorkersCount;

          selfHouse->getGoodStore().storeAll( house->getGoodStore() );
        }
      }

      _d->currentHabitants = sumHabitants;
      _d->freeWorkersCount = sumFreeWorkers;
      _d->houseLevelSpec = HouseSpecHelper::getInstance().getHouseLevelSpec(_d->houseLevel);
      _d->nextHouseLevelSpec = _d->houseLevelSpec.next();

      _update();
      _updateDesirabilityInfluence( Construction::duNegative );
      setSize( getSize() + Size(1) );
      build( _getCity(), getTile().getIJ() );
    }
  }
void Level::setPlayerCharacter(Player * player, int xPos, int yPos) {
	this->player = player;
	player->setPosition(getTile(xPos, yPos));
}
Пример #13
0
frameSprite_* getFrameSprite(unsigned char *image8bpp, int wi, int x, int y, int w, int h)
{
    int i, j;
    int p, pal;
    int index;
    unsigned int tile[8];
    frameSprite_* result;
    tileset_* tileset;

    // get palette for this sprite
    pal = getTile(image8bpp, tile, 0, 0, wi * 8);
    // error retrieving tile --> return NULL
    if (pal == -1) return NULL;

    // allocate tileset
    tileset = createTileSet(malloc(w * h * 32), 0);

    for(i = 0; i < w; i++)
    {
        for(j = 0; j < h; j++)
        {
            p = getTile(image8bpp, tile, i + x, j + y, wi * 8);

            // error retrieving tile --> return NULL
            if (p == -1)
            {
                freeTileset(tileset);
                return NULL;
            }
            // different palette in VDP same sprite --> error
            if (p != pal)
            {
                printf("Error: Sprite at position (%d,%d) of size [%d,%d] reference different palette.", x, y, w, h);
                freeTileset(tileset);
                return NULL;
            }

            index = addTile(tile, tileset, FALSE);
            // error adding new tile --> return NULL
            if (index == -1)
            {
                freeTileset(tileset);
                return NULL;
            }
        }
    }

    // allocate result
    result = malloc(sizeof(frameSprite_));
    // always first index as we
    result->ind = 0;
    result->attr = TILE_ATTR(pal, FALSE, FALSE, FALSE);
    // initialized afterward
    result->x = 0;
	result->y = 0;
    result->w = w;
    result->h = h;
	result->tileset = tileset;

    return result;
}
Пример #14
0
void CMapGenerator::fillZones()
{
	//init native town count with 0
	for (auto faction : VLC->townh->getAllowedFactions())
		zonesPerFaction[faction] = 0;

	findZonesForQuestArts();

	logGlobal->infoStream() << "Started filling zones";

	//initialize possible tiles before any object is actually placed
	for (auto it : zones)
		it.second->initFreeTiles(this);

	createDirectConnections(); //direct
	//make sure all connections are passable before creating borders
	for (auto it : zones)
		it.second->createBorder(this); //once direct connections are done

	createConnections2(); //subterranean gates and monoliths

	//we need info about all town types to evaluate dwellings and pandoras with creatures properly
	for (auto it : zones)
		it.second->initTownType(this);

	std::vector<CRmgTemplateZone*> treasureZones;
	for (auto it : zones)
	{
		it.second->fill(this);
		if (it.second->getType() == ETemplateZoneType::TREASURE)
			treasureZones.push_back(it.second);
	}

	//set apriopriate free/occupied tiles, including blocked underground rock
	createObstaclesCommon1();
	//set back original terrain for underground zones
	for (auto it : zones)
		it.second->createObstacles1(this);
	createObstaclesCommon2();
	//place actual obstacles matching zone terrain
	for (auto it : zones)
	{
		it.second->createObstacles2(this);
	}

	#define PRINT_MAP_BEFORE_ROADS true
	if (PRINT_MAP_BEFORE_ROADS) //enable to debug
	{
		std::ofstream out("road debug");
		int levels = map->twoLevel ? 2 : 1;
		int width = map->width;
		int height = map->height;
		for (int k = 0; k < levels; k++)
		{
			for (int j = 0; j<height; j++)
			{
				for (int i = 0; i<width; i++)
				{
					char t = '?';
					switch (getTile(int3(i, j, k)).getTileType())
					{
					case ETileType::FREE:
						t = ' '; break;
					case ETileType::BLOCKED:
						t = '#'; break;
					case ETileType::POSSIBLE:
						t = '-'; break;
					case ETileType::USED:
						t = 'O'; break;
					}

					out << t;
				}
				out << std::endl;
			}
			out << std::endl;
		}
		out << std::endl;
	}

	for (auto it : zones)
	{
		it.second->connectRoads(this); //draw roads after everything else has been placed
	}

	//find place for Grail
	if (treasureZones.empty())
	{
		for (auto it : zones)
			treasureZones.push_back(it.second);
	}
	auto grailZone = *RandomGeneratorUtil::nextItem(treasureZones, rand);

	map->grailPos = *RandomGeneratorUtil::nextItem(*grailZone->getFreePaths(), rand);

	logGlobal->infoStream() << "Zones filled successfully";
}
Пример #15
0
int msDrawShadeSymbol(mapObj *map, imageObj *image, shapeObj *p, styleObj *style, double scalefactor)
{
  int ret = MS_SUCCESS;
  symbolObj *symbol;
  if (!p)
    return MS_SUCCESS;
  if (p->numlines <= 0)
    return MS_SUCCESS;

  if (style->symbol >= map->symbolset.numsymbols || style->symbol < 0)
    return MS_SUCCESS; /* no such symbol, 0 is OK */
  symbol = map->symbolset.symbol[style->symbol];

  /*
   * if only an outlinecolor was defined, and not a color,
   * switch to the line drawing function
   *
   * this behavior is kind of a mapfile hack, and must be
   * kept for backwards compatibility
   */
  if (symbol->type != MS_SYMBOL_PIXMAP && symbol->type != MS_SYMBOL_SVG ) {
    if (!MS_VALID_COLOR(style->color)) {
      if(MS_VALID_COLOR(style->outlinecolor))
        return msDrawLineSymbol(map, image, p, style, scalefactor);
      else {
        /* just do nothing if no color has been set */
        return MS_SUCCESS;
      }
    }
  }
  if (image) {
    if (MS_RENDERER_PLUGIN(image->format)) {
      rendererVTableObj *renderer = image->format->vtable;
      shapeObj *offsetPolygon = NULL;
      /* store a reference to the renderer to be used for freeing */
      if(style->symbol)
        symbol->renderer = renderer;

      if (style->offsetx != 0 || style->offsety != 0) {
        if(style->offsety==MS_STYLE_SINGLE_SIDED_OFFSET) {
          offsetPolygon = msOffsetPolyline(p, style->offsetx*scalefactor, MS_STYLE_SINGLE_SIDED_OFFSET);
        } else if(style->offsety==MS_STYLE_DOUBLE_SIDED_OFFSET) {
          offsetPolygon = msOffsetPolyline(p,style->offsetx * scalefactor ,MS_STYLE_DOUBLE_SIDED_OFFSET);
        } else {
          offsetPolygon = msOffsetPolyline(p, style->offsetx*scalefactor,style->offsety*scalefactor);
        }
      } else {
        offsetPolygon=p;
      }
      /* simple polygon drawing, without any specific symbol.
       * also draws an optional outline */
      if(style->symbol == 0 || symbol->type == MS_SYMBOL_SIMPLE) {
        ret = renderer->renderPolygon(image,offsetPolygon,&style->color);
        if(ret != MS_SUCCESS) goto cleanup;
        if(MS_VALID_COLOR(style->outlinecolor)) {
          strokeStyleObj s;
          INIT_STROKE_STYLE(s);
          s.color = &style->outlinecolor;
          s.color->alpha = style->color.alpha;
          s.width = (style->width == 0)?scalefactor:style->width*scalefactor;
          s.width = MS_MIN(s.width, style->maxwidth);
          s.width = MS_MAX(s.width, style->minwidth);
          ret = renderer->renderLine(image,offsetPolygon,&s);
        }
        goto cleanup; /*finished plain polygon*/
      } else if(symbol->type == MS_SYMBOL_HATCH) {
        double width, spacing;
        double pattern[MS_MAXPATTERNLENGTH];
        int i;

        if(MS_VALID_COLOR(style->backgroundcolor)) {
          ret = renderer->renderPolygon(image,offsetPolygon, &style->backgroundcolor);
          if(ret != MS_SUCCESS) goto cleanup;
        }
        width = (style->width <= 0)?scalefactor:style->width*scalefactor;
        width = MS_MIN(width, style->maxwidth*image->resolutionfactor);
        width = MS_MAX(width, style->minwidth*image->resolutionfactor);
        spacing = (style->size <= 0)?scalefactor:style->size*scalefactor;
        spacing = MS_MIN(spacing, style->maxsize*image->resolutionfactor);
        spacing = MS_MAX(spacing, style->minsize*image->resolutionfactor);

        /* scale the pattern by the factor applied to the width */
        for(i=0; i<style->patternlength; i++) {
          pattern[i] = style->pattern[i]*width/style->width;
        }

        ret = msHatchPolygon(image,offsetPolygon,spacing,width,pattern,style->patternlength,style->angle, &style->color);
        goto cleanup;
      } else {
        symbolStyleObj s;
        int pw,ph;
        imageObj *tile;
        int seamless = 0;

        if(preloadSymbol(&map->symbolset,symbol,renderer) != MS_SUCCESS) {
          return MS_FAILURE;
        }

        INIT_SYMBOL_STYLE(s);
        computeSymbolStyle(&s,style,symbol,scalefactor,image->resolutionfactor);
        s.style = style;

        if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP && symbol->type != MS_SYMBOL_SVG) {
          ret = MS_SUCCESS; /* nothing to do (colors are required except for PIXMAP symbols */
          goto cleanup;
        }

        if(s.backgroundcolor) {
          ret = renderer->renderPolygon(image,offsetPolygon, s.backgroundcolor);
          if(ret != MS_SUCCESS) goto cleanup;
        }

        if(s.scale != 1) {
          if (s.gap > 0) {
            pw = MS_MAX(MS_NINT(s.gap),symbol->sizex * s.scale);
            ph = MS_MAX(MS_NINT(s.gap),symbol->sizey * s.scale);
          } else {
            pw = MS_NINT(symbol->sizex * s.scale);
            ph = MS_NINT(symbol->sizey * s.scale);
          }
        } else {
          if (s.gap > 0) {
            pw = MS_MAX(s.gap,symbol->sizex);
            ph = MS_MAX(s.gap,symbol->sizey);
          } else {
            pw = symbol->sizex;
            ph = symbol->sizey;
          }
        }
        if(pw<1) pw=1;
        if(ph<1) ph=1;

        /* if we're doing vector symbols with an antialiased pixel rendererer, we want to enable
         * seamless mode, i.e. comute a tile that accounts for the blending of neighbouring
         * tiles at the tile border
         */
        if(symbol->type == MS_SYMBOL_VECTOR && style->gap == 0 &&
            (image->format->renderer == MS_RENDER_WITH_AGG ||
             image->format->renderer == MS_RENDER_WITH_CAIRO_RASTER)) {
          seamless = 1;
        }
        tile = getTile(image,symbol,&s,pw,ph,seamless);
        ret = renderer->renderPolygonTiled(image,offsetPolygon, tile);
      }

cleanup:
      if (offsetPolygon != p) {
        msFreeShape(offsetPolygon);
        msFree(offsetPolygon);
      }
      return ret;
    } else if( MS_RENDERER_IMAGEMAP(image->format) )
      msDrawShadeSymbolIM(map, image, p, style, scalefactor);
  }
  return ret;
}
Пример #16
0
void Construction::burn()
{
   deleteLater();
   Scenario::instance().getCity().disaster( getTile().getIJ(), DSTR_BURN );
}
Пример #17
0
int msDrawMarkerSymbol(mapObj *map, imageObj *image, pointObj *p, styleObj *style,
                       double scalefactor)
{
  int ret = MS_SUCCESS;
  if (!p)
    return MS_SUCCESS;
  if (style->symbol >= map->symbolset.numsymbols || style->symbol <= 0)
    return MS_SUCCESS; /* no such symbol, 0 is OK   */

  if (image) {
    if(MS_RENDERER_PLUGIN(image->format)) {
      rendererVTableObj *renderer = image->format->vtable;
      symbolStyleObj s;
      double p_x,p_y;
      symbolObj *symbol = map->symbolset.symbol[style->symbol];
      /* store a reference to the renderer to be used for freeing */
      symbol->renderer = renderer;
      if(preloadSymbol(&map->symbolset,symbol,renderer) != MS_SUCCESS) {
        return MS_FAILURE;
      }

      computeSymbolStyle(&s,style,symbol,scalefactor,image->resolutionfactor);
      s.style = style;
      if (!s.color && !s.outlinecolor && symbol->type != MS_SYMBOL_PIXMAP &&
          symbol->type != MS_SYMBOL_SVG) {
        return MS_SUCCESS; // nothing to do if no color, except for pixmap symbols
      }
      if(s.scale == 0) {
        return MS_SUCCESS;
      }



      /* TODO: skip the drawing of the symbol if it's smaller than a pixel ?
      if (s.size < 1)
       return; // size too small
       */

      p_x = p->x;
      p_y = p->y;

      if (style->polaroffsetpixel != 0 ||
          style->polaroffsetangle != 0) {
        double angle = style->polaroffsetangle * MS_DEG_TO_RAD;
        p_x +=  (style->polaroffsetpixel * cos(-angle)) * scalefactor;
        p_y +=  (style->polaroffsetpixel * sin(-angle)) * scalefactor;
      }

      p_x +=  style->offsetx * scalefactor;
      p_y +=  style->offsety * scalefactor;

      if(symbol->anchorpoint_x != 0.5 || symbol->anchorpoint_y != 0.5) {
        double sx,sy;
        double ox, oy;
        if(UNLIKELY(MS_FAILURE == msGetMarkerSize(map, style, &sx, &sy, scalefactor))) {
          return MS_FAILURE;
        }
        ox = (0.5 - symbol->anchorpoint_x) * sx;
        oy = (0.5 - symbol->anchorpoint_y) * sy;
        if(s.rotation != 0) {
          double sina, cosa;
          double rox,roy;
          sina = sin(-s.rotation);
          cosa = cos(-s.rotation);
          rox = ox * cosa - oy * sina;
          roy = ox * sina + oy * cosa;
          p_x += rox;
          p_y += roy;
        } else {
          p_x += ox;
          p_y += oy;
        }
      }

      if(renderer->use_imagecache) {
        imageObj *tile = getTile(image, symbol, &s, -1, -1,0);
        if(tile!=NULL)
          return renderer->renderTile(image, tile, p_x, p_y);
        else {
          msSetError(MS_RENDERERERR, "problem creating cached tile", "msDrawMarkerSymbol()");
          return MS_FAILURE;
        }
      }
      switch (symbol->type) {
        case (MS_SYMBOL_TRUETYPE): {
          unsigned int unicode;
          glyph_element *glyphc;
          face_element *face = msGetFontFace(symbol->font, &map->fontset);
          if(UNLIKELY(!face)) return MS_FAILURE;
          msUTF8ToUniChar(symbol->character,&unicode);
          unicode = msGetGlyphIndex(face,unicode);
          glyphc = msGetGlyphByIndex(face,s.scale,unicode);
          if(UNLIKELY(!glyphc)) return MS_FAILURE;
          ret = drawGlyphMarker(image, face, glyphc, p_x, p_y, s.scale, s.rotation, s.color, s.outlinecolor, s.outlinewidth);
        }
        break;
        case (MS_SYMBOL_PIXMAP): {
          assert(symbol->pixmap_buffer);
          ret = renderer->renderPixmapSymbol(image,p_x,p_y,symbol,&s);
        }
        break;
        case (MS_SYMBOL_ELLIPSE): {
          ret = renderer->renderEllipseSymbol(image, p_x, p_y,symbol, &s);
        }
        break;
        case (MS_SYMBOL_VECTOR): {
          ret = renderer->renderVectorSymbol(image, p_x, p_y, symbol, &s);
        }
        break;
        case (MS_SYMBOL_SVG): {
          if (renderer->supports_svg) {
            ret = renderer->renderSVGSymbol(image, p_x, p_y, symbol, &s);
          } else {
#if defined(USE_SVG_CAIRO) || defined(USE_RSVG)
            ret = msRenderRasterizedSVGSymbol(image, p_x,p_y, symbol, &s);
#else
            msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msDrawMarkerSymbol()");
            return MS_FAILURE;
#endif
          }
        }
        break;
        default:
          break;
      }
      return ret;
    } else if( MS_RENDERER_IMAGEMAP(image->format) )
      msDrawMarkerSymbolIM(map, image, p, style, scalefactor);

  }
  return ret;
}
Пример #18
0
void Construction::collapse()
{
   deleteLater();
   Scenario::instance().getCity().disaster( getTile().getIJ(), DSTR_COLLAPSE );
}
Пример #19
0
/* Get tile index for tile behind sprite. */
uint8_t getSpriteLadderTile(uint8_t slot) {
	return getTile(getSpriteTileX(slot,0),getSpriteTileY(slot,-1));
}
Пример #20
0
void MapLayer::draw(Graphics *graphics,
                    int startX, int startY,
                    int endX, int endY,
                    int scrollX, int scrollY,
                    const Actors &actors, int debugFlags) const
{
    startX -= mX;
    startY -= mY;
    endX -= mX;
    endY -= mY;

    if (startX < 0) startX = 0;
    if (startY < 0) startY = 0;
    if (endX > mWidth) endX = mWidth;
    if (endY > mHeight) endY = mHeight;

    Actors::const_iterator ai = actors.begin();

    int dx = (mX * mMap->getTileWidth()) - scrollX;
    int dy = (mY * mMap->getTileHeight()) - scrollY + mMap->getTileHeight();

    for (int y = startY; y < endY; y++)
    {
        int pixelY = y * mMap->getTileHeight();

        // If drawing the fringe layer, make sure all actors above this row of
        // tiles have been drawn
        if (mIsFringeLayer)
        {
            while (ai != actors.end() && (*ai)->getPixelY()
                   <= y * mMap->getTileHeight())
            {
                (*ai)->draw(graphics, -scrollX, -scrollY);
                ++ai;
            }
        }

        if (!(debugFlags & Map::MAP_SPECIAL3))
        {
            const int py0 = pixelY + dy;

            for (int x = startX; x < endX; x++)
            {
                Image *img = getTile(x, y);
                if (img)
                {
                    const int px = (x * mMap->getTileWidth()) + dx;
                    const int py = py0 - img->getHeight();
                    if (!(debugFlags & (Map::MAP_SPECIAL1 | Map::MAP_SPECIAL2))
                        || img->getHeight() <= mMap->getTileHeight())
                    {
                        int width = 0;
                        int c = getTileDrawWidth(x, y, endX, width);
                        if (!c)
                        {
                            graphics->drawImage(img, px, py);
                        }
                        else
                        {
                            graphics->drawImagePattern(img, px, py,
                                width, img->getHeight());
                        }
                        x += c;
                    }
                }
            }
        }
    }

    // Draw any remaining actors
    if (mIsFringeLayer)
    {
        while (ai != actors.end())
        {
            (*ai)->draw(graphics, -scrollX, -scrollY);
            ai++;
        }
    }
}
Пример #21
0
/**
 * Get a widget at a position in the layout.
 * @param row :: The row of the tile
 * @param col :: The column of the tile
 * @return :: A pointer to the MdiSubWindow at this position or NULL if the tile
 * is empty.
 */
MdiSubWindow *TiledWindow::getWidget(int row, int col) {
  Tile *tile = getTile(row, col);
  return tile->widget();
}
Пример #22
0
//--------------------------------------------------------------
void ofApp::update(){
	//clear and update the renderer
	spriteRenderer->clear();
	spriteRenderer->update(ofGetElapsedTimeMillis());
	
	//add the Link sprite to the renderer.
	spriteRenderer->addCenteredTile(&player->animation, player->pos.x - cameraCenter.x, player->pos.y - cameraCenter.y, 1, F_NONE, SCALE);
	
	//if there are backgrounds, loop through it and add each one to the renderer.
	if (backgrounds.size() > 0) {
		for (int i = backgrounds.size()-1; i>=0; i--) {
			//this line isn't necessary and in fact is imperfect, but uncomment to see how we might limit drawing to only the current screen area.
			//if (backgrounds[i]->pos.x > 0 && backgrounds[i]->pos.x < ofGetWindowWidth() && backgrounds[i]->pos.y > 0 && backgrounds[i]->pos.y < ofGetWindowHeight()) {
			spriteRenderer->addCenteredTile(backgrounds[i]->tileName, 0, backgrounds[i]->pos.x, backgrounds[i]->pos.y, 0, 1, 1, F_NONE, SCALE);
			//}
		}
	}
	
	//update the background position based on the grid and the camera position.
	for (int i = 0; i < GRIDH; i++) {
		for (int j = 0; j < GRIDW; j++) {
			backgrounds[i * GRIDW + j]->pos.set(j*spriteRenderer->getTileSize()*SCALE - cameraCenter.x, i*spriteRenderer->getTileSize()*SCALE - cameraCenter.y);
		}
	}
	
	//update the player's position and animation index based on key presses.
	int runModifier = runPressed ? 2 : 1;
	
	ofPoint newPos = player->pos;
	
	if (leftPressed) {
		newPos.x -= player->speed * runModifier * spriteRenderer->getTileSize()*SCALE;
		player->animation.index = 4;
	}
	if (rightPressed) {
		newPos.x += player->speed * runModifier * spriteRenderer->getTileSize()*SCALE;
		player->animation.index = 2;
	}
	if (upPressed) {
		newPos.y -= player->speed * runModifier * spriteRenderer->getTileSize()*SCALE;
		player->animation.index = 0;
	}
	if (downPressed) {
		newPos.y += player->speed * runModifier * spriteRenderer->getTileSize()*SCALE;
		player->animation.index = 6;
	}
	
	//if no keys are being pressed, stop animating.
	//if keys are being pressed, animate Link's sprite.
	if (!leftPressed && !rightPressed && !upPressed && !downPressed) {
		player->animation.loops = 0;
	} else {
		player->animation.loops = -1;
		
		//this is an application of how we could check the player's position against the tiles.
		//we could use this approach to do collision detection for example.
		
		float xAdj = player->pos.x > newPos.x
			? (spriteRenderer->getTileSize() * SCALE) / 2
			: (spriteRenderer->getTileSize() * SCALE) / 2;
		float yAdj = player->pos.y > newPos.y
			? (spriteRenderer->getTileSize() * SCALE) / 2
			: (spriteRenderer->getTileSize() * SCALE) / 2;

		int tilePosX = floor((newPos.x + (spriteRenderer->getTileSize() * SCALE) / 2) / (spriteRenderer->getTileSize() * SCALE));
		int tilePosY = floor((newPos.y + (spriteRenderer->getTileSize() * SCALE) / 2) / (spriteRenderer->getTileSize() * SCALE));

		
		
		basicSprite* tile = getTile(tilePosX, tilePosY);
		if (tile != NULL) {
			if (!tile->isWall) {
				player->pos = newPos;
				wallBreaktimer = 0;
			} else {
				wallBreaktimer++;
				if (wallBreaktimer > wallBreaktimerDuration) {
					wallBreaktimer = 0;
					tile->isWall = false;
					tile->tileName = (int)ofRandom(8,11);
				}
			}
		} else {
			player->pos = newPos;
			wallBreaktimer = 0;
		}
		
		
		cout << "pos.x relative to tiles: " <<  tilePosX << ", pos.y relative to tiles: " <<  tilePosY << endl;
		
		cout << "background sprite index: " << getTileName(tilePosX, tilePosY) << endl;
	}
	
	//update the camera position to focus on the player's position.
	cameraCenter.x = player->pos.x - ofGetWindowWidth()/2;
	cameraCenter.y = player->pos.y - ofGetWindowHeight()/2;
}
Пример #23
0
bool BaseAI::startTurn()
{
  static bool initialized = false;
  int count = 0;
  count = getPlayerCount(c);
  players.clear();
  players.resize(count);
  for(int i = 0; i < count; i++)
  {
    players[i] = Player(getPlayer(c, i));
  }

  count = getMappableCount(c);
  mappables.clear();
  mappables.resize(count);
  for(int i = 0; i < count; i++)
  {
    mappables[i] = Mappable(getMappable(c, i));
  }

  count = getTileCount(c);
  tiles.clear();
  tiles.resize(count);
  for(int i = 0; i < count; i++)
  {
    tiles[i] = Tile(getTile(c, i));
  }

  count = getTrapCount(c);
  traps.clear();
  traps.resize(count);
  for(int i = 0; i < count; i++)
  {
    traps[i] = Trap(getTrap(c, i));
  }

  count = getThiefCount(c);
  thiefs.clear();
  thiefs.resize(count);
  for(int i = 0; i < count; i++)
  {
    thiefs[i] = Thief(getThief(c, i));
  }

  count = getThiefTypeCount(c);
  thiefTypes.clear();
  thiefTypes.resize(count);
  for(int i = 0; i < count; i++)
  {
    thiefTypes[i] = ThiefType(getThiefType(c, i));
  }

  count = getTrapTypeCount(c);
  trapTypes.clear();
  trapTypes.resize(count);
  for(int i = 0; i < count; i++)
  {
    trapTypes[i] = TrapType(getTrapType(c, i));
  }

  if(!initialized)
  {
    initialized = true;
    init();
  }
  return run();
}
Пример #24
0
void Item::calculatePatterns(int& xPattern, int& yPattern, int& zPattern)
{
    if(isStackable() && getNumPatternX() == 4 && getNumPatternY() == 2) {
        if(m_countOrSubType <= 0) {
            xPattern = 0;
            yPattern = 0;
        } else if(m_countOrSubType < 5) {
            xPattern = m_countOrSubType-1;
            yPattern = 0;
        } else if(m_countOrSubType < 10) {
            xPattern = 0;
            yPattern = 1;
        } else if(m_countOrSubType < 25) {
            xPattern = 1;
            yPattern = 1;
        } else if(m_countOrSubType < 50) {
            xPattern = 2;
            yPattern = 1;
        } else {
            xPattern = 3;
            yPattern = 1;
        }
    } else if(isHangable()) {
        const TilePtr& tile = getTile();
        if(tile) {
            if(tile->mustHookSouth())
                xPattern = getNumPatternX() >= 2 ? 1 : 0;
            else if(tile->mustHookEast())
                xPattern = getNumPatternX() >= 3 ? 2 : 0;
        }
    } else if(isSplash() || isFluidContainer()) {
        int color = Otc::FluidTransparent;
        switch(m_countOrSubType) {
            case Otc::FluidNone:
                color = Otc::FluidTransparent;
                break;
            case Otc::FluidWater:
                color = Otc::FluidBlue;
                break;
            case Otc::FluidMana:
                color = Otc::FluidPurple;
                break;
            case Otc::FluidBeer:
                color = Otc::FluidBrown;
                break;
            case Otc::FluidOil:
                color = Otc::FluidBrown;
                break;
            case Otc::FluidBlood:
                color = Otc::FluidRed;
                break;
            case Otc::FluidSlime:
                color = Otc::FluidGreen;
                break;
            case Otc::FluidMud:
                color = Otc::FluidBrown;
                break;
            case Otc::FluidLemonade:
                color = Otc::FluidYellow;
                break;
            case Otc::FluidMilk:
                color = Otc::FluidWhite;
                break;
            case Otc::FluidWine:
                color = Otc::FluidPurple;
                break;
            case Otc::FluidHealth:
                color = Otc::FluidRed;
                break;
            case Otc::FluidUrine:
                color = Otc::FluidYellow;
                break;
            case Otc::FluidRum:
                color = Otc::FluidBrown;
                break;
            case Otc::FluidFruidJuice:
                color = Otc::FluidYellow;
                break;
            case Otc::FluidCoconutMilk:
                color = Otc::FluidWhite;
                break;
            case Otc::FluidTea:
                color = Otc::FluidBrown;
                break;
            case Otc::FluidMead:
                color = Otc::FluidBrown;
                break;
            default:
                color = Otc::FluidTransparent;
                break;
        }

        xPattern = (color % 4) % getNumPatternX();
        yPattern = (color / 4) % getNumPatternY();
    } else if(isGround() || isOnBottom()) {
        xPattern = m_position.x % getNumPatternX();
        yPattern = m_position.y % getNumPatternY();
        zPattern = m_position.z % getNumPatternZ();
    }
}
Пример #25
0
void TileManager::update()
{
    static Tile * clicked = nullptr;

    //the mouse in the window.
    sf::Vector2i mousePos = Controller::mousePosition;

	Scene & scene = Scene::instance();
	sf::Vector2f worldMousePos = scene.getWindow().mapPixelToCoords(mousePos, scene.getView());

    //transform the mouse position in to tile space
    sf::Vector2f transformedPosition = tiledWorld_->getTransform().getInverse().transformPoint(worldMousePos.x, worldMousePos.y);

    sf::Vector2i coordinates = sf::Vector2i(transformedPosition.x / getTileSize().x, transformedPosition.y / getTileSize().y);

    if(coordinatesAreIn(coordinates))
    {
    	//the tile that the mouse is currently hovering over
        Tile * hoverTile = getTile(coordinates);
        assert(hoverTile != nullptr);
        if(Controller::getButton(sf::Mouse::Button::Right))
        {
            for(auto * tile : hoverTile->getAllNeighbours())
            {
                tile->setColor(sf::Color::Red);
                tile->setText("");
                coloredTiles_.push_back(tile);
            }
        }

        if(Controller::getButton(sf::Mouse::Button::Middle))
		{
			if(Controller::getKey(sf::Keyboard::Key::LShift))hoverTile->setTraversable(true);
			else hoverTile->setTraversable(false);
			hoverTile->recolor();
		}


        if(Controller::getButtonDown(sf::Mouse::Button::Left))
        {
            clicked = getTile(coordinates);
        }
        else if(Controller::getButtonUp(sf::Mouse::Button::Left) && clicked != nullptr)
        {
            TileManager::instance().forEachTile([](Tile & tile)
            {
                tile.g_ = 0;
                tile.h_ = 0;
                tile.f_ = 0;
                tile.recolor();
                tile.setText("");
            });

            path_ = Pathfinder::instance().getPath(clicked, hoverTile);
            clicked = nullptr;



         //   auto steps = path.size();

            TileManager::instance().forEachTile([&](Tile & tile)
            {
                std::stringstream sstream;
				if(tile.f_ > 0)
				{
					sstream << tile.g_ << "\n" << tile.h_ << "\n" << tile.f_;
					tile.setText(sstream.str());
				}

                //tile.setColor(sf::Color(r, g, b));
            }
                                               );

            for(auto * pn : path_)
            {
                auto * tile = static_cast<Tile*>(pn);

				tile->setColor(sf::Color::Yellow);
                //coloredTiles_.push_back(tile);
            }

        }

		Scene::instance().debugText_.setString(hoverTile->getTilePropertiesString());

    }

}
Пример #26
0
void TileMap::draw(BITMAP* dest, int scrollX, int scrollY, unsigned int layer)
{
    if (!mShowForegroundLayer && layer == FOREGROUND_LAYER)
    {
        return;
    }

    if (!mShowBackgroundLayer && layer == BACKGROUND_LAYER)
    {
        return;
    }

    if (!mShowEntities && layer == ENTITY_LAYER)
    {
        return;
    }

    int tileMapX = scrollX / 16;

    if (tileMapX < 0)
    {
        tileMapX = 0;
    }

    int tileMapY = scrollY / 16;

    // We ignore the first line as it's not a part of the tilemap.
    if (tileMapY < 0)
    {
        tileMapY = 0;
    }

    int tileMapEndX = scrollX / 16 + dest->w / 16 + 1;

    if (tileMapEndX > getWidth())
    {
        tileMapEndX = getWidth();
    }

    int tileMapEndY = scrollY / 16 + dest->h / 16 + 1;

    if (tileMapEndY > getHeight())
    {
        tileMapEndY = getHeight();
    }

    int y;
    for (y = tileMapY; y < tileMapEndY; y++)
    {
        int x;
        for (x = tileMapX; x< tileMapEndX; x++)
        {
            if (layer == ENTITY_LAYER)
            {
                int g = getTileEntity(x, y);

                if (g != 0)
                {
                    drawEntity(dest,
                               x * 16 - scrollX,
                               y * 16 - scrollY,
                               g);
                }
            }
            else
            {
                int r = getTile(x, y);

                int b = getTileFlags(x, y);

                bool drawInLayer = (layer == FOREGROUND_LAYER && !(b & BACKGROUND)
                                    || (layer == BACKGROUND_LAYER && (b & BACKGROUND)));

                if (r != 0 && drawInLayer)
                {
                    drawTile(dest,
                             x * 16 - scrollX,
                             y * 16 - scrollY,
                             r);
                }

                if (mShowSolidity)
                {
                    drawFlags(dest,
                              x * 16 - scrollX,
                              y * 16 - scrollY,
                              b);
                }
            }
        }
    }
}
Пример #27
0
const Tile*
TileGrid::getTile(rcoord virt) const noexcept {
    return getTile(virt2phys(virt));
}
Пример #28
0
int msDrawLineSymbol(mapObj *map, imageObj *image, shapeObj *p,
                     styleObj *style, double scalefactor)
{
  int status = MS_SUCCESS;
  if (image) {
    if (MS_RENDERER_PLUGIN(image->format)) {
      rendererVTableObj *renderer = image->format->vtable;
      symbolObj *symbol;
      shapeObj *offsetLine = p;
      int i;
      double width;
      double finalscalefactor;

      if (p->numlines == 0)
        return MS_SUCCESS;

      if (style->symbol >= map->symbolset.numsymbols || style->symbol < 0)
        return MS_SUCCESS; /* no such symbol, 0 is OK   */

      symbol = map->symbolset.symbol[style->symbol];
      /* store a reference to the renderer to be used for freeing */
      symbol->renderer = renderer;

      width = style->width * scalefactor;
      width = MS_MIN(width,style->maxwidth*image->resolutionfactor);
      width = MS_MAX(width,style->minwidth*image->resolutionfactor);
      if(style->width != 0) {
        finalscalefactor = width / style->width;
      } else {
        finalscalefactor = 1.0;
      }

      if(style->offsety==MS_STYLE_SINGLE_SIDED_OFFSET) {
        offsetLine = msOffsetPolyline(p,style->offsetx * finalscalefactor ,MS_STYLE_SINGLE_SIDED_OFFSET);
      } else if(style->offsety==MS_STYLE_DOUBLE_SIDED_OFFSET) {
        offsetLine = msOffsetPolyline(p,style->offsetx * finalscalefactor ,MS_STYLE_DOUBLE_SIDED_OFFSET);
      } else if(style->offsetx!=0 || style->offsety!=0) {
        offsetLine = msOffsetPolyline(p, style->offsetx * finalscalefactor,
                                      style->offsety * finalscalefactor);
      }
      if(style->symbol == 0 || (symbol->type==MS_SYMBOL_SIMPLE)) {
        strokeStyleObj s;
        s.linecap = style->linecap;
        s.linejoin = style->linejoin;
        s.linejoinmaxsize = style->linejoinmaxsize;
        s.width = width;
        s.patternlength = style->patternlength;
        for(i=0; i<s.patternlength; i++)
          s.pattern[i] = style->pattern[i] * finalscalefactor;
        s.patternoffset = (style->initialgap<=0) ? 0 : (style->initialgap * finalscalefactor);

        if(MS_VALID_COLOR(style->color))
          s.color = &style->color;
        else if(MS_VALID_COLOR(style->outlinecolor))
          s.color = &style->outlinecolor;
        else {
          /* msSetError(MS_MISCERR,"no color defined for line styling","msDrawLineSymbol()");
           * not really an error */
          status = MS_SUCCESS;
          goto draw_line_cleanup;
        }
        status = renderer->renderLine(image,offsetLine,&s);
      } else {
        symbolStyleObj s;
        if(preloadSymbol(&map->symbolset, symbol, renderer) != MS_SUCCESS) {
          return MS_FAILURE;
        }

        INIT_SYMBOL_STYLE(s);
        computeSymbolStyle(&s,style,symbol,scalefactor,image->resolutionfactor);
        s.style = style;

        /* compute a markerStyle and use it on the line */
        if(style->gap<0) {
          /* special function that treats any other symbol used as a marker, not a brush */
          status = msImagePolylineMarkers(image,offsetLine,symbol,&s,-s.gap,
                                 style->initialgap * finalscalefactor, 1);
        } else if(style->gap>0) {
          status = msImagePolylineMarkers(image,offsetLine,symbol,&s,s.gap,
                                 style->initialgap * finalscalefactor,0);
        } else {
          if(renderer->renderLineTiled != NULL) {
            int pw,ph;
            imageObj* tile=NULL;
            if(s.scale != 1) {
              pw = MS_NINT(symbol->sizex * s.scale);
              ph = MS_NINT(symbol->sizey * s.scale);
            } else {
              pw = symbol->sizex;
              ph = symbol->sizey;
            }
            if(pw<1) pw=1;
            if(ph<1) ph=1;
            tile = getTile(image, symbol,&s,pw,ph,0);
            status = renderer->renderLineTiled(image, offsetLine, tile);
          } else {
            msSetError(MS_RENDERERERR, "renderer does not support brushed lines", "msDrawLineSymbol()");
            status = MS_FAILURE;
          }
        }
      }

draw_line_cleanup:
      if(offsetLine!=p) {
        msFreeShape(offsetLine);
        msFree(offsetLine);
      }
    } else if( MS_RENDERER_IMAGEMAP(image->format) )
      msDrawLineSymbolIM(map, image, p, style, scalefactor);
    else {
      msSetError(MS_RENDERERERR, "unsupported renderer", "msDrawShadeSymbol()");
      status = MS_FAILURE;
    }
  } else {
    status = MS_FAILURE;
  }
  return status;
}
Пример #29
0
/*
this functions returns one target tile or invalid tile. We will use it to poll possible destinations
For ship construction etc, another function (goal?) is needed
*/
int3 SectorMap::firstTileToGet(HeroPtr h, crint3 dst)
{
	int3 ret(-1, -1, -1);

	int sourceSector = retrieveTile(h->visitablePos());
	int destinationSector = retrieveTile(dst);

	const Sector * src = &infoOnSectors[sourceSector];
	const Sector * dest = &infoOnSectors[destinationSector];

	if (sourceSector != destinationSector) //use ships, shipyards etc..
	{
		if (ai->isAccessibleForHero(dst, h)) //pathfinder can find a way using ships and gates if tile is not blocked by objects
			return dst;

		std::map<const Sector *, const Sector *> preds;
		std::queue<const Sector *> sectorQueue;
		sectorQueue.push(src);
		while (!sectorQueue.empty())
		{
			const Sector * s = sectorQueue.front();
			sectorQueue.pop();

			for (int3 ep : s->embarkmentPoints)
			{
				Sector * neigh = &infoOnSectors[retrieveTile(ep)];
				//preds[s].push_back(neigh);
				if (!preds[neigh])
				{
					preds[neigh] = s;
					sectorQueue.push(neigh);
				}
			}
		}

		if (!preds[dest])
		{
			//write("test.txt");

			return ret;
			//throw cannotFulfillGoalException(boost::str(boost::format("Cannot find connection between sectors %d and %d") % src->id % dst->id));
		}

		std::vector<const Sector *> toTraverse;
		toTraverse.push_back(dest);
		while (toTraverse.back() != src)
		{
			toTraverse.push_back(preds[toTraverse.back()]);
		}

		if (preds[dest])
		{
			//TODO: would be nice to find sectors in loop
			const Sector * sectorToReach = toTraverse.at(toTraverse.size() - 2);

			if (!src->water && sectorToReach->water) //embark
			{
				//embark on ship -> look for an EP with a boat
				auto firstEP = boost::find_if(src->embarkmentPoints, [=](crint3 pos) -> bool
				{
					const TerrainTile * t = getTile(pos);
					if (t && t->visitableObjects.size() == 1 && t->topVisitableId() == Obj::BOAT)
					{
						if (retrieveTile(pos) == sectorToReach->id)
							return true;
					}
					return false;
				});

				if (firstEP != src->embarkmentPoints.end())
				{
					return *firstEP;
				}
				else
				{
					//we need to find a shipyard with an access to the desired sector's EP
					//TODO what about Summon Boat spell?
					std::vector<const IShipyard *> shipyards;
					for (const CGTownInstance * t : cb->getTownsInfo())
					{
						if (t->hasBuilt(BuildingID::SHIPYARD))
							shipyards.push_back(t);
					}

					for (const CGObjectInstance * obj : ai->getFlaggedObjects())
					{
						if (obj->ID != Obj::TOWN) //towns were handled in the previous loop
						{
							if (const IShipyard * shipyard = IShipyard::castFrom(obj))
								shipyards.push_back(shipyard);
						}
					}

					shipyards.erase(boost::remove_if(shipyards, [=](const IShipyard * shipyard) -> bool
					{
						return shipyard->shipyardStatus() != 0 || retrieveTile(shipyard->bestLocation()) != sectorToReach->id;
					}), shipyards.end());

					if (!shipyards.size())
					{
						//TODO consider possibility of building shipyard in a town
						return ret;

						//throw cannotFulfillGoalException("There is no known shipyard!");
					}

					//we have only shipyards that possibly can build ships onto the appropriate EP
					auto ownedGoodShipyard = boost::find_if(shipyards, [](const IShipyard * s) -> bool
					{
						return s->o->tempOwner == ai->playerID;
					});

					if (ownedGoodShipyard != shipyards.end())
					{
						const IShipyard * s = *ownedGoodShipyard;
						TResources shipCost;
						s->getBoatCost(shipCost);
						if (cb->getResourceAmount().canAfford(shipCost))
						{
							int3 ret = s->bestLocation();
							cb->buildBoat(s); //TODO: move actions elsewhere
							return ret;
						}
						else
						{
							//TODO gather res
							return ret;

							//throw cannotFulfillGoalException("Not enough resources to build a boat");
						}
					}
					else
					{
						//TODO pick best shipyard to take over
						return shipyards.front()->o->visitablePos();
					}
				}
			}
			else if (src->water && !sectorToReach->water)
			{
				//TODO
				//disembark
				return ret;
			}
			else //use subterranean gates - not needed since gates are now handled via Pathfinder
			{
				return ret;
				//throw cannotFulfillGoalException("Land-land and water-water inter-sector transitions are not implemented!");
			}
		}
		else
		{
			return ret;
			//throw cannotFulfillGoalException("Inter-sector route detection failed: not connected sectors?");
		}
	}
	else //tiles are in same sector
	{
		return findFirstVisitableTile(h, dst);
	}
}
Пример #30
0
void Map::loadOtbm(const std::string& fileName)
{
    try {
        if(!g_things.isOtbLoaded())
            stdext::throw_exception("OTB isn't loaded yet to load a map.");

        FileStreamPtr fin = g_resources.openFile(fileName);
        if(!fin)
            stdext::throw_exception(stdext::format("Unable to load map '%s'", fileName));
        fin->cache();

        char identifier[4];
        if(fin->read(identifier, 1, 4) < 4)
            stdext::throw_exception("Could not read file identifier");

        if(memcmp(identifier, "OTBM", 4) != 0 && memcmp(identifier, "\0\0\0\0", 4) != 0)
            stdext::throw_exception(stdext::format("Invalid file identifier detected: %s", identifier));

        BinaryTreePtr root = fin->getBinaryTree();
        if(root->getU8())
            stdext::throw_exception("could not read root property!");

        uint32 headerVersion = root->getU32();
        if(headerVersion > 3)
            stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion));

        setWidth(root->getU16());
        setHeight(root->getU16());

        uint32 headerMajorItems = root->getU8();
        if(headerMajorItems > g_things.getOtbMajorVersion()) {
            stdext::throw_exception(stdext::format("This map was saved with different OTB version. read %d what it's supposed to be: %d",
                                               headerMajorItems, g_things.getOtbMajorVersion()));
        }

        root->skip(3);
        uint32 headerMinorItems =  root->getU32();
        if(headerMinorItems > g_things.getOtbMinorVersion()) {
            g_logger.warning(stdext::format("This map needs an updated OTB. read %d what it's supposed to be: %d or less",
                                        headerMinorItems, g_things.getOtbMinorVersion()));
        }

        BinaryTreePtr node = root->getChildren()[0];
        if(node->getU8() != OTBM_MAP_DATA)
            stdext::throw_exception("Could not read root data node");

        while(node->canRead()) {
            uint8 attribute = node->getU8();
            std::string tmp = node->getString();
            switch (attribute) {
            case OTBM_ATTR_DESCRIPTION:
                setDescription(tmp);
                break;
            case OTBM_ATTR_SPAWN_FILE:
                setSpawnFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp);
                break;
            case OTBM_ATTR_HOUSE_FILE:
                setHouseFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp);
                break;
            default:
                stdext::throw_exception(stdext::format("Invalid attribute '%d'", (int)attribute));
            }
        }

        for(const BinaryTreePtr& nodeMapData : node->getChildren()) {
            uint8 mapDataType = nodeMapData->getU8();
            if(mapDataType == OTBM_TILE_AREA) {
                Position basePos;
                basePos.x = nodeMapData->getU16();
                basePos.y = nodeMapData->getU16();
                basePos.z = nodeMapData->getU8();

                for(const BinaryTreePtr &nodeTile : nodeMapData->getChildren()) {
                    uint8 type = nodeTile->getU8();
                    if(unlikely(type != OTBM_TILE && type != OTBM_HOUSETILE))
                        stdext::throw_exception(stdext::format("invalid node tile type %d", (int)type));

                    HousePtr house = nullptr;
                    uint32 flags = TILESTATE_NONE;
                    Position pos = basePos + nodeTile->getPoint();

                    if(type == OTBM_HOUSETILE) {
                        uint32 hId = nodeTile->getU32();
                        TilePtr tile = getOrCreateTile(pos);
                        if(!(house = g_houses.getHouse(hId))) {
                            house = HousePtr(new House(hId));
                            g_houses.addHouse(house);
                        }
                        house->setTile(tile);
                    }

                    while(nodeTile->canRead()) {
                        uint8 tileAttr = nodeTile->getU8();
                        switch(tileAttr) {
                            case OTBM_ATTR_TILE_FLAGS: {
                                uint32 _flags = nodeTile->getU32();
                                if((_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE)
                                    flags |= TILESTATE_PROTECTIONZONE;
                                else if((_flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE)
                                    flags |= TILESTATE_OPTIONALZONE;
                                else if((_flags & TILESTATE_HARDCOREZONE) == TILESTATE_HARDCOREZONE)
                                    flags |= TILESTATE_HARDCOREZONE;

                                if((_flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT)
                                    flags |= TILESTATE_NOLOGOUT;

                                if((_flags & TILESTATE_REFRESH) == TILESTATE_REFRESH)
                                    flags |= TILESTATE_REFRESH;
                                break;
                            }
                            case OTBM_ATTR_ITEM: {
                                addThing(Item::createFromOtb(nodeTile->getU16()), pos);
                                break;
                            }
                            default: {
                                stdext::throw_exception(stdext::format("invalid tile attribute %d at pos %s",
                                                                   (int)tileAttr, stdext::to_string(pos)));
                            }
                        }
                    }

                    for(const BinaryTreePtr& nodeItem : nodeTile->getChildren()) {
                        if(unlikely(nodeItem->getU8() != OTBM_ITEM))
                            stdext::throw_exception("invalid item node");

                        ItemPtr item = Item::createFromOtb(nodeItem->getU16());
                        item->unserializeItem(nodeItem);

                        if(item->isContainer()) {
                            for(const BinaryTreePtr& containerItem : nodeItem->getChildren()) {
                                if(containerItem->getU8() != OTBM_ITEM)
                                    stdext::throw_exception("invalid container item node");

                                ItemPtr cItem = Item::createFromOtb(containerItem->getU16());
                                cItem->unserializeItem(containerItem);
                                item->addContainerItem(cItem);
                            }
                        }

                        if(house && item->isMoveable()) {
                            g_logger.warning(stdext::format("Moveable item found in house: %d at pos %s - escaping...", item->getId(), stdext::to_string(pos)));
                            item.reset();
                        }

                        addThing(item, pos);
                    }

                    if(const TilePtr& tile = getTile(pos)) {
                        if(house)
                            tile->setFlag(TILESTATE_HOUSE);
                        tile->setFlag(flags);
                    }
                }
            } else if(mapDataType == OTBM_TOWNS) {
                TownPtr town = nullptr;
                for(const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
                    if(nodeTown->getU8() != OTBM_TOWN)
                        stdext::throw_exception("invalid town node.");

                    uint32 townId = nodeTown->getU32();
                    std::string townName = nodeTown->getString();

                    Position townCoords;
                    townCoords.x = nodeTown->getU16();
                    townCoords.y = nodeTown->getU16();
                    townCoords.z = nodeTown->getU8();

                    if(!(town = g_towns.getTown(townId)))
                        g_towns.addTown(TownPtr(new Town(townId, townName, townCoords)));
                }
                g_towns.sort();
            } else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) {
                for(const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) {
                    if(nodeWaypoint->getU8() != OTBM_WAYPOINT)
                        stdext::throw_exception("invalid waypoint node.");

                    std::string name = nodeWaypoint->getString();

                    Position waypointPos;
                    waypointPos.x = nodeWaypoint->getU16();
                    waypointPos.y = nodeWaypoint->getU16();
                    waypointPos.z = nodeWaypoint->getU8();

                    if(waypointPos.isValid() && !name.empty() && m_waypoints.find(waypointPos) == m_waypoints.end())
                        m_waypoints.insert(std::make_pair(waypointPos, name));
                }
            } else
                stdext::throw_exception(stdext::format("Unknown map data node %d", (int)mapDataType));
        }

        fin->close();
    } catch(std::exception& e) {
        g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what()));
    }
}