Exemplo n.º 1
0
void Build::drawTile( const RenderInfo& rinfo, Tile& tile )
{
  __D_IMPL(_d,Build);

  ConstructionPtr cntr = tile.overlay<Construction>();
  city::AreaInfo info( _city(), tile.epos(), &_d->buildTiles );

  const Picture* picBasic = 0;
  const Picture* picOver = 0;
  if( cntr.isValid() && info.tiles().size() > 0 )
  {
    picBasic = &cntr->picture();
    picOver = &cntr->picture( info );
  }

  if( picOver && picBasic != picOver )
  {
    Point screenPos = tile.mappos() + rinfo.offset;
    drawLandTile( rinfo, tile );
    rinfo.engine.draw( *picOver, screenPos );
    drawPass( rinfo, tile, Renderer::overlayAnimation );
  }
  else if( _d->lastLayer.isValid() )
  {
    _d->lastLayer->drawTile( rinfo, tile );
  }
  else
  {
    Layer::drawTile( rinfo, tile );
  }

  if( !_d->overdrawBuilding )
    _tryDrawBuildTile( rinfo, tile );
}
Exemplo n.º 2
0
void ShowTileInfo::_exec(Game& game, unsigned int time)
{
  switch( _mode )
  {
  case current:
  break;

  case next:
  case prew:
  {
    city::Helper helper( game.city() );
    ConstructionPtr c =  ptr_cast<Construction>( game.city()->getOverlay( _pos ) );
    c = (_mode == next ? helper.next( c ) : helper.prew( c ));

    if( c.isValid() )
    {
      _pos = c->pos();

      GameEventPtr e = MoveCamera::create( _pos );
      e->dispatch();
    }
  }
  break;

  default:
  break;
  }

  gui::infobox::Manager::getInstance().showHelp( game.city(), game.gui(), _pos );
}
Exemplo n.º 3
0
void Fire::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 )
      {
        ConstructionPtr constr = ptr_cast<Construction>( tile->overlay() );
        if( constr != 0 )
        {
          int fireLevel = math::clamp<int>( constr->state( pr::fire ), 0, 100 );
          text = fireLevelName[ math::clamp<int>( fireLevel / 10, 0, 9 ) ];
        }
      }

      _setTooltipText( _(text) );
    }
    break;

    default: break;
    }
  }

  Layer::handleEvent( event );
}
Exemplo n.º 4
0
void Game::load(std::string filename)
{
  StringHelper::debug( 0xff, "Load game begin" );

  _d->empire->initialize( GameSettings::rcpath( GameSettings::citiesModel ) );

  GameLoader loader;
  _d->loadOk = loader.load( filename, *this);

  if( !_d->loadOk )
  {
    StringHelper::debug( 0xff, "LOADING ERROR: can't load game from %s", filename.c_str() );
    return;
  }

  _d->empire->initPlayerCity( _d->city.as<EmpireCity>() );

  LandOverlayList& llo = _d->city->getOverlayList();
  foreach( LandOverlayPtr overlay, llo )
  {
    ConstructionPtr construction = overlay.as<Construction>();
    if( construction.isValid() )
    {
      construction->computeAccessRoads();
    }
  }
Exemplo n.º 5
0
void RandomFire::_exec( Game& game, unsigned int time)
{
  int population = game.city()->population();
  if( population > _d->minPopulation && population < _d->maxPopulation )
  {
    Logger::warning( "Execute random fire event" );
    _d->isDeleted = true;

    Priorities<int> exclude;
    exclude << objects::waterGroup
            << objects::roadGroup
            << objects::disasterGroup;

    ConstructionList ctrs;
    ctrs << game.city()->overlays();

    for( ConstructionList::iterator it=ctrs.begin(); it != ctrs.end(); )
    {
      if( exclude.count( (*it)->group() ) ) { it = ctrs.erase( it ); }
      else { ++it; }
    }

    unsigned int number4burn = math::clamp<unsigned int>( (ctrs.size() * _d->strong / 100), 1u, 100u );

    for( unsigned int k=0; k < number4burn; k++ )
    {
      ConstructionPtr building = ctrs.random();
      building->burn();
    }
  }
}
Exemplo n.º 6
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 );

    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();
}
Exemplo n.º 7
0
void Build::_drawBuildTile( const RenderInfo& rinfo, Tile* tile)
{
  if( tile == nullptr )
    return;

  __D_IMPL(_d,Build);
  city::AreaInfo areaInfo( _city(), TilePos(), &_d->buildTiles );

  Tile* postTile = tile;
  postTile->resetRendered();

  if( postTile->master() )
    postTile = postTile->master();

  ConstructionPtr construction = postTile->overlay<Construction>();
  rinfo.engine.resetColorMask();

  areaInfo.pos = postTile->epos();
  bool maskSet = false;
  Size size(1,1);

  if( construction.isValid() && construction->canBuild( areaInfo ) )
  {
    rinfo.engine.setColorMask( 0x00000000, 0x0000ff00, 0, 0xff000000 );
    maskSet = true;

    size = construction->size();
  }

  if( postTile == tile && maskSet )
  {
    TilesArray area = _city()->tilemap().area( areaInfo.pos, size );
    for( auto gtile : area )
      drawLandTile( rinfo, *gtile );
  }

  drawLandTile( rinfo, *postTile );

  if( maskSet )
  {
    const Picture& picOver = construction->picture( areaInfo );
    rinfo.engine.draw( picOver, postTile->mappos() + rinfo.offset );
    drawPass( rinfo, *postTile, Renderer::overlayAnimation );
    rinfo.engine.resetColorMask();
  }
}
Pathway ChastenerElephant::_findPathway2NearestConstruction( unsigned int range )
{
  Pathway ret;

  for( unsigned int tmpRange=1; tmpRange <= range; tmpRange++ )
  {
    ConstructionList constructions = _findContructionsInRange( tmpRange );

    foreach( it, constructions )
    {
      ConstructionPtr c = ptr_cast<Construction>( *it );
      ret = PathwayHelper::create( pos(), c->pos(), makeDelegate( _d.data(), &Impl::mayMove ) );
      if( ret.isValid() )
      {
        return ret;
      }
    }
  }
Exemplo n.º 9
0
void Build::_buildAll()
{
  __D_REF(d,Build);
  auto command = d.renderer->mode().as<BuildMode>();
  if( command.isNull() )
    return;

  ConstructionPtr construction = command->contruction();

  if( !construction.isValid() )
  {
    Logger::warning( "LayerBuild: No construction for build" );
    return;
  }

  if( !_city()->treasury().haveMoneyForAction( 1 ) )
  {
    events::dispatch<WarningMessage>( "##out_of_credit##", 2 );
    return;
  }

  bool buildOk = false;
  bool tileBusyBuilding = false;
  city::AreaInfo areaInfo( _city(), TilePos() );
  for( auto tile : d.buildTiles )
  {
    areaInfo.pos = tile->epos();
    tileBusyBuilding |= tile->overlay().is<Building>();

    if( construction->canBuild( areaInfo ) && tile->isMaster())
    {
      events::dispatch<BuildAny>( tile->epos(), construction->type() );
      buildOk = true;

      events::dispatch<UndoAction>( UndoAction::built, construction->type(),
                                    tile->epos(), construction->info().cost() );
    }
  }

  d.startTilePos = d.lastTilePos;

  if( !buildOk )
  {
    std::string errorStr = construction->errorDesc();
    std::string busyText = tileBusyBuilding
                              ? "##need_build_on_free_area##"
                              : "##need_build_on_cleared_area##";
    events::dispatch<WarningMessage>( errorStr.empty() ? busyText : errorStr,
                                         WarningMessage::neitral );
  }

  d.needUpdateTiles = true;
}
Exemplo n.º 10
0
void RandomFire::_exec( Game& game, unsigned int time)
{
    int population = game.city()->states().population;
    if( _d->popRange.contain( population ) )
    {
        Logger::warning( "Execute random fire event" );
        _d->isDeleted = true;

        std::set<object::Group> exclude;
        exclude << object::group::water
                << object::group::road
                << object::group::disaster;

        ConstructionList ctrs = statistic::getObjectsNotIs<Construction>( game.city(), exclude );

        unsigned int number4burn = math::clamp<unsigned int>( (ctrs.size() * _d->strong / 100), 1u, 100u );

        for( unsigned int k=0; k < number4burn; k++ )
        {
            ConstructionPtr building = ctrs.random();
            building->burn();
        }
    }
}
Exemplo n.º 11
0
void RomeArcher::timeStep(const unsigned long time)
{
  Soldier::timeStep( time );

  switch( _subAction() )
  {
  case Soldier::fightEnemy:
  {
    WalkerList enemies = _findEnemiesInRange( attackDistance() );

    if( !enemies.empty() )
    {
      WalkerPtr p = enemies.front();
      turn( p->pos() );

      if( _animationRef().index() == (int)(_animationRef().frameCount()-1) )
      {
        _fire( p->pos() );
        _updateAnimation( time+1 );
      }
    }
    else
    {
      //_check4attack();
      send2patrol();
    }
  }
  break;

  case Soldier::destroyBuilding:
  {
    ConstructionList constructions = _findContructionsInRange( attackDistance() );

    if( !constructions.empty() )
    {
      ConstructionPtr b = constructions.front();
      turn( b->pos() );

      if( _animationRef().index() == (int)(_animationRef().frameCount()-1) )
      {
        _fire( b->pos() );
        _updateAnimation( time+1 );
      }
    }
    else
    {
      //_check4attack();
      send2patrol();
    }
  }

  case Soldier::patrol:
    if( game::Date::current().day() % 2 == 0 )
    {
      _tryAttack();
    }
  break;

  default: break;
  } // end switch( _d->action )
}
Exemplo n.º 12
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();
    }
  }
}
Exemplo n.º 13
0
bool Game::load(std::string filename)
{
    Logger::warning( "Game: try load from " + filename );

    Logger::warning( "Game: reseting variables" );
    reset();

    scene::SplashScreen screen;

    screen.initialize();
    bool usingOldgfx = SETTINGS_VALUE( oldgfx ) || !SETTINGS_VALUE( c3gfx ).toString().empty();
    screen.setImage( usingOldgfx ? "load4" : "freska", 1 );
    screen.update( *_d->engine );

    vfs::Path fPath( filename );
    if( !fPath.exist() )
    {
        Logger::warning( "Game: Cannot find file " + fPath.toString() );
        fPath = game::Settings::rpath( filename );

        if( !fPath.exist() )
        {
            Logger::warning( "Game: Cannot find file " + fPath.toString() );
            Logger::warning( "Game: Try find file in resource's folder " );

            fPath = game::Settings::rcpath( filename ).absolutePath();
            if( !fPath.exist() )
            {
                Logger::warning( "Game: Cannot find file " + fPath.toString() );
                return false;
            }
        }
    }

    Logger::warning( "Game: init empire start options" );
    events::Dispatcher::instance().reset();
    _d->empire->initialize( SETTINGS_RC_PATH( citiesModel ),
                            SETTINGS_RC_PATH( empireObjectsModel ),
                            SETTINGS_RC_PATH( worldModel ) );

    Logger::warning( "Game: try find loader" );
    game::Loader loader;
    loader.onUpdate().connect( &screen, &scene::SplashScreen::setText );

    bool loadOk = loader.load( fPath, *this );

    if( !loadOk )
    {
        Logger::warning( "LOADING ERROR: can't load game from " + filename );
        return false;
    }

    _d->restartFile = loader.restartFile();
    Logger::warning( "Game: init player city" );
    world::CityPtr city = _d->empire->initPlayerCity( ptr_cast<world::City>( _d->city ) );
    if( city.isNull() )
    {
        Logger::warning( "INIT ERROR: can't initalize city %s in empire" + _d->city->name() );
        return false;
    }
    _d->empire->emperor().checkCities();

    Logger::warning( "Game: calculate road access for buildings" );
    const OverlayList& llo = _d->city->overlays();
    for( auto overlay : llo )
    {
        ConstructionPtr construction = overlay.as<Construction>();
        if( construction.isValid() )
        {
            construction->computeRoadside();
        }
    }

    Logger::warning( "Game: initialize local pathfinder" );
    Pathfinder::instance().update( _d->city->tilemap() );

    Logger::warning( "Game: load finished" );

    screen.exitScene( scene::SplashScreen::hideDevText );
    return true;
}
Exemplo n.º 14
0
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;
  }