containerbase.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           containerbase.cpp  -  description
00003                              -------------------
00004     begin                : Fri Sep 29 2000
00005     copyright            : (C) 2003 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00014 /***************************************************************************
00015  *                                                                         *
00016  *   This program is free software; you can redistribute it and/or modify  *
00017  *   it under the terms of the GNU General Public License as published by  *
00018  *   the Free Software Foundation; either version 2 of the License, or     *
00019  *   (at your option) any later version.                                   *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 #include <algorithm>
00024 #include "typen.h"
00025 #include "containerbase.h"
00026 #include "vehicletype.h"
00027 #include "vehicle.h"
00028 #include "spfst.h"
00029 #include "graphics/blitter.h"
00030 #include "graphics/ColorTransform_PlayerColor.h"
00031 #include "containercontrols.h"
00032 #include "resourcenet.h"
00033 #include "accessconstraints.h"
00034 
00035 
00036 ContainerBase ::  ContainerBase ( const ContainerBaseType* bt, GameMap* map, int player ) : gamemap ( map ), cargoParent(NULL), baseType (bt)
00037 {
00038    view = bt->view;
00039    damage = 0;
00040    color = player*8;
00041    maxresearchpoints = baseType->defaultMaxResearchpoints;
00042    researchpoints = min ( maxresearchpoints, baseType->nominalresearchpoints );
00043    maxplus = baseType->maxplus;
00044    repairedThisTurn = 0;
00045   
00046    plus = baseType->defaultProduction;
00047    
00048    for ( int i = 0; i < map->getVehicleTypeNum(); ++i ) {
00049       const VehicleType* vt = map->getvehicletype_bypos(i);
00050       if ( vt ) 
00051          for ( int j = 0; j < bt->vehiclesInternallyProduceable.size(); ++j ) 
00052             if ( vt->id >= bt->vehiclesInternallyProduceable[j].from  && vt->id <= bt->vehiclesInternallyProduceable[j].to )
00053                internalUnitProduction.push_back ( vt ); 
00054    }
00055 }
00056 
00057 
00058 ASCString ContainerBase::getPrivateName() const
00059 {
00060    if ( privateName.empty())
00061       return getName();
00062    else
00063       return privateName;  
00064 }
00065 
00066 
00067 SigC::Signal1<void,ContainerBase*> ContainerBase :: anyContainerDestroyed;
00068 SigC::Signal1<void,ContainerBase*> ContainerBase :: anyContainerConquered;
00069 
00070 
00071 Resources ContainerBase :: putResource ( const Resources& res, bool queryonly, int scope, int player)
00072 {
00073    Resources result;
00074    for ( int i = 0; i < resourceNum; i++ )
00075       result.resource(i) = putResource ( res.resource(i), i , queryonly, scope, player );
00076    return result;
00077 }
00078 
00079 
00080 Resources ContainerBase :: getResource ( const Resources& res, bool queryonly, int scope, int player)
00081 {
00082    Resources result;
00083    for ( int i = 0; i < resourceNum; i++ )
00084       result.resource(i) = getResource ( res.resource(i), i , queryonly, scope, player );
00085    return result;
00086 }
00087 
00088 Resources ContainerBase :: getResource ( const Resources& res ) const
00089 {
00090    Resources result;
00091    for ( int i = 0; i < resourceNum; i++ )
00092       result.resource(i) = getAvailableResource ( res.resource(i), i );
00093    return result;
00094 }
00095 
00096 
00097 int ContainerBase :: repairItem   ( ContainerBase* item, int newDamage  )
00098 {
00099    if ( !canRepair( item ) )
00100       return item->damage;
00101 
00102    if ( item == this ) 
00103       if ( damage - repairableDamage() > newDamage )
00104          newDamage = damage - repairableDamage();
00105    
00106    int orgdam = item->damage;
00107 
00108    Resources cost;
00109    newDamage = getMaxRepair ( item, newDamage, cost );
00110    item->damage = newDamage;
00111    getResource ( cost, 0 );
00112 
00113    item->postRepair( orgdam );
00114 
00115    return newDamage;
00116 }
00117 
00118 int ContainerBase :: getMaxRepair ( const ContainerBase* item ) const
00119 {
00120    Resources res;
00121    return getMaxRepair ( item, 0, res );
00122 }
00123 
00124 int ContainerBase :: getMaxRepair ( const ContainerBase* item, int newDamage, Resources& cost, bool ignoreCost  ) const
00125 {
00126    if ( !canRepair( item ) )
00127       return item->damage;
00128 
00129    if ( item == this ) {
00130       if ( damage - repairableDamage() > newDamage )
00131          newDamage = damage - repairableDamage();
00132    } else if ( item->getCarrier() != this ) {
00133       if ( newDamage < item->baseType->minFieldRepairDamage )
00134          newDamage = item->baseType->minFieldRepairDamage;
00135    }
00136 
00137    if ( newDamage > item->damage )
00138       newDamage = item->damage;
00139    
00140    int toRepair = item->damage - newDamage;
00141 
00142    Resources maxNeeded = getRepairEfficiency() * item->baseType->productionCost;
00143 
00144    Resources needed;
00145    for ( int i = 0; i < resourceTypeNum; i++ )
00146       needed.resource(i) = maxNeeded.resource(i) * (item->damage-newDamage) / 100;
00147 
00148    if ( !ignoreCost ) {
00149       Resources avail = getResource ( needed );
00150    
00151       for ( int i = 0; i < resourceTypeNum; i++ )
00152          if ( needed.resource(i) ) {
00153             int repairable = toRepair * avail.resource(i) / needed.resource(i);
00154             if ( item->damage - repairable > newDamage )
00155                newDamage = item->damage - repairable;
00156          }
00157    }
00158 
00159    for ( int i = 0; i < resourceTypeNum; i++ )
00160       cost.resource(i) = maxNeeded.resource(i) * (item->damage-newDamage) / 100;
00161 
00162    return newDamage;
00163 }
00164 
00165 int ContainerBase :: vehiclesLoaded ( void ) const
00166 {
00167    int a = 0;
00168 
00169    for ( Cargo::const_iterator i = cargo.begin(); i != cargo.end(); ++i )
00170       if ( *i )
00171          ++a;
00172 
00173    return a;
00174 }
00175 
00176 
00177 int ContainerBase::cargoWeight() const
00178 {
00179    int w = 0;
00180    for ( Cargo::const_iterator i = cargo.begin(); i != cargo.end(); ++i )
00181       if ( *i )
00182          w += (*i)->weight();
00183 
00184    return w;
00185 }
00186 
00187 
00188 int ContainerBase :: cargoNestingDepth()
00189 {
00190    ContainerBase* cb = getCarrier();
00191    if ( cb )
00192       return cb->cargoNestingDepth() +1;
00193    else
00194       return 0;
00195 }
00196 
00197 void ContainerBase :: compactCargo()
00198 {
00199    for ( Cargo::iterator i = cargo.begin(); i != cargo.end(); ) {
00200       if ( *i == NULL )
00201          i = cargo.erase(i);
00202       else
00203          ++i;
00204    }
00205 }
00206 
00207 
00208 Vehicle* ContainerBase :: getCargo( int i )
00209 {
00210    if ( i < 0 || i >= cargo.size() )
00211       return NULL;
00212    else  
00213       return cargo.at(i);
00214 }
00215 
00216 
00217 
00218 ContainerBase* ContainerBase :: getCarrier() const
00219 {
00220    return cargoParent;
00221 }
00222 
00223 
00224 Vehicle* ContainerBase :: findUnit ( int nwid, bool recursive ) const
00225 {
00226    for ( Cargo::const_iterator i = cargo.begin(); i != cargo.end(); ++i )
00227       if ( *i ) {
00228          if ( (*i)->networkid == nwid )
00229             return *i;
00230          else {
00231             if ( recursive ) {
00232                Vehicle* cb = (*i)->findUnit( nwid );
00233                if ( cb )
00234                   return cb;
00235             }
00236          }
00237       }
00238 
00239    return NULL;
00240 }
00241 
00242 
00243 template<int pixelSize>
00244 class ColorTransform_UnitGray
00245 { }
00246 ;
00247 
00248 template<>
00249 class ColorTransform_UnitGray<1> : public ColorTransform_XLAT<1>
00250 {
00251    public:
00252       ColorTransform_UnitGray( NullParamType npt  = nullParam )
00253       {
00254          setTranslationTable( *xlatpictgraytable );
00255       };
00256 };
00257 
00258 template<>
00259 class ColorTransform_UnitGray<4> : public ColorTransform_Gray<4>
00260 {
00261    public:
00262       ColorTransform_UnitGray( NullParamType npt  = nullParam )
00263       {}
00264 }
00265 ;
00266 
00267 
00268 int ContainerBase::calcShadowDist( int binaryHeight )
00269 {
00270    if ( binaryHeight <= 1 )
00271       return 0;
00272 
00273    if ( binaryHeight <= 3 )
00274       return 1;
00275 
00276    return 6 * ( binaryHeight - getFirstBit ( chfahrend ));
00277 }
00278 
00279 
00280 void ContainerBase::paintField ( const Surface& img, Surface& dest, SPoint pos, int dir, bool shaded, int shadowDist ) const
00281 {
00282 
00283    pair<const Surface*, int> dirpair = make_pair(&img, directionangle[dir]);
00284 
00285    int height = getHeight();
00286    if ( height <= chgetaucht ) {
00287       if ( shaded ) {
00288          megaBlitter< ColorTransform_UnitGray,
00289          ColorMerger_AlphaMixer,
00290          SourcePixelSelector_CacheRotation,
00291          TargetPixelSelector_All>
00292          ( img, dest, pos, nullParam,nullParam, dirpair, nullParam);
00293       } else {
00294          if ( img.GetPixelFormat().BytesPerPixel() == 1 ) {
00295             MegaBlitter<1,gamemapPixelSize,ColorTransform_PlayerCol, ColorMerger_AlphaMixer, SourcePixelSelector_CacheRotation> blitter;
00296             blitter.setPlayer( getOwner() );
00297             blitter.setAngle( img, directionangle[dir] );
00298             blitter.blit( img, dest, pos );
00299 
00300             /*
00301             megaBlitter< ColorTransform_PlayerCol,
00302             ColorMerger_AlphaMixer,
00303             SourcePixelSelector_CacheRotation,
00304             TargetPixelSelector_All>
00305             ( img, dest, pos, getOwner(),nullParam, dirpair, nullParam);
00306             */
00307          } else {
00308             MegaBlitter<4,gamemapPixelSize,ColorTransform_PlayerTrueCol, ColorMerger_AlphaMixer, SourcePixelSelector_CacheRotation> blitter;
00309             blitter.setColor( gamemap->player[getOwner()].getColor() );
00310             blitter.setAngle( img, directionangle[dir] );
00311             blitter.blit( img, dest, pos );
00312 
00313          }
00314       }
00315    } else {
00316       if ( height >= chfahrend && shadowDist ) {
00317          if ( shadowDist == -1 )
00318             shadowDist = calcShadowDist( getFirstBit( height ));
00319 
00320          megaBlitter< ColorTransform_None,
00321          ColorMerger_AlphaShadow,
00322          SourcePixelSelector_CacheRotation,
00323          TargetPixelSelector_All>
00324          ( img, dest, SPoint(pos.x+shadowDist, pos.y+shadowDist), nullParam,nullParam, dirpair, nullParam);
00325       }
00326 
00327       if ( shaded ) {
00328          megaBlitter< ColorTransform_UnitGray,
00329          ColorMerger_AlphaOverwrite,
00330          SourcePixelSelector_CacheRotation,
00331          TargetPixelSelector_All>
00332          ( img, dest, pos, nullParam,nullParam, dirpair, nullParam);
00333       } else {
00334          if ( img.GetPixelFormat().BytesPerPixel() == 1 ) {
00335             MegaBlitter<1,gamemapPixelSize,ColorTransform_PlayerCol, ColorMerger_AlphaOverwrite, SourcePixelSelector_CacheRotation> blitter;
00336             blitter.setPlayer( getOwner() );
00337             blitter.setAngle( img, directionangle[dir] );
00338             blitter.blit( img, dest, pos );
00339          } else {
00340             MegaBlitter<4,gamemapPixelSize,ColorTransform_PlayerTrueCol, ColorMerger_AlphaMerge, SourcePixelSelector_CacheRotation> blitter;
00342             blitter.setColor( gamemap->player[getOwner()].getColor() );
00343             blitter.setAngle( img, directionangle[dir] );
00344             blitter.blit( img, dest, pos );
00345          }
00346       }
00347    }
00348 }
00349 
00350 
00351 void ContainerBase :: clearCargo()
00352 {
00353    while ( !cargo.empty() )
00354       if ( cargo.front() )
00355          delete cargo.front();
00356       else
00357          cargo.erase( cargo.begin() );
00358 
00359    cargoChanged();
00360 }
00361 
00362 
00363 void ContainerBase :: addToCargo( Vehicle* veh, int position )
00364 {
00365    if ( veh == this )
00366       fatalError ("Trying to add unit to its own cargo");
00367    
00368    bool slotFound = false;
00369    for ( Cargo::iterator i = cargo.begin(); i != cargo.end(); ++i )
00370       if ( ! (*i) && (position == -1 || position == i - cargo.begin() )) {
00371          *i = veh;
00372          slotFound = true;
00373          break;
00374       }
00375 
00376    if ( !slotFound )
00377       cargo.push_back( veh );
00378    
00379    veh->cargoParent = this;
00380    veh->setnewposition(getPosition());
00381    cargoChanged();
00382 }
00383 
00384 bool ContainerBase :: removeUnitFromCargo( Vehicle* veh, bool recursive )
00385 {
00386    if ( !veh )
00387       return false;
00388    else {
00389       if ( removeUnitFromCargo( veh->networkid, recursive )) {
00390          cargoChanged();
00391          return true;
00392       } else
00393          return false;
00394    }
00395 }
00396 
00397 bool ContainerBase :: removeUnitFromCargo( int nwid, bool recursive )
00398 {
00399    for ( Cargo::iterator i = cargo.begin(); i != cargo.end(); ++i )
00400       if ( *i ) {
00401          if ( (*i)->networkid == nwid ) {
00402             (*i)->cargoParent = NULL;
00403             *i = NULL;
00404 
00405             if ( cargo.size() > baseType->maxLoadableUnits ) {
00406                // we only compact the cargo when we have more slots than allowed (may happen when conquering fully occupied buildings).
00407                // because else we would confuse the user if the position of units in the cargo dialog changes
00408                compactCargo();
00409             }
00410 
00411             cargoChanged();
00412             return true;
00413          }
00414          if ( recursive )
00415             if ( (*i)->removeUnitFromCargo( nwid, recursive ))
00416                return true;
00417       }
00418 
00419    return false;
00420 }
00421 
00422 bool ContainerBase :: canCarryWeight( int additionalWeight, const Vehicle*  vehicle) const
00423 {
00424    // if the unit already carries this unit, there is no additional weight to check
00425    if ( vehicle && findUnit( vehicle->networkid ))
00426       additionalWeight = 0;
00427 
00428 
00429    if ( cargoWeight() + additionalWeight > baseType->maxLoadableWeight )
00430       return false;
00431    else
00432       if ( getCarrier() )
00433          return getCarrier()->canCarryWeight( additionalWeight, vehicle );
00434       else
00435          return true;
00436 }
00437 
00438 
00439 bool ContainerBase :: vehicleFit ( const Vehicle* vehicle ) const
00440 {
00441    bool isConquering = isBuilding() && getMap()->getPlayer(this).diplomacy.isHostile( vehicle) && vehicle->color != color;
00442    if ( baseType->vehicleFit ( vehicle->typ )) // checks size and type
00443       if ( vehiclesLoaded() < baseType->maxLoadableUnits || isConquering )
00444          if ( canCarryWeight( vehicle->weight(), vehicle ) || findUnit ( vehicle->networkid ) || isConquering) // if the unit is already  loaded, the container already bears its weight
00445             return true;
00446 
00447    return false;
00448 }
00449 
00450 
00451 bool  ContainerBase :: vehicleLoadable ( const Vehicle* vehicle, int uheight, const bool* attacked ) const
00452 {
00453    if ( vehicle->attacked )
00454       return false;
00455 
00456    bool hasAttacked = vehicle->attacked;
00457    if ( attacked )
00458       hasAttacked = *attacked;
00459 
00460    if ( uheight == -1 )
00461       uheight = vehicle->height;
00462 
00463    if ( vehicleFit ( vehicle ))
00464       for ( ContainerBaseType::EntranceSystems::const_iterator i = baseType->entranceSystems.begin(); i != baseType->entranceSystems.end(); i++ )
00465          if ( (i->height_abs & uheight) || (i->height_abs == 0 ))
00466             if ( i->mode & ContainerBaseType::TransportationIO::In )
00467                if ( i->height_rel == -100 || i->height_rel == getheightdelta ( getPosition().getNumericalHeight(), getFirstBit(uheight)  ) )
00468                   if ( (i->container_height & getPosition().getBitmappedHeight()) || (i->container_height == 0))
00469                      if ( vehicle->typ->hasAnyFunction(i->requiresUnitFeature) || i->requiresUnitFeature.none() )
00470                         if ( i->vehicleCategoriesLoadable & (1<<vehicle->typ->movemalustyp)) {
00471                            if ( getMap()->getPlayer(this).diplomacy.isAllied( vehicle->getOwner()) ) 
00472                               return true;
00473 
00474                            if ( isBuilding() ) {
00475                               if ( !hasAttacked ) {
00476                                  if ( getOwner() == 8 )
00477                                     return true;
00478                                  if ( gamemap->getPlayer(this).diplomacy.isHostile( vehicle->getOwner())  )
00479                                     if (damage >= minimumBuildingDamageForConquering  || vehicle->typ->hasFunction( ContainerBaseType::ConquerBuildings ) )
00480                                        return true;
00481                               }
00482                            }
00483                         }
00484    return false;
00485 }
00486 
00487 int  ContainerBase :: vehicleUnloadable ( const VehicleType* vehicleType, int carrierHeight ) const
00488 {
00489    if (carrierHeight == -1 )
00490       return baseType->vehicleUnloadable( vehicleType, getPosition().getNumericalHeight());
00491    else
00492       return baseType->vehicleUnloadable( vehicleType, carrierHeight );
00493 
00494 }
00495 
00496 const ContainerBaseType::TransportationIO* ContainerBase::vehicleUnloadSystem ( const VehicleType* vehicleType, int height )
00497 {
00498    if ( baseType->vehicleFit ( vehicleType ))
00499       for ( ContainerBaseType::EntranceSystems::const_iterator i = baseType->entranceSystems.begin(); i != baseType->entranceSystems.end(); i++ )
00500          if ( i->mode & ContainerBaseType::TransportationIO::Out )
00501             if ( (i->container_height & getPosition().getBitmappedHeight()) || (i->container_height == 0))
00502                if ( i->vehicleCategoriesLoadable & (1<<vehicleType->movemalustyp))
00503                   if ( vehicleType->hasAnyFunction(i->requiresUnitFeature) || i->requiresUnitFeature.none() ) {
00504                      if ( i->height_abs != 0 && i->height_rel != -100 ) {
00505                         if ( height & ( i->height_abs & (1 << (getPosition().getNumericalHeight() + i->height_rel ))))
00506                            return &(*i);
00507                      } else
00508                         if ( i->height_rel != -100 ) {
00509                            if ( height & ( 1 << (getPosition().getNumericalHeight() + i->height_rel)))
00510                               return &(*i);
00511                         } else
00512                            if ( height & i->height_abs )
00513                               return &(*i);
00514                   }
00515    return NULL;
00516 
00517 }
00518 
00519 int  ContainerBase :: vehicleDocking ( const Vehicle* vehicle, bool out ) const
00520 {
00521    if ( vehicle == this )
00522       return 0;
00523 
00524    int height = 0;
00525 
00526    if ( baseType->vehicleFit ( vehicle->typ ) && ( vehicleFit( vehicle ) || out ) )
00527       for ( ContainerBaseType::EntranceSystems::const_iterator i = baseType->entranceSystems.begin(); i != baseType->entranceSystems.end(); i++ )
00528          if ( i->mode & ContainerBaseType::TransportationIO::Docking )
00529             if ( (i->container_height & getPosition().getBitmappedHeight()) || (i->container_height == 0))
00530                if ( i->vehicleCategoriesLoadable & (1<<vehicle->typ->movemalustyp)) {
00531                   if ( i->dockingHeight_abs != 0 && i->dockingHeight_rel != -100 )
00532                      height |= i->dockingHeight_abs & (1 << (getPosition().getNumericalHeight() + i->dockingHeight_rel ));
00533                   else
00534                      if ( i->dockingHeight_rel != -100 )
00535                         height |= 1 << (getPosition().getNumericalHeight() + i->dockingHeight_rel) ;
00536                      else
00537                         height |= i->dockingHeight_abs ;
00538                }
00539    return height;
00540 }
00541 
00542 const ContainerBase::Production& ContainerBase::getProduction() const
00543 {
00544    if ( productionCache.empty() && !internalUnitProduction.empty() ) {
00545       for ( int height = 0; height < 8; ++height )
00546          if ( (1 << height) & baseType->height )
00547             for ( Production::const_iterator i = internalUnitProduction.begin(); i != internalUnitProduction.end(); ++i )
00548                if ( baseType->hasFunction( ContainerBaseType::ProduceNonLeavableUnits ) || vehicleUnloadable( *i, height ) )
00549                   if( find ( productionCache.begin(), productionCache.end(), *i ) == productionCache.end() )
00550                      productionCache.push_back ( *i );
00551    }
00552 
00553    return productionCache;
00554 }
00555 
00556 Resources ContainerBase::getProductionCost( const VehicleType* unit ) const
00557 {
00558    return baseType->productionEfficiency * unit->productionCost;
00559 }
00560 
00561 
00562 void ContainerBase ::deleteProductionLine( const VehicleType* type )
00563 {
00564    internalUnitProduction.erase( remove( internalUnitProduction.begin(), internalUnitProduction.end(), type ), internalUnitProduction.end());
00565    productionCache.clear();
00566 }
00567 
00568 void ContainerBase ::deleteAllProductionLines()
00569 {
00570    internalUnitProduction.clear();
00571    productionCache.clear();
00572 }
00573 
00574 void ContainerBase :: addProductionLine( const VehicleType* type )
00575 {
00576    if ( find ( internalUnitProduction.begin(), internalUnitProduction.end(), type ) == internalUnitProduction.end() )
00577       internalUnitProduction.push_back( type );
00578    productionCache.clear();
00579 }
00580 
00581 bool ContainerBase :: hasProductionLine( const VehicleType* type )
00582 {
00583    return find ( internalUnitProduction.begin(), internalUnitProduction.end(), type ) != internalUnitProduction.end();
00584 }
00585 
00586 
00587 void ContainerBase :: setProductionLines( const Production& production  )
00588 {
00589    internalUnitProduction = production;
00590    productionCache.clear();
00591 }
00592 
00593 
00594 void ContainerBase :: setName ( const ASCString& name )
00595 {
00596    if ( !checkModificationConstraints( this ) )
00597       return;
00598    
00599    this->name = name;
00600 }
00601 
00602 
00603 ContainerBase :: ~ContainerBase ( )
00604 {
00605    /* removing a unit from cargo (which is done when deleting) may cause a call to compactCargo, 
00606       which in turn invalidates the iterators to cargo 
00607       That's why we iterate through a copy of cargo */ 
00608    Cargo toDelete = cargo;
00609    
00610    for ( Cargo::iterator i = toDelete.begin(); i != toDelete.end(); ++i )
00611       if ( *i )
00612          delete *i;
00613 
00614    if ( gamemap->state != GameMap::Destruction ) {
00615       destroyed();
00616       anyContainerDestroyed( this );
00617    }
00618 }
00619 
00620 
00621 TemporaryContainerStorage :: TemporaryContainerStorage ( ContainerBase* _cb, bool storeCargo )
00622 {
00623    cb = _cb;
00624    MemoryStream stream ( &buf, tnstream::writing );
00625    cb->write ( stream, storeCargo );
00626    _storeCargo = storeCargo;
00627 }
00628 
00629 void TemporaryContainerStorage :: restore (  )
00630 {
00631    if ( _storeCargo ) {
00632       cb->clearCargo();
00633    }
00634 
00635    MemoryStream stream ( &buf, tnstream::reading );
00636    cb->read ( stream );
00637 }
00638 
00639 
00640 
00641 
00642 
00643 
00644 void ContainerBase::endOwnTurn( void )
00645 {
00646 }
00647 
00648 void ContainerBase::endAnyTurn( void )
00649 {
00650 }
00651 
00652 void ContainerBase::endRound ( void )
00653 {
00654    view = baseType->view;
00655 }
00656 
00657 
00658 
00659 Resources ContainerBase ::netResourcePlus( ) const
00660 {
00661    Resources res;
00662    for ( int resourcetype = 0; resourcetype < resourceTypeNum; resourcetype++ ) {
00663       GetResourcePlus grp ( getMap() );
00664       res.resource(resourcetype) += grp.getresource ( getPosition().x, getPosition().y, resourcetype, color/8, 1 );
00665    }
00666    return res;
00667 }
00668 
00669 
00670 
00671 Player& ContainerBase :: getOwningPlayer() const 
00672 { 
00673    return getMap()->getPlayer(this); 
00674 }
00675 
00676 void ContainerBase :: setInternalResourcePlus( const Resources& res )
00677 {
00678    for ( int r = 0; r < Resources::count; ++r ) 
00679       plus.resource(r) = min ( res.resource(r), min( maxplus.resource(r), baseType->maxplus.resource(r)));
00680 }
00681 
00682 void ContainerBase :: setInternalResourceMaxPlus( const Resources& res )
00683 {
00684    for ( int r = 0; r < Resources::count; ++r ) 
00685       maxplus.resource(r) = min ( res.resource(r), baseType->maxplus.resource(r));
00686 }
00687 
00688 Resources ContainerBase :: getInternalResourcePlus() const
00689 {
00690    return plus;
00691 }
00692 
00693 Resources ContainerBase :: getInternalResourceMaxPlus() const
00694 {
00695    return maxplus;
00696 }
00697 
00698 
00699 Resources ContainerBase :: getResourcePlus( )
00700 {
00701    Work* w = spawnWorkClasses ( true );
00702    Resources r;
00703    if ( w )
00704       r = w->getPlus();
00705    delete w;
00706 
00707    //  printf ("building %s %d / %d : plus %d %d %d \n", typ->name.c_str(), getPosition().x, getPosition().y, r.energy, r.material, r.fuel );
00708 
00709    return r;
00710 }
00711 
00712 Resources ContainerBase :: getResourceUsage( )
00713 {
00714    Work* w = spawnWorkClasses ( true );
00715    Resources r;
00716    if ( w )
00717       r = w->getUsage();
00718    delete w;
00719 
00720    if ( baseType->hasFunction( ContainerBaseType::Research ) )
00721       r += returnResourcenUseForResearch( this, researchpoints );
00722 
00723 
00724    return r;
00725 }
00726 
00727 Resources ContainerBase::getStorageCapacity() const
00728 {
00729    if ( gamemap && gamemap->_resourcemode == 1 && isBuilding() )
00730       return baseType->getStorageCapacity( 1 );
00731    else
00732       return baseType->getStorageCapacity( 0 );
00733 }
00734 
00735 
00736 
00737 
00738 bool ContainerBase::registerWorkClassFactory( WorkClassFactory* wcf, bool ASCmode )
00739 {
00740    if ( ASCmode )  {
00741       if ( !workClassFactoriesASC )
00742          workClassFactoriesASC = new WorkerClassList;
00743       
00744       workClassFactoriesASC->push_back( wcf );
00745    } else {
00746       if ( !workClassFactoriesBI )
00747          workClassFactoriesBI = new WorkerClassList;
00748       
00749       workClassFactoriesBI->push_back( wcf );
00750    }
00751    return true;
00752 }
00753 
00754 ContainerBase::WorkerClassList* ContainerBase::workClassFactoriesASC = NULL;
00755 ContainerBase::WorkerClassList* ContainerBase::workClassFactoriesBI = NULL;
00756 
00757 
00758 ContainerBase ::Work* ContainerBase ::spawnWorkClasses( bool justQuery )
00759 {
00760    if ( getMap()->_resourcemode != 1 ) {
00761       for ( WorkerClassList::iterator i = workClassFactoriesASC->begin(); i != workClassFactoriesASC->end(); ++i )
00762          if ( (*i)->available( this ) )
00763             return (*i)->produce(this, justQuery);
00764    } else {
00765       for ( WorkerClassList::iterator i = workClassFactoriesBI->begin(); i != workClassFactoriesBI->end(); ++i )
00766          if ( (*i)->available( this ) )
00767             return (*i)->produce(this, justQuery);
00768    }
00769    return NULL;
00770 }
00771 
00772 
00773 

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