Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

servicing.cpp

Go to the documentation of this file.
00001 /*
00002      This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003      Copyright (C) 1994-1999  Martin Bickel  and  Marc Schellenberger
00004  
00005      This program is free software; you can redistribute it and/or modify
00006      it under the terms of the GNU General Public License as published by
00007      the Free Software Foundation; either version 2 of the License, or
00008      (at your option) any later version.
00009  
00010      This program is distributed in the hope that it will be useful,
00011      but WITHOUT ANY WARRANTY; without even the implied warranty of
00012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013      GNU General Public License for more details.
00014  
00015      You should have received a copy of the GNU General Public License
00016      along with this program; see the file COPYING. If not, write to the 
00017      Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
00018      Boston, MA  02111-1307  USA
00019 */
00020 
00021 #include <sigc++/sigc++.h>
00022 
00023 #include "servicing.h"
00024 
00025 #include "../vehicle.h"
00026 #include "../unitctrl.h"
00027 #include "../containercontrols.h"
00028 #include "../gameoptions.h"
00029 #include "../replay.h"
00030 
00031 
00032 
00033 enum TransferLimitation { NONE, GET, ALL };
00034 
00035 TransferLimitation getTransferLimitation( const ContainerBase* target )
00036 {
00037    if ( target->getOwner() == target->getMap()->actplayer )
00038       return NONE;
00039 
00040    if ( target->getMap()->player[target->getMap()->actplayer].diplomacy.isAllied( target->getOwner() ))
00041       return NONE;
00042 
00043    if ( target->getMap()->player[target->getMap()->actplayer].diplomacy.getState( target->getOwner() ) >= PEACE )
00044       return GET;
00045 
00046    return ALL;
00047 }
00048 
00049 
00050 
00051 ResourceWatch::ResourceWatch( ContainerBase* container )
00052 {
00053    this->container = container;
00054    orgAmount = available = container->getResource( Resources( maxint, maxint, maxint), true );
00055    storagelimit = container->putResource( Resources( maxint, maxint, maxint), true );
00056    for ( int r = 0; r < 3; ++r )
00057       if ( maxint - available.resource(r) > storagelimit.resource(r))
00058          storagelimit.resource(r) += available.resource(r);
00059       else
00060          storagelimit.resource(r) = maxint;
00061 };
00062 
00063 ContainerBase* ResourceWatch::getContainer()
00064 {
00065    return container;
00066 };
00067 
00068 const Resources ResourceWatch::amount()
00069 {
00070    return available;
00071 }
00072 
00073 
00074 const Resources ResourceWatch::avail() {
00075    TransferLimitation limit = getTransferLimitation( container );
00076    if ( limit == ALL )
00077       return Resources();
00078 
00079    if ( limit == GET ) {
00080       Resources res = available - orgAmount;
00081       for ( int r = 0; r < resourceTypeNum; ++r )
00082          if ( res.resource(r) < 0 )
00083             res.resource(r) = 0;
00084 
00085       return res;
00086    }
00087 
00088    return available;
00089 };
00090 
00091 const Resources ResourceWatch::limit() {
00092    if(  getTransferLimitation( container ) == ALL )
00093       return available;
00094    else
00095       return storagelimit;
00096 };
00097 
00098 bool ResourceWatch::putResource( int resourcetype, int amount )
00099 {
00100    Resources rr = available;
00101    rr.resource(resourcetype) += amount;
00102 
00103    for ( int r = 0; r < resourceTypeNum; ++r)
00104       if ( rr.resource(r) > storagelimit.resource(r))
00105          return false;
00106    available = rr;
00107    sigChanged( resourcetype );
00108    return true;
00109 }
00110 
00111 
00112 bool ResourceWatch::getResource( int resourcetype, int amount )
00113 {
00114    if ( available.resource(resourcetype) >= amount ) {
00115       available.resource(resourcetype) -= amount;
00116       sigChanged( resourcetype );
00117       return true;
00118    }
00119    return false;
00120 }
00121 
00122 bool ResourceWatch::getResources( Resources res )
00123 {
00124    bool b = true;
00125    for ( int r = 0; r < resourceTypeNum; ++r)
00126       if ( res.resource(r) > 0 )
00127          if ( !getResource( r, res.resource(r) ))
00128             b = false;
00129    return b;
00130 }
00131 
00132 
00133       
00134    ResourceWatch& Transferrable::getResourceWatch( const ContainerBase* unit )
00135    {
00136       assert( unit == source.getContainer() || unit == dest.getContainer() );
00137       if ( unit == source.getContainer() )
00138          return source;
00139       else
00140          return dest;
00141    }
00142 
00143    ResourceWatch& Transferrable::getOpposingResourceWatch( const ContainerBase* unit )
00144    {
00145       return getResourceWatch ( opposingContainer( unit ));
00146    }
00147 
00148    ContainerBase* Transferrable::opposingContainer( const ContainerBase* unit )
00149    {
00150       assert( unit == source.getContainer() || unit == dest.getContainer() );
00151       if ( unit == dest.getContainer() )
00152          return source.getContainer();
00153       else
00154          return dest.getContainer();
00155    }
00156 
00157    void Transferrable::show( const ContainerBase* unit )
00158    {
00159       assert( unit == source.getContainer() || unit == dest.getContainer() );
00160       if ( unit == dest.getContainer() )
00161          return sigDestAmount( ASCString::toString( getAmount( unit )));
00162       else
00163          return sigSourceAmount( ASCString::toString( getAmount( unit )));
00164    }
00165 
00166 
00167    Transferrable::Transferrable( ResourceWatch& s, ResourceWatch& d ) : source( s ) , dest( d ) {};
00168 
00169    ContainerBase* Transferrable::getSrcContainer()
00170    {
00171       return source.getContainer();
00172    }
00173 
00174    ContainerBase* Transferrable::getDstContainer()
00175    {
00176       return dest.getContainer();
00177    }
00178 
00179    bool Transferrable::setDestAmount( long amount )
00180    {
00181       setAmount( getDstContainer(), amount );
00182       return true;
00183    }
00184 
00185    void Transferrable::showAll()
00186    {
00187       show( source.getContainer() );
00188       show( dest.getContainer() );
00189    }
00190 
00191    int Transferrable::setAmount( ContainerBase* target, int newamount )
00192    {
00193       transfer( target, newamount - getAmount( target ) );
00194       return getAmount( target );
00195    }
00196 
00197    void Transferrable::fill( ContainerBase* target )
00198    {
00199       setAmount( target, getMax( target, true ));
00200    }
00201 
00202 
00203    void Transferrable::empty( ContainerBase* target )
00204    {
00205       setAmount( target, 0 );
00206    }
00207 
00208 
00209 
00210       
00211 
00212 
00213 class ResourceTransferrable : public Transferrable {
00214    private:
00215       int resourceType;
00216       bool exchangable;
00217       
00218       void warn()
00219       {
00220          warning( "Inconsistency in ResourceTransfer");
00221       };
00222 
00223       void srcChanged( int res )
00224       {
00225          if ( res == resourceType ) {
00226             show( source.getContainer() );
00227          }
00228       }
00229       
00230       void dstChanged( int res )
00231       {
00232          if ( res == resourceType ) {
00233             show( dest.getContainer() );
00234          }
00235       }
00236             
00237       void executeTransfer( ContainerBase* from, ContainerBase* to, int amount )
00238       {
00239          if ( amount == 0 )
00240             return;
00241          
00242          if ( amount < 0 )
00243             executeTransfer( to, from, -amount );
00244          else {
00245             int got = from->getResource( amount, resourceType, false );
00246             if ( got != amount )
00247                warning( ASCString("did not succeed in transfering resource ") + Resources::name( resourceType ) );
00248             to->putResource( got, resourceType, false );
00249 
00250             logtoreplayinfo( rpl_refuel3, from->getIdentification(), 1000+resourceType, got );
00251             logtoreplayinfo( rpl_refuel3, to->getIdentification(), 1000+resourceType, -got );
00252          }
00253       }
00254          
00255       
00256    public:
00257       ResourceTransferrable( int resource, ResourceWatch& src, ResourceWatch& dst, bool isExchangable = true ) : Transferrable( src, dst ), resourceType ( resource ), exchangable( isExchangable )
00258       {
00259          source.sigChanged.connect( SigC::slot( *this, &ResourceTransferrable::srcChanged ));
00260          dest.sigChanged.connect( SigC::slot( *this, &ResourceTransferrable::dstChanged ));
00261       };
00262       ASCString getName() { return Resources::name( resourceType ); };
00263       
00264       int getMax( ContainerBase* c, bool avail )
00265       {
00266          if ( avail ) {
00267             int needed = getResourceWatch( c ).limit().resource(resourceType) - getAvail( c );
00268             int av = min ( needed, getOpposingResourceWatch( c ).avail().resource(resourceType) );
00269 
00270             return getAvail( c ) + av;
00271          } else
00272             return getResourceWatch( c ).limit().resource(resourceType);
00273       }
00274       
00275       int getMin( ContainerBase* c, bool avail )
00276       {
00277          if ( avail ) {
00278             int space = getOpposingResourceWatch( c ).limit().resource(resourceType) - getOpposingResourceWatch( c ).avail().resource(resourceType);
00279             if ( space > getAvail( c ) )
00280                return 0;
00281             else
00282                return getAvail( c ) - space;
00283          } else
00284             return 0;
00285       }
00286       
00287       int getAmount ( const ContainerBase* target )
00288       {
00289          return getResourceWatch( target ).amount().resource(resourceType);
00290       }
00291       
00292       int getAvail ( const ContainerBase* target )
00293       {
00294          return getResourceWatch( target ).avail().resource(resourceType);
00295       }
00296       
00297       int transfer( ContainerBase* target, int delta )
00298       {
00299          if ( delta < 0 )
00300             return transfer( opposingContainer( target ), -delta );
00301          else {
00302             delta = min( delta, getOpposingResourceWatch( target ).avail().resource(resourceType) );
00303             delta = min( delta, getResourceWatch( target ).limit().resource(resourceType) - getAvail( target ));
00304             getOpposingResourceWatch( target ).getResource( resourceType, delta );
00305             getResourceWatch( target ).putResource(resourceType, delta);
00306             return delta;
00307          }
00308       }
00309 
00310       bool isExchangable() const
00311       {
00312          return exchangable;
00313       }
00314       
00315       void commit()
00316       {
00317          ContainerBase* target = dest.getContainer();
00318          executeTransfer( source.getContainer(), target, getAmount( target ) - target->getResource( maxint, resourceType, true ));
00319       }
00320       
00321 };
00322 
00323 class AmmoTransferrable : public Transferrable {
00324    private:
00325       int ammoType;
00326       int sourceAmmo;
00327       int destAmmo;
00328       map<const ContainerBase*,int> produced;
00329       map<const ContainerBase*,int> orgAmmo;
00330       bool& allowAmmoProduction;
00331 
00332 
00333       int& getAmmo( const ContainerBase* unit )
00334       {
00335          assert( unit == source.getContainer() || unit == dest.getContainer() );
00336          if ( unit == source.getContainer() )
00337             return sourceAmmo;
00338          else
00339             return destAmmo;
00340       }
00341       
00342       int put( ContainerBase* c, int toPut, bool queryOnly )
00343       {
00344          TransferLimitation limit = getTransferLimitation( c );
00345 
00346          if ( limit == ALL )
00347             return 0;
00348          
00349          int undoProduction = min( toPut, produced[c]);
00350          if ( undoProduction > 0 ) {
00351             if ( !queryOnly ) {
00352                for ( int r = 0; r < resourceTypeNum; ++r )
00353                   getResourceWatch( c ).putResource(  r, cwaffenproduktionskosten[ammoType][r] * undoProduction );
00354                
00355                produced[c] -= undoProduction;
00356             }
00357          }
00358          toPut -= undoProduction;
00359 
00360          toPut = min( toPut, c->maxAmmo(ammoType) - getAmmo( c ));
00361 
00362          if( !queryOnly ) {
00363             getAmmo(c) += toPut;
00364             show(c);
00365          }
00366          
00367          return toPut + undoProduction;
00368       }
00369             
00370       int get( ContainerBase* c, int toGet, bool queryOnly )
00371       {
00372          TransferLimitation limit = getTransferLimitation( c );
00373 
00374          if ( limit == ALL )
00375             return 0;
00376          
00377          int gettable;
00378          
00379          if ( limit == GET ) {
00380             gettable = getAmmo(c) - orgAmmo[c];
00381             if ( gettable < 0 )
00382                gettable = 0;
00383          } else
00384             gettable = getAmmo( c );
00385          
00386          int got = min ( toGet, gettable);
00387          int toProduce = toGet - got;
00388 
00389          if ( allowAmmoProduction && toProduce > 0 && weaponAmmo[ammoType] ) {
00390             for ( int r = 0; r < resourceTypeNum; ++r ) {
00391                if ( cwaffenproduktionskosten[ammoType][r] ) {
00392                   int produceable = getResourceWatch(c).avail().resource(r) / cwaffenproduktionskosten[ammoType][r];
00393                   if ( produceable < toProduce )
00394                      toProduce = produceable;
00395                }
00396             }
00397             if ( !queryOnly ) {
00398                Resources res;
00399                for ( int r = 0; r < resourceTypeNum; ++r )
00400                   res.resource(r) = cwaffenproduktionskosten[ammoType][r] * toProduce;
00401 
00402                getResourceWatch( c ).getResources( res );
00403                produced[c] += toProduce;
00404                
00405                getAmmo(c) -= got;
00406             }
00407             got += toProduce;
00408          } else {
00409             if ( !queryOnly ) {
00410                getAmmo(c) -= got;
00411                show( c );
00412             }
00413                
00414          }
00415          return got;
00416       }
00417 
00418       void executeTransfer( ContainerBase* from, ContainerBase* to, int amount )
00419       {
00420          if ( amount < 0 )
00421             executeTransfer( to, from, -amount );
00422          else {
00423             ContainerControls cc( from );
00424             int got = cc.getammunition( ammoType, amount, true, allowAmmoProduction );
00425             if ( got != amount )
00426                warning( "did not succeed in transfering ammo" );
00427             to->putAmmo( ammoType, got, false );
00428 
00429             logtoreplayinfo( rpl_refuel3, from->getIdentification(), ammoType, got );
00430             logtoreplayinfo( rpl_refuel3, to->getIdentification(), ammoType, -got );
00431             
00432          }
00433       }
00434       
00435    public:
00436       AmmoTransferrable( int ammo, ResourceWatch& src, ResourceWatch& dst, bool& allowProduction ) : Transferrable( src, dst ), ammoType ( ammo ), allowAmmoProduction( allowProduction )
00437       {
00438          sourceAmmo = src.getContainer()->getAmmo( ammoType, maxint, true );
00439          destAmmo   = dst.getContainer()->getAmmo( ammoType, maxint, true );
00440          
00441          orgAmmo[src.getContainer()] = sourceAmmo;
00442          orgAmmo[dst.getContainer()] = destAmmo;
00443       };
00444       
00445       ASCString getName() { return cwaffentypen[ ammoType ]; };
00446       
00447       
00448       int getMax( ContainerBase* c, bool avail )
00449       {
00450          if ( avail ) {
00451             int needed = c->maxAmmo( ammoType ) - getAmount( c );
00452             int av = get( opposingContainer( c ), needed, true );
00453             return getAmount( c ) + av;
00454          } else
00455             return c->maxAmmo( ammoType );
00456       }
00457       
00458       int getMin( ContainerBase* c, bool avail )
00459       {
00460          if ( avail ) {
00461             int storable = opposingContainer(c)->maxAmmo(ammoType) - getAmmo( opposingContainer(c) );
00462             int transferable = min( getAmmo(c), storable );
00463             return getAmmo(c) - transferable;
00464          } else
00465             return 0;
00466       }
00467       
00468       int getAmount ( const ContainerBase* target )
00469       {
00470          return getAmmo( target );
00471       }
00472       
00473       int transfer( ContainerBase* target, int delta )
00474       {
00475          if ( delta < 0 )
00476             return transfer( opposingContainer( target ), -delta );
00477          else {
00478             delta = min( delta, put( target, delta, true ));
00479             int got = get( opposingContainer( target ), delta, false );
00480             put( target, got, false );
00481             return got;
00482          }
00483       }
00484       
00485       bool isExchangable() const
00486       {
00487          return true;
00488       };
00489       
00490       void commit()
00491       {
00492          executeTransfer( source.getContainer(), dest.getContainer(), destAmmo - orgAmmo[dest.getContainer()] );
00493       }
00494       
00495 };
00496 
00497 
00498 
00499 
00500 const SingleWeapon* ServiceChecker :: getServiceWeapon()
00501 {
00502    Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
00503    if ( !srcVehicle )
00504       return false;
00505 
00506    const SingleWeapon* serviceWeapon = NULL;
00507    for (int i = 0; i < srcVehicle->typ->weapons.count ; i++)
00508       if ( srcVehicle->typ->weapons.weapon[i].service() )
00509          serviceWeapon = &srcVehicle->typ->weapons.weapon[i];
00510 
00511    return serviceWeapon;
00512 }
00513 
00514 bool ServiceChecker::serviceWeaponFits( ContainerBase* dest )
00515 {
00516    const SingleWeapon* serviceWeapon = getServiceWeapon();
00517    if ( serviceWeapon )
00518       if ( (ignoreChecks & ignoreHeight) || (serviceWeapon->sourceheight & source->getHeight()) )
00519          if ( (ignoreChecks & ignoreHeight) || (serviceWeapon->targ & dest->getHeight() )) {
00520             int dist = beeline( source->getPosition(), dest->getPosition() );
00521             if ( (ignoreChecks & ignoreDistance) || (serviceWeapon->mindistance <= dist && serviceWeapon->maxdistance >= dist) )
00522                if ( serviceWeapon->targetingAccuracy[dest->baseType->getMoveMalusType()] > 0  )
00523                   if ( (ignoreChecks & ignoreHeight) || (serviceWeapon->efficiency[6+getheightdelta(source,dest)] > 0  ))
00524                      if ( ! ((source->getHeight() & (chtieffliegend | chfliegend | chhochfliegend)) && dest->baseType->hasFunction(ContainerBaseType::NoInairRefuelling)))
00525                         return true;
00526 
00527          }
00528 
00529    return false;
00530 }
00531 
00532 ServiceChecker :: ServiceChecker( ContainerBase* src, int skipChecks ) : source(src), ignoreChecks( skipChecks )
00533 {
00534 }
00535 
00536 
00537 void ServiceChecker :: check( ContainerBase* dest )
00538 {
00539    MapCoordinate spos = source->getPosition();
00540    MapCoordinate dpos = dest->getPosition();
00541    bool externalTransfer = spos != dpos;
00542 
00543    if ( source->isBuilding() && dest->isBuilding() )
00544       return; 
00545 
00546    if ( getTransferLimitation( dest ) == ALL )
00547       return;
00548 
00549 
00550    if ( source->getMap()->getPlayer(source).diplomacy.getState(dest->getOwner()) < PEACE )
00551       return;
00552 
00553    static ContainerBaseType::ContainerFunctions resourceVehicleFunctions[resourceTypeNum] = { ContainerBaseType::ExternalEnergyTransfer,
00554       ContainerBaseType::ExternalMaterialTransfer,
00555       ContainerBaseType::ExternalFuelTransfer };
00556 
00557 
00558       for ( int r = 0; r < resourceTypeNum; r++ ) {
00559          if (  externalTransfer ) {
00560             Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
00561             if ( !srcVehicle ) {// it's a building
00562                Building* bld = dynamic_cast<Building*>(source);
00563                assert(bld);
00564                bool active = source->baseType->hasFunction( resourceVehicleFunctions[r] ) ||  dest->baseType->hasFunction( resourceVehicleFunctions[r] );
00565                if ( (ignoreChecks & ignoreHeight) || (bld->typ->externalloadheight & dest->getHeight()) )
00566                   if ( (ignoreChecks & ignoreDistance) || beeline(source->getPosition(), dest->getPosition()) < 20 )
00567                      resource( dest, r, active );
00568             } else {
00569                if ( serviceWeaponFits( dest )) {
00570                   bool active = source->baseType->hasFunction( resourceVehicleFunctions[r] ) ||  dest->baseType->hasFunction( resourceVehicleFunctions[r] );
00571                   resource( dest, r, active );
00572                }
00573             }
00574 
00575          } else {
00576             bool active =  (source->getStorageCapacity().resource(r) || source->isBuilding() )
00577                         && (dest->getStorageCapacity().resource(r) || dest->isBuilding());
00578             resource( dest, r, active );
00579          }
00580       }
00581 
00582    /* it is important that the ammo transfers are in front of the resource transfers, because ammo production affects resource amounts
00583       and their prelimarny commitment would cause inconsistencies */
00584 
00585       for ( int a = 0; a < cwaffentypennum; ++a ) {
00586          if ( source->maxAmmo( a ) && dest->maxAmmo( a )) {
00587             if ( weaponAmmo[a] ) {
00588                if ( externalTransfer ) {
00589                   if ( source->baseType->hasFunction( ContainerBaseType::ExternalAmmoTransfer ) ||  dest->baseType->hasFunction( ContainerBaseType::ExternalAmmoTransfer ) ) {
00590                      Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
00591                      if ( !srcVehicle ) {// it's a building
00592                         Building* bld = dynamic_cast<Building*>(source);
00593                         assert(bld);
00594                         if ( (ignoreChecks & ignoreHeight) || (bld->typ->externalloadheight & dest->getHeight()) )
00595                            if ( (ignoreChecks & ignoreDistance) || beeline(source->getPosition(), dest->getPosition()) < 20 )
00596                               ammo(dest, a);
00597                      } else {
00598                         if ( serviceWeaponFits( dest ) )
00599                            ammo(dest, a);
00600                      }
00601                   }
00602                } else {
00603                   ammo(dest, a);
00604                }
00605             }
00606          }
00607       }
00608 
00609 }
00610 
00611 
00612 
00613 void ServiceTargetSearcher::fieldChecker( const MapCoordinate& pos )
00614 {
00615    tfield* fld = gamemap->getField( pos );
00616    if ( fld && fld->getContainer() )
00617       check( fld->getContainer() );
00618 }
00619 
00620 void ServiceTargetSearcher::addTarget( ContainerBase* target )
00621 {
00622    if ( find( targets.begin(), targets.end(), target ) == targets.end() )
00623       targets.push_back( target );
00624 }
00625 
00626 void ServiceTargetSearcher::ammo( ContainerBase* dest, int type )
00627 {
00628    addTarget ( dest );
00629 }
00630 
00631 void ServiceTargetSearcher::resource( ContainerBase* dest, int type, bool active )
00632 {
00633    if ( active )
00634       addTarget ( dest );
00635 }
00636       
00637 ServiceTargetSearcher::ServiceTargetSearcher( ContainerBase* src ) : ServiceChecker( src )
00638 {
00639    gamemap = src->getMap();
00640 }
00641 
00642 
00643 bool ServiceTargetSearcher::available()
00644 {
00645    Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
00646    if ( srcVehicle ) {
00647       if ( srcVehicle->attacked ) 
00648          return false;
00649 
00650 
00651       if ( srcVehicle->reactionfire.getStatus() == Vehicle::ReactionFire::off || srcVehicle->baseType->hasFunction(ContainerBaseType::MoveWithReactionFire))
00652          if ( source->getMap()->getField( source->getPosition() )->unitHere( srcVehicle )) {
00653             const SingleWeapon* weap = getServiceWeapon();
00654             if( weap ) 
00655                if ( source->baseType->hasFunction( ContainerBaseType::ExternalEnergyTransfer  ) || 
00656                     source->baseType->hasFunction( ContainerBaseType::ExternalMaterialTransfer  ) || 
00657                     source->baseType->hasFunction( ContainerBaseType::ExternalFuelTransfer  ) || 
00658                     source->baseType->hasFunction( ContainerBaseType::ExternalAmmoTransfer  )) 
00659                     return true;
00660             
00661          }         
00662    } else {
00663       if ( source->baseType->hasFunction( ContainerBaseType::ExternalEnergyTransfer  ) )
00664          // if ( source->getStorageCapacity().energy )
00665             return true;
00666 
00667       if ( source->baseType->hasFunction( ContainerBaseType::ExternalMaterialTransfer  ) )
00668          // if ( source->getStorageCapacity().material )
00669             return true;
00670 
00671       if ( source->baseType->hasFunction( ContainerBaseType::ExternalFuelTransfer  ) )
00672          // if ( source->getStorageCapacity().fuel )
00673             return true;
00674 
00675    }
00676    return false;
00677 }
00678 
00679 
00680 void ServiceTargetSearcher::startSearch()
00681 {
00682    Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
00683    if ( srcVehicle ) {
00684       if ( source->getMap()->getField( source->getPosition() )->unitHere( srcVehicle )) {
00685          const SingleWeapon* weap = getServiceWeapon();
00686          if( weap )
00687             circularFieldIterator(source->getMap(), source->getPosition(), weap->maxdistance / maxmalq, (weap->mindistance + maxmalq - 1) / maxmalq, FieldIterationFunctor( this, &ServiceTargetSearcher::fieldChecker ) );
00688       }
00689    } else
00690       circularFieldIterator(source->getMap(), source->getPosition(), 1, 1, FieldIterationFunctor( this, &ServiceTargetSearcher::fieldChecker ) );
00691 
00692       for ( ContainerBase::Cargo::const_iterator i = source->getCargo().begin(); i != source->getCargo().end(); ++i )
00693          if ( *i )
00694             check( *i );
00695 };
00696 
00697 
00698 
00699 void TransferHandler::ammo( ContainerBase* dest, int type )
00700 {
00701    transfers.push_back ( new AmmoTransferrable( type, sourceRes, destRes, allowProduction ));
00702 }
00703 
00704 void TransferHandler::resource( ContainerBase* dest, int type, bool active )
00705 {
00706    transfers.push_back(  new ResourceTransferrable( type, sourceRes, destRes, active ));
00707 }
00708 
00709 TransferHandler::TransferHandler( ContainerBase* src, ContainerBase* dst ) : ServiceChecker( src), sourceRes( src ), destRes( dst ), source(src), dest(dst)
00710 {
00711    allowProduction = CGameOptions::Instance()->autoproduceammunition ;
00712 
00713    if ( dest->getMap()->player[dest->getMap()->actplayer].diplomacy.getState( dest->getOwner() ) <= TRUCE )
00714       return;
00715 
00716    check( dst );
00717 };
00718 
00719 bool TransferHandler::allowAmmoProduction( bool allow )
00720 {
00721    if ( ammoProductionPossible() ) {
00722       allowProduction = allow;
00723       updateRanges();
00724       return true;
00725    } else
00726       return false;
00727 }
00728 
00729 bool TransferHandler::allowAmmoProductionAllowed()
00730 {
00731    return allowProduction;
00732 }
00733 
00734 
00735 
00736 TransferHandler::~TransferHandler()
00737 {
00738    if ( allowProduction != CGameOptions::Instance()->autoproduceammunition  ) {
00739       CGameOptions::Instance()->autoproduceammunition = allowProduction ;
00740       CGameOptions::Instance()->setChanged();
00741    }
00742 }
00743 
00744 bool TransferHandler::ammoProductionPossible()
00745 {
00746    return source->baseType->hasFunction( ContainerBaseType::AmmoProduction ) ||  dest->baseType->hasFunction( ContainerBaseType::AmmoProduction );
00747 }
00748 
00749 TransferHandler::Transfers& TransferHandler::getTransfers()
00750 {
00751    return transfers;
00752 }
00753 
00754 void TransferHandler::fillDest()
00755 {
00756    for ( Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
00757       if ( (*i)->isExchangable())
00758          (*i)->fill( dest );
00759 }
00760 
00761 void TransferHandler::emptyDest()
00762 {
00763    for ( Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
00764       (*i)->empty( dest );
00765 
00766 }
00767 
00768 bool TransferHandler::commit()
00769 {
00770    for ( Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
00771       (*i)->commit();
00772 
00773    return true;
00774 }
00775 
00776 
00777 

Generated on Tue Jun 24 01:27:52 2008 for Advanced Strategic Command by  doxygen 1.4.2