00001
00002
00003
00004
00005
00006
00007
00008
00014
00015
00016
00017
00018
00019
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
00302
00303
00304
00305
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
00407
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
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 ))
00443 if ( vehiclesLoaded() < baseType->maxLoadableUnits || isConquering )
00444 if ( canCarryWeight( vehicle->weight(), vehicle ) || findUnit ( vehicle->networkid ) || isConquering)
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
00606
00607
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
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