Ejemplo n.º 1
0
void Garden::setTerrain(TerrainTile &terrain)
{
  terrain.reset();
  terrain.setOverlay(this);
  terrain.setBuilding(true);
  terrain.setGarden(true);
}
Ejemplo n.º 2
0
void Garden::setTerrain(TerrainTile &terrain)
{
  terrain.reset();
  terrain.setOverlay(this);
  terrain.setBuilding(true); // are gardens buildings or not???? try to investigate from original game
  terrain.setGarden(true);
}
Ejemplo n.º 3
0
void Plaza::setTerrain(TerrainTile &terrain)
{
  //std::cout << "Plaza::setTerrain" << std::endl;
  
  terrain.reset();
  terrain.setOverlay(this);
  terrain.setRoad(true);
}
Ejemplo n.º 4
0
uint8 TerrainHolder::GetLiquidType(float x, float y)
{
    TerrainTile* tile = GetTile(x, y);

    if (tile == NULL)
        return 0;
    uint8 rv = tile->m_map.GetLiquidType(x, y);
    tile->DecRef();
    return rv;
}
Ejemplo n.º 5
0
float TerrainHolder::GetLiquidHeight(float x, float y)
{
    TerrainTile* tile = GetTile(x, y);

    if (tile == NULL)
        return TERRAIN_INVALID_HEIGHT;
    float rv = tile->m_map.GetLiquidHeight(x, y);
    tile->DecRef();
    return rv;
}
Ejemplo n.º 6
0
void Terrain::traverse(osg::NodeVisitor &nv)
{
    if (nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
    {
        // need to check if any TerrainTechniques need to have their update called on them.
        osgUtil::UpdateVisitor *uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
        if (uv)
        {
            typedef std::list<osg::ref_ptr<TerrainTile> >  TerrainTileList;
            TerrainTileList tiles;
            {
                OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_mutex);

                for (TerrainTileSet::iterator itr = _updateTerrainTileSet.begin(); itr != _updateTerrainTileSet.end(); ++itr)
                {
                    // take a reference first to make sure that the referenceCount can be safely read without another thread decrementing it to zero.
                    (*itr)->ref();

                    // only if referenceCount is 2 or more indicating there is still a reference held elsewhere is it safe to add it to list of tiles to be updated
                    if ((*itr)->referenceCount() > 1)
                        tiles.push_back(*itr);

                    // use unref_nodelete to avoid any issues when the *itr TerrainTile has been deleted by another thread while this for loop has been running.
                    (*itr)->unref_nodelete();
                }

                _updateTerrainTileSet.clear();
            }

            for (TerrainTileList::iterator itr = tiles.begin();
                 itr != tiles.end();
                 ++itr)
            {
                TerrainTile *tile = itr->get();
                tile->traverse(nv);
            }
        }
    }

    if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
    {
        osgUtil::CullVisitor *cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
        osg::StateSet        *ss = _geometryPool.valid() ? _geometryPool->getRootStateSetForTerrain(this) : 0;
        if (cv && ss)
        {
            cv->pushStateSet(ss);
            Group::traverse(nv);
            cv->popStateSet();
            return;
        }
    }

    Group::traverse(nv);
}
Ejemplo n.º 7
0
TerrainTile* TerrainHolder::GetTile(int32 tx, int32 ty)
{
    TerrainTile* rv = NULL;
    m_lock[tx][ty].Acquire();
    rv = m_tiles[tx][ty];
    if (rv != NULL)
        rv->AddRef();
    m_lock[tx][ty].Release();

    return rv;
}
Ejemplo n.º 8
0
void Building::setTerrain(TerrainTile &terrain)
{
  // here goes the problem
  // when we reset tile, we delete information
  // about it's original information
  // try to fix
  bool isMeadow = terrain.isMeadow();
  terrain.reset();
  terrain.setOverlay(this);
  terrain.setBuilding(true);
  terrain.setMeadow(isMeadow);
}
Ejemplo n.º 9
0
uint32 TerrainHolder::GetAreaFlag(float x, float y)
{
    TerrainTile* tile = GetTile(x, y);

    if (tile == NULL)
    {
        // No generated map for this area (usually instances)
        return 0;
    }
    uint32 rv = tile->m_map.GetArea(x, y);
    tile->DecRef();
    return rv;
}
Ejemplo n.º 10
0
void drawWater(float maxX,float maxY,float minX,float minY){
    TerrainTile water;
    water.red = 0;
    water.green = 0;
    water.blue = .1;
    water.alpha = .8;
    water.z1 = 0; water.z2 = 0; water.z3 = 0; water.z4 = 0;
    water.x=minX;
    water.y=minY;
    water.xMax =maxX;
    water.yMax =maxY;
    water.drawTile();
    
}
Ejemplo n.º 11
0
void TerrainMap::UpdateInfoLayer(int LayerChangeIndex)
{
    TerrainTile *Temp = NULL;
    for (int x = 0; x < m_MapSizeX; x++)
    {
        for (int y = 0; y < m_MapSizeY; y++)
        {
            Temp = &m_Map[LayerChangeIndex]->Get_Tile(Vec2i(x, y));
            if (Temp->Get_Collidable())
            {
                m_InfoLayer[x][y] = Temp;
            }
        }
    }
}
Ejemplo n.º 12
0
TerrainTile::TerrainTile(const TerrainTile& terrain,const osg::CopyOp& copyop):
    Group(terrain,copyop),
    _terrain(0),
    _dirtyMask(NOT_DIRTY),
    _hasBeenTraversal(false),
    _elevationLayer(terrain._elevationLayer),
    _colorLayers(terrain._colorLayers),
    _requiresNormals(terrain._requiresNormals),
    _treatBoundariesToValidDataAsDefaultValue(terrain._treatBoundariesToValidDataAsDefaultValue),
    _blendingPolicy(terrain._blendingPolicy)
{
    if (terrain.getTerrainTechnique())
    {
        setTerrainTechnique(dynamic_cast<TerrainTechnique*>(terrain.getTerrainTechnique()->clone(osg::CopyOp::SHALLOW_COPY)));
    }
}
Ejemplo n.º 13
0
TerrainTile Level::convert_byte(int y, int x, unsigned char byte){
	float sheet_width = 914.0f;
	float sheet_height = 936.0f;
	TerrainTile tile;
	//tile.exists = false;
	if (byte == (unsigned char)1){
		//"stoneCenter.png" x="144" y="576" width="70" height="70"
		Sheetposition position = Sheetposition(144.0f, 576.0f, 70.0f, 70.0f, tilesize, sheet_width, sheet_height);
		tile = TerrainTile(x*tilesize + tilesize/2, y*tilesize +tilesize/2, tile_texture, position, program);
		tile.set_behaviors(true, true, true, true);
		tile.set_exists(true);
		tile.set_hitbox(tilesize, tilesize);

	}
	else if (byte == (unsigned char)2){
		//"stoneMid.png" x="72" y="432" width="70" height="70"
		Sheetposition position = Sheetposition(72.0f, 432.0f, 70.0f, 70.0f, tilesize, sheet_width, sheet_height);
		tile = TerrainTile(x * tilesize + tilesize /2, y*tilesize + tilesize /2, tile_texture, position, program);
		tile.set_behaviors(true, true , true, true);
		tile.set_exists(true);
		tile.set_hitbox(tilesize, tilesize);

	}
	return tile;
}
Ejemplo n.º 14
0
Archivo: World.cpp Proyecto: eggw/xviii
//Returns true if can be placed at this position
bool World::canBePlacedAtPixelPos(sf::Vector2i _pos){

	//If out of bounds, return false immediately
	if (_pos.x >= getDimensionsInPixels().x || _pos.y >= getDimensionsInPixels().y ||
		_pos.x <= 0 || _pos.y <= 0){

		return false;
	}

    TerrainTile* here = terrainLayer[indexAtPixelPos(_pos)].get();

	if (here->getUnit() == nullptr){
		return true;
	}
	else{
		return false;
	}
}
Ejemplo n.º 15
0
Archivo: World.cpp Proyecto: eggw/xviii
bool World::canBePlacedAtCartesianPos(sf::Vector2i _pos){

	//If out of bounds, return false immediately
	if (_pos.x > getDimensions().x - 1 || _pos.y > getDimensions().y - 1 ||
		_pos.x < 0 || _pos.y < 0){

		return false;
	}

	TerrainTile* here = terrainLayer[indexAtCartesianPos(_pos)].get();

	if (here->getUnit() == nullptr){
		return true;
	}
	else{
		return false;
	}
}
Ejemplo n.º 16
0
void TerrainMap::InitInfoLayer()
{
    m_InfoLayer.resize(m_MapSizeX, std::vector<TerrainTile*>(m_MapSizeY, NULL));

    TerrainTile *Temp = NULL;

    for (int i = 0; i < m_Map.size(); i++)
    {
        for (int x = 0; x < m_MapSizeX; x++)
        {
            for (int y = 0; y < m_MapSizeY; y++)
            {
                Temp = &m_Map[i]->Get_Tile(Vec2i(x, y));

                if (Temp->Get_Collidable())
                {
                    m_InfoLayer[x][y] = Temp;
                }
            }
        }
    }
}
Ejemplo n.º 17
0
void Terrain::traverse(osg::NodeVisitor& nv)
{
    if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
    {
        // need to check if any TerrainTechniques need to have their update called on them.
        osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
        if (uv)
        {
            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
            for(TerrainTileSet::iterator itr = _updateTerrainTileSet.begin();
                itr != _updateTerrainTileSet.end();
                ++itr)
            {
                TerrainTile* tile = *itr;
                tile->traverse(nv);
            }
            _updateTerrainTileSet.clear();
        }
    }

    Group::traverse(nv);
}
Ejemplo n.º 18
0
TerrainTile *
ctb::TerrainTiler::createTile(const TileCoordinate &coord) const {
  // Get a terrain tile represented by the tile coordinate
  TerrainTile *terrainTile = new TerrainTile(coord);
  GDALTile *rasterTile = createRasterTile(coord); // the raster associated with this tile coordinate
  GDALRasterBand *heightsBand = rasterTile->dataset->GetRasterBand(1);

  // Copy the raster data into an array
  float rasterHeights[TerrainTile::TILE_CELL_SIZE];
  if (heightsBand->RasterIO(GF_Read, 0, 0, TILE_SIZE, TILE_SIZE,
                            (void *) rasterHeights, TILE_SIZE, TILE_SIZE, GDT_Float32,
                            0, 0) != CE_None) {
    throw CTBException("Could not read heights from raster");
  }

  delete rasterTile;

  // Convert the raster data into the terrain tile heights.  This assumes the
  // input raster data represents meters above sea level. Each terrain height
  // value is the number of 1/5 meter units above -1000 meters.
  // TODO: try doing this using a VRT derived band:
  // (http://www.gdal.org/gdal_vrttut.html)
  for (unsigned short int i = 0; i < TerrainTile::TILE_CELL_SIZE; i++) {
    terrainTile->mHeights[i] = (i_terrain_height) ((rasterHeights[i] + 1000) * 5);
  }

  // If we are not at the maximum zoom level we need to set child flags on the
  // tile where child tiles overlap the dataset bounds.
  if (coord.zoom != maxZoomLevel()) {
    CRSBounds tileBounds = mGrid.tileBounds(coord);

    if (! (bounds().overlaps(tileBounds))) {
      terrainTile->setAllChildren(false);
    } else {
      if (bounds().overlaps(tileBounds.getSW())) {
        terrainTile->setChildSW();
      }
      if (bounds().overlaps(tileBounds.getNW())) {
        terrainTile->setChildNW();
      }
      if (bounds().overlaps(tileBounds.getNE())) {
        terrainTile->setChildNE();
      }
      if (bounds().overlaps(tileBounds.getSE())) {
        terrainTile->setChildSE();
      }
    }
  }

  return terrainTile;
}
Ejemplo n.º 19
0
Archivo: World.cpp Proyecto: eggw/xviii
bool World::calculateViewDistance(UnitTile* unit, TerrainTile* target, bool randomisePerceivedPositions){
    //IMPORTANT:
    //Due to the fact that Tile::getCartesianPos() bases its result on the physical location of the sprite,
    //which for units can be in disagreement with its real position, we use getTruePosition() instead.

    bool enemyFound{false};

    sf::Vector2i currentPos = target->getCartesianPos();

    int unitViewDistance = unit->getDefaultUnitViewDistance() - getWeatherUnitViewDistance();
    int flagViewDistance = unit->getDefaultFlagViewDistance() - getWeatherFlagViewDistance();


    if(getIsNighttime()){
        unitViewDistance /= 2;
        flagViewDistance /= 2;
    }

    if(unitViewDistance < 1){
        unitViewDistance = 1;
    }
    if(flagViewDistance < 1){
        flagViewDistance = 1;
    }

    unit->setCurrentUnitViewDistance(unitViewDistance);
    unit->setCurrentFlagViewDistance(flagViewDistance);

    Player* owner = unit->getPlayer();

    for (int y{-1 * unitViewDistance}; y <= unitViewDistance; ++y){
        for(int x{-1 * unitViewDistance}; x <= unitViewDistance; ++x){

            sf::Vector2i adjacentPos{currentPos.x + x, currentPos.y + y};

            TerrainTile* terrainHere = terrainAtCartesianPos(adjacentPos);

            if(terrainHere == nullptr){
                continue;
            }

            UnitTile* targetUnit = terrainHere->getUnit();
            visibleTiles.insert(terrainHere);

            if (targetUnit != nullptr){
                if(targetUnit->getPlayer() != owner){

                    if(!targetUnit->drawUnit){
                        enemyFound = true;
                        targetUnit->drawUnit = true;
                    }

                    targetUnit->updateStats(randomisePerceivedPositions);
                }
            }
        }
    }

    for (int y{-1 * flagViewDistance}; y <= flagViewDistance; ++y){
        for(int x{-1 * flagViewDistance}; x <= flagViewDistance; ++x){

            sf::Vector2i adjacentPos{currentPos.x + x, currentPos.y + y};

            TerrainTile* terrainHere = terrainAtCartesianPos(adjacentPos);

            if(terrainHere == nullptr){
                continue;
            }

            UnitTile* targetUnit = terrainHere->getUnit();

            if (targetUnit != nullptr){
                if(targetUnit->getPlayer() != owner){
                    targetUnit->drawFlag = true;
                    targetUnit->updateStats(randomisePerceivedPositions);
                }
            }
        }
    }

    return enemyFound;

}
Ejemplo n.º 20
0
PLAYER_UPDATE_STATE Player::Update(float delta_, Goal* goal_, std::vector<Bullet> bullets_, std::set<TerrainTile*> monitoredTiles_)
{
	playerWaitTimer += delta_;
	animationTimer += delta_;

	//set animation
	if (animationTimer > 0.6f)
	{
		animationTimer = 0.0f;
		animSwitch++;

		if (animSwitch % 2 == 0)
		{
			playerTexture = textures[0];
		}
		else
		{
			playerTexture = textures[1];
		}
	}




	if (spotted && behaviour != FLEE)
	{
		cout << "behaviour == FLEE" << endl;
		behaviour = FLEE;
		navigationList.clear();
		
		spotted = false;
	}

	//update player on normal path 
	//while the navigationList is not empty. 
	if (navigationList.empty() && behaviour == SEEK)
	{
		//		//convert click location to tile
		TerrainTile* dstTile = terrain->TileAtMouseCoords(goal_->Pos());

		//convert player location to tile
		TerrainTile* playerTile = terrain->TileAtMouseCoords(static_cast<int>(pos.x), static_cast<int>(pos.y));

		//		//get the vector of tiles to nav to 
		navigationList = terrain->ShortestPath(playerTile, dstTile, monitoredTiles_);
	}

	if (navigationList.empty() && behaviour == FLEE)
	{
		TerrainTile* playerTile = terrain->TileAtMouseCoords(static_cast<int>(pos.x), static_cast<int>(pos.y));
		//get a new path from terrain to get away from enemy
		navigationList = terrain->ClosestUnmonitoredTile(playerTile, monitoredTiles_);

		//is current tile monitored? 
		if (std::find(monitoredTiles_.begin(), monitoredTiles_.end(), playerTile) == monitoredTiles_.end())
		{
			behaviour = SEEK;
		}
	}

	////wait for x seconds
	//if (navigationList.empty() && behaviour == FLEE)
	//{
	//	cout << "behaviour == WAIT" << endl;
	//	behaviour = WAIT;
	//}

	//if (behaviour == WAIT)
	//{
	//	
	//	if (playerWaitTimer > 0.1f)
	//	{			
	//		playerWaitTimer = 0.0f;
	//		cout << "behaviour == SEEK" << endl;
	//		behaviour = SEEK;
	//	}
	//}

	if (!navigationList.empty())
	{
		//if ( behaviour != WAIT )
		//{
			//get the next node and move towards it
			TerrainTile* nextNode = navigationList[navigationList.size() - 1];
			Vector2 nextNodePos = nextNode->Pos();

			//if reached pop it off the top
			if ((pos - nextNode->Pos()).GetMagnitude() < 1.0f)
			{
				pos = nextNode->Pos();
				navigationList.erase(navigationList.end() - 1);
				navigationList.clear();
			}
			else
			{
				int currentTerrainCost = 1;
				if ((pos - nextNode->Pos()).GetMagnitude() < TILE_SIZE * 0.5f)
				{
					currentTerrainCost = nextNode->Cost();
				}

				//TODO FIX - .GetNormal does not work on vector with Magnitude of 0
				Vector2 direction = (nextNodePos - pos).GetNormal();
				Vector2 velocity = (direction * 75) * delta_;
				velocity *= 1.f / (float)currentTerrainCost;
				pos += velocity;

				//rotate animation
				if (direction.x > 0.6) //heading right
				{
					RotateSprite(playerTexture, 0);
				}
				else if (direction.x < -0.6) //heading left
				{
					RotateSprite(playerTexture, PI);
				}
				else if (direction.y > 0.6) //heading down
				{
					RotateSprite(playerTexture, PI / 2);
				}
				else if (direction.y < -0.6) //heading up
				{
					RotateSprite(playerTexture, -(PI / 2));
				}
			}



			//if ( playerWaitTimer > 2.0f )
			//{
			//	navigationList.clear();
			//	playerWaitTimer = 0.0f;
			//}
		//}
	}
	



	//update player rect
	rect.centre = pos;

	//check if bullet collided with player
	for (auto& bullet : bullets_)
	{
		if (Collision::RectCollision(bullet.GetRect(), rect))
		{
			cout << "bullet struck player" << endl;
			return PUS_DIED;
		}
	}

	if (terrain->TileAtMouseCoords(pos) == terrain->TileAtMouseCoords(goal_->Pos()))
	{
		return PUS_WON;
	}

	// if (IsKeyDown(SDLK_UP) || IsKeyDown(SDLK_w))
	// {		
	// 	pos.y -= 100 * delta_;
	// }
	// if (IsKeyDown(SDLK_DOWN) || IsKeyDown(SDLK_s))
	// {
	// 	pos.y += 100 * delta_;
	// }
	// if (IsKeyDown(SDLK_RIGHT) || IsKeyDown(SDLK_d))
	// {
	// 	pos.x += 100 * delta_;
	// }
	// if (IsKeyDown(SDLK_LEFT) || IsKeyDown(SDLK_a))
	// {
	// 	pos.x -= 100 * delta_;
	// }
	return PUS_NORMAL;
}
Ejemplo n.º 21
0
void TerrainGenerator::diamondSquare(TerrainTile & tile) const
{
    // assuming the edge length of the field is a power of 2, + 1
    // assuming the field is square

    const unsigned fieldEdgeLength = tile.samplesPerAxis;
    const float maxHeight = m_settings.maxHeight;

    float randomMax = 50.0f;
    std::function<float(float)> clampHeight = [maxHeight](float value) {
        if (value > maxHeight)
            value = maxHeight;
        if (value < -maxHeight)
            value = -maxHeight;
        return value;
    };

    std::function<void(unsigned int, unsigned int, unsigned int, std::function<float(unsigned int, unsigned int)>&)> squareStep =
        [&tile, fieldEdgeLength, &clampHeight](unsigned int diamondRadius, unsigned int diamondCenterRow, unsigned int diamondCenterColumn, std::function<float(unsigned int, unsigned int)>& heightRnd)
    {
        // get the existing data values first: if we get out of the valid range, wrap around, to the next existing value on the other field side
        int upperRow = signed(diamondCenterRow) - signed(diamondRadius);
        if (upperRow < 0)
            upperRow = fieldEdgeLength - 1 - diamondRadius; // example: nbRows=5, centerRow=0, upperRow gets -1, we want the second last row (with existing value), so it's 3
        int lowerRow = signed(diamondCenterRow) + signed(diamondRadius);
        if (lowerRow >= signed(fieldEdgeLength))
            lowerRow = diamondRadius; // this is easier: use the first row in our column, that is already set
        int leftColumn = signed(diamondCenterColumn) - signed(diamondRadius);
        if (leftColumn < 0)
            leftColumn = fieldEdgeLength - 1 - diamondRadius;
        int rightColumn = signed(diamondCenterColumn) + signed(diamondRadius);
        if (rightColumn >= signed(fieldEdgeLength))
            rightColumn = diamondRadius;
        float value =
            (tile.valueAt(upperRow, diamondCenterColumn)
            + tile.valueAt(lowerRow, diamondCenterColumn)
            + tile.valueAt(diamondCenterRow, leftColumn)
            + tile.valueAt(diamondCenterRow, rightColumn))
            * 0.25f
            + heightRnd(diamondCenterRow, diamondCenterColumn);

        float clampedHeight = clampHeight(value);
        tile.setValue(diamondCenterRow, diamondCenterColumn, clampedHeight);

        // in case we are at the borders of the tile: also set the value at the opposite border, to allow seamless tile wrapping
        if (upperRow > signed(diamondCenterRow))
            tile.setValue(fieldEdgeLength - 1, diamondCenterColumn, clampedHeight);
        if (leftColumn > signed(diamondCenterColumn))
            tile.setValue(diamondCenterRow, fieldEdgeLength - 1, clampedHeight);
    };
    
    unsigned nbSquareRows = 1; // number of squares in a row, doubles each time the current edge length increases [same for the columns]

    for (unsigned int len = fieldEdgeLength; len > 2; len = (len / 2) + 1) // length: 9, 5, 3, finished
    {
        const unsigned int currentEdgeLength = len;
        std::uniform_real_distribution<float> dist(-randomMax, randomMax);
        std::function<float(unsigned int, unsigned int)> heightRndPos =
            [fieldEdgeLength, &dist](unsigned int row, unsigned int column) {
            glm::vec2 pos(row, column);
            pos = pos / (fieldEdgeLength - 1.0f) * 2.0f - 1.0f;
            return float(glm::length(pos)) * dist(rng);
            //return std::abs(float(row + column) / float(2 * fieldEdgeLength - 2) * 2.0f - 1.0f) * dist(rng);
        };
        // create diamonds
        for (unsigned int rowN = 0; rowN < nbSquareRows; ++rowN) {
            const unsigned int row = rowN * (currentEdgeLength - 1);
            const unsigned int midpointRow = row + (currentEdgeLength - 1) / 2; // this is always divisible, because of the edge length 2^n + 1
            for (unsigned int columnN = 0; columnN < nbSquareRows; ++columnN) {
                const unsigned int column = columnN * (currentEdgeLength - 1);
                const unsigned int midpointColumn = column + (currentEdgeLength - 1) / 2;
                float heightValue =
                    (tile.valueAt(row, column)
                    + tile.valueAt(row + currentEdgeLength - 1, column)
                    + tile.valueAt(row, column + currentEdgeLength - 1)
                    + tile.valueAt(row + currentEdgeLength - 1, column + currentEdgeLength - 1))
                    * 0.25f
                    + heightRndPos(midpointRow, midpointColumn);

                tile.setValue(midpointRow, midpointColumn, clampHeight(heightValue));
            }
        }

        // create squares
        unsigned int diamondRadius = (currentEdgeLength - 1) / 2;
        // don't iterate over the last row/column here. These values are set with the first row/column, to allow seamless tile wrapping
        for (unsigned int rowN = 0; rowN < nbSquareRows; ++rowN) {
            const unsigned int seedpointRow = rowN * (currentEdgeLength - 1);
            for (unsigned int columnN = 0; columnN < nbSquareRows; ++columnN) {
                const unsigned int seedpointColumn = columnN * (currentEdgeLength - 1);

                unsigned int rightDiamondColumn = seedpointColumn + currentEdgeLength / 2;
                if (rightDiamondColumn < tile.samplesPerAxis)
                    squareStep(diamondRadius, seedpointRow, rightDiamondColumn, heightRndPos);

                unsigned int bottomDiamondRow = seedpointRow + currentEdgeLength / 2;
                if (bottomDiamondRow < tile.samplesPerAxis)
                    squareStep(diamondRadius, bottomDiamondRow, seedpointColumn, heightRndPos);
            }
        }

        nbSquareRows *= 2;
        randomMax *= 0.5;
    }
}
Ejemplo n.º 22
0
float TerrainInteraction::setValue(TerrainTile & tile, unsigned row, unsigned column, float value, bool setToInteractionElement)
{
    float stddev = tile.interactStdDeviation;
    assert(stddev > 0);

    /** clamp value */
    if (value < tile.minValidValue) value = tile.minValidValue;
    if (value > tile.maxValidValue) value = tile.maxValidValue;

    // define the size of the affected interaction area, in grid coords
    const float effectRadiusWorld = stddev * 3;
    const uint32_t effectRadius = static_cast<uint32_t>(std::ceil(effectRadiusWorld * tile.samplesPerWorldCoord)); // = 0 means to change only the value at (row,column)

    bool moveUp = (value - tile.valueAt(row, column)) > 0;
    int invert = moveUp ? 1 : -1;   // invert the curve if moving downwards

    float norm0Inv = 1.0f / normalDist(0, 0, stddev);
    float valueRange = std::abs(tile.maxValidValue - tile.minValidValue);
    std::function<float(float)> interactHeight = [stddev, norm0Inv, value, valueRange, invert](float x) {
        return normalDist(x, 0, stddev)     // - normalize normDist to
                   * norm0Inv               //    normDist value at interaction center
               * (valueRange + 10)          // - scale to value range + offset to omit norm values near 0
               * invert                     // - mirror the curve along the y axis if moving downward
               + value                      // - move along y so that value==0 => y==0
               - (valueRange + 10) * invert;
    };

    unsigned int minRow, maxRow, minColumn, maxColumn;
    {
        // unchecked signed min/max values, possibly < 0 or > numRows/Column
        int iMinRow = row - effectRadius, iMaxRow = row + effectRadius, iMinColumn = column - effectRadius, iMaxColumn = column + effectRadius;
        // work on rows and column that are in range of the terrain tile settings and larger than 0
        minRow = iMinRow < 0 ? 0 : (iMinRow >= static_cast<signed>(tile.samplesPerAxis) ? tile.samplesPerAxis - 1 : static_cast<unsigned int>(iMinRow));
        maxRow = iMaxRow < 0 ? 0 : (iMaxRow >= static_cast<signed>(tile.samplesPerAxis) ? tile.samplesPerAxis - 1 : static_cast<unsigned int>(iMaxRow));
        minColumn = iMinColumn < 0 ? 0 : (iMinColumn >= static_cast<signed>(tile.samplesPerAxis) ? tile.samplesPerAxis - 1 : static_cast<unsigned int>(iMinColumn));
        maxColumn = iMaxColumn < 0 ? 0 : (iMaxColumn >= static_cast<signed>(tile.samplesPerAxis) ? tile.samplesPerAxis - 1 : static_cast<unsigned int>(iMaxColumn));
    }

    // also change element id's if requested and the tile supports it
    PhysicalTile * physicalTile = dynamic_cast<PhysicalTile*>(&tile);
    
    if (setToInteractionElement) {
        assert(physicalTile);
    }

    uint8_t elementIndex = 0;
    if (physicalTile)
        elementIndex = physicalTile->elementIndex(m_interactElement);

    for (unsigned int r = minRow; r <= maxRow; ++r) {
        float relWorldX = (signed(r) - signed(row)) * tile.sampleInterval;
        for (unsigned int c = minColumn; c <= maxColumn; ++c) {
            float relWorldZ = (signed(c) - signed(column)) * tile.sampleInterval;

            float localRadius = std::sqrt(relWorldX*relWorldX + relWorldZ*relWorldZ);

            if (localRadius > effectRadiusWorld)  // interaction in a circle, not square
                continue;

            float newLocalHeight = interactHeight(localRadius);

            bool localMoveUp = newLocalHeight > tile.valueAt(r, c);
            // don't do anything if we pull up the terrain but the local height point is already higher than its calculated height. (vice versa)
            if (localMoveUp != moveUp)
                continue;

            tile.setValue(r, c, newLocalHeight);
            if (setToInteractionElement)
                physicalTile->setElement(r, c, elementIndex);
        }
        tile.addBufferUpdateRange(minColumn + r * tile.samplesPerAxis, 1u + effectRadius * 2u);
    }

    if (physicalTile)
        physicalTile->addToPxUpdateBox(minRow, maxRow, minColumn, maxColumn);

    return value;
}
Ejemplo n.º 23
0
void
Terrain::buildGeometry(Ogre::SceneNode* parent, bool editable)
{
    clearGeometry();	

    assert(parent);

    // NB: We must adjust world geometry bounding box, especially for OctreeSceneManager
    Ogre::AxisAlignedBox aabb = mData->getBoundBox();
    Ogre::Vector3 centre = aabb.getCenter();
    const Ogre::Vector3 adjust(2000, 10000, 2000);
    const Ogre::Real scale = 1.5f;
    aabb.setExtents(
        (aabb.getMinimum() - centre) * scale + centre - adjust,
        (aabb.getMaximum() - centre) * scale + centre + adjust);
    parent->getCreator()->setOption("Size", &aabb);

    mEditable = editable;

    if (!mData->mXSize || !mData->mZSize)
    {
        // Do nothing if it's empty terrain.
        return;
    }

    // Prepare atlas texture
    for (size_t pixmapId = 0, numPixmap = mData->mPixmaps.size(); pixmapId < numPixmap; ++pixmapId)
    {
        _getPixmapAtlasId(pixmapId);
    }

	prepareLightmapTexture();

    int depth = mData->mZSize;
    int width = mData->mXSize;
    int tileSize = mData->mTileSize;
    int numTilePerX = mData->mNumTilePerX;
    int numTilePerZ = mData->mNumTilePerZ;

    if (mEditable)
    {
        mGridTypeInfos.resize(2);
        mGridTypeInfos[0].material.setNull();
        mGridTypeInfos[1].material = Ogre::MaterialManager::getSingleton().getByName(
            "FairyEditor/GridType");
    }
    else
    {
        _initIndexBuffer(tileSize * tileSize);
    }

    mTiles.reserve(numTilePerX * numTilePerZ);
    for (int z = 0; z < numTilePerZ; ++z)
    {
        for (int x = 0; x < numTilePerX; ++x)
        {
            // Create the tile
            int tileX = x * tileSize;
            int tileZ = z * tileSize;
            int tileWidth = std::min(width - tileX, tileSize);
            int tileDepth = std::min(depth - tileZ, tileSize);
            TerrainTile* tile;
			if (mEditable)
				tile = new TerrainTileEditable(parent, this, tileX, tileZ, tileWidth, tileDepth);
			else
				tile = new TerrainTileOptimized(parent, this, tileX, tileZ, tileWidth, tileDepth);

            // Use the render queue that the world geometry associated with.
            tile->setRenderQueueGroup(parent->getCreator()->getWorldGeometryRenderQueue());

            // Attach it to the aux data
            mTiles.push_back(tile);
        }
    }
}
Ejemplo n.º 24
0
void Aqueduct::setTerrain(TerrainTile &terrain)
{
  terrain.reset();
  terrain.setOverlay(this);
  terrain.setBuilding(true);
}
Ejemplo n.º 25
0
void Road::setTerrain(TerrainTile &terrain)
{
   terrain.reset();
   terrain.setOverlay(this);
   terrain.setRoad(true);
}
Ejemplo n.º 26
0
 void setTerrain( TerrainTile& terrain )
 {
   terrain.clearFlags();
   terrain.setOverlay( this );
   terrain.setRoad( true );
 }
Ejemplo n.º 27
0
Archivo: World.cpp Proyecto: eggw/xviii
void World::turnlyUpdate(){
    boost::random::uniform_int_distribution<int> dist(1, 100);

    incrementElapsedTurns();
    getCurrentTime().increment();

    //The weather will tend to change every ~8 hours, or 480 minutes.
    //Ideally, something like this:

    //1 hour  (60)  -> 4%
    //2 hours (120) -> 6%
    //3 hours (180) -> 8%
    //4 hours (240) -> 12.5%
    //5 hours (300) -> 16%
    //6 hours (360) -> 24%
    //7 hours (420) -> 30%
    //8 hours (480) -> 40%

    for(auto& effect : weatherEffects){
        effect.second += minutesPerTurn;
    }

    auto effect = std::begin(weatherEffects);
    while(effect != std::end(weatherEffects)){

        int removeEffect{dist(masterManager.randomEngine)};
        //For instance, if the effect has been there for 240 minutes, it will have an
        //40% chance of being removed. There is a hard cap of 80%.

        int totalChance = effect->second / 15;
        if(totalChance > 50){
            totalChance = 50;
        }

        if(removeEffect <= totalChance){
            effect = weatherEffects.erase(effect);
        }
        else{
            effect++;
        }

    }

    int hourlyChance = 20;
    int turnlyChance = hourlyChance / (60/minutesPerTurn);

    int randomRoll{dist(masterManager.randomEngine)};

    if (randomRoll <= turnlyChance){
        addWeather();
    }


    ////////////////////////////////////////////////////////////////////////////////
    //////////////////MUD CREATION AND REMOVAL//////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////


    //Firstly, depending on whether the rain is heavy or light, there will be a varying
    //amount of mud formations per turn.


    bool rain{false};
    int minimumMudFormations{0};

    for(auto& effect : weatherEffects){

        if(effect.first == World::Weather::HEAVY_RAIN){
            rain = true;
            minimumMudFormations = 4;
            break;
        }
        else if(effect.first == World::Weather::LIGHT_RAIN){
            rain = true;
            minimumMudFormations = 2;
            break;
        }

    }

    //A random tile on the map that we call the origin is converted to mud (if possible).

    if(rain){

        for (int i{0}; i < minimumMudFormations; ++i){
            boost::random::uniform_int_distribution<int> randomIndexDist(0, getDimensions().x * getDimensions().y);
            int randomIndex{randomIndexDist(masterManager.randomEngine)};

            sf::Vector2i originPosition{cartesianPosAtIndex(randomIndex)};
            TerrainTile* origin = terrainAtCartesianPos(originPosition);

            bool originConvertedToMud{false};

            if(origin->getTerrainType() == TerrainTile::TerrainType::MEADOW){
                toggleMud(origin);
                originConvertedToMud = true;
            }

            if(!originConvertedToMud){
                break;
            }

            //There is then an 4/5 chance that a neighboring tile is also converted, if possible...

            int randomNumber{0};
            do{
                boost::random::uniform_int_distribution<int> randomDist(1, 5);
                randomNumber = randomDist(masterManager.randomEngine);

                if(randomNumber >= 2){
                    boost::random::uniform_int_distribution<int> randomDisplacementDist(-1, 1);
                    int randomDisplacementX{randomDisplacementDist(masterManager.randomEngine)};
                    int randomDisplacementY{randomDisplacementDist(masterManager.randomEngine)};

                    sf::Vector2i newPosition{originPosition.x + randomDisplacementX, originPosition.y + randomDisplacementY};
                    TerrainTile* newTerrain = terrainAtCartesianPos(newPosition);

                    if(newTerrain != nullptr){
                        if(newTerrain->getTerrainType() == TerrainTile::TerrainType::MEADOW){
                            toggleMud(newTerrain);
                        }
                    }
                }

            //... and a 3/5 chance for this process to repeat.
            }while(randomNumber >= 3);

        }


        //While new mud tiles are formed, every old mud tile has a 1/8 chance to spread to a neighboring tile, if possible

        //IMPORTANT NOTE: here we use an integer-based index rather than a foreach loop, because toggleMud()
        //itself actually erases a mud tile from mudTiles. So if we do a foreach mudTiles loop, we end up with
        //messy dangling pointers and, in my case, days of debugging crashes.

        for(std::vector<Mud*>::size_type i{0}; i < mudTiles.size(); i++){
            boost::random::uniform_int_distribution<int> randomDist(1, 8);
            int randomNumber = randomDist(masterManager.randomEngine);

            if(randomNumber == 1){
                    boost::random::uniform_int_distribution<int> randomDisplacementDist(-1, 1);
                    int randomDisplacementX{randomDisplacementDist(masterManager.randomEngine)};
                    int randomDisplacementY{randomDisplacementDist(masterManager.randomEngine)};

                    sf::Vector2i originPosition = mudTiles[i]->getCartesianPos();
                    sf::Vector2i newPosition{originPosition.x + randomDisplacementX, originPosition.y + randomDisplacementY};
                    TerrainTile* newTerrain = terrainAtCartesianPos(newPosition);

                    if(newTerrain != nullptr){
                        if(newTerrain->getTerrainType() == TerrainTile::TerrainType::MEADOW){
                            toggleMud(newTerrain);
                        }
                    }
                }
        }

    }

    //Finally, after the rain has stopped, each mud tile has a 9/10 chance to dry up.

    else if (!rain){

        //IMPORTANT NOTE: here we use an integer-based index rather than a foreach loop, because toggleMud()
        //itself actually erases a mud tile from mudTiles. So if we do a foreach mudTiles loop, we end up with
        //messy dangling pointers and, in my case, days of debugging crashes.

        for(std::vector<Mud*>::size_type i{0}; i < mudTiles.size(); i++){
            boost::random::uniform_int_distribution<int> randomDryingChanceDist(1, 10);
            int randomDryingChance{randomDryingChanceDist(masterManager.randomEngine)};

            if(randomDryingChance <= 9){
                toggleMud(mudTiles[i]);
            }
        }

    }

    unhighlightVisibleTiles();
    visibleTiles.clear();
}
Ejemplo n.º 28
0
void Reservoir::setTerrain(TerrainTile &terrain)
{
  terrain.reset();
  terrain.setOverlay(this);
  terrain.setBuilding(true);
}
Ejemplo n.º 29
0
void GameState_Setup::getInput(){
	sf::Event event;

	while (game->mWindow.pollEvent(event)){

		switch (event.type){

		case sf::Event::MouseMoved:
			game->mousePos.x = event.mouseMove.x;
			game->mousePos.y = event.mouseMove.y;
			break;

		case sf::Event::Resized:
			handleResize();
			break;

		case sf::Event::MouseButtonPressed:
			if (event.mouseButton.button == sf::Mouse::Middle){
				middleButtonHeld = true;
				middleButtonCoords = {event.mouseButton.x, event.mouseButton.y};
			}

			else if (event.mouseButton.button == sf::Mouse::Left && drawUI){

				//If no menu item was selectedSpawnableUnit, select it

				if (selectedSpawnableUnit == nullptr){
					sf::Vector2f worldCoords{game->mWindow.mapPixelToCoords(game->mousePos, *game->currentView)};
					sf::Vector2f uiCoords{game->mWindow.mapPixelToCoords(game->mousePos, setupUI.uiView)};

					std::vector<SpawnableUnit> current{game->currentPlayer->getSpawnableUnits()};

					for (size_t i{0}; i < current.size(); ++i){
						if (uiCoords.x > current[i].left() && uiCoords.x < current[i].right()
							&&
							uiCoords.y > current[i].top() && uiCoords.y < current[i].bottom()){

							selectedSpawnableUnit = std::move(std::unique_ptr<SpawnableUnit>(new SpawnableUnit(current[i])));
							break;

						}
					}


					if (uiCoords.x >= setupUI.getButton().left() && uiCoords.x <= setupUI.getButton().right()
						&&
						uiCoords.y >= setupUI.getButton().top() && uiCoords.y <= setupUI.getButton().bottom()){

						//As long as the player has at least one non-general unit
						if (game->currentPlayer->getDeploymentPoints() <= game->currentPlayer->getMaxDeploymentPoints() - 1){
							game->currentPlayer->setReady(true);
						}

					}

					if(selectedSpawnableUnit == nullptr){
						middleButtonHeld = true;
						middleButtonCoords = {event.mouseButton.x, event.mouseButton.y};
					}
				}

				//Spawn a unit on the tile:

				else{
					sf::Vector2i mouseCoords{event.mouseButton.x, event.mouseButton.y};
					sf::Vector2i worldCoords{game->mWindow.mapPixelToCoords(mouseCoords, *game->currentView)};

					TerrainTile* terrain = game->mWorld->terrainAtPixelPos(worldCoords);

					if (terrain != nullptr){

                        if(terrain->getTerrainType() != TerrainTile::TerrainType::WATER){
                            game->currentPlayer->spawnUnit(selectedSpawnableUnit->unitID, worldCoords);
                        }

					}

					selectedSpawnableUnit = nullptr;
					break;
				}
			}


			else if (event.mouseButton.button == sf::Mouse::Right && drawUI){

				//Deselect the currently selectedSpawnableUnit icon:

				if (selectedSpawnableUnit != nullptr){
					selectedSpawnableUnit = nullptr;
					break;
				}

				//Delete a unit from a tile:

				else{
					sf::Vector2i mouseCoords{event.mouseButton.x, event.mouseButton.y};
					sf::Vector2i worldCoords{game->mWindow.mapPixelToCoords(mouseCoords, *game->currentView)};

					auto removed = game->currentPlayer->removeUnit(worldCoords);

					if(removed != nullptr){
                        game->currentPlayer->setDeploymentPoints(game->currentPlayer->getDeploymentPoints() + removed.get()->getCost());
					}

					break;
				}

			}

			break;

		case sf::Event::MouseButtonReleased:

			if (event.mouseButton.button == sf::Mouse::Middle){
				middleButtonHeld = false;
			}
			else if(event.mouseButton.button == sf::Mouse::Left){
				middleButtonHeld = false;
			}

			break;

		case sf::Event::Closed:
			game->exitGame(false);
			break;

		case sf::Event::KeyPressed:

			switch (event.key.code){

			case Key::UP_KEY:
				cameraVelocity = {0.f, -2.f};
				break;

			case Key::RIGHT_KEY:
				cameraVelocity = {2.f, 0.f};
				break;

			case Key::DOWN_KEY:
				cameraVelocity = {0.f, 2.f};
				break;

			case Key::LEFT_KEY:
				cameraVelocity = {-2.f, 0.f};
				break;

			case Key::RESETZOOM_KEY:
				game->currentView->setSize(game->mWindow.getSize().x, game->mWindow.getSize().y);
				break;

            case Key::ZOOMIN_KEY:
				game->currentView->setSize(game->currentView->getSize().x - xResolution / 10, game->currentView->getSize().y - yResolution / 10);
                break;

            case Key::ZOOMOUT_KEY:
				game->currentView->setSize(game->currentView->getSize().x + xResolution / 10, game->currentView->getSize().y + yResolution / 10);
                break;

            case sf::Keyboard::Escape:
            {
                game->setGameState(game->SetupPauseMenuState.get());
            }

            break;

			case Key::HIDE_UI_KEY:
				if (drawUI){
					drawUI = false;
				}
				else if (!drawUI){
					drawUI = true;
				}
				break;

			default: break;
			}

			break;

		case sf::Event::MouseWheelMoved:
			smoothZoom_zooming = true;
			smoothZoom_lerpFactor = 0.0085f;

			if (event.mouseWheel.delta > 0 && game->currentView->getSize().x > xResolution && game->currentView->getSize().y > yResolution){
                //zoom in
                //std::cout << game->currentView->getSize().x << ',' << game->currentView->getSize().y << std::endl;
				//game->currentView->setSize(game->currentView->getSize().x - xResolution / 12, game->currentView->getSize().y - yResolution / 12);
				smoothZoom_targetZoom = 0.8f;
			}
			else if (event.mouseWheel.delta < 0 && game->currentView->getSize().x < xResolution * 4 && game->currentView->getSize().y < yResolution * 4){
			    //zoom out
			    //std::cout << game->currentView->getSize().x << ',' << game->currentView->getSize().y << std::endl;
				//game->currentView->setSize(game->currentView->getSize().x + xResolution / 12, game->currentView->getSize().y + yResolution / 12);
				smoothZoom_targetZoom = 1.2f;
			}

			smoothZoom_currentZoom = 1.0f;
			smoothZoom_previousZoom = smoothZoom_currentZoom;

			smoothZoom_currentCenter = game->currentView->getCenter();

			if(smoothZoom_targetZoom >= 1.f){
				smoothZoom_targetCenter = game->mWindow.mapPixelToCoords(game->mousePos, *(game->currentView));
				auto dist = smoothZoom_targetCenter - smoothZoom_currentCenter;
				dist.x /= 2;
				dist.y /= 2;
				smoothZoom_targetCenter = smoothZoom_currentCenter - dist;
			}
			else{
				smoothZoom_targetCenter = game->mWindow.mapPixelToCoords(game->mousePos, *(game->currentView));
				auto dist = smoothZoom_targetCenter - smoothZoom_currentCenter;
				dist.x /= 2;
				dist.y /= 2;
				smoothZoom_targetCenter = smoothZoom_targetCenter - dist;
			}

			break;

		default: break;
		}

	}

}