foreach( it, buildings ) { if( (*it)->type() == object::house ) { HousePtr house = it->as<House>(); TilePos pos = house->pos(); int hash = (pos.i() << 8) | pos.i(); _d->servedHouses[ hash ] = house->habitants().count(); } }
TilesArray Tilemap::getRectangle( TilePos start, TilePos stop, const bool corners /*= true*/ ) { TilesArray res; int mini = math::min( start.i(), stop.i() ); int minj = math::min( start.j(), stop.j() ); int maxi = math::max( start.i(), stop.i() ); int maxj = math::max( start.j(), stop.j() ); start = TilePos( mini, minj ); stop = TilePos( maxi, maxj ); size_t expected = 2 * ((maxi - mini) + (maxj - minj)) + corners; res.reserve(expected); int delta_corners = 0; if(!corners) { delta_corners = 1; } int tmpij = start.i(); //west side for(int j = start.j() + delta_corners; j <= stop.j() - delta_corners; ++j) { if( isInside( TilePos( tmpij, j ) ) ) res.push_back( &at( tmpij, j )); } tmpij = stop.j(); for(int i = start.i() + 1; i <= stop.i() - delta_corners; ++i) { if( isInside( TilePos( i, tmpij ) ) ) res.push_back( &at(i, tmpij )); } tmpij = stop.i(); for (int j = stop.j() - 1; j >= start.j() + delta_corners; --j) // corners have been handled already { if( isInside( TilePos( tmpij, j ) )) res.push_back(&at( tmpij, j)); } tmpij = start.j(); for( int i = stop.i() - 1; i >= start.i() + 1; --i) // corners have been handled already { if( isInside( TilePos( i, tmpij )) ) res.push_back(&at( i, tmpij)); } return res; }
TilePos Tilemap::fit( const TilePos& pos ) const { TilePos ret; ret.setI( math::clamp( pos.i(), 0, _d->size ) ); ret.setJ( math::clamp( pos.j(), 0, _d->size ) ); return ret; }
TilesArray Layer::_getSelectedArea( TilePos startPos ) { __D_IMPL(_d,Layer) TilePos outStartPos, outStopPos; Tile* startTile = startPos.i() < 0 ? _d->camera->at( _d->startCursorPos, true ) // tile under the cursor (or NULL) : _d->camera->at( startPos ); Tile* stopTile = _d->camera->at( _d->lastCursorPos, true ); TilePos startPosTmp = startTile->epos(); TilePos stopPosTmp = stopTile->epos(); outStartPos = TilePos( std::min<int>( startPosTmp.i(), stopPosTmp.i() ), std::min<int>( startPosTmp.j(), stopPosTmp.j() ) ); outStopPos = TilePos( std::max<int>( startPosTmp.i(), stopPosTmp.i() ), std::max<int>( startPosTmp.j(), stopPosTmp.j() ) ); return _city()->tilemap().getArea( outStartPos, outStopPos ); }
// Get tiles inside of rectangle TilesArray Tilemap::getArea(const TilePos& start, const TilePos& stop ) const { TilesArray res; int expected = math::min((abs(stop.i() - start.i()) + 1) * (abs(stop.j() - start.j()) + 1), 100); res.reserve(expected); Rect r( start.i(), start.j(), stop.i(), stop.j() ); r.repair(); for (int i = r.left(); i <= r.right(); ++i) { for (int j = r.top(); j <= r.bottom(); ++j) { if( isInside( TilePos( i, j ) )) { res.push_back( &( const_cast<Tilemap*>( this )->at( TilePos( i, j ) )) ); } } } return res; }
void CartPusher::_brokePathway(TilePos pos) { _d->brokePathCounter++; if( _pathway().isValid() && _d->brokePathCounter < 5 ) { Pathway way = PathwayHelper::create( pos, _pathway().stopPos(), PathwayHelper::roadFirst ); if( way.isValid() ) { setPathway( way ); go(); return; } } Logger::warning( "CartPusher::_brokePathway not destination point [%d,%d]", pos.i(), pos.j() ); deleteLater(); }
void PlayerArmy::setFortPos(const TilePos& base) { _d->fortPos = base; setName( utils::format( 0xff, "expedition_from_%dx%d", base.i(), base.j() ) ); }
bool isValidLocation(const TilePos &pos) { return pos.i() >= 0 && pos.j() >=0; }
void Build::_updatePreviewTiles( bool force ) { __D_REF(d,Build); Tile* curTile = _camera()->at( _lastCursorPos(), true ); if( !curTile ) return; if( !force && d.lastTilePos == curTile->epos() ) return; if( !d.multiBuilding ) { _setStartCursorPos( _lastCursorPos() ); d.startTilePos = curTile->pos(); } d.lastTilePos = curTile->epos(); _discardPreview(); d.money4Construction = 0; if( d.borderBuilding ) { Tile* startTile = _camera()->at( d.startTilePos ); // tile under the cursor (or NULL) Tile* stopTile = _camera()->at( _lastCursorPos(), true ); TilesArray pathTiles = RoadPropagator::createPath( _city()->tilemap(), startTile->epos(), stopTile->epos(), d.roadAssignment, d.kbShift ); Tilemap& tmap = _city()->tilemap(); TilePos leftUpCorner = pathTiles.leftUpCorner(); TilePos rigthDownCorner = pathTiles.rightDownCorner(); TilePos leftDownCorner( leftUpCorner.i(), rigthDownCorner.j() ); TilesArray ret; int mmapSize = std::max<int>( leftUpCorner.j() - rigthDownCorner.j() + 1, rigthDownCorner.i() - leftUpCorner.i() + 1 ); for( int y=0; y < mmapSize; y++ ) { for( int t=0; t <= y; t++ ) { TilePos tpos = leftDownCorner + TilePos( t, mmapSize - 1 - ( y - t ) ); if( pathTiles.contain( tpos ) ) ret.push_back( &tmap.at( tpos ) ); } } for( int x=1; x < mmapSize; x++ ) { for( int t=0; t < mmapSize-x; t++ ) { TilePos tpos = leftDownCorner + TilePos( x + t, t ); if( pathTiles.contain( tpos ) ) ret.push_back( &tmap.at( tpos ) ); } } pathTiles = ret; for( auto tile : pathTiles ) _checkPreviewBuild( tile->epos() ); } else { TilesArray tiles = _getSelectedArea( d.startTilePos ); for( auto tile : tiles ) _checkPreviewBuild( tile->epos() ); } d.sortBuildTiles(); d.text.image.fill( ColorList::clear, Rect() ); d.text.font.setColor( ColorList::red ); d.text.font.draw( d.text.image, fmt::format( "{} Dn", d.money4Construction ), Point() ); }
TilesArea::TilesArea(const Tilemap &tmap, const TilePos& leftup, const TilePos& rightdown) { _size = Size( abs( rightdown.i() - leftup.i() ), abs( rightdown.j() - leftup.j() ) ); append( tmap.area( leftup, rightdown ) ); }
void AmbientSound::timeStep( const unsigned int time ) { if( time % ambientsnd::updateInterval != 1 ) return; if( !_d->camera ) return; Tile* tile = _d->camera->centerTile(); if( !tile ) return; _d->cameraPos = tile->pos(); audio::Engine& ae = audio::Engine::instance(); //add new emitters _d->emmitersArea.clear(); _d->emmitersArea.reset( _city()->tilemap(), _d->cameraPos, ambientsnd::maxDistance ); foreach( tile, _d->emmitersArea ) _d->emitters.insert( SoundEmitter( *tile, _d->cameraPos ) ); //remove so far emitters for( Emitters::iterator i=_d->emitters.begin(); i != _d->emitters.end(); ) { TilePos distance = _d->cameraPos - (*i).tile->pos(); if( abs( distance.i() ) > ambientsnd::maxDistance || abs( distance.j() ) > ambientsnd::maxDistance || !(*i).isValid() ) { //ae.stop( (*i).getSound() ); _d->emitters.erase( i++ ); } else { ++i; } } //create emitters map _d->processedSounds.clear(); std::string resourceName; resourceName.reserve(256); for( Emitters::reverse_iterator i=_d->emitters.rbegin(); i != _d->emitters.rend(); ++i ) { resourceName = i->sound(); if( resourceName.empty() ) continue; unsigned int hash = Hash(resourceName); bool alsoResolved = _d->processedSounds.count( hash ) > 0; if( !alsoResolved ) { _d->processedSounds.insert( hash ); ae.play( resourceName, sound::maxLevel / (ambientsnd::maxDistance *(i->distance( _d->cameraPos )+1)), audio::ambient ); } } }