void Tax::drawTile(Engine& engine, Tile& tile, const Point& offset) { Point screenPos = tile.mappos() + offset; if( tile.overlay().isNull() ) { //draw background engine.draw( tile.picture(), screenPos ); } else { bool needDrawAnimations = false; TileOverlayPtr overlay = tile.overlay(); int taxLevel = -1; if( _isVisibleObject( overlay->type() ) ) { // Base set of visible objects needDrawAnimations = true; } else if( overlay->type() == objects::house ) { HousePtr house = ptr_cast<House>( overlay ); //taxLevel = house->getServiceValue( Service::forum ); taxLevel = math::clamp<int>( house->taxesThisYear(), 0, 100 ); needDrawAnimations = (house->spec().level() == 1) && (house->habitants().empty()); if( needDrawAnimations ) { int taxAccess = house->hasServiceAccess( Service::forum ); needDrawAnimations = (taxAccess < 25); } if( !needDrawAnimations ) { city::Helper helper( _city() ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase ); } } else { city::Helper helper( _city() ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } if( needDrawAnimations ) { Layer::drawTile( engine, tile, offset ); registerTileForRendering( tile ); } else if( taxLevel > 0 ) { _addColumn( screenPos, taxLevel ); //drawColumn( engine, screenPos, taxLevel ); } } tile.setWasDrawn(); }
void Fire::drawTile(Engine& engine, Tile& tile, const Point& offset) { Point screenPos = tile.mappos() + offset; if( tile.overlay().isNull() ) { //draw background engine.draw( tile.picture(), screenPos ); } else { bool needDrawAnimations = false; TileOverlayPtr overlay = tile.overlay(); int fireLevel = 0; if( _isVisibleObject( overlay->type() ) ) { // Base set of visible objects needDrawAnimations = true; } else if( overlay->type() == objects::house ) { HousePtr house = ptr_cast<House>( overlay ); fireLevel = (int)house->state( Construction::fire ); needDrawAnimations = (house->spec().level() == 1) && house->habitants().empty(); city::Helper helper( _city() ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase ); } else //other buildings { ConstructionPtr constr = ptr_cast<Construction>( overlay ); if( constr != 0 ) { fireLevel = (int)constr->state( Construction::fire ); } city::Helper helper( _city() ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } if( needDrawAnimations ) { Layer::drawTile( engine, tile, offset ); registerTileForRendering( tile ); } else if( fireLevel >= 0) { _addColumn( screenPos, fireLevel ); } } tile.setWasDrawn(); }
void LoaderHelper::decodeTerrain( Tile &oTile, PlayerCityPtr city, unsigned int forceId ) { unsigned int imgId = oTile.originalImgId(); TileOverlay::Type ovType = construction::unknown; if( oTile.getFlag( Tile::tlRoad ) ) // road { ovType = construction::road; Picture pic = Picture::load( ResourceGroup::land1a, 230 + math::random( 59) ); oTile.setPicture( pic ); oTile.setOriginalImgId( TileHelper::convPicName2Id( pic.name() ) ); } else if( (imgId >= 372 && imgId <= 427) ) { oTile.setFlag( Tile::tlCoast, true ); if( imgId >= 388 ) oTile.setFlag( Tile::tlRubble, true ); } else /*if( oTile.getFlag( Tile::tlBuilding ) )*/ { unsigned id = forceId > 0 ? forceId : oTile.originalImgId(); ovType = convImgId2ovrType( id ); } if( ovType == construction::unknown ) return; TileOverlayPtr overlay; // This is the overlay object, if any overlay = TileOverlayFactory::instance().create( ovType ); if( ovType == building::elevation ) { std::string elevationPicName = TileHelper::convId2PicName( oTile.originalImgId() ); overlay->setPicture( Picture::load( elevationPicName ) ); } if( overlay != NULL ) { //Logger::warning( "Building at ( %d, %d ) with ID: %x", oTile.i(), oTile.j(), oTile.originalImgId() ); if( oTile.overlay().isValid() ) return; overlay->build( city, oTile.pos() ); city->overlays().push_back( overlay ); } }
void GameLoaderC3Map::Impl::decodeTerrain(Tile &oTile, CityPtr city ) { if (!oTile.isMasterTile() && oTile.getMasterTile()!=NULL) return; TileOverlayPtr overlay; // This is the overlay object, if any if( oTile.getFlag( Tile::tlRoad ) ) // road { overlay = TileOverlayFactory::getInstance().create( B_ROAD ).as<TileOverlay>(); } else if( oTile.getFlag( Tile::tlBuilding ) ) { StringHelper::debug( 0xff, "Building at ( %d, %d ) with ID: %x", oTile.getI(), oTile.getJ(), oTile.getOriginalImgId() ); switch ( oTile.getOriginalImgId() ) { case 0xb0e: case 0xb0f: case 0xb0b: case 0xb0c: overlay = TileOverlayFactory::getInstance().create( B_NATIVE_HUT ).as<TileOverlay>(); break; case 0xb10: case 0xb0d: overlay = TileOverlayFactory::getInstance().create( B_NATIVE_CENTER ).as<TileOverlay>(); StringHelper::debug( 0xff, "creation of Native center at (%d,%d)", oTile.getI(), oTile.getJ() ); break; case 0xb11: case 0xb44: overlay = TileOverlayFactory::getInstance().create( B_NATIVE_FIELD ).as<TileOverlay>(); break; } } //terrain.setOverlay( overlay ); if( overlay != NULL ) { overlay->build( city, oTile.getIJ() ); city->getOverlayList().push_back(overlay); } }
void CityServiceFishPlace::update( const unsigned int time ) { if( time % 44 != 1 ) return; if( _d->places.empty() ) { CityHelper helper( _d->city ); _d->places = helper.find<FishPlace>( constants::place::fishPlace ); } while( _d->places.size() < _d->maxFishPlace ) { TileOverlayPtr fishplace = TileOverlayFactory::getInstance().create( constants::place::fishPlace ); if( fishplace != 0 ) { fishplace->build( _d->city, _d->city->getBorderInfo().boatEntry ); _d->city->addOverlay( fishplace ); _d->places.push_back( fishplace.as<FishPlace>() ); } } FishPlaceList::iterator fit = _d->places.begin(); while( fit != _d->places.end() ) { if( (*fit)->isDeleted() ) { fit = _d->places.erase( fit ); } else { fit++; } } }
bool LowBridge::canBuild(PlayerCityPtr city, TilePos pos, const TilesArray& ) const { //bool is_constructible = Construction::canBuild( pos ); TilePos endPos, startPos; _d->direction=noneDirection; TileOverlayPtr bridge = city->getOverlay( pos ); if( bridge.isNull() ) { _d->subtiles.clear(); LowBridge* thisp = const_cast< LowBridge* >( this ); thisp->_fgPicturesRef().clear(); _checkParams( city, _d->direction, startPos, endPos, pos ); if( _d->direction != noneDirection ) { thisp->_computePictures( city, startPos, endPos, _d->direction ); } } return (_d->direction != noneDirection); }
void Disaster::_exec( Game& game, unsigned int ) { Tilemap& tmap = game.city()->tilemap(); Tile& tile = tmap.at( _pos ); TilePos rPos = _pos; bool mayContinue = tile.getFlag( Tile::isDestructible ); if( _type == Disaster::rift ) { mayContinue = tile.getFlag( Tile::isConstructible ); mayContinue |= is_kind_of<Construction>( tile.overlay() ); } if( mayContinue ) { Size size( 1 ); TileOverlayPtr overlay = tile.overlay(); if( overlay.isValid() ) { overlay->deleteLater(); rPos = overlay->pos(); size = overlay->size(); } switch( _type ) { case Disaster::collapse: { GameEventPtr e = PlaySound::create( "explode", rand() % 2, 100 ); e->dispatch(); } break; default: break; } city::PeacePtr peaceSrvc; peaceSrvc << game.city()->findService( city::Peace::defaultName() ); if( peaceSrvc.isValid() ) { peaceSrvc->buildingDestroyed( overlay, _type ); } TilesArray clearedTiles = tmap.getArea( rPos, size ); foreach( tile, clearedTiles ) { bool needBuildRuins = !( _type == Disaster::rift && (*tile)->pos() == _pos ); TileOverlayPtr ov; if( needBuildRuins ) { TileOverlay::Type dstr2constr[] = { objects::burning_ruins, objects::collapsed_ruins, objects::plague_ruins, objects::collapsed_ruins, objects::collapsed_ruins }; ov = TileOverlayFactory::instance().create( dstr2constr[_type] ); if( ov.isValid() ) { SmartPtr< Ruins > ruins = ptr_cast< Ruins >( ov ); if( ruins.isValid() ) { std::string typev = _infoType > 1000 ? utils::format( 0xff, "house%02d", _infoType - 1000 ) : MetaDataHolder::findTypename( _infoType ); ruins->setInfo( utils::format( 0xff, "##ruins_%s_text##", typev.c_str() ) ); ruins->afterBuild(); } } } else { ov = TileOverlayFactory::instance().create( objects::rift ); TilesArray tiles = game.city()->tilemap().getNeighbors(_pos, Tilemap::FourNeighbors); /*foreach( it, tiles ) { ConstructionPtr c = ptr_cast<Construction>( (*it)->overlay() ); if( c.isValid() ) { c->burn(); } }*/ } Dispatcher::instance().append( BuildAny::create( (*tile)->pos(), ov ) ); } std::string dstr2string[] = { "##alarm_fire_in_city##", "##alarm_building_collapsed##", "##alarm_plague_in_city##", "##alarm_earthquake##" }; emit game.city()->onDisasterEvent()( _pos, _( dstr2string[_type] ) ); }
void LayerEntertainment::drawTile(Engine& engine, Tile& tile, const Point& offset) { Point screenPos = tile.mappos() + offset; if( tile.overlay().isNull() ) { //draw background engine.draw( tile.picture(), screenPos ); } else { bool needDrawAnimations = false; TileOverlayPtr overlay = tile.overlay(); int entertainmentLevel = -1; switch( overlay->type() ) { // Base set of visible objects case construction::road: case construction::plaza: case construction::garden: case building::burnedRuins: case building::collapsedRuins: case building::lowBridge: case building::highBridge: case building::elevation: case building::rift: needDrawAnimations = true; break; case building::theater: case building::amphitheater: case building::colloseum: case building::hippodrome: case building::lionsNursery: case building::actorColony: case building::gladiatorSchool: needDrawAnimations = _flags.count( overlay->type() ) > 0; if( !needDrawAnimations ) { city::Helper helper( _city() ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } break; //houses case building::house: { HousePtr house = ptr_cast<House>( overlay ); entertainmentLevel = _getLevelValue( house ); needDrawAnimations = (house->spec().level() == 1) && (house->habitants().empty()); city::Helper helper( _city() ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase ); } break; //other buildings default: { city::Helper helper( _city() ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } break; } if( needDrawAnimations ) { Layer::drawTile( engine, tile, offset ); registerTileForRendering( tile ); } else if( entertainmentLevel > 0 ) { _addColumn( screenPos, entertainmentLevel ); } } tile.setWasDrawn(); }
static void __createRivers(Game& game ) { PlayerCityPtr oCity = game.city(); Tilemap& oTilemap = oCity->tilemap(); TerrainGeneratorHelper tgHelper; Pathfinder& pathfinder = Pathfinder::instance(); pathfinder.setCondition( makeDelegate( &tgHelper, &TerrainGeneratorHelper::canBuildRiver ) ); TilesArray terrainTiles = oTilemap.getArea( TilePos(0,0), Size( oTilemap.size() ) ); for( TilesArray::iterator it=terrainTiles.begin(); it != terrainTiles.end(); ) { Tile* tile = *it; if( tile->isWalkable( true ) || tile->getFlag( Tile::tlTree ) ) { ++it; } else { it = terrainTiles.erase( it ); } } int riverCount = 0; for( int tryCount=0; tryCount < 20; tryCount++ ) { if( riverCount++ > oTilemap.size() / 60 ) break; Tile* centertile = terrainTiles.random(); Pathway way; for( int range=0; range < 99; range++ ) { TilesArray perimeter = oTilemap.getRectangle( range, centertile->pos() ); foreach( it, perimeter ) { Tile* currentTile = *it; if( currentTile->getFlag( Tile::tlWater ) ) { way = pathfinder.getPath( *centertile, *currentTile, Pathfinder::customCondition | Pathfinder::fourDirection ); if( way.isValid() ) { break; } } } if( way.isValid() ) break; } if( way.isValid() ) { TilesArray wayTiles = way.allTiles(); foreach( it, wayTiles ) { TileOverlayPtr overlay = TileOverlayFactory::instance().create( constants::objects::river ); //Picture pic = Picture::load( ResourceGroup::land1a, 62 + math::random( 57 ) ); (*it)->setPicture( Picture::getInvalid() ); //(*it)->setOriginalImgId( TileHelper::convPicName2Id( pic.name() ) ); (*it)->setOriginalImgId( 0 ); bool isWater = (*it)->getFlag( Tile::tlWater ); CityAreaInfo info = { oCity, (*it)->pos(), TilesArray() }; overlay->build( info ); oCity->overlays().push_back( overlay ); if( isWater ) break; }
void BuildAny::_exec( Game& game, unsigned int ) { if( _overlay.isNull() ) return; TileOverlayPtr ctOv = game.city()->getOverlay( _pos ); bool mayBuild = true; if( ctOv.isValid() ) { mayBuild = ctOv->isDestructible(); } city::Helper helper( game.city() ); TilePos offset(10, 10); EnemySoldierList enemies = helper.find<EnemySoldier>( walker::any, _pos - offset, _pos + offset ); if( !enemies.empty() && _overlay->group() != objects::disasterGroup ) { GameEventPtr e = WarningMessage::create( "##too_close_to_enemy_troops##" ); e->dispatch(); return; } if( !_overlay->isDeleted() && mayBuild ) { CityAreaInfo info = { game.city(), _pos, TilesArray() }; bool buildOk = _overlay->build( info ); if( !buildOk ) return; helper.updateDesirability( _overlay, city::Helper::onDesirability ); game.city()->addOverlay( _overlay ); ConstructionPtr construction = ptr_cast<Construction>( _overlay ); if( construction.isValid() ) { const MetaData& buildingData = MetaDataHolder::getData( _overlay->type() ); game.city()->funds().resolveIssue( FundIssue( city::Funds::buildConstruction, -(int)buildingData.getOption( MetaDataOptions::cost ) ) ); if( construction->group() != objects::disasterGroup ) { GameEventPtr e = PlaySound::create( "buildok", 1, 100 ); e->dispatch(); } if( construction->isNeedRoadAccess() && construction->getAccessRoads().empty() ) { GameEventPtr e = WarningMessage::create( "##building_need_road_access##" ); e->dispatch(); } std::string error = construction->errorDesc(); if( !error.empty() ) { GameEventPtr e = WarningMessage::create( error ); e->dispatch(); } WorkingBuildingPtr wb = ptr_cast<WorkingBuilding>( construction ); if( wb.isValid() && wb->maximumWorkers() > 0 ) { unsigned int worklessCount = statistic::getWorklessNumber( game.city() ); if( worklessCount < wb->maximumWorkers() ) { GameEventPtr e = WarningMessage::create( "##city_need_more_workers##" ); e->dispatch(); } } } } else { ConstructionPtr construction = ptr_cast<Construction>( _overlay ); if( construction.isValid() ) { GameEventPtr e = WarningMessage::create( construction->errorDesc() ); e->dispatch(); } } }
void LayerHealth::drawTile(GfxEngine& engine, Tile& tile, Point offset) { Point screenPos = tile.getXY() + offset; tile.setWasDrawn(); bool needDrawAnimations = false; if( tile.getOverlay().isNull() ) { //draw background engine.drawPicture( tile.getPicture(), screenPos ); } else { TileOverlayPtr overlay = tile.getOverlay(); int healthLevel = -1; switch( overlay->getType() ) { //fire buildings and roads case construction::road: case construction::B_PLAZA: needDrawAnimations = true; engine.drawPicture( tile.getPicture(), screenPos ); break; case building::B_DOCTOR: case building::B_HOSPITAL: case building::B_BARBER: case building::B_BATHS: needDrawAnimations = _flags.count( overlay->getType() ); if( needDrawAnimations ) { engine.drawPicture( tile.getPicture(), screenPos ); } else { CityHelper helper( _city ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } break; //houses case building::house: { HousePtr house = overlay.as< House >(); if( _flags.count( building::B_DOCTOR ) ) { healthLevel = house->getHealthLevel(); } else if( _flags.count( building::B_HOSPITAL ) ) { healthLevel = house->getServiceValue( Service::hospital ); } else if( _flags.count( building::B_BARBER ) ) { healthLevel = house->getServiceValue( Service::barber ); } else if( _flags.count( building::B_BATHS ) ) { healthLevel = house->getServiceValue( Service::baths ); } needDrawAnimations = (house->getSpec().getLevel() == 1) && (house->getHabitants().size() == 0); CityHelper helper( _city ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase ); } break; //other buildings default: { CityHelper helper( _city ); drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } break; } if( needDrawAnimations ) { _renderer->registerTileForRendering( tile ); } else if( healthLevel > 0 ) { drawColumn( engine, screenPos, 9, healthLevel ); } } }