00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "containerbasetype.h"
00019 #include "textfiletags.h"
00020 #include "textfile_evaluation.h"
00021 #include "vehicletype.h"
00022 #include "graphics/blitter.h"
00023
00024
00025 const char* ccontainerfunctions[ContainerBaseType::functionNum+1] =
00026 { "training",
00027 "internal vehicle production",
00028 "ammunition production",
00029 "internal unit repair",
00030 "recycling",
00031 "research",
00032 "sonar",
00033 "view satellites",
00034 "view mines",
00035 "wind power plant",
00036 "solar power plant",
00037 "matter converter",
00038 "mining station",
00039 "construct units that cannot move out",
00040 "resource sink",
00041 "external energy transfer",
00042 "external material transfer",
00043 "external fuel transfer",
00044 "external ammo transfer",
00045 "external repair",
00046 "no object chaining",
00047 "self destruct on conquer",
00048 "paratrooper",
00049 "mine-layer",
00050 "cruiser landing",
00051 "conquer buildings",
00052 "move after attack",
00053 "external vehicle production",
00054 "construct specific buildings",
00055 "icebreaker",
00056 "cannot be refuelled in air",
00057 "makes tracks",
00058 "search for mineral resources automatically",
00059 "no reactionfire",
00060 "auto repair",
00061 "Kamikaze only",
00062 "immune to mines",
00063 "jams only own field",
00064 "move with reaction fire on",
00065 "only move to and from transports",
00066 "AutoHarvestObjects",
00067 "No customization of production",
00068 "Manual self-destruct",
00069 NULL };
00070
00071
00072 ContainerBaseType :: ContainerBaseType ()
00073 {
00074 maxLoadableUnits = 0;
00075 maxLoadableUnitSize = 0;
00076 maxLoadableWeight = maxint;
00077 vehicleCategoriesStorable = -1;
00078 id = 0;
00079 jamming = 0;
00080 view = 0;
00081 efficiencyfuel = 1024;
00082 efficiencymaterial = 1024;
00083
00084 maxresearchpoints = 0;
00085 defaultMaxResearchpoints = 0;
00086 nominalresearchpoints = 0;
00087 vehicleCategoriesProduceable = 0xfffffff;
00088 autoHarvest.range = 0;
00089 autoHarvest.maxFieldsPerTurn = maxint;
00090 }
00091
00092 bool ContainerBaseType::hasFunction( ContainerFunctions function ) const
00093 {
00094 int f = int(function);
00095 return features.test( f );
00096 }
00097
00098 bool ContainerBaseType::hasAnyFunction( BitSet functions ) const
00099 {
00100 bool result = (features & functions).any();
00101 return result;
00102 }
00103
00104 void ContainerBaseType::setFunction( ContainerFunctions function )
00105 {
00106 features.set( int(function) );
00107 }
00108
00109
00110
00111
00112 const char* ContainerBaseType::getFunctionName( ContainerFunctions function )
00113 {
00114 if ( function < functionNum )
00115 return ccontainerfunctions[function];
00116 else
00117 return NULL;
00118 }
00119
00120
00121 ContainerBaseType::TransportationIO::TransportationIO()
00122 {
00123 mode = 0;
00124 height_abs = 0;
00125 height_rel = 0;
00126 container_height = 0;
00127 vehicleCategoriesLoadable = -1;
00128 dockingHeight_abs = 0;
00129 dockingHeight_rel = 0;
00130 disableAttack = false;
00131 movecost = -1;
00132 }
00133
00134
00135 void ContainerBaseType :: TransportationIO :: runTextIO ( PropertyContainer& pc )
00136 {
00137 pc.addTagInteger( "Mode", mode, entranceModeNum, entranceModes );
00138 pc.addTagInteger( "UnitHeightAbs", height_abs, choehenstufennum, heightTags );
00139 pc.addInteger( "UnitHeightRel", height_rel, -100 );
00140 pc.addTagInteger( "ContainerHeight", container_height, choehenstufennum, heightTags );
00141 pc.addTagInteger( "CategoriesNOT", vehicleCategoriesLoadable, cmovemalitypenum, unitCategoryTags, true );
00142 pc.addTagInteger( "DockingHeightAbs", dockingHeight_abs, choehenstufennum, heightTags, 0 );
00143 pc.addInteger( "DockingHeightRel", dockingHeight_rel, -100 );
00144 if ( pc.find( "RequireUnitFunction" )) {
00145 int r = 0;
00146 pc.addTagInteger( "RequireUnitFunction", r, Vehicletype::legacyVehicleFunctionNum, vehicleAbilities, 0 );
00147 requiresUnitFeature = Vehicletype::convertOldFunctions(r, pc.getFileName() );
00148 } else
00149 if ( pc.find( "RequiresUnitFeature" ) || !pc.isReading() )
00150 pc.addTagArray( "RequiresUnitFeature", requiresUnitFeature, ContainerBaseType::functionNum, containerFunctionTags );
00151 else
00152 requiresUnitFeature.reset();
00153
00154 pc.addBool( "DisableAttack", disableAttack, false );
00155 pc.addInteger( "MoveCost", movecost, -1 );
00156 if ( movecost < 10 && movecost >= 0 )
00157 fatalError ( "MoveCost for TransportationIO is lower than 10! file: " + pc.getFileName() );
00158 }
00159
00160
00161 void ContainerBaseType :: runTextIO ( PropertyContainer& pc )
00162 {
00163 pc.addBreakpoint();
00164 pc.openBracket ( "Transportation" );
00165 int num = entranceSystems.size();
00166 pc.addInteger ( "EntranceSystemNum", num, 0 );
00167 entranceSystems.resize(num);
00168 for ( int i = 0; i < num; i++ ) {
00169 pc.openBracket ( ASCString("EntranceSystem") + strrr(i) );
00170 entranceSystems[i].runTextIO( pc );
00171 pc.closeBracket();
00172 }
00173 pc.addInteger ( "MaxLoadableUnits", maxLoadableUnits, 0 );
00174
00175 pc.addInteger ( "MaxLoadableUnitSize", maxLoadableUnitSize, maxint );
00176 pc.addInteger ( "MaxLoadableMass", maxLoadableWeight, maxint );
00177 pc.addTagInteger( "CategoriesNOT", vehicleCategoriesStorable, cmovemalitypenum, unitCategoryTags, -1, true );
00178 pc.closeBracket();
00179
00180 pc.addString( "Name", name );
00181
00182 pc.addString( "Infotext", infotext, "" );
00183
00184 while ( infotext.find ( "#CRT#" ) != ASCString::npos )
00185 infotext.replace ( infotext.find ( "#CRT#" ), 5, "\n" );
00186 while ( infotext.find ( "#crt#" ) != ASCString::npos )
00187 infotext.replace ( infotext.find ( "#crt#" ), 5, "\n" );
00188 while ( infotext.find ( "\r" ) != ASCString::npos )
00189 infotext.replace ( infotext.find ( "\r" ), 1, "" );
00190
00191 pc.addInteger( "ID", id );
00192
00193 if ( pc.find( "SecondaryIDs") || !pc.isReading())
00194 pc.addIntegerArray("SecondaryIDs", secondaryIDs );
00195
00196 pc.addInteger( "View", view );
00197 if ( view > maxViewRange )
00198 view = maxViewRange;
00199
00200 pc.addInteger( "Jamming", jamming, 0 );
00201 pc.addString( "InfoImage", infoImageFilename, "" );
00202
00203 pc.openBracket ( "MaxResourceProduction" );
00204 maxplus.runTextIO ( pc, Resources(0,0,0) );
00205 pc.closeBracket ();
00206
00207 pc.openBracket ( "ResourceExtractionEfficiency");
00208 pc.addInteger( "Material", efficiencymaterial, 1024 );
00209 pc.addInteger( "Fuel", efficiencyfuel, 1024 );
00210 pc.closeBracket ();
00211
00212 pc.openBracket ( "StorageCapacity" );
00213 pc.openBracket( "BImode" );
00214 bi_mode_tank.runTextIO ( pc, Resources(0,0,0) );
00215 pc.closeBracket();
00216 pc.openBracket ( "ASCmode" );
00217 asc_mode_tank.runTextIO ( pc, Resources(0,0,0) );
00218 pc.closeBracket();
00219 pc.closeBracket ();
00220
00221 pc.addInteger ( "MaxResearch", maxresearchpoints, 0 );
00222 pc.addInteger ( "NominalResearch", nominalresearchpoints, maxresearchpoints/2 );
00223 pc.addInteger ( "MaxResearchpointsDefault", defaultMaxResearchpoints, maxresearchpoints );
00224
00225 pc.openBracket( "DefaultProduction" );
00226 defaultProduction.runTextIO ( pc, Resources(0,0,0) );
00227 pc.closeBracket();
00228
00229 pc.addTagInteger( "CategoriesProduceable", vehicleCategoriesProduceable, cmovemalitypenum, unitCategoryTags, -1 );
00230
00231 pc.openBracket( "AutoHarvestObjects" );
00232 pc.addIntRangeArray( "objects", autoHarvest.objectsHarvestable, false );
00233 pc.addIntRangeArray( "objectGroups", autoHarvest.objectGroupsHarvestable, false );
00234 pc.addInteger( "Range", autoHarvest.range, 0 );
00235 pc.addInteger( "MaxFieldsPerTurn", autoHarvest.maxFieldsPerTurn, maxint);
00236 pc.closeBracket();
00237
00238
00239 pc.openBracket ( "Construction" );
00240 pc.addIntRangeArray ( "VehiclesInternally", vehiclesInternallyProduceable, false );
00241 productionEfficiency.runTextIO("ProductionEfficiency", pc, productionEfficiency );
00242 pc.closeBracket();
00243 }
00244
00245
00246 bool ContainerBaseType :: vehicleFit ( const Vehicletype* fzt ) const
00247 {
00248 if ( maxLoadableUnits > 0 )
00249 if ( maxLoadableWeight > 0 )
00250 if ( vehicleCategoriesStorable & (1<<fzt->movemalustyp) )
00251 if ( maxLoadableUnitSize >= fzt->maxsize() )
00252 return true;
00253
00254 return false;
00255 }
00256
00257 const int containerBaseTypeVersion = 6;
00258
00259
00260 void ContainerBaseType :: read ( tnstream& stream )
00261 {
00262 int version = stream.readInt();
00263 if ( version > containerBaseTypeVersion || version < 1 ) {
00264 ASCString s = "invalid version for reading ContainerBaseType: ";
00265 s += strrr ( version );
00266 throw ASCmsgException ( s );
00267 }
00268 maxLoadableUnits = stream.readInt();
00269 maxLoadableUnitSize = stream.readInt();
00270 maxLoadableWeight = stream.readInt();
00271 vehicleCategoriesStorable = stream.readInt();
00272 int num = stream.readInt();
00273 entranceSystems.resize(num);
00274 for ( int i = 0; i < num; i++ )
00275 entranceSystems[i].read( stream );
00276
00277 if ( version >= 2 )
00278 infoImageFilename = stream.readString();
00279
00280 if ( version >= 3 )
00281 stream.readBitset( features );
00282
00283 if ( version >= 4 )
00284 vehicleCategoriesProduceable = stream.readInt();
00285
00286 if ( version >= 5 )
00287 readClassContainer( secondaryIDs, stream );
00288
00289 if ( version >= 6 ) {
00290 autoHarvest.range = stream.readInt();
00291 readClassContainer( autoHarvest.objectsHarvestable, stream );
00292 readClassContainer( autoHarvest.objectGroupsHarvestable, stream );
00293 autoHarvest.maxFieldsPerTurn = stream.readInt();
00294
00295 readClassContainer( vehiclesInternallyProduceable, stream );
00296 productionEfficiency.read( stream );
00297 }
00298 }
00299
00300 void ContainerBaseType :: write ( tnstream& stream ) const
00301 {
00302 stream.writeInt( containerBaseTypeVersion );
00303 stream.writeInt( maxLoadableUnits );
00304 stream.writeInt( maxLoadableUnitSize );
00305 stream.writeInt( maxLoadableWeight );
00306 stream.writeInt( vehicleCategoriesStorable );
00307 stream.writeInt( entranceSystems.size() );
00308 for ( int i = 0; i < entranceSystems.size(); i++ )
00309 entranceSystems[i].write( stream );
00310 stream.writeString( infoImageFilename );
00311 stream.writeBitset( features );
00312 stream.writeInt( vehicleCategoriesProduceable );
00313 writeClassContainer( secondaryIDs, stream );
00314
00315 stream.writeInt( autoHarvest.range );
00316 writeClassContainer( autoHarvest.objectsHarvestable, stream );
00317 writeClassContainer( autoHarvest.objectGroupsHarvestable, stream );
00318 stream.writeInt( autoHarvest.maxFieldsPerTurn );
00319
00320 writeClassContainer( vehiclesInternallyProduceable, stream );
00321 productionEfficiency.write( stream );
00322 }
00323
00324 const int containerBaseTypeTransportVersion = 3;
00325
00326
00327 void ContainerBaseType :: TransportationIO :: read ( tnstream& stream )
00328 {
00329 int version = stream.readInt();
00330 if ( version > containerBaseTypeTransportVersion || version < 1 ) {
00331 ASCString s = "invalid version for reading ContainerBaseTypeTransportation: ";
00332 s += strrr ( version );
00333 throw ASCmsgException ( s );
00334 }
00335 mode = stream.readInt();
00336 height_abs = stream.readInt();
00337 height_rel = stream.readInt();
00338 container_height = stream.readInt();
00339 vehicleCategoriesLoadable = stream.readInt();
00340 dockingHeight_abs = stream.readInt();
00341 dockingHeight_rel = stream.readInt();
00342 if ( version <= 2 ) {
00343 int r = stream.readInt();
00344 requiresUnitFeature = Vehicletype::convertOldFunctions(r, stream.getLocation());
00345 } else
00346 stream.readBitset( requiresUnitFeature );
00347
00348 disableAttack = stream.readInt();
00349 if ( version >= 2 )
00350 movecost = stream.readInt();
00351 else
00352 movecost = -1;
00353
00354 }
00355
00356 void ContainerBaseType :: TransportationIO :: write ( tnstream& stream ) const
00357 {
00358 stream.writeInt ( containerBaseTypeTransportVersion );
00359 stream.writeInt ( mode );
00360 stream.writeInt ( height_abs );
00361 stream.writeInt ( height_rel );
00362 stream.writeInt ( container_height );
00363 stream.writeInt ( vehicleCategoriesLoadable );
00364 stream.writeInt ( dockingHeight_abs );
00365 stream.writeInt ( dockingHeight_rel );
00366 stream.writeBitset ( requiresUnitFeature );
00367 stream.writeInt ( disableAttack );
00368 stream.writeInt ( movecost );
00369 }
00370
00371
00372 Resources ContainerBaseType::getStorageCapacity( int mode ) const
00373 {
00374 if ( mode == 1 )
00375 return bi_mode_tank;
00376 else
00377 return asc_mode_tank;
00378 }
00379
00380