// 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; }