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 );
}
Beispiel #2
0
Pathway Emigrant::_findSomeWay( TilePos startPoint )
{
  HousePtr house = _findBlankHouse();  
  _d->failedWayCount++;

  Pathway pathway;
  if( house.isValid() )
  {    
    pathway = PathwayHelper::create( startPoint, house->pos(), PathwayHelper::roadFirst  );

    if( !pathway.isValid() )
    {
      pathway = PathwayHelper::create( startPoint, ptr_cast<Construction>(house),
                                       PathwayHelper::roadFirst  );
    }

    if( pathway.isValid() )
    {
      _lockHouse( house );
    }
  }

  if( !pathway.isValid() || _d->failedWayCount > 10 )
  {    
    pathway = PathwayHelper::create( startPoint,
                                     _city()->borderInfo().roadExit,
                                     PathwayHelper::allTerrain );
  }

  return pathway;
}
Beispiel #3
0
void Immigrant::onDestination()
{
    bool gooutCity = true;
    if( _d->destination.getI() > 0 && _d->destination.getJ() > 0 )  //have destination
    {
        const Tile& tile = _getCity()->getTilemap().at( _d->destination );

        HousePtr house = tile.getOverlay().as<House>();
        if( house.isValid() )
        {
            int freeRoom = house->getMaxHabitants() - house->getHabitants().count();
            if( freeRoom > 0 )
            {
                house->addHabitants( _d->peoples );
                Walker::onDestination();

                gooutCity = (_d->peoples.count() > 0);
            }
        }
    }

    if( gooutCity )
    {
        _findPath2blankHouse( _getCity()->getTilemap().at( getIJ() ) );
    }
    else
    {
        deleteLater();
    }
}
void MarketAccess::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<House>();
        if( house.isValid() )
        {
          int accessLevel = house->getServiceValue( Service::market );
          accessLevel = math::clamp<int>( accessLevel / maxAccessLevel, 0, maxAccessLevel-1 );
          text = marketLevelName[ accessLevel ];
        }
      }

      _setTooltipText( text );
    }
    break;

    default: break;
    }
  }

  Layer::handleEvent( event );
}
Beispiel #5
0
void TaxCollector::_centerTile()
{
  Walker::_centerTile();

  int difficulty = SETTINGS_VALUE(difficulty);
  float multiply = 1.0f;
  switch (difficulty)
  {
    case 0: multiply = 3.0f; break;
    case 1: multiply = 2.0f; break;
    case 2: multiply = 1.5f; break;
    case 3: multiply = 1.0f; break;
    case 4: multiply = 0.75f; break;
  }

  ReachedBuildings buildings = getReachedBuildings( pos() );
  foreach( it, buildings )
  {
    HousePtr house = ptr_cast<House>( *it );

    if( house.isValid() )
    {
      float tax = house->collectTaxes() * multiply;
      _d->money += tax;
      house->applyService( this );

      std::string posStr = utils::format( 0xff, "%02dx%02d", house->pos().i(), house->pos().j() );
      _d->history[ posStr ] += tax;
    }
  }
Beispiel #6
0
void Sentiment::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>();
        if( house.isValid() )
        {
          int happiness = math::clamp<int>( house->state( pr::happiness ) / maxSentimentLevel, 0, maxSentimentLevel-1 );
          text = sentimentLevelName[ happiness ];
        }
      }

      _setTooltipText( text );
    }
    break;

    default: break;
    }
  }

  Layer::handleEvent( event );
}
Beispiel #7
0
void Emigrant::_lockHouse( HousePtr house )
{
  if( _d->housePosLock.i() >= 0 )
  {
    HousePtr oldHouse = ptr_cast<House>( _city()->tilemap().at( _d->housePosLock ).overlay() );
    if( oldHouse.isValid() )
    {
      _d->housePosLock = TilePos( -1, -1 );
      oldHouse->setState( House::settleLock, 0 );
    }
  }

  if( house.isValid() )
  {
    _d->housePosLock = house->pos();
    house->setState( House::settleLock, TileHelper::hash( _d->housePosLock ) );
  }
}
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() );
  }
}
Beispiel #9
0
void Emigrant::_reachedPathway()
{
  bool gooutCity = true;
  Walker::_reachedPathway();

  if( pos() == _city()->borderInfo().roadExit )
  {
    city::MigrationPtr migration;
    migration << _city()->findService( city::Migration::defaultName() );

    if( migration.isValid() )
    {
      migration->citizenLeaveCity( this );
    }

    deleteLater();
    return;
  }

  HousePtr house = ptr_cast<House>( _city()->getOverlay( pos() ) );
  if( house.isValid() )
  {
    _append2house( house );
    gooutCity = (_d->peoples.count() > 0);
  }
  else
  {
    if( _checkNearestHouse() )
    {
      return;
    }
  }

  if( gooutCity )
  {
    Pathway way = _findSomeWay( pos() );
    if( way.isValid() )
    {
      _updatePathway( way );
      go();
    }
    else
    {
      die();
    }
  }
  else
  {
    deleteLater();
  }
}
Beispiel #10
0
void Immigrant::_findPath2blankHouse( Tile& startPoint )
{
    HousePtr house = _findBlankHouse();

    Pathway pathWay;

    Tilemap& citymap = _getCity()->getTilemap();
    Tile& destTile = house.isValid() ? house->getTile() : citymap.at( _getCity()->getBorderInfo().roadExit );
    Size arrivedArea( house.isValid() ? house->getSize() : 1 );

    bool pathFound = Pathfinder::getInstance().getPath( startPoint.getIJ(), destTile.getIJ(), pathWay,
                     false, arrivedArea );
    if( pathFound )
    {
        setPathway( pathWay );
        setIJ( startPoint.getIJ() );
        go();
    }

    if( !pathFound )
    {
        deleteLater();
    }
}
void TaxCollector::onMidTile()
{
  ServiceWalker::onMidTile();

  ReachedBuildings buildings = getReachedBuildings( getIJ() );
  for( ReachedBuildings::iterator it=buildings.begin(); it != buildings.end(); it++ )
  {
    HousePtr house = (*it).as<House>();
    if( house.isValid() )
    {
      int money = house->collectTaxes();
      _d->money += money;
      _d->peoplesReached += money > 0 ? house->getNbHabitants() : 0;
    }
  }
}
Beispiel #12
0
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 );
}
Beispiel #13
0
void Tax::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 )
            {
                BuildingPtr bld = ptr_cast<Building>( tile->overlay() );

                if( bld.isNull() )
                {
                    text = "##no_people_in_this_locality##";
                }
                else
                {
                    HousePtr house = ptr_cast<House>( tile->overlay() );
                    if( house.isValid() )
                    {
                        int taxAccess = house->hasServiceAccess( Service::forum );
                        if( taxAccess < 25 )
                            text = "##house_not_registered_for_taxes##";
                    }
                }
            }

            _setTooltipText( _(text) );
        }
        break;

        default:
            break;
        }
    }

    Layer::handleEvent( event );
}
void CityServiceEmigrant::update( const unsigned int time )
{
  if( time % 44 != 1 )
    return;
  
  unsigned int vacantPop=0;

  LandOverlays houses = _d->city->getBuildingList(B_HOUSE);
  for( LandOverlays::iterator itHouse = houses.begin(); itHouse != houses.end(); ++itHouse )
  {
    HousePtr house = (*itHouse).as<House>();
    if( house.isValid() && house->getAccessRoads().size() > 0 )
    {
      vacantPop += math::clamp( house->getMaxHabitants() - house->getNbHabitants(), 0, 0xff );
    }
  }

  if( vacantPop == 0 )
  {
    return;
  }

  Walkers walkers = _d->city->getWalkerList( WT_EMIGRANT );

  if( vacantPop <= walkers.size() * 5 )
  {
    return;
  }

  Tile& roadTile = _d->city->getTilemap().at( _d->city->getRoadEntry() );

  EmigrantPtr emigrant = Emigrant::create( _d->city );

  if( emigrant.isValid() )
  {
    emigrant->send2City( roadTile );
  }
}
Beispiel #15
0
 void mayWalk( const Tile* tile, bool& ret )
 {
   HousePtr f = ptr_cast<House>( tile->overlay() );
   ret = ( tile->isWalkable( true ) || f.isValid() );
 }  
Beispiel #16
0
void House::_tryUpdate_1_to_11_lvl( int level4grow, int startSmallPic, int startBigPic, const char desirability )
{       
  if( getSize() == 1 )
  {
    CityPtr city = Scenario::instance().getCity();
    Tilemap& tmap = city->getTilemap();
    PtrTilesList tiles = tmap.getFilledRectangle( getTile().getIJ(), Size(2) );   
    bool mayGrow = true;

    for( PtrTilesList::iterator it=tiles.begin(); it != tiles.end(); it++ )
    {
      if( *it == NULL )
      {
        mayGrow = false;   //some broken, can't grow
        break;
      }

      HousePtr house = (*it)->getTerrain().getOverlay().as<House>();
      if( house != NULL && house->getLevelSpec().getHouseLevel() == level4grow )
      {
        if( house->getSize().getWidth() > 1 )  //bigger house near, can't grow
        {
          mayGrow = false;
          break;
        }            
      }
      else
      {
        mayGrow = false; //no house near, can't grow
        break;
      }
    }

    if( mayGrow )
    {
      int sumHabitants = getNbHabitants();
      int sumFreeWorkers = _d->freeWorkersCount;
      PtrTilesList::iterator delIt=tiles.begin();
      delIt++; //don't remove himself
      for( ; delIt != tiles.end(); delIt++ )
      {
        HousePtr house = (*delIt)->getTerrain().getOverlay().as<House>();
        if( house.isValid() )
        {
          house->deleteLater();
          house->_d->currentHabitants = 0;
          sumHabitants += house->getNbHabitants();
          sumFreeWorkers += house->_d->freeWorkersCount;
        }
      }

      _d->currentHabitants = sumHabitants;
      _d->freeWorkersCount = sumFreeWorkers;
      _d->houseLevelSpec = HouseSpecHelper::getInstance().getHouseLevelSpec(_d->houseLevel);
      _d->nextHouseLevelSpec = _d->houseLevelSpec.next();

      _update();
      _updateDesirabilityInfluence( Construction::duNegative );
      setSize( getSize() + Size(1) );
      build( getTile().getIJ() );      
    }
  }

  _updateDesirabilityInfluence( Construction::duNegative );
  _d->desirability = desirability;       
  _updateDesirabilityInfluence( Construction::duPositive );

  bool bigSize = getSize().getWidth() > 1;
  _d->houseId = bigSize ? startBigPic : startSmallPic; 
  _d->picIdOffset = bigSize ? 0 : ( (rand() % 10 > 6) ? 1 : 0 );
}
void House::_tryUpdate_1_to_11_lvl( int level4grow, int startSmallPic, int startBigPic, const char desirability )
{       
  if( getSize() == 1 )
  {
    Tilemap& tmap = _getCity()->getTilemap();
    TilemapTiles area = tmap.getFilledRectangle( getTile().getIJ(), Size(2) );
    bool mayGrow = true;

    foreach( Tile* tile, area )
    {
      if( tile == NULL )
      {
        mayGrow = false;   //some broken, can't grow
        break;
      }

      HousePtr house = tile->getOverlay().as<House>();
      if( house != NULL && house->getLevelSpec().getHouseLevel() == level4grow )
      {
        if( house->getSize().getWidth() > 1 )  //bigger house near, can't grow
        {
          mayGrow = false;
          break;
        }            
      }
      else
      {
        mayGrow = false; //no house near, can't grow
        break;
      }
    }

    if( mayGrow )
    {
      int sumHabitants = getNbHabitants();
      int sumFreeWorkers = _d->freeWorkersCount;
      TilemapTiles::iterator delIt=area.begin();
      HousePtr selfHouse = (*delIt)->getOverlay().as<House>();

      delIt++; //don't remove himself
      for( ; delIt != area.end(); delIt++ )
      {
        HousePtr house = (*delIt)->getOverlay().as<House>();
        if( house.isValid() )
        {
          house->deleteLater();
          house->_d->currentHabitants = 0;

          sumHabitants += house->getNbHabitants();
          sumFreeWorkers += house->_d->freeWorkersCount;

          selfHouse->getGoodStore().storeAll( house->getGoodStore() );
        }
      }

      _d->currentHabitants = sumHabitants;
      _d->freeWorkersCount = sumFreeWorkers;
      _d->houseLevelSpec = HouseSpecHelper::getInstance().getHouseLevelSpec(_d->houseLevel);
      _d->nextHouseLevelSpec = _d->houseLevelSpec.next();

      _update();
      _updateDesirabilityInfluence( Construction::duNegative );
      setSize( getSize() + Size(1) );
      build( _getCity(), getTile().getIJ() );
    }
  }
void WalkerPrefect::onMidTile()
{
  ReachedBuildings reachedBuildings;
  TilePos firePos;
  bool haveBurningRuinsNear = _looks4Fire( reachedBuildings, firePos );  
  bool isDestination = _getPathway().isDestination();

  switch( _d->action )
  {
  case Impl::doNothing:
  break;

  case Impl::patrol:
  {
    if( haveBurningRuinsNear )
    {
      //tell our prefecture that need send prefect with water to fight with fire
      //on next deliverService

      //found fire, no water, go prefecture
      getBase().as<Prefecture>()->fireDetect( firePos );
      _back2Prefecture();

      Walker::onNewDirection();
    }
    else
    {
      foreach( BuildingPtr building, reachedBuildings )
      {
        building->applyService( ServiceWalkerPtr( this ) );

        HousePtr house = building.as<House>();
        if( house.isValid() && house->getHealthLevel() < 1 )
        {
          house->deleteLater();

          GameEventMgr::append( DisasterEvent::create( house->getTilePos(), DisasterEvent::plague ) );
        }
      }
    }

    if( isDestination )
    {
      _back2Prefecture();
    }

    Walker::onMidTile();
  }
  break;

  case Impl::back2Prefecture:
  {
    if( haveBurningRuinsNear )
    {
      //tell our prefecture that need send prefect with water to fight with fire
      //on next deliverService
      getBase().as<Prefecture>()->fireDetect( firePos );
    }

    if( isDestination )
    {
      deleteLater();
      _d->action = Impl::doNothing;
    }

    Walker::onMidTile();
  }
  break;

  case Impl::gotoFire:
  {
    if( _getPathway().getDestination().getIJ().distanceFrom( getIJ() ) < 1.5f )
    {
      LandOverlayPtr overlay = _getPathway().getDestination().getOverlay();
      if( overlay.isValid() && overlay->getType() == B_BURNING_RUINS )
      {
        _d->action = Impl::fightFire;
        _setGraphic( WG_PREFECT_FIGHTS_FIRE );
        Walker::onNewDirection();
        isDestination = false;
      }
    }

    if( isDestination )
    {
      if( !haveBurningRuinsNear || _d->water == 0 )
      {
        _back2Prefecture();
      }
      else
      {
        _setGraphic( WG_PREFECT_DRAG_WATER );
        _d->action = Impl::gotoFire;

        _checkPath2NearestFire( reachedBuildings );
        Walker::onNewDirection();
      }
    }

    Walker::onMidTile();
  }
  break;

  case Impl::fightFire:
  break;
  }