TilesArea::TilesArea(const Tilemap& tmap, int distance, OverlayPtr overlay) { if( overlay.isNull() ) return; TilePos offset( distance, distance ); TilePos size( overlay->size().width(), overlay->size().height() ); TilePos start = overlay->tile().epos(); _size = overlay->size(); append( tmap.area( start - offset, start + size + offset ) ); }
OverlayList Statistic::_Objects::neighbors(OverlayPtr overlay, bool v) const { if( overlay.isNull() ) return OverlayList(); Size size = overlay->size(); TilePos start = overlay->pos() - gfx::tilemap::unitLocation(); TilePos stop = start + TilePos( size.width(), size.height() ); OverlayList ret; gfx::TilesArray tiles = _parent.rcity.tilemap().rect( start, stop ); std::set<OverlayPtr> checked; for( auto tile : tiles ) { OverlayPtr ov = tile->overlay(); if( ov.isValid() && checked.count( ov ) == 0 ) { checked.insert( ov ); ret.push_back( ov ); } } return ret; }
void Water::drawTile( const RenderInfo& rinfo, Tile& tile) { bool needDrawAnimations = false; Size areaSize = Size::square(1); if( tile.overlay().isNull() ) { drawLandTile( rinfo, tile ); } else { OverlayPtr overlay = tile.overlay(); if( _isVisibleObject( overlay->type() ) ) { // Base set of visible objects needDrawAnimations = true; areaSize = overlay->size(); } else { int tileNumber = 0; bool haveWater = tile.param( Tile::pFountainWater ) > 0 || tile.param( Tile::pWellWater ) > 0; needDrawAnimations = false; if ( overlay->type() == object::house ) { auto house = overlay.as<House>(); needDrawAnimations = (house->level() <= HouseLevel::hovel) && house->habitants().empty(); tileNumber = config::tile.house-1; haveWater = haveWater || house->hasServiceAccess(Service::fountain) || house->hasServiceAccess(Service::well); } if( !needDrawAnimations ) { tileNumber += (haveWater ? config::layer.haveWater : 0); tileNumber += tile.param( Tile::pReservoirWater ) > 0 ? config::layer.reservoirRange : 0; drawArea( rinfo, overlay->area(), config::layer.water, config::tile.constr + tileNumber ); areaSize = Size::zero; } } if ( needDrawAnimations ) { Point screenPos = tile.mappos() + rinfo.offset; Layer::drawTile( rinfo, tile ); if( _d->showWaterValue ) { auto aqueduct = tile.overlay<Aqueduct>(); if( aqueduct.isValid() ) { Font f = Font::create( "FONT_2" ).withColor( ColorList::red ); int df = aqueduct->water(); f.draw( rinfo.engine.screen(), utils::format( 0xff, "%x", df), screenPos + Point( 20, -80 ), false ); } int wellValue = tile.param( Tile::pWellWater ); int fountainValue = tile.param( Tile::pFountainWater ); int reservoirWater = tile.param( Tile::pReservoirWater ); if( wellValue > 0 || fountainValue > 0 || reservoirWater > 0 ) { std::string text = utils::format( 0xff, "%d/%d/%d", wellValue, fountainValue, reservoirWater ); Font f = Font::create( "FONT_2" ).withColor( ColorList::red ); f.draw( rinfo.engine.screen(), text, screenPos + Point( 20, -80 ), false ); } } registerTileForRendering( tile ); } } if( !needDrawAnimations && ( tile.isWalkable(true) || tile.getFlag( Tile::tlOverlay ) ) ) { _drawLandTile( rinfo, tile, areaSize ); } tile.setRendered(); }
void ClearTile::_exec( Game& game, unsigned int ) { Tilemap& tmap = game.city()->tilemap(); Tile& cursorTile = tmap.at( _pos ); if( cursorTile.getFlag( Tile::isDestructible ) ) { Size size( 1 ); TilePos rPos = _pos; OverlayPtr overlay = cursorTile.overlay(); bool deleteRoad = cursorTile.getFlag( Tile::tlRoad ); if( overlay.isValid() ) { const MetaData& md = MetaDataHolder::find( overlay->type() ); if( !overlay->canDestroy() ) { GameEventPtr e = WarningMessage::create( _( overlay->errorDesc() ), WarningMessage::neitral ); e->dispatch(); if( md.getFlag( MetaDataOptions::requestDestroy, false ) ) { e = RequestDestroy::create( overlay ); e->dispatch(); } return; } if( md.getFlag( MetaDataOptions::precisionDestroy, false ) ) { //overlay->partlyDestroy( _pos ); } } if( overlay.isValid() ) { size = overlay->size(); rPos = overlay->pos(); overlay->deleteLater(); } TilesArray clearedTiles = tmap.area( rPos, size ); for( auto tile : clearedTiles ) { tile->setMaster( NULL ); tile->setFlag( Tile::tlTree, false); tile->setFlag( Tile::tlRoad, false); tile->setFlag( Tile::tlGarden, false); tile->setOverlay( NULL ); deleteRoad |= tile->getFlag( Tile::tlRoad ); if( tile->getFlag( Tile::tlMeadow ) || tile->getFlag( Tile::tlWater ) ) { //tile->setPicture( imgid::toResource( tile->originalImgId() ) ); } else { // choose a random landscape picture: // flat land1a 2-9; // wheat: land1a 18-29; // green_something: land1a 62-119; => 58 // green_flat: land1a 232-289; => 58 // choose a random background image, green_something 62-119 or green_flat 232-240 // 30% => choose green_sth 62-119 // 70% => choose green_flat 232-289 int startOffset = ( (math::random( 10 ) > 6) ? 62 : 232 ); int imgId = math::random( 58-1 ); Picture pic; pic.load( ResourceGroup::land1a, startOffset + imgId ); tile->setPicture( pic ); tile->setImgId( imgid::fromResource( pic.name() ) ); } } // recompute roads; // there is problem that we NEED to recompute all roads map for all buildings // because MaxDistance2Road can be any number // if( deleteRoad ) { game.city()->setOption( PlayerCity::updateRoads, 1 ); } } game.city()->setOption( PlayerCity::updateTiles, 1 ); }