00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 ) {
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
00583
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 ) {
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
00665 return true;
00666
00667 if ( source->baseType->hasFunction( ContainerBaseType::ExternalMaterialTransfer ) )
00668
00669 return true;
00670
00671 if ( source->baseType->hasFunction( ContainerBaseType::ExternalFuelTransfer ) )
00672
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