CartSupplier::CartSupplier( CityPtr city ) : _d( new Impl ) { _walkerGraphic = WG_PUSHER; _walkerType = WT_CART_PUSHER; _d->storageBuildingPos = TilePos( -1, -1 ); _d->baseBuildingPos = TilePos( -1, -1 ); _d->maxDistance = 25; _d->city = city; }
CartSupplier::CartSupplier( CityPtr city ) : Walker( city ), _d( new Impl ) { _setGraphic( WG_PUSHER ); _setType( WT_CART_PUSHER ); _d->storageBuildingPos = TilePos( -1, -1 ); _d->baseBuildingPos = TilePos( -1, -1 ); _d->maxDistance = 25; _d->city = city; setName( NameGenerator::rand( NameGenerator::male ) ); }
void Construction::_updateDesirabilityInfluence( bool onBuild ) { City &city = Scenario::instance().getCity(); Tilemap &tilemap = city.getTilemap(); PtrTilesList desirabilityArea = tilemap.getFilledRectangle( getTile().getIJ() - TilePos( 2, 2 ), getTile().getIJ() + TilePos( 2 + getSize(), 2 + getSize() ) ); int mul = (onBuild ? 1 : -1); for( PtrTilesList::iterator it=desirabilityArea.begin(); it != desirabilityArea.end(); it++ ) { (*it)->get_terrain().appendDesirability( mul * getDesirabilityInfluence() ); } }
void Warehouse::init() { _fgPictures[0] = &Picture::load(ResourceGroup::warehouse, 1); _fgPictures[1] = &Picture::load(ResourceGroup::warehouse, 18); _fgPictures[2] = _animation.getCurrentPicture(); _fgPictures[3] = _animFlag.getCurrentPicture(); // add subTiles in Z-order (from far to near) _subTiles.clear(); _subTiles.push_back( WarehouseTile( TilePos( 1, 2 ) )); _subTiles.push_back( WarehouseTile( TilePos( 0, 1 ) )); _subTiles.push_back( WarehouseTile( TilePos( 2, 2 ) )); _subTiles.push_back( WarehouseTile( TilePos( 1, 1 ) )); _subTiles.push_back( WarehouseTile( TilePos( 0, 0 ) )); _subTiles.push_back( WarehouseTile( TilePos( 2, 1 ) )); _subTiles.push_back( WarehouseTile( TilePos( 1, 0 ) )); _subTiles.push_back( WarehouseTile( TilePos( 2, 0 ) )); for (unsigned int n = 0; n<_subTiles.size(); ++n) { _fgPictures[n+4] = &_subTiles[n]._picture; } _goodStore.init(*this); GoodStock stock; stock._goodType = G_POTTERY; stock._currentQty = 300; _goodStore.store(stock, 300); computePictures(); }
void BuildingPrefecture::deliverService() { if( getWorkers() > 0 && getWalkerList().size() == 0 ) { bool fireDetect = _fireDetect.getI() >= 0; WalkerPrefectPtr walker = WalkerPrefect::create( Scenario::instance().getCity() ); walker->setMaxDistance( 26 ); //bool patrol = true; if( fireDetect ) { PathWay pathway; TilePos startPos = _accessRoads.front()->getIJ(); bool pathFounded = Pathfinder::getInstance().getPath( startPos, _fireDetect, pathway, false, Size( 0 ) ); //patrol = !pathFounded; if( pathFounded ) { walker->setPathWay( pathway ); walker->setIJ( pathway.getOrigin().getIJ() ); } _fireDetect = TilePos( -1, -1 ); } walker->send2City( BuildingPrefecturePtr( this ), fireDetect ? 200 : 0 ); addWalker( walker.as<Walker>() ); } }
void TileOverlay::build( CityPtr city, const TilePos& pos ) { Tilemap &tilemap = city->getTilemap(); _d->city = city; _d->masterTile = &tilemap.at( pos ); for (int dj = 0; dj < _d->size.getWidth(); ++dj) { for (int di = 0; di < _d->size.getHeight(); ++di) { Tile& tile = tilemap.at( pos + TilePos( di, dj ) ); tile.setMasterTile( _d->masterTile ); tile.setPicture( &_d->picture ); if( tile.getOverlay().isValid() && tile.getOverlay() != this ) { tile.getOverlay()->deleteLater(); } tile.setOverlay( this ); initTerrain( tile ); } } }
void WDT::ReadTileTable() { Chunk* chunk = Data->GetChunkByName("MAIN"); if (!chunk) return; IsValid = true; FILE* stream = chunk->GetStream(); for (int y = 0; y < 64; ++y) { for (int x = 0; x < 64; ++x) { const uint32 hasTileFlag = 0x1; uint32 flags; uint32 discard; int count = 0; count += fread(&flags, sizeof(uint32), 1, stream); count += fread(&discard, sizeof(uint32), 1, stream); if (count != 2) printf("WDT::ReadTileTable: Failed to read some data expected 2, read %d\n", count); if (flags & hasTileFlag) TileTable.push_back(TilePos(x, y)); } } }
int getGScore(AStarPoint* p) { int offset = p->tile->get_terrain().isRoad() ? -5 : +10; TilePos pos = tile ? tile->getIJ() : TilePos( 0, 0 ); TilePos otherPos = p->tile->getIJ(); return p->g + ((pos.getI() == otherPos.getI() || pos.getJ() == otherPos.getJ()) ? 10 : 14) + offset; }
/* INCORRECT! */ bool Wharf::canBuild(const TilePos& pos ) const { bool is_constructible = Construction::canBuild( pos ); // We can build wharf only on straight border of water and land // // ?WW? ???? ???? ???? // ?XX? WXX? ?XXW ?XX? // ?XX? WXX? ?XXW ?XX? // ???? ???? ???? ?WW? // bool bNorth = true; bool bSouth = true; bool bWest = true; bool bEast = true; Tilemap& tilemap = Scenario::instance().getCity().getTilemap(); std::list<Tile*> rect = tilemap.getRectangle( pos + TilePos( -1, -1 ), Size( _size+2 ), false); for (std::list<Tile*>::iterator itTiles = rect.begin(); itTiles != rect.end(); ++itTiles) { Tile &tile = **itTiles; std::cout << tile.getI() << " " << tile.getJ() << " " << pos.getI() << " " << pos.getJ() << std::endl; // if (tiles.get_terrain().isWater()) if (tile.getJ() > (pos.getJ() + _size -1) && !tile.get_terrain().isWater()) { bNorth = false; } if (tile.getJ() < pos.getJ() && !tile.get_terrain().isWater()) { bSouth = false; } if (tile.getI() > (pos.getI() + _size -1) && !tile.get_terrain().isWater()) { bEast = false; } if (tile.getI() < pos.getI() && !tile.get_terrain().isWater()) { bWest = false; } } return (is_constructible && (bNorth || bSouth || bEast || bWest)); }
TilePosList TileGrid::nearestNeighbors(TilePos origin) { TilePosList toReturn; toReturn.reserve(8); auto mods = { -1, 0, 1 }; for (auto &x : mods) { for (auto &y : mods) { if (x || y) { auto pos = TilePos(origin.x + x, origin.y + y); if (isTilePosValid(pos)) { toReturn.push_back(pos); } } } } return toReturn; }
void Fishery::timeStep(const unsigned int time ) { if( !game::Date::isMonthChanged() ) return; if( _d->places.empty() ) { _d->places = city::statistic::getWalkers<FishPlace>( _city(), walker::fishPlace, TilePos(-1, -1) ); } while( _d->places.size() < _d->maxFishPlace ) { FishPlacePtr fishplace = FishPlace::create( _city() ); TilePos travelingPoint = _city()->borderInfo().boatExit; if( !_d->locations.empty() ) { travelingPoint = _d->locations.size() > 1 ? _d->locations[ math::random( _d->locations.size() ) ] : _d->locations.front(); } fishplace->send2city( _city()->borderInfo().boatEntry, travelingPoint ); if( fishplace->isDeleted() ) { _d->nFailed++; return; } _d->places.push_back( ptr_cast<FishPlace>( fishplace ) ); } utils::eraseDeletedElements( _d->places ); }
std::list<Tile*> Tilemap::getRectangle( const TilePos& start, const TilePos& stop, const bool corners /*= true*/ ) { std::list<Tile*> res; int delta_corners = 0; if (! corners) { delta_corners = 1; } /*Rect maxRect( 0, 0, _size, _size ); Rect rect( start.getI()+delta_corners, start.getJ()+delta_corners, stop.getI()-delta_corners, stop.getJ()-delta_corners ); rect.constrainTo( maxRect ); for( int i=rect.getLeft(); i < rect.getRight(); i++ ) for( int j=rect.getTop(); j < rect.getBottom(); j++ ) ret.push_back( &at( TilePos( i, j ) ) ); */ for(int i = start.getI()+delta_corners; i <= stop.getI()-delta_corners; ++i) { if (is_inside( TilePos( i, start.getJ() ) )) { res.push_back( &at(i, start.getJ() )); } if (is_inside( TilePos( i, stop.getJ() ) )) { res.push_back( &at( i, stop.getJ() )); } } for (int j = start.getJ()+1; j <= stop.getJ()-1; ++j) // corners have been handled already { if (is_inside( TilePos( start.getI(), j ) )) { res.push_back(&at(start.getI(), j)); } if (is_inside( TilePos( stop.getI(), j ) )) { res.push_back(&at(stop.getI(), j)); } } return res; }
std::list<Tile*> Tilemap::getFilledRectangle(const TilePos& start, const TilePos& stop ) { std::list<Tile*> res; for (int i = start.getI(); i <= stop.getI(); ++i) { for (int j = start.getJ(); j <= stop.getJ(); ++j) { if( is_inside( TilePos( i, j ) )) { res.push_back(&at( TilePos( i, j ) ) ); } } } return res; }
TilePos TileOverlay::getTilePos() const { if( !_d->masterTile ) { Logger::warning( "master tile can't be null" ); return TilePos( -1, -1 ); } return _d->masterTile->getIJ(); }
Prefecture::Prefecture() : ServiceBuilding(Service::prefect, constants::building::prefecture, Size(1)) { _fireDetect = TilePos( -1, -1 ); setPicture( ResourceGroup::security, 1 ); _getAnimation().load( ResourceGroup::security, 2, 10); _getAnimation().setDelay( 4 ); _getAnimation().setOffset( Point( 20, 36 ) ); _getFgPictures().resize(1); }
Prefecture::Prefecture() : ServiceBuilding(Service::S_PREFECT, B_PREFECTURE, Size(1)) { _fireDetect = TilePos( -1, -1 ); setPicture( Picture::load( ResourceGroup::security, 1 ) ); _getAnimation().load( ResourceGroup::security, 2, 10); _getAnimation().setFrameDelay( 4 ); _getAnimation().setOffset( Point( 20, 36 ) ); _fgPictures.resize(1); }
void GameLoaderC3Map::Impl::initCameraStartPos(std::fstream &f, CityPtr ioCity) { unsigned short int i = 0; unsigned short int j = 0; f.seekg(kCamera, std::ios::beg); f.read((char*)&i, 2); f.read((char*)&j, 2); ioCity->setCameraPos( TilePos( i, j ) ); }
Tile& TileOverlay::getTile() const { if( !_d->masterTile ) { Logger::warning( "master tile must be exists" ); static Tile invalid( TilePos( -1, -1 )); return invalid; } return *_d->masterTile; }
void MarketLady::computeWalkerDestination( MarketPtr market ) { _d->market = market; std::list<GoodType> priorityGoods = _d->market->getMostNeededGoods(); _d->destBuildingPos = TilePos( -1, -1 ); // no destination yet if( priorityGoods.size() > 0 ) { // we have something to buy! // get the list of buildings within reach PathWay pathWay; Propagator pathPropagator( _d->city ); pathPropagator.init( _d->market.as<Construction>() ); pathPropagator.propagate( _d->maxDistance); // try to find the most needed good for (std::list<GoodType>::iterator itGood = priorityGoods.begin(); itGood != priorityGoods.end(); ++itGood) { _d->priorityGood = *itGood; if( _d->priorityGood == G_WHEAT || _d->priorityGood == G_FISH || _d->priorityGood == G_MEAT || _d->priorityGood == G_FRUIT || _d->priorityGood == G_VEGETABLE) { // try get that good from a granary _d->destBuildingPos = getWalkerDestination2<Granary>( pathPropagator, B_GRANARY, _d->market, _d->basket, _d->priorityGood, pathWay, _d->reservationID ); } else { // try get that good from a warehouse _d->destBuildingPos = getWalkerDestination2<Warehouse>( pathPropagator, B_WAREHOUSE, _d->market, _d->basket, _d->priorityGood, pathWay, _d->reservationID ); } if( _d->destBuildingPos.getI() >= 0 ) { // we found a destination! setPathWay(pathWay); break; } } } if( _d->destBuildingPos.getI() < 0) { // we have nothing to buy, or cannot find what we need to buy deleteLater(); return; } setIJ( _getPathway().getOrigin().getIJ() ); }
bool RoadPropagator::getPath( const Tile& destination, ConstWayOnTiles& oPathWay ) const { TilePos startPos = _d->startTile.getIJ(); TilePos stopPos = destination.getIJ(); int iStep = (startPos.getI() < stopPos.getI()) ? 1 : -1; int jStep = (startPos.getJ() < stopPos.getJ()) ? 1 : -1; std::cout << "RoadPropagator::getPath" << std::endl; StringHelper::debug( 0xff, "(%d, %d) to (%d, %d)", startPos.getI(), startPos.getJ(), stopPos.getI(), stopPos.getJ() ); if( startPos == stopPos ) { oPathWay.push_back( &_d->startTile ); return true; } std::cout << "propagate by I axis" << std::endl; // propagate on I axis for( TilePos tmp( startPos.getI(), stopPos.getJ() ); ; tmp+=TilePos( iStep, 0 ) ) { const Tile& curTile = _d->tilemap.at( tmp ); if( curTile.getTerrain().isConstructible() || curTile.getTerrain().isRoad() || curTile.getTerrain().isAqueduct() ) { StringHelper::debug( 0xff, "+ (%d, %d)", curTile.getI(), curTile.getJ() ); oPathWay.push_back( &curTile ); } else return false; if (tmp.getI() == stopPos.getI()) break; } std::cout << "propagate by J axis" << std::endl; // propagate on J axis for( int j = startPos.getJ();; j+=jStep ) { const Tile& curTile = _d->tilemap.at( startPos.getI(), j ); if( curTile.getTerrain().isConstructible() || curTile.getTerrain().isRoad() || curTile.getTerrain().isAqueduct() ) { std::cout << "+ (" << curTile.getI() << " " << curTile.getJ() << ") "; oPathWay.push_back( &curTile ); } else return false; if( j == stopPos.getJ() ) break; } return true; }
bool MarbleQuarry::canBuild( CityPtr city, const TilePos& pos ) const { bool is_constructible = Construction::canBuild( city, pos ); bool near_mountain = false; // tells if the factory is next to a mountain Tilemap& tilemap = city->getTilemap(); TilemapTiles perimetr = tilemap.getRectangle( pos + TilePos( -1, -1 ), getSize() + Size( 2 ), Tilemap::checkCorners); foreach( Tile* tile, perimetr ) { near_mountain |= tile->getFlag( Tile::tlRock ); }
void C3Map::Impl::initCameraStartPos(std::fstream &f, PlayerCityPtr ioCity) { /*unsigned short int i = 0; unsigned short int j = 0; f.seekg(kCamera, std::ios::beg); f.read((char*)&i, 2); f.read((char*)&j, 2);*/ int mapSize = ioCity->tilemap().size(); ioCity->setCameraPos( TilePos( mapSize / 2, mapSize / 2 ) ); }
void Garden::build( CityPtr city, const TilePos& pos ) { // this is the same arrangement of garden tiles as existed in C3 int theGrid[2][2] = {{113, 110}, {112, 111}}; Construction::build( city, pos ); setPicture( ResourceGroup::entertaiment, theGrid[pos.getI() % 2][pos.getJ() % 2] ); if( getSize().getArea() == 1 ) { TilemapTiles tilesAround = city->getTilemap().getRectangle( getTilePos() - TilePos( 1, 1), getTilePos() + TilePos( 1, 1 ) ); foreach( Tile* tile, tilesAround ) { GardenPtr garden = tile->getOverlay().as<Garden>(); if( garden.isValid() ) { garden->update(); } }
void GuiTilemap::checkPreviewRemove(const int i, const int j) { if (_removeTool) { Tile& cursorTile = _tilemap->at(i, j); TerrainTile& terrain = cursorTile.get_terrain(); //if( terrain.isDestructible() ) { Picture& pic_clear = PicLoader::instance().get_picture( "oc3_land", 2 ); LandOverlay* overlay = terrain.getOverlay(); if (overlay == NULL) { // this is maybe a lonely tree Tile* tile = new Tile(_tilemap->at(i, j)); // make a copy of tile tile->set_picture(&pic_clear); tile->set_master_tile(NULL); // single tile _d->postTiles.push_back( tile ); //_priorityTiles.push_back(&tile); } else { PictureConverterPtr converter = PictureConverter::create(); converter->rgbBalance( _d->buildInstncePicture, overlay->getPicture(), +0, -255, -255 ); // remove the overlay, and make single tile of cleared land int size = overlay->getSize(); TilePos tilePos = overlay->getTile().getIJ(); // master I Tile* masterTile = 0; for (int dj = 0; dj<size; ++dj) { for (int di = 0; di<size; ++di) { Tile* tile = new Tile(_tilemap->at( tilePos + TilePos( di, dj ) ) ); // make a copy of tile if (di==0 && dj==0) { // this is the masterTile masterTile = tile; } tile->set_picture( &_d->buildInstncePicture ); tile->set_master_tile( masterTile ); // single tile TerrainTile &terrain = tile->get_terrain(); terrain.setOverlay( overlay ); _d->postTiles.push_back( tile ); } } } } } }
// here the problem lays: if we remove road, it is left in _accessRoads array // also we need to recompute _accessRoads if we place new road tile // on next to this road tile buildings void Construction::computeAccessRoads() { _accessRoads.clear(); if( !_master_tile ) return; Tilemap& tilemap = Scenario::instance().getCity().getTilemap(); Uint8 maxDst2road = getMaxDistance2Road(); std::list<Tile*> rect = tilemap.getRectangle( _master_tile->getIJ() + TilePos( -maxDst2road, -maxDst2road ), _master_tile->getIJ() + TilePos( _size + maxDst2road - 1, _size + maxDst2road - 1 ), !Tilemap::checkCorners ); for (std::list<Tile*>::iterator itTiles = rect.begin(); itTiles != rect.end(); ++itTiles) { Tile* tile = *itTiles; if ( tile->get_terrain().isRoad() ) { _accessRoads.push_back( tile ); } } }
void CartPusher::save( VariantMap& stream ) const { Walker::save( stream ); stream[ "stock" ] = _d->stock.save(); stream[ "producerPos" ] = _d->producerBuilding->getTile().getIJ(); stream[ "consumerPos" ] = _d->consumerBuilding.isValid() ? _d->consumerBuilding->getTile().getIJ() : TilePos( -1, -1 ); stream[ "maxDistance" ] = _d->maxDistance; stream[ "reservationID" ] = static_cast<int>(_d->reservationID); }
void GameLoaderC3Map::Impl::initEntryExit(std::fstream &f, CityPtr ioCity) { unsigned int size = ioCity->getTilemap().getSize(); // init road entry/exit point unsigned short int i = 0; unsigned short int j = 0; f.seekg(kRoadEntry, std::ios::beg); f.read((char*)&i, 2); f.read((char*)&j, 2); ioCity->setRoadEntry( TilePos( i, size - j - 1 ) ); i = 0; j = 0; f.read((char*)&i, 2); f.read((char*)&j, 2); ioCity->setRoadExit( TilePos( i, size - j - 1 ) ); // init boat entry/exit point i = 0; j = 0; f.seekg(kBoatEntry, std::ios::beg); f.read((char*)&i, 2); f.read((char*)&j, 2); ioCity->setBoatEntry( TilePos( i, size - j - 1 ) ); i = 0; j = 0; f.read((char*)&i, 2); f.read((char*)&j, 2); ioCity->setBoatExit( TilePos( i, size - j - 1) ); //std::cout << "road entry at:" << ioCity.getRoadEntryI() << "," << ioCity.getRoadEntryJ() << std::endl; //std::cout << "road exit at:" << ioCity.getRoadExitI() << "," << ioCity.getRoadExitJ() << std::endl; //std::cout << "boat entry at:" << ioCity.getBoatEntryI() << "," << ioCity.getBoatEntryJ() << std::endl; //std::cout << "boat exit at:" << ioCity.getBoatExitI() << "," << ioCity.getBoatExitJ() << std::endl; }
bool FactoryClay::canBuild(const TilePos& pos ) const { bool is_constructible = Construction::canBuild( pos ); bool near_water = false; Tilemap& tilemap = Scenario::instance().getCity().getTilemap(); PtrTilesList rect = tilemap.getRectangle( pos + TilePos( -1, -1), Size( _size + 2 ), Tilemap::checkCorners ); for( PtrTilesList::iterator itTiles = rect.begin(); itTiles != rect.end(); ++itTiles ) { near_water |= (*itTiles)->get_terrain().isWater(); } return (is_constructible && near_water); }
void FireWorkers::exec(Game& game) { Tilemap& tilemap = game.getCity()->getTilemap(); const int defaultFireWorkersDistance = 40; for( int curRange=1; curRange < defaultFireWorkersDistance; curRange++ ) { TilemapArea perimetr = tilemap.getRectangle( _center - TilePos( curRange, curRange ), _center + TilePos( curRange, curRange ) ); foreach( Tile* tile, perimetr ) { WorkingBuildingPtr wrkBuilding = tile->getOverlay().as<WorkingBuilding>(); if( wrkBuilding.isValid() ) { int bldWorkersCount = wrkBuilding->getWorkersCount(); wrkBuilding->removeWorkers( _workers ); _workers -= math::clamp<int>( bldWorkersCount, 0, _workers ); } if( !_workers ) return; } }
bool IronMine::canBuild(const TilePos& pos ) const { bool is_constructible = WorkingBuilding::canBuild( pos ); bool near_mountain = false; // tells if the factory is next to a mountain Tilemap& tilemap = Scenario::instance().getCity()->getTilemap(); PtrTilesArea rect = tilemap.getRectangle( pos + TilePos( -1, -1 ), getSize() + Size(2), Tilemap::checkCorners ); for( PtrTilesArea::iterator itTiles = rect.begin(); itTiles != rect.end(); ++itTiles) { near_mountain |= (*itTiles)->getTerrain().isRock(); } return (is_constructible && near_mountain); }