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(); }
void AboutConstruction::_resolveToggleWorking() { WorkingBuildingPtr working = base().as<WorkingBuilding>(); if( working.isValid() ) { working->setActive( !working->isActive() ); _setWorkingActive( working->isActive() ); } }
InfoBoxWorkingBuilding::InfoBoxWorkingBuilding( Widget* parent, WorkingBuildingPtr building) : GuiInfoBox( parent, Rect( 0, 0, 510, 256 ), -1 ), _sd( new Impl ) { _sd->building = building; setTitle( BuildingDataHolder::instance().getData( building->getType() ).getPrettyName() ); paint(); }
void Unemployed::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 = tile->overlay().as<House>(); WorkingBuildingPtr workBuilding = tile->overlay().as<WorkingBuilding>(); if( house.isValid() ) { int workless = house->getServiceValue( Service::recruter ); if( workless > 0 ) text = utils::format( 0xff, "%s %d %s", _("##this_house_have##"), workless, _("##unemployers##") ); else text = "##this_house_haveno_unemployers##"; } else if( workBuilding.isValid() ) { int need = workBuilding->needWorkers(); if( need > 0 ) text = utils::format( 0xff, "%s %d %s", _("##this_building_need##"), need, _("##workers##") ); else text = "##this_building_have_all_workers##"; } } _setTooltipText( text ); } break; default: break; } } Layer::handleEvent( event ); }
bool WorkersHire::Impl::haveRecruter( WorkingBuildingPtr building ) { for( auto recruter : recrutesInCity ) { if( recruter->baseLocation() == building->pos() ) return true; } return false; }
void WorkersHire::Impl::hireWorkers(PlayerCityPtr city, WorkingBuildingPtr bld) { if( excludeTypes.count( bld->type() ) > 0 ) return; if( bld->numberWorkers() == bld->maximumWorkers() ) return; if( haveRecruter( bld ) ) return; if( bld->roadside().size() > 0 ) { RecruterPtr hr = Recruter::create( city ); hr->setPriority( priorities ); hr->setMaxDistance( distance ); hr->send2City( bld, bld->needWorkers() ); } }
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; } }
int Statistic::_Objects::laborAccess(WorkingBuildingPtr wb) const { if( wb.isNull() ) return 0; TilePos offset( maxLaborDistance, maxLaborDistance ); TilePos wbpos = wb->pos(); HouseList houses = find<House>( object::house, wbpos - offset, wbpos + offset ); float averageDistance = 0; for( auto house : houses ) { if( house->level() > HouseLevel::vacantLot && house->level() < HouseLevel::smallVilla ) { averageDistance += wbpos.distanceFrom( house->pos() ); } } if( houses.size() > 0 ) averageDistance /= houses.size(); return math::clamp( math::percentage( averageDistance, maxLaborDistance ) * 2, 25, 100 ); }
void FireWorkers::_exec(Game& game, unsigned int) { Tilemap& tilemap = game.city()->tilemap(); for( int curRange=1; curRange < defaultReturnWorkersDistance; curRange++ ) { TilePos range( curRange, curRange ); TilesArray perimetr = tilemap.rect( _center - range, _center + range ); for( auto& tile : perimetr ) { WorkingBuildingPtr wrkBuilding = tile->overlay<WorkingBuilding>(); if( wrkBuilding.isValid() ) { int removedFromWb = wrkBuilding->removeWorkers( _workers ); _workers -= removedFromWb; } if( !_workers ) return; } } if( _workers > 0 ) { WorkingBuildingList buildings = game.city()->statistic().objects.find<WorkingBuilding>( object::any ); for( auto&& building : buildings ) { int removedFromWb = building->removeWorkers( _workers ); _workers -= removedFromWb; if( !_workers ) return; } } }
void CityServiceWorkersHire::_hireByType( const BuildingType type ) { CityHelper hlp( _city ); WorkingBuildings buildings = hlp.getBuildings< WorkingBuilding >( type ); for( WorkingBuildings::iterator it = buildings.begin(); it != buildings.end(); ++it ) { WorkingBuildingPtr wb = *it; if( _haveHr( wb ) ) continue; if( wb.isValid() && wb->getAccessRoads().size() > 0 && wb->getWorkers() < wb->getMaxWorkers() ) { WorkersHunterPtr hr = WorkersHunter::create( _city ); hr->setMaxDistance( 20 ); hr->send2City( wb, wb->getMaxWorkers() - wb->getWorkers()); } } }
void AboutConstruction::_updateWorkingText() { WorkingBuildingPtr working = base().as<WorkingBuilding>(); _setWorkingActive( working.isValid() ? working->isActive() : false ); }
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(); } } }
foreach( WorkingBuildingPtr building, buildings ) { ret.currentWorkers += building->getWorkers(); ret.needWorkers += building->getMaxWorkers(); }