Example #1
0
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();
}
Example #2
0
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();
}
Example #3
0
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 );
  }
}
Example #4
0
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++;
    }
  }
}
Example #6
0
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);
}
Example #7
0
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;
      }
Example #10
0
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();
    }
  }
}
Example #11
0
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 );
    }
  }
}