Example #1
0
// unit handler
int UnitHandler::ParseSection( ifstream &in, const string *opt, unsigned long &line ) {
  int rc = KeyValueSectionHandler::ParseSection( in, opt, line );

  if ( rc == 0 ) {
    bool named = false;

    EdUnitType t;
    t.SetTerrain( TT_ENTRANCE );
    t.SetImage( 0 );
    t.SetFlags( 0 );
    t.SetMoves( 0 );
    t.SetWeight( 0 );
    t.SetDefence( 0 );
    t.SetPowerGround( 0 );
    t.SetPowerShip( 0 );
    t.SetPowerAir( 0 );
    t.SetMinRangeGround( 1 );
    t.SetMaxRangeGround( 1 );
    t.SetMinRangeShip( 1 );
    t.SetMaxRangeShip( 1 );
    t.SetMinRangeAir( 1 );
    t.SetMaxRangeAir( 1 );
    t.SetCost( 0 );
    t.SetTransSlots( 0 );
    t.SetTransMinWeight( 0 );
    t.SetTransMaxWeight( 0 );
    t.SetPortrait( -1 );

    for ( vector<pair<string, string> >::iterator it = pairs.begin();
          it != pairs.end(); ++it ) {
      string key = (*it).first;
      string val = (*it).second;

      if ( key == "type" ) {
        if ( val == "ground" ) t.AddFlags( U_GROUND );
        else if ( val == "ship" ) t.AddFlags( U_SHIP );
        else if ( val == "aircraft" ) t.AddFlags( U_AIR );
        else if ( val == "trooper" ) t.AddFlags( U_CONQUER );
        else if ( val == "slow" ) t.AddFlags( U_SLOW );
        else if ( val == "mine" ) t.AddFlags( U_MINE );
        else if ( val == "medic" ) t.AddFlags( U_MEDIC );
        else if ( val == "sweeper" ) t.AddFlags( U_MINESWEEPER );
        else {
          rc = 1;
          cerr << "Error near line " << line << ": Invalid unit class '" << val << "'" << endl;
          break;
        }
      }
      else if ( key == "terrain" ) {
        if ( val == "road" ) t.AddTerrain( TT_ROAD );
        else if ( val == "plains" ) t.AddTerrain( TT_PLAINS );
        else if ( val == "forest" ) t.AddTerrain( TT_FOREST );
        else if ( val == "swamp" ) t.AddTerrain( TT_SWAMP );
        else if ( val == "mountains" ) t.AddTerrain( TT_MOUNTAINS );
        else if ( val == "shallowwater" ) t.AddTerrain( TT_WATER_SHALLOW );
        else if ( val == "deepwater" ) t.AddTerrain( TT_WATER_DEEP );
        else if ( val == "water" ) t.AddTerrain( TT_WATER );
        else if ( val == "rough" ) t.AddTerrain( TT_BARRICADES );
        else if ( val == "rails" ) t.AddTerrain( TT_RAILS );
        else if ( val == "restricted" ) t.AddTerrain( TT_RESTRICTED );
        else if ( val == "trenches" ) t.AddTerrain( TT_TRENCHES );
        else {
          rc = 1;
          cerr << "Error near line " << line << ": Invalid terrain '" << val << "'" << endl;
          break;
        }
      }
      else if ( key == "icon" ) t.SetImage( StrToNum( val ) );
      else if ( key == "armour" ) t.SetDefence( StrToNum( val ) );
      else if ( key == "speed" ) t.SetMoves( StrToNum( val ) );
      else if ( key == "price" ) t.SetCost( StrToNum( val ) );
      else if ( key == "weight" ) t.SetWeight( StrToNum( val ) );
      else if ( key == "transslots" ) t.SetTransSlots( StrToNum( val ) );
      else if ( key == "transminweight" ) t.SetTransMinWeight( StrToNum( val ) );
      else if ( key == "transmaxweight" ) t.SetTransMaxWeight( StrToNum( val ) );
      else if ( key == "portrait" ) {
        vector<string>::iterator it =
                find( info.portraits.begin(), info.portraits.end(), val );
        if ( it == info.portraits.end() ) {
          t.SetPortrait( info.portraits.size() );
          info.portraits.push_back( val );
        } else {
          t.SetPortrait( distance( info.portraits.begin(), it ) );
        }
      }
      else if ( key.substr( 0, 5 ) == "power" ) {
        string type = ParseOpt( key );

        if ( type == "" ) rc = 1;
        else rc = ParsePower( val, type, t );
      }
      else if ( key.substr( 0, 4 ) == "name" ) {
        string lang = ParseOpt( key );

        if ( lang == "" ) rc = 1;
        else if ( lang.size() != 2 ) {
          rc = 1;
          cerr << "Error near line " << line << ": '" << val << "' is not a valid language" << endl;
        } else {
          map <string, Language>::iterator it = names.find( lang );
          if ( it == names.end() ) {
            // only accept new languages for the first unit
            if ( units.size() == 0 ) {
              Language l;
              l.SetID( lang.c_str() );
              l.AddMsg( val );
              names[lang] = l;
              named = true;
            } else
              cerr << "Warning near line " << line << ": New language '" << lang << "' ignored" << endl;
          } else {
            it->second.AddMsg( val );
            named = true;
          }
        }
      } else {
        rc = 1;
        cerr << "Error near line " << line << ": Invalid keyword '" << key << "' in this context" << endl;
      }
    }

    if ( t.Firepower( U_GROUND ) == 0 ) {
      t.SetMinRangeGround( 0 );
      t.SetMaxRangeGround( 0 );
    }
    if ( t.Firepower( U_SHIP ) == 0 ) {
      t.SetMinRangeShip( 0 );
      t.SetMaxRangeShip( 0 );
    }
    if ( t.Firepower( U_AIR ) == 0 ) {
      t.SetMinRangeAir( 0 );
      t.SetMaxRangeAir( 0 );
    }
    if ( t.Slots() > 0 ) t.AddFlags( U_TRANSPORT );
    if ( t.Terrain() == 0 ) {
      rc = 1;
      cerr << "Error near line " << line << ": Unit does not specify terrain" << endl;
    }

    if ( !named ) {
      rc = 1;
      cerr << "Error near line " << line << ": Unit does not specify a name" << endl;
    } else {
      unsigned short msgs = names[CF_LANG_DEFAULT].Size();
      for ( map<string, Language>::iterator it = names.begin();
            it != names.end(); ++it ) {
        if ( it->second.Size() != msgs ) {
          const char *defname = names[CF_LANG_DEFAULT].GetMsg(msgs-1);
          if ( defname ) {
            cerr << "Warning near line " << line
                 << ": Unit does not specify name for language '" << it->first
                 << "', using '" << CF_LANG_DEFAULT << "' default ("
                 << defname << ')' << endl;
            it->second.AddMsg( defname );
          } else {
            rc = 1;
            cerr << "Error near line " << line
                 << ": Unit does not specify name for language '" << it->first << "'" << endl;
          }
        }
      }
    }

    units.push_back( t );
  }
  return rc;
}