containerbasetype.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           containerbasetype.h  -  description
00003                              -------------------
00004     begin                : Sun Feb 18 2001
00005     copyright            : (C) 2001 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
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                "No removal of mines", 
00070                NULL };
00071 
00072 
00073 ContainerBaseType :: ContainerBaseType ()
00074 {
00075    maxLoadableUnits = 0;
00076    maxLoadableUnitSize = 0;
00077    maxLoadableWeight = maxint;
00078    vehicleCategoriesStorable = -1;
00079    id = 0;
00080    jamming = 0;
00081    view = 0;
00082    efficiencyfuel = 1024;
00083    efficiencymaterial = 1024;
00084 
00085    maxresearchpoints = 0;
00086    defaultMaxResearchpoints = 0;
00087    nominalresearchpoints = 0;
00088    vehicleCategoriesProduceable = 0xfffffff;
00089    autoHarvest.range = 0;
00090    autoHarvest.maxFieldsPerTurn = maxint;
00091    minFieldRepairDamage = 0;
00092 }
00093 
00094 bool ContainerBaseType::hasFunction( ContainerFunctions function ) const
00095 {
00096    int f = int(function);
00097    return features.test( f );
00098 }
00099 
00100 bool ContainerBaseType::hasAnyFunction( BitSet functions ) const
00101 {
00102    bool result = (features & functions).any(); 
00103    return result;
00104 }
00105 
00106 void ContainerBaseType::setFunction( ContainerFunctions function )
00107 {
00108    features.set( int(function) );
00109 }
00110 
00111            
00112 
00113 
00114 const char* ContainerBaseType::getFunctionName( ContainerFunctions function )
00115 {
00116    if ( function < functionNum )
00117       return ccontainerfunctions[function];
00118    else
00119       return NULL;
00120 }
00121 
00122 
00123 ContainerBaseType::TransportationIO::TransportationIO()
00124 {
00125   mode = 0;
00126   height_abs = 0;
00127   height_rel = 0;
00128   container_height = 0;
00129   vehicleCategoriesLoadable = -1;
00130   dockingHeight_abs = 0;
00131   dockingHeight_rel = 0;
00132   disableAttack = false;
00133   movecost = -1;
00134 }
00135 
00136 
00137 void ContainerBaseType :: TransportationIO :: runTextIO ( PropertyContainer& pc )
00138 {
00139    pc.addTagInteger( "Mode", mode, entranceModeNum, entranceModes );
00140    pc.addTagInteger( "UnitHeightAbs", height_abs, choehenstufennum, heightTags );
00141    pc.addInteger( "UnitHeightRel", height_rel, -100 );
00142    pc.addTagInteger( "ContainerHeight", container_height, choehenstufennum, heightTags );
00143    pc.addTagInteger( "CategoriesNOT", vehicleCategoriesLoadable, cmovemalitypenum, unitCategoryTags, true );
00144    pc.addTagInteger( "DockingHeightAbs", dockingHeight_abs, choehenstufennum, heightTags, 0 );
00145    pc.addInteger( "DockingHeightRel", dockingHeight_rel, -100 );
00146    if ( pc.find( "RequireUnitFunction" )) {
00147       int r = 0;
00148       pc.addTagInteger( "RequireUnitFunction", r, VehicleType::legacyVehicleFunctionNum, vehicleAbilities, 0 );
00149       requiresUnitFeature = VehicleType::convertOldFunctions(r, pc.getFileName() );
00150    } else
00151       if ( pc.find( "RequiresUnitFeature" ) || !pc.isReading() )
00152          pc.addTagArray( "RequiresUnitFeature", requiresUnitFeature, ContainerBaseType::functionNum, containerFunctionTags );
00153       else
00154          requiresUnitFeature.reset();
00155       
00156    pc.addBool( "DisableAttack", disableAttack, false );
00157    pc.addInteger( "MoveCost", movecost, -1 );
00158    if ( movecost < 10 && movecost >= 0 )
00159       fatalError ( "MoveCost for TransportationIO is lower than 10! file: " + pc.getFileName() );
00160 }
00161 
00162 
00163 void ContainerBaseType :: runTextIO ( PropertyContainer& pc )
00164 {
00165    pc.addBreakpoint();
00166    pc.openBracket ( "Transportation" );
00167     int num = entranceSystems.size();
00168     pc.addInteger ( "EntranceSystemNum", num, 0 );
00169     entranceSystems.resize(num);
00170     for ( int i = 0; i < num; i++ ) {
00171        pc.openBracket ( ASCString("EntranceSystem") + strrr(i) );
00172        entranceSystems[i].runTextIO( pc );
00173        pc.closeBracket();
00174     }
00175     pc.addInteger ( "MaxLoadableUnits", maxLoadableUnits, 0 );
00176 
00177     pc.addInteger ( "MaxLoadableUnitSize", maxLoadableUnitSize, maxint );
00178     pc.addInteger ( "MaxLoadableMass", maxLoadableWeight, maxint );
00179     pc.addTagInteger( "CategoriesNOT", vehicleCategoriesStorable, cmovemalitypenum, unitCategoryTags, -1, true );
00180    pc.closeBracket();
00181 
00182    pc.addString( "Name", name );
00183    pc.addString( "Description", description, "" );
00184    pc.addString( "Infotext", infotext, "" );
00185 
00186    while ( infotext.find ( "#CRT#" ) != ASCString::npos )
00187       infotext.replace ( infotext.find ( "#CRT#" ), 5, "\n" );
00188    while ( infotext.find ( "#crt#" ) != ASCString::npos )
00189       infotext.replace ( infotext.find ( "#crt#" ), 5, "\n" );
00190    while ( infotext.find ( "\r" ) != ASCString::npos )
00191       infotext.replace ( infotext.find ( "\r" ), 1, "" );
00192 
00193    pc.addInteger( "ID", id );
00194 
00195    if ( pc.find( "SecondaryIDs") || !pc.isReading())
00196       pc.addIntegerArray("SecondaryIDs", secondaryIDs );
00197 
00198    pc.addInteger( "View", view );
00199    if ( view > maxViewRange )
00200       view = maxViewRange;
00201 
00202    pc.addInteger( "Jamming", jamming, 0 );
00203    pc.addString( "InfoImage", infoImageFilename, "" );
00204    pc.addString( "InfoImageSmall", infoImageSmallFilename, "" );
00205 
00206    pc.openBracket ( "MaxResourceProduction" );
00207    maxplus.runTextIO ( pc, Resources(0,0,0) );
00208    pc.closeBracket ();
00209 
00210    pc.openBracket ( "ResourceExtractionEfficiency");
00211     pc.addInteger( "Material", efficiencymaterial, 1024 );
00212     pc.addInteger( "Fuel", efficiencyfuel, 1024 );
00213    pc.closeBracket ();
00214 
00215    pc.openBracket ( "StorageCapacity" );
00216     pc.openBracket( "BImode" );
00217      bi_mode_tank.runTextIO ( pc, Resources(0,0,0) );
00218     pc.closeBracket();
00219     pc.openBracket ( "ASCmode" );
00220      asc_mode_tank.runTextIO ( pc, Resources(0,0,0) );
00221     pc.closeBracket();
00222    pc.closeBracket ();
00223    
00224    pc.addInteger ( "MaxResearch", maxresearchpoints, 0 );
00225    pc.addInteger ( "NominalResearch", nominalresearchpoints, maxresearchpoints/2 );
00226    pc.addInteger ( "MaxResearchpointsDefault", defaultMaxResearchpoints, maxresearchpoints );
00227    
00228    pc.openBracket( "DefaultProduction" );
00229     defaultProduction.runTextIO ( pc, Resources(0,0,0) );
00230    pc.closeBracket();
00231 
00232    pc.addTagInteger( "CategoriesProduceable", vehicleCategoriesProduceable, cmovemalitypenum, unitCategoryTags, -1 );
00233          
00234    pc.openBracket( "AutoHarvestObjects" );
00235    pc.addIntRangeArray( "objects", autoHarvest.objectsHarvestable, false );
00236    pc.addIntRangeArray( "objectGroups", autoHarvest.objectGroupsHarvestable, false );
00237    pc.addInteger( "Range", autoHarvest.range, 0 );
00238    pc.addInteger( "MaxFieldsPerTurn", autoHarvest.maxFieldsPerTurn, maxint);
00239    pc.closeBracket();
00240    
00241    
00242    pc.openBracket ( "Construction" );
00243    pc.addIntRangeArray ( "VehiclesInternally", vehiclesInternallyProduceable, false );
00244    productionEfficiency.runTextIO("ProductionEfficiency", pc, productionEfficiency );
00245    pc.closeBracket();
00246    
00247    pc.addInteger("minFieldRepairDamage", minFieldRepairDamage , 0 );
00248 }
00249 
00250 
00251 bool ContainerBaseType :: vehicleFit ( const VehicleType* fzt ) const
00252 {
00253    if ( maxLoadableUnits > 0 )
00254       if ( maxLoadableWeight > 0 )
00255          if ( vehicleCategoriesStorable & (1<<fzt->movemalustyp) )
00256             if ( maxLoadableUnitSize >= fzt->maxsize() )
00257                return true;
00258 
00259    return false;
00260 }
00261 
00262 int  ContainerBaseType :: vehicleUnloadable ( const VehicleType* vehicleType, int carrierHeight ) const
00263 {
00264    int height = 0;
00265 
00266    int carrierBinHeight = 1 << carrierHeight;
00267 
00268    if ( vehicleFit ( vehicleType ))
00269       for ( ContainerBaseType::EntranceSystems::const_iterator i = entranceSystems.begin(); i != entranceSystems.end(); i++ )
00270          if ( i->mode & ContainerBaseType::TransportationIO::Out )
00271             if ( (i->container_height & carrierBinHeight) || (i->container_height == 0))
00272                if ( i->vehicleCategoriesLoadable & (1<<vehicleType->movemalustyp))
00273                   if ( vehicleType->hasAnyFunction(i->requiresUnitFeature) || i->requiresUnitFeature.none() ) {
00274                      if ( i->height_abs != 0 && i->height_rel != -100 ) {
00275                         int h = 0;
00276                         for ( int hh = 0; hh < 8; ++hh)
00277                            if ( getheightdelta(carrierHeight, hh) == i->height_rel )
00278                               h += 1 << hh;
00279                         height |= i->height_abs & h;
00280                      } else
00281                         if ( i->height_rel != -100 )
00282                            height |= 1 << (carrierHeight + i->height_rel) ;
00283                         else
00284                            height |= i->height_abs ;
00285                   }
00286    return height & vehicleType->height;
00287 }
00288 
00289 
00290 const int containerBaseTypeVersion = 8;
00291 
00292 
00293 void ContainerBaseType :: read ( tnstream& stream )
00294 {
00295    int version = stream.readInt();
00296    if ( version > containerBaseTypeVersion || version < 1 ) {
00297       ASCString s = "invalid version for reading ContainerBaseType: ";
00298       s += strrr ( version );
00299       throw ASCmsgException ( s );
00300    }
00301    maxLoadableUnits = stream.readInt();
00302    maxLoadableUnitSize = stream.readInt();
00303    maxLoadableWeight = stream.readInt();
00304    vehicleCategoriesStorable = stream.readInt();
00305    int num = stream.readInt();
00306    entranceSystems.resize(num);
00307    for ( int i = 0; i < num; i++ )
00308       entranceSystems[i].read( stream );
00309 
00310    if ( version >= 2 )
00311       infoImageFilename = stream.readString();
00312 
00313    if ( version >= 3 )
00314       stream.readBitset( features );
00315 
00316    if ( version >= 4 )
00317       vehicleCategoriesProduceable = stream.readInt();
00318 
00319    if ( version >= 5 )
00320       readClassContainer( secondaryIDs, stream );
00321 
00322    if ( version >= 6 ) {
00323                  autoHarvest.range = stream.readInt();
00324        readClassContainer( autoHarvest.objectsHarvestable, stream );
00325        readClassContainer( autoHarvest.objectGroupsHarvestable, stream );
00326        autoHarvest.maxFieldsPerTurn = stream.readInt();
00327        
00328        readClassContainer( vehiclesInternallyProduceable, stream );
00329        productionEfficiency.read( stream );
00330          }
00331    if ( version >= 7 ) 
00332       infoImageSmallFilename = stream.readString();
00333    
00334    if ( version >= 8 )
00335       minFieldRepairDamage = stream.readInt();
00336    else
00337       minFieldRepairDamage  = 0;
00338 }
00339 
00340 void ContainerBaseType :: write ( tnstream& stream ) const
00341 {
00342    stream.writeInt( containerBaseTypeVersion );
00343    stream.writeInt( maxLoadableUnits );
00344    stream.writeInt( maxLoadableUnitSize );
00345    stream.writeInt( maxLoadableWeight );
00346    stream.writeInt( vehicleCategoriesStorable );
00347    stream.writeInt( entranceSystems.size() );
00348    for ( int i = 0; i < entranceSystems.size(); i++ )
00349       entranceSystems[i].write( stream );
00350    stream.writeString( infoImageFilename );
00351    stream.writeBitset( features );
00352    stream.writeInt( vehicleCategoriesProduceable );
00353    writeClassContainer( secondaryIDs, stream );
00354 
00355    stream.writeInt( autoHarvest.range );
00356    writeClassContainer( autoHarvest.objectsHarvestable, stream );
00357    writeClassContainer( autoHarvest.objectGroupsHarvestable, stream );
00358    stream.writeInt( autoHarvest.maxFieldsPerTurn );
00359    
00360    writeClassContainer( vehiclesInternallyProduceable, stream );
00361    productionEfficiency.write( stream );
00362    stream.writeString( infoImageSmallFilename );
00363    stream.writeInt( minFieldRepairDamage  );
00364 }
00365 
00366 const int containerBaseTypeTransportVersion = 3;
00367 
00368 
00369 void ContainerBaseType :: TransportationIO :: read ( tnstream& stream )
00370 {
00371    int version = stream.readInt();
00372    if ( version > containerBaseTypeTransportVersion || version < 1 ) {
00373       ASCString s = "invalid version for reading ContainerBaseTypeTransportation: ";
00374       s += strrr ( version );
00375       throw ASCmsgException ( s );
00376    }
00377    mode = stream.readInt();
00378    height_abs = stream.readInt();
00379    height_rel = stream.readInt();
00380    container_height = stream.readInt();
00381    vehicleCategoriesLoadable = stream.readInt();
00382    dockingHeight_abs = stream.readInt();
00383    dockingHeight_rel = stream.readInt();
00384    if ( version <= 2 ) {
00385       int r = stream.readInt();
00386       requiresUnitFeature = VehicleType::convertOldFunctions(r, stream.getLocation());
00387    } else
00388       stream.readBitset( requiresUnitFeature );
00389       
00390    disableAttack = stream.readInt();
00391    if ( version >= 2 )
00392       movecost = stream.readInt();
00393    else
00394       movecost = -1;
00395    
00396 }
00397 
00398 void ContainerBaseType :: TransportationIO :: write ( tnstream& stream ) const
00399 {
00400    stream.writeInt ( containerBaseTypeTransportVersion );
00401    stream.writeInt ( mode );
00402    stream.writeInt ( height_abs );
00403    stream.writeInt ( height_rel );
00404    stream.writeInt ( container_height );
00405    stream.writeInt ( vehicleCategoriesLoadable );
00406    stream.writeInt ( dockingHeight_abs );
00407    stream.writeInt ( dockingHeight_rel );
00408    stream.writeBitset ( requiresUnitFeature );
00409    stream.writeInt ( disableAttack );
00410    stream.writeInt ( movecost );
00411 }
00412 
00413 
00414 Resources ContainerBaseType::getStorageCapacity( int mode ) const
00415 {
00416    if ( mode == 1 )
00417       return bi_mode_tank;
00418    else
00419       return asc_mode_tank;
00420 }
00421 
00422 

Generated on Mon May 21 01:26:30 2012 for Advanced Strategic Command by  doxygen 1.5.1