void Religion::drawTile(Engine& engine, Tile& tile, const Point& offset) { Point screenPos = tile.mappos() + offset; if( tile.overlay().isNull() ) { //draw background //engine.draw( tile.picture(), screenPos ); drawPass( engine, tile, offset, Renderer::ground ); drawPass( engine, tile, offset, Renderer::groundAnimation ); } else { bool needDrawAnimations = false; OverlayPtr overlay = tile.overlay(); int religionLevel = -1; if( _isVisibleObject( overlay->type() ) ) { // Base set of visible objects needDrawAnimations = true; } else if( overlay->type() == object::house ) { HousePtr house = ptr_cast<House>( overlay ); religionLevel = (int) house->getServiceValue(Service::religionMercury); religionLevel += house->getServiceValue(Service::religionVenus); religionLevel += house->getServiceValue(Service::religionMars); religionLevel += house->getServiceValue(Service::religionNeptune); religionLevel += house->getServiceValue(Service::religionCeres); religionLevel = math::clamp( religionLevel / (house->spec().minReligionLevel()+1), 0, 100 ); needDrawAnimations = (house->spec().level() == 1) && house->habitants().empty(); if( !needDrawAnimations ) { drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase ); } } else { drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } if( needDrawAnimations ) { Layer::drawTile( engine, tile, offset ); registerTileForRendering( tile ); } else if( religionLevel > 0 ) { drawColumn( engine, screenPos, religionLevel ); } } tile.setWasDrawn(); }
int Education::_getLevelValue( HousePtr house ) const { switch(_type) { case citylayer::education: { float acc = 0; int level = house->spec().minEducationLevel(); switch(level) { case 3: acc += house->getServiceValue( Service::academy ); case 2: acc += house->getServiceValue( Service::library ); case 1: acc += house->getServiceValue( Service::school ); return static_cast<int>(acc / level); default: return 0; } } case citylayer::school: return (int) house->getServiceValue( Service::school ); case citylayer::library: return (int) house->getServiceValue( Service::library ); case citylayer::academy: return (int) house->getServiceValue( Service::academy ); } return 0; }
void Religion::handleEvent(NEvent& event) { if( event.EventType == sEventMouse ) { switch( event.mouse.type ) { case mouseMoved: { Tile* tile = _camera()->at( event.mouse.pos(), false ); // tile under the cursor (or NULL) std::string text = ""; if( tile != 0 ) { HousePtr house = ptr_cast<House>( tile->overlay() ); if( house.isValid() ) { int templeAccess = house->spec().computeReligionLevel( house ); bool oracleAccess = house->hasServiceAccess( Service::oracle ); text = (templeAccess == 5 && oracleAccess ) ? "##religion_access_full##" : utils::format( 0xff, "##religion_access_%d_temple##", templeAccess ); } } _setTooltipText( _(text) ); } break; default: break; } } Layer::handleEvent( event ); }
void Health::drawTile(Engine& engine, Tile& tile, const Point& offset) { Point screenPos = tile.mappos() + offset; if( tile.overlay().isNull() ) { //draw background //engine.draw( tile.picture(), screenPos ); drawPass( engine, tile, offset, Renderer::ground ); drawPass( engine, tile, offset, Renderer::groundAnimation ); } else { bool needDrawAnimations = false; OverlayPtr overlay = tile.overlay(); int healthLevel = -1; if( _isVisibleObject( overlay->type() ) ) { // Base set of visible objects needDrawAnimations = true; } else if( _flags.count( overlay->type() ) ) { needDrawAnimations = true; //city::Helper helper( _city() ); //drawArea( engine, helper.getArea( overlay ), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } else if( overlay->type() == object::house ) { HousePtr house = ptr_cast<House>( overlay ); healthLevel = _getLevelValue( house ); needDrawAnimations = (house->spec().level() == 1) && (house->habitants().empty()); if( !needDrawAnimations ) { drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase ); } } else //other buildings { drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } if( needDrawAnimations ) { Layer::drawTile( engine, tile, offset ); registerTileForRendering( tile ); } else if( healthLevel > 0 ) { drawColumn( engine, screenPos, healthLevel ); } } tile.setWasDrawn(); }
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 Unemployed::drawTile(Engine& engine, Tile& tile, const Point& offset) { Point screenPos = tile.mappos() + offset; if( tile.overlay().isNull() ) { //draw background //engine.draw( tile.picture(), screenPos ); drawPass( engine, tile, offset, Renderer::ground ); drawPass( engine, tile, offset, Renderer::groundAnimation ); } else { bool needDrawAnimations = false; OverlayPtr overlay = tile.overlay(); WorkingBuildingPtr workBuilding = overlay.as<WorkingBuilding>(); int worklessPercent = 0; if( _isVisibleObject( overlay->type() ) ) { needDrawAnimations = true; } else if( overlay->type() == object::house ) { HousePtr house = overlay.as<House>(); int worklessNumber = (int)house->getServiceValue( Service::recruter ); int matureNumber = (int)house->habitants().mature_n(); worklessPercent = math::percentage( worklessNumber, matureNumber ); needDrawAnimations = (house->spec().level() == 1) && house->habitants().empty(); if( !needDrawAnimations ) { drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase ); } } else if( workBuilding.isValid() ) { worklessPercent = math::percentage( workBuilding->needWorkers(), workBuilding->maximumWorkers() ); needDrawAnimations = workBuilding->needWorkers() > 0; if( !needDrawAnimations ) drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } if( needDrawAnimations ) { Layer::drawTile( engine, tile, offset ); registerTileForRendering( tile ); } else if( worklessPercent > 0 ) { drawColumn( engine, screenPos, worklessPercent ); } } tile.setWasDrawn(); }
int Entertainment::_getLevelValue( HousePtr house ) { switch( _type ) { case citylayer::entertainment: { int entLevel = house->spec().computeEntertainmentLevel( house ); int minLevel = house->spec().minEntertainmentLevel(); return math::percentage( entLevel, minLevel ); } case citylayer::theater: return (int) house->getServiceValue( Service::theater ); case citylayer::amphitheater: return (int) house->getServiceValue( Service::amphitheater ); case citylayer::colloseum: return (int) house->getServiceValue( Service::colloseum ); case citylayer::hippodrome: return (int) house->getServiceValue( Service::hippodrome ); } return 0; }
void Peace::buildingDestroyed(gfx::TileOverlayPtr overlay) { HousePtr house = ptr_cast<House>( overlay ); if( house.isValid() && house->spec().level() > HouseLevel::tent ) { _d->significantBuildingsDestroyed = true; } else { _d->significantBuildingsDestroyed |= !_d->unsignificantBuildings.count( overlay->type() ); } }
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 ); drawPass( engine, tile, offset, Renderer::ground ); drawPass( engine, tile, offset, Renderer::groundAnimation ); } else { bool needDrawAnimations = false; OverlayPtr overlay = tile.overlay(); int fireLevel = 0; if( _isVisibleObject( overlay->type() ) ) { // Base set of visible objects needDrawAnimations = true; } else if( overlay->type() == object::house ) { HousePtr house = ptr_cast<House>( overlay ); fireLevel = (int)house->state( pr::fire ); needDrawAnimations = (house->spec().level() == 1) && house->habitants().empty(); drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase ); } else //other buildings { ConstructionPtr constr = ptr_cast<Construction>( overlay ); if( constr != 0 ) { fireLevel = (int)constr->state( pr::fire ); } drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } if( needDrawAnimations ) { Layer::drawTile( engine, tile, offset ); registerTileForRendering( tile ); } else if( fireLevel >= 0) { _addColumn( screenPos, fireLevel ); } } tile.setWasDrawn(); }
void Sentiment::drawTile(Engine& engine, Tile& tile, const Point& offset) { Point screenPos = tile.mappos() + offset; if( tile.overlay().isNull() ) { //draw background //engine.draw( tile.picture(), screenPos ); drawPass( engine, tile, offset, Renderer::ground ); drawPass( engine, tile, offset, Renderer::groundAnimation ); } else { bool needDrawAnimations = false; OverlayPtr overlay = tile.overlay(); int sentimentLevel = 0; if( _isVisibleObject( overlay->type() ) ) { needDrawAnimations = true; } else if( overlay->type() == object::house ) { HousePtr house = overlay.as<House>(); sentimentLevel = (int)house->state( pr::happiness ); needDrawAnimations = (house->spec().level() == 1) && house->habitants().empty(); if( !needDrawAnimations ) { drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::inHouseBase ); } } else { drawArea( engine, overlay->area(), offset, ResourceGroup::foodOverlay, OverlayPic::base ); } if( needDrawAnimations ) { Layer::drawTile( engine, tile, offset ); registerTileForRendering( tile ); } else if( sentimentLevel > 0 ) { drawColumn( engine, screenPos, 100 - sentimentLevel ); } } tile.setWasDrawn(); }
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(); }
void Rioter::timeStep(const unsigned long time) { Walker::timeStep( time ); switch( _d->state ) { case Impl::searchHouse: { city::Helper helper( _city() ); ConstructionList constructions = helper.find<Construction>( objects::house ); for( ConstructionList::iterator it=constructions.begin(); it != constructions.end(); ) { HousePtr h = ptr_cast<House>( *it ); if( h->spec().level() <= _d->houseLevel ) { it=constructions.erase( it ); } else { ++it; } } Pathway pathway = _d->findTarget( _city(), constructions, pos() ); //find more expensive house, fire this!!! if( pathway.isValid() ) { setPos( pathway.startPos() ); setPathway( pathway ); go(); _d->state = Impl::go2destination; } else //not find house, try find any, that rioter can destroy { _d->state = Impl::searchAnyBuilding; } } break; case Impl::searchAnyBuilding: { city::Helper helper( _city() ); ConstructionList constructions = helper.find<Construction>( objects::house ); for( ConstructionList::iterator it=constructions.begin(); it != constructions.end(); ) { TileOverlay::Type type = (*it)->type(); TileOverlay::Group group = (*it)->group(); if( type == objects::house || type == objects::road || _d->excludeGroups.count( group ) > 0 ) { it=constructions.erase( it ); } else { it++; } } Pathway pathway = _d->findTarget( _city(), constructions, pos() ); if( pathway.isValid() ) { setPos( pathway.startPos() ); setPathway( pathway ); go(); _d->state = Impl::go2destination; } else { _d->state = Impl::go2anyplace; } } break; case Impl::go2anyplace: { Pathway pathway = PathwayHelper::randomWay( _city(), pos(), 10 ); if( pathway.isValid() ) { setPathway( pathway ); go(); _d->state = Impl::go2destination; } else { die(); _d->state = Impl::wait; } } break; case Impl::go2destination: case Impl::wait: break; case Impl::destroyConstruction: { if( game::Date::isDayChanged() ) { city::Helper helper( _city() ); ConstructionList constructions = helper.find<Construction>( objects::any, pos() - TilePos( 1, 1), pos() + TilePos( 1, 1) ); for( ConstructionList::iterator it=constructions.begin(); it != constructions.end(); ) { if( (*it)->type() == objects::road || _d->excludeGroups.count( (*it)->group() ) > 0 ) { it=constructions.erase( it ); } else { ++it; } } if( constructions.empty() ) { _animationRef().clear(); _setAction( acMove ); _d->state = Impl::searchHouse; } else { foreach( it, constructions ) { ConstructionPtr c = *it; c->updateState( Construction::fire, 1 ); c->updateState( Construction::damage, 1 ); if( c->state( Construction::damage ) < 10 || c->state( Construction::fire ) < 10 ) { events::GameEventPtr e = events::Disaster::create( c->tile(), events::Disaster::riots ); e->dispatch(); } break; } } } } break; default: break; }
void Info::timeStep(const unsigned int time ) { if( !game::Date::isMonthChanged() ) return; if( game::Date::current().month() != _d->lastDate.month() ) { bool yearChanged = game::Date::current().year() != _d->lastDate.year(); _d->lastDate = game::Date::current(); _d->lastYearHistory.erase( _d->lastYearHistory.begin() ); _d->lastYearHistory.push_back( Parameters() ); Parameters& last = _d->lastYearHistory.back(); last.date = _d->lastDate; last[ population ] = _city()->population(); last[ funds ] = _city()->funds().treasury(); last[ taxpayes ] = 0;//_d->city->getLastMonthTaxpayer(); last[ foodStock ] = statistic::getFoodStock( _city() ); last[ foodMontlyConsumption ] = statistic::getFoodMonthlyConsumption( _city() ); last[ monthWithFood ] = last[ foodMontlyConsumption ] > 0 ? (last[ foodStock ] / last[ foodMontlyConsumption ]) : 0; int foodProducing = statistic::getFoodProducing( _city() ); int yearlyFoodConsumption = last[ foodMontlyConsumption ] * DateTime::monthsInYear; last[ foodKoeff ] = ( foodProducing - yearlyFoodConsumption > 0 ) ? foodProducing / (yearlyFoodConsumption+1) : -(yearlyFoodConsumption / (foodProducing+1) ); int currentWorkers, rmaxWorkers; statistic::getWorkersNumber( _city(), currentWorkers, rmaxWorkers ); last[ needWorkers ] = rmaxWorkers - currentWorkers; last[ maxWorkers ] = rmaxWorkers; last[ workless ] = statistic::getWorklessPercent( _city() ); last[ payDiff ] = _city()->empire()->workerSalary() - _city()->funds().workerSalary(); last[ tax ] = _city()->funds().taxRate(); last[ cityWages ] = _city()->funds().workerSalary(); last[ romeWages ] = _city()->empire()->workerSalary(); last[ crimeLevel ] = statistic::getCrimeLevel( _city() ); last[ favour ] = _city()->favour(); last[ prosperity ] = _city()->prosperity(); last[ monthWtWar ] = statistic::months2lastAttack( _city() ); last[ peace ] = 0; PeacePtr peaceSrvc; peaceSrvc << _city()->findService( Peace::defaultName() ); if( peaceSrvc.isValid() ) { last[ peace ] = peaceSrvc->value(); } MilitaryPtr mil; mil << _city()->findService( Military::defaultName() ); if( mil.isValid() ) { last[ Info::milthreat ] = mil->threatValue(); } Helper helper( _city() ); HouseList houses = helper.find<House>( objects::house ); last[ houseNumber ] = 0; last[ shackNumber ] = 0; foreach( it, houses ) { HousePtr h = *it; if( h->habitants().count() > 0 ) { int hLvl = h->spec().level(); last[ slumNumber ] += ( hLvl == HouseLevel::hovel || hLvl == HouseLevel::tent ? 1 : 0); last[ shackNumber ] += ( hLvl >= HouseLevel::shack || hLvl < HouseLevel::hut ? 1 : 0); last[ houseNumber ]++; } }