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

containerbase-functions.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  ***************************************************************************/
00009 
00010 #include <algorithm>
00011 #include <cmath>
00012 #include "containerbase-functions.h"
00013 #include "typen.h"
00014 #include "containercontrols.h"
00015 #include "resourcenet.h"
00016 #include <iostream>
00017 
00018 
00019 
00020 template <class T, ContainerBaseType::ContainerFunctions f>
00021 class GenericWorkerFactory : public ContainerBase::WorkClassFactory
00022 {
00023       bool available( const ContainerBase* cnt )
00024       {
00025          return cnt->baseType->hasFunction( f );
00026       };
00027 
00028       ContainerBase::Work* produce( ContainerBase* cnt, bool queryOnly )
00029       {
00030          return new T(cnt);
00031       };
00032 };
00033 
00034 
00035 class BiResourceGenerationFactory : public ContainerBase::WorkClassFactory
00036 {
00037       bool available( const ContainerBase* cnt )
00038       {
00039          return true;
00040       };
00041 
00042       ContainerBase::Work* produce( ContainerBase* cnt, bool queryOnly )
00043       {
00044          return new BiResourceGeneration(cnt);
00045       };
00046 };
00047 
00048 class MiningStationFactory : public ContainerBase::WorkClassFactory
00049 {
00050       bool available( const ContainerBase* cnt )
00051       {
00052          return cnt->baseType->hasFunction( ContainerBaseType::MiningStation );
00053       };
00054 
00055       ContainerBase::Work* produce( ContainerBase* cnt, bool queryOnly )
00056       {
00057          return new MiningStation(cnt, queryOnly);
00058       };
00059 };
00060 
00061 class AutoHarvestObjectsFactory : public ContainerBase::WorkClassFactory
00062 {
00063       bool available( const ContainerBase* cnt )
00064       {
00065          return cnt->baseType->hasFunction( ContainerBaseType::AutoHarvestObjects );
00066       };
00067 
00068       ContainerBase::Work* produce( ContainerBase* cnt, bool queryOnly )
00069       {
00070          return new AutoHarvestObjects(cnt, queryOnly);
00071       };
00072 };
00073 
00074 namespace
00075 {
00076    const bool r5 = ContainerBase::registerWorkClassFactory( new BiResourceGenerationFactory, false );
00077    const bool r1 = ContainerBase::registerWorkClassFactory( new GenericWorkerFactory<MatterConverter, ContainerBaseType::MatterConverter>() );
00078    const bool r2 = ContainerBase::registerWorkClassFactory( new GenericWorkerFactory<ResourceSink, ContainerBaseType::ResourceSink> );
00079    const bool r3 = ContainerBase::registerWorkClassFactory( new GenericWorkerFactory<WindPowerplant, ContainerBaseType::WindPowerPlant> );
00080    const bool r4 = ContainerBase::registerWorkClassFactory( new GenericWorkerFactory<SolarPowerplant, ContainerBaseType::SolarPowerPlant> );
00081    const bool r6 = ContainerBase::registerWorkClassFactory( new MiningStationFactory );
00082    const bool r7 = ContainerBase::registerWorkClassFactory( new AutoHarvestObjectsFactory );
00083 }
00084 
00085 AutoHarvestObjects::AutoHarvestObjects( ContainerBase* _bld, bool justQuery_ )
00086 {
00087    base = _bld;
00088    justQuery = justQuery_;
00089    hasRun = false;
00090    fieldCounter = 0;
00091 }
00092 
00093 bool AutoHarvestObjects::finished()
00094 {
00095    return hasRun;
00096 }
00097 
00098 
00099 void AutoHarvestObjects::harvestObject( const MapCoordinate& pos, const ObjectType* obj )
00100 {
00101    tfield* currentField = base->getMap()->getField(pos);
00102    if ( !currentField )
00103       return;
00104 
00105    // we are only harvesting on fields who have non-harvestable neighbouring field, 
00106    // to prevent clearing of areas where the 'island' fields that are supposed to remain
00107    // are not covered by the oject
00108    int regrowFields = 0;
00109    int spreadingFields = 0;
00110     for ( int i = 0; i < 6; ++i ) {
00111       MapCoordinate nextField = getNeighbouringFieldCoordinate( pos, i );
00112       if ( !harvestOnPosition(nextField)) {
00113          tfield* fld = base->getMap()->getField( nextField);
00114          if ( fld ) {
00115             if ( fld->checkforobject(obj))
00116                ++regrowFields ;
00117             else {
00118                if ( obj->buildable(fld))
00119                   ++spreadingFields;
00120             }
00121          }
00122       }
00123    }
00124    if ( regrowFields <= 0 || spreadingFields > 0 )
00125       return;
00126 
00127 
00128    Object* object = currentField->checkforobject( obj );
00129 
00130    if( object != NULL ) {
00131       Resources removeValue = object->typ->removecost;
00132       Resources removeCost;
00133       Resources removeBenefit;
00134 
00135       if( removeValue.energy < 0 )
00136          removeBenefit.energy = -removeValue.energy;
00137       else
00138          removeCost.energy = removeValue.energy;
00139 
00140       if( removeValue.material < 0 )
00141          removeBenefit.material = -removeValue.material;
00142       else
00143          removeCost.material = removeValue.material;
00144 
00145       if( removeValue.fuel < 0 )
00146          removeBenefit.fuel = -removeValue.fuel;
00147       else
00148          removeCost.fuel = removeValue.fuel;
00149 
00150       if( base->getResource( removeCost, true, 1, base->getOwner() ) == removeCost ) {
00151          cost += removeCost;
00152          harvested += removeBenefit;
00153          if( !justQuery ) {
00154             base->getResource( removeCost, false,  1, base->getOwner());
00155             base->putResource( removeBenefit, false,  1, base->getOwner() );
00156             currentField->removeobject( obj, true );
00157          }
00158          ++fieldCounter;
00159       }
00160    }
00161 }
00162 
00163 void AutoHarvestObjects::processField( const MapCoordinate& pos )
00164 {
00165    tfield* currentField = base->getMap()->getField(pos);
00166    if ( !currentField )
00167       return;
00168    
00169    if ( currentField->building )
00170       return;
00171 
00172    if ( fieldCounter >= base->baseType->autoHarvest.maxFieldsPerTurn )
00173       return;
00174    
00175    for ( vector<IntRange>::const_iterator i = base->baseType->autoHarvest.objectsHarvestable.begin(); i != base->baseType->autoHarvest.objectsHarvestable.end();  ++i )
00176       for( int id=i->from; id <= i->to; ++id ) {
00177          const ObjectType *obj = base->getMap()->getobjecttype_byid( id );
00178          if ( obj )
00179             harvestObject( pos, obj );
00180       }
00181 
00182    for ( vector<IntRange>::const_iterator i = base->baseType->autoHarvest.objectGroupsHarvestable.begin(); i != base->baseType->autoHarvest.objectGroupsHarvestable.end(); ++i )
00183       for( int j = 0; j < base->getMap()->getObjectTypeNum(); ++j ) {
00184          const ObjectType *obj = base->getMap()->getobjecttype_bypos( j );
00185          if ( obj->groupID >= i->from && obj->groupID <= i->to )
00186             harvestObject( pos, obj );
00187       }
00188 
00189 }
00190 
00191 
00192 
00193 bool AutoHarvestObjects::harvestOnPosition( const MapCoordinate& pos )
00194 {
00195    if ((pos.y+1)%3) 
00196       return true;
00197    else
00198       return false;
00199 }
00200 
00201 void AutoHarvestObjects::iterateField( const MapCoordinate& pos )
00202 {
00203    /*
00204    if ( pos.y & 1 ) {
00205       processField(pos);
00206       return ;
00207    } else {
00208       if ( (((pos.y >> 1) & 1) && (pos.x & 1 )) || (((pos.y >> 1 ) & 1 )==0 && (pos.x & 1 )==0 )) {
00209          processField(pos);
00210          return;
00211       }
00212    }
00213    */
00214    if ( harvestOnPosition(pos ) ) 
00215       // y+1 is to match the harvesting pattern of player Xyphagoroszh on PBP planet Lussx :)
00216       processField(pos);
00217    
00218 }
00219 
00220 
00221 
00222 
00223 bool AutoHarvestObjects::run()
00224 {
00225    hasRun = true;
00226    if( base->getCarrier() != NULL )
00227       return false;
00228 
00229    circularFieldIterator( base->getMap(), base->getPosition(), 0, base->baseType->autoHarvest.range, FieldIterationFunctor( this, &AutoHarvestObjects::iterateField ));
00230 
00231    return true;
00232 }
00233 
00234 Resources AutoHarvestObjects::getPlus()
00235 {
00236    return harvested;
00237 }
00238 
00239 Resources AutoHarvestObjects::getUsage()
00240 {
00241    return Resources();
00242 }
00243 
00244 
00245 float  getminingstationeficency ( int dist )
00246 {
00247    // f ( x ) = a / ( b * ( x + d ) ) - c
00248 
00249    double a,b,c,d;
00250 
00251    a          =     10426.400 ;
00252    b          =     1.0710969 ;
00253    c          =     568.88887 ;
00254    d          =     6.1111109 ;
00255 
00256    return (a / ( b * (dist + d)) - c) / 1024;
00257 }
00258 
00259 
00260 GetMiningInfo::MiningInfo::MiningInfo()
00261 {
00262    for ( int i = 0; i < maxminingrange+2; i++ )
00263       efficiency[i] = 0;
00264    nextMiningDistance = -1;
00265 }
00266 
00267 GetMiningInfo :: GetMiningInfo ( const ContainerBase* container ) : SearchFields ( container->getMap() ), miningStation( container )
00268 {
00269    run();
00270 }
00271 
00272 void GetMiningInfo :: testfield ( const MapCoordinate& mc )
00273 {
00274    tfield* fld = gamemap->getField ( mc );
00275    if ( miningInfo.efficiency[ dist ] == 0 )
00276       miningInfo.efficiency[ dist ] = int(getminingstationeficency ( dist ) * 1024);
00277 
00278    miningInfo.avail[dist].material += fld->material * resource_material_factor;
00279    miningInfo.avail[dist].fuel     += fld->fuel     * resource_fuel_factor;
00280    miningInfo.max[dist].material   += 255 * resource_material_factor;
00281    miningInfo.max[dist].fuel       += 255 * resource_fuel_factor;
00282    if ( miningInfo.nextMiningDistance == -1 ) {
00283       if ( miningStation->maxplus.fuel > 0 && fld->fuel > 0 )
00284          miningInfo.nextMiningDistance = dist;
00285 
00286       if ( miningStation->maxplus.material > 0 && fld->material > 0 )
00287          miningInfo.nextMiningDistance = dist;
00288    }
00289 }
00290 
00291 
00292 void GetMiningInfo :: run ()
00293 {
00294    initsearch ( miningStation->getPosition(), 0, maxminingrange );
00295    startsearch();
00296 }
00297 
00298 
00299 
00300 
00301 MatterConverter :: MatterConverter( ContainerBase* _bld ) : bld ( _bld ), percentage ( 100 )
00302 {}
00303 
00304 bool MatterConverter :: run()
00305 {
00306    int perc = percentage;
00307 
00308    int usageNum = 0;
00309    for ( int r = 0; r < 3; r++ )
00310       if ( bld->plus.resource(r) < 0 )
00311          ++usageNum;
00312 
00313    if ( usageNum > 0 ) {
00314       // if the resource generation requires other resources, don't waste anything
00315       // by producing more than storage capacity available
00316 
00317       for ( int r = 0; r < 3; r++ )
00318          if ( bld->plus.resource(r) > 0 ) {
00319             int p = bld->putResource ( bld->plus.resource(r), r, true, 1, bld->getOwner() );
00320 
00321             if ( perc > 100 * p / bld->plus.resource(r) )
00322                perc = 100 * p / bld->plus.resource(r) ;
00323          }
00324    }
00325 
00326    Resources toGet = bld->plus * perc / 100  ;
00327    for ( int r = 0; r < 3; r++ )
00328       if ( toGet.resource(r) < 0 )
00329          toGet.resource(r)  = - toGet.resource(r) ;
00330       else
00331          toGet.resource(r) = 0;
00332 
00333 
00334    Resources avail = bld->getResource ( toGet, true, 1, bld->getOwner() );
00335 
00336    for ( int r = 0; r < 3; r++ ) {
00337       if ( bld->plus.resource(r) < 0 ) {
00338          int p = 100 * avail.resource(r) / -bld->plus.resource(r);
00339          if ( p < perc )
00340             perc = p;
00341       }
00342    }
00343 
00344 
00345    bool didSomething = false;
00346 
00347    for ( int r = 0; r < 3; r++ )
00348       if ( bld->plus.resource(r) > 0 ) {
00349          bld->putResource( bld->plus.resource(r) * perc  / 100, r , false, 1, bld->getOwner() );
00350          if ( bld->plus.resource(r) * perc / 100  > 0)
00351             didSomething = true;
00352 
00353       } else {
00354          if ( bld->plus.resource(r) < 0 )
00355             bld->getResource( -bld->plus.resource(r) * perc  / 100, r , false, 1, bld->getOwner());
00356       }
00357 
00358    percentage -= perc;
00359    return didSomething;
00360 }
00361 
00362 
00363 bool MatterConverter :: finished()
00364 {
00365    return percentage == 0;
00366 }
00367 
00368 Resources MatterConverter :: getPlus()
00369 {
00370    Resources r;
00371    for ( int i = 0; i < 3; i++ )
00372       if ( bld->plus.resource(i) > 0 )
00373          r.resource(i) = bld->plus.resource(i);
00374    return r;
00375 }
00376 
00377 Resources MatterConverter :: getUsage()
00378 {
00379    Resources r;
00380    for ( int i = 0; i < 3; i++ )
00381       if ( bld->plus.resource(i) < 0 )
00382          r.resource(i) = -bld->plus.resource(i);
00383    return r;
00384 }
00385 
00386 
00387 ResourceSink :: ResourceSink( ContainerBase* _bld ) : bld ( _bld )
00388 {
00389    toGet = bld->plus;
00390    for ( int r = 0; r < 3; r++ )
00391       if ( toGet.resource(r) < 0 )
00392          toGet.resource(r)  = - toGet.resource(r) ;
00393       else
00394          toGet.resource(r) = 0;
00395 }
00396 
00397 bool ResourceSink :: run()
00398 {
00399    Resources got  = bld->getResource( toGet, false, 1, bld->getOwner() );
00400    toGet -= got;
00401    for ( int r = 0; r < 3; r++ )
00402       if ( got.resource(r) > 0 )
00403          return true;
00404 
00405    return false;
00406 }
00407 
00408 
00409 bool ResourceSink :: finished()
00410 {
00411    for ( int r = 0; r < 3; r++ )
00412       if ( toGet.resource(r) > 0 )
00413          return false;
00414    return true;
00415 }
00416 
00417 Resources ResourceSink :: getPlus()
00418 {
00419    return Resources();
00420 }
00421 
00422 Resources ResourceSink :: getUsage()
00423 {
00424    Resources r;
00425    for ( int i = 0; i < 3; i++ )
00426       if ( bld->plus.resource(i) < 0 )
00427          r.resource(i) = -bld->plus.resource(i);
00428    return r;
00429 }
00430 
00431 
00432 /*
00433 Research :: Research( Building* _bld ) : bld ( _bld ), percentage ( 100 )
00434 {
00435 }
00436  
00437 bool Research :: run()
00438 {
00439    int perc = percentage;
00440  
00441    int usageNum = 0;
00442    for ( int r = 0; r < 3; r++ )
00443       if ( plus.resource(r) < 0 )
00444          ++usageNum;
00445  
00446    if ( usageNum > 0 ) {
00447       // if the resource generation requires other resources, don't waste anything
00448       // by producing more than storage capacity available
00449  
00450       for ( int r = 0; r < 3; r++ )
00451          if ( bld->plus.resource(r) > 0 ) {
00452             int p = putResource ( bld->plus.resource(r), 0, 1 );
00453  
00454             if ( perc > 100 * p / bld->plus.resource(r) )
00455                perc = 100 * p / bld->plus.resource(r) ;
00456 }
00457 }
00458  
00459    Resources toGet = bld->plus * perc / 100  ;
00460    for ( int r = 0; r < 3; r++ )
00461       if ( toGet.resource(r) < 0 )
00462          toGet.resource(r)  = - toGet.resource(r) ;
00463       else
00464          toGet.resource(r) = 0;
00465  
00466  
00467    Resources avail = bld->getResource ( toGet, 1 );
00468  
00469    for ( int r = 0; r < 3; r++ ) {
00470       if ( bld->plus.resource(r) ) {
00471          int p = 100 * avail.resource(r) / bld->plus.resource(r);
00472          if ( p < perc )
00473             perc = P;
00474 }
00475 }
00476  
00477  
00478    bool didSomething = false;
00479  
00480    for ( int r = 0; r < 3; r++ )
00481       if ( bld->plus.resource(r) > 0 ) {
00482          bld->putResource( bld->plus.resource(r) * perc  / 100, r , 0);
00483          if ( bld->plus.resource(r) * perc / 100  > 0)
00484             didSomething = true;
00485  
00486 } else {
00487          bld->getResource( -bld->plus.resource(r) * perc  / 100, r , 0);
00488 }
00489  
00490    percentage = perc;
00491    return didSomething;
00492 }
00493  
00494  
00495 bool Research :: finished()
00496 {
00497    return percentage == 0;
00498 }
00499  
00500 Resources Research :: getUsage()
00501 {
00502   Resources r;
00503   for ( int i = 0; i < 3; i++ 9
00504      if ( bld->plus.resource(r) < 0 )
00505         r.resource(r) = -bld->plus.resource(r)
00506   return r;
00507 }
00508    **/
00509 
00510 RegenerativePowerPlant :: RegenerativePowerPlant( ContainerBase* _bld ) : bld ( _bld )
00511 {}
00512 
00513 bool RegenerativePowerPlant :: finished()
00514 {
00515    for( int r = 0; r < 3; r++ )
00516       if ( toProduce.resource(r) > 0 )
00517          return false;
00518    return true;
00519 }
00520 
00521 bool RegenerativePowerPlant :: run()
00522 {
00523    Resources tp = bld->putResource( toProduce , false, 1, bld->getOwner() );
00524    bool didSomething = false;
00525    for  ( int r = 0; r < 3; r++ )
00526       if ( tp.resource(r) ) {
00527          didSomething = true;
00528          toProduce.resource(r) -= tp.resource(r);
00529       }
00530    return didSomething;
00531 }
00532 
00533 Resources RegenerativePowerPlant :: getUsage()
00534 {
00535    return Resources();
00536 }
00537 
00538 Resources WindPowerplant :: getPlus()
00539 {
00540    Resources p;
00541    for ( int r = 0; r < 3; r++ )
00542       p.resource(r) =  bld->maxplus.resource(r) * bld->getMap()->weather.windSpeed / 255;
00543    return p;
00544 }
00545 
00546 Resources SolarPowerplant :: getPlus()
00547 {
00548    int sum = 0;
00549    int num = 0;
00550    vector<MapCoordinate> fields = bld->getCoveredFields();
00551    for ( vector<MapCoordinate>::iterator i = fields.begin(); i != fields.end(); ++i ) {
00552       tfield* fld = bld->getMap()->getField ( *i );
00553       int weather = 0;
00554       while ( fld->typ != fld->typ->terraintype->weather[weather] )
00555          weather++;
00556 
00557       sum += csolarkraftwerkleistung[weather];
00558       num ++;
00559    }
00560 
00561    Resources rplus;
00562    for ( int r = 0; r < 3; r++ )
00563       rplus.resource(r) = bld->maxplus.resource(r) * sum / ( num * 1024 );
00564    return rplus;
00565 }
00566 
00567 
00568 Resources BiResourceGeneration::getPlus()
00569 {
00570    return bld->bi_resourceplus;
00571 }
00572 
00573 
00574 
00575 
00576 MiningStation :: MiningStation( ContainerBase* bld_  , bool justQuery_) : SearchFields ( bld_->getMap() ), bld ( bld_ ), justQuery( justQuery_ )
00577 {
00578    int counter = 0;
00579    for ( int r = 1; r < 3; r++ ) {
00580       if ( bld->plus.resource(r) > 0 ) {
00581          ++counter;
00582          if ( counter == 2 )
00583             fatalError( ASCString("A mining station can only produce ONE kind of resource; building ID" ) + strrr(bld->baseType->id) + " is violating this" );
00584 
00585          toExtract_thisTurn.resource(r) = bld->plus.resource(r);
00586 
00587          for ( int rr = 0; rr < 3; rr++ )
00588             if ( bld->plus.resource(rr) < 0 )
00589                usageRatio[rr] = -double(bld->plus.resource(rr)) / double(bld->plus.resource(r));
00590             else
00591                usageRatio[rr] = 0;
00592       }
00593    }
00594 
00595    if( justQuery ) {
00596       hasRun = false;
00597       run();
00598       hasRun = true;
00599    } else
00600       hasRun = false;
00601 }
00602 
00603 bool MiningStation :: run()
00604 {
00605    if ( justQuery && hasRun )
00606       return false;
00607 
00608    actuallyExtracted = Resources();
00609 
00610    for ( int r = 0; r < 3;++r)
00611       consumed[r] = 0;
00612 
00613    if ( !justQuery ) {
00614       spaceAvail = bld->putResource( toExtract_thisTurn, true, 1, bld->getOwner() );
00615       for ( int r = 0; r <3; ++r )
00616          if ( spaceAvail.resource(r) < 0 ) {
00617             warning( ASCString("map corruption detected; building space availability is negative! ") + resourceNames[r] );
00618             spaceAvail.resource( r ) = 0;
00619          }
00620    } else
00621       spaceAvail = toExtract_thisTurn;
00622 
00623    Resources toConsume;
00624    for ( int r = 0; r < 3; r++ )
00625       if ( bld->plus.resource(r) < 0 )
00626          toConsume.resource(r) = -bld->plus.resource(r);
00627 
00628    if ( !justQuery ) {
00629       powerAvail = bld->getResource( toConsume, true, 1, bld->getOwner() );
00630       for ( int r = 0; r <3; ++r )
00631          if ( powerAvail.resource(r) < 0 ) {
00632             warning( ASCString("map corruption detected; available power for mining station is negative! ") + resourceNames[r] );
00633             powerAvail.resource( r ) = 0;
00634          }
00635    } else
00636       powerAvail = toConsume;
00637 
00638 
00639    initsearch( bld->getPosition(), 0, maxminingrange );
00640    startsearch();
00641 
00642    if ( !justQuery) {
00643       for ( int r = 0; r < 3; ++r )
00644          bld->getResource( int(consumed[r]), r, false, 1, bld->getOwner() );
00645       bld->putResource(actuallyExtracted, false, 1, bld->getOwner() );
00646    }
00647 
00648    for ( int r = 0; r < 3; r++ )
00649       if ( actuallyExtracted.resource(r) > 0 )
00650          return true;
00651 
00652    return false;
00653 }
00654 
00655 void MiningStation :: testfield ( const MapCoordinate& mc )
00656 {
00657    cancelSearch = true;
00658    for ( int r = 0; r < 3; r++ )
00659       if ( toExtract_thisTurn.resource(r) > 0 )
00660          cancelSearch = false;
00661 
00662    if ( cancelSearch == false ) {
00663       tfield* fld = gamemap->getField ( mc );
00664       float distEfficiency = getminingstationeficency ( dist );
00665 
00666       for ( int r = 1; r < 3; r++ ) {
00667          if ( toExtract_thisTurn.resource(r) > 0 ) {
00668 
00669             float resourceFactor;
00670             char *fieldResource;
00671 
00672             if ( r==1) {
00673                // resourceFactor = resource_material_factor * double(bld->baseType->efficiencymaterial) / 1024;
00674                resourceFactor = resource_material_factor;
00675                fieldResource = &fld->material;
00676             } else {
00677                // resourceFactor = resource_fuel_factor * double(bld->baseType->efficiencyfuel) / 1024;
00678                resourceFactor = resource_fuel_factor;
00679                fieldResource = &fld->fuel;
00680             }
00681 
00682             float perc = 1;
00683 
00684             // is enough resource available on the field
00685             perc = min  ( perc, (*fieldResource * resourceFactor) / (toExtract_thisTurn.resource(r) * distEfficiency));
00686 
00687             perc = min ( perc, float( double(spaceAvail.resource(r)) / (toExtract_thisTurn.resource(r) * distEfficiency )));
00688 
00689             for ( int i = 0; i < 3; ++i )
00690                if ( usageRatio[i] * toExtract_thisTurn.resource(r) > 0 )
00691                   perc = min  ( perc, float( double(powerAvail.resource(i)) / usageRatio[i] * toExtract_thisTurn.resource(r)));
00692 
00693             if ( perc < 0 ) {
00694                warning("Warning: mining station inconsistency\n");
00695                perc = 0;
00696             }
00697 
00698             if ( !justQuery )
00699                *fieldResource -= int( toExtract_thisTurn.resource(r) * perc * distEfficiency / resourceFactor );
00700 
00701             int ex = int( ceil(toExtract_thisTurn.resource(r) * perc * distEfficiency));
00702             actuallyExtracted.resource(r) += ex;
00703             spaceAvail.resource(r) -= ex;
00704             for ( int i = 0; i < 3; ++i) {
00705                if ( spaceAvail.resource(i) < -2 )  // we allow for small deviations due to rounding errors
00706                   warning("Warning: mining station inconsistency 2!\n");
00707 
00708                if ( spaceAvail.resource(i) < 0 )
00709                   spaceAvail.resource(i) = 0;
00710             }
00711 
00712 
00713             for ( int i = 0; i < 3; i++ ) {
00714                float c = usageRatio[i] * toExtract_thisTurn.resource(r) * perc;
00715                consumed[i] += c;
00716                powerAvail.resource(i) -= int( ceil(c) );
00717                if ( powerAvail.resource(i) < 0 )
00718                   powerAvail.resource(i) = 0;
00719 
00720             }
00721 
00722             toExtract_thisTurn.resource(r) -= int( toExtract_thisTurn.resource(r) * perc);
00723 
00724 
00725             if ( !justQuery ) {
00726                if ( !fld->resourceview )
00727                   fld->resourceview = new tfield::Resourceview;
00728                fld->resourceview->visible |= 1 << bld->getOwner();
00729                fld->resourceview->fuelvisible[bld->getOwner()] = fld->fuel;
00730                fld->resourceview->materialvisible[bld->getOwner()] = fld->material;
00731             }
00732          }
00733       }
00734    }
00735 }
00736 
00737 bool MiningStation :: finished()
00738 {
00739    for ( int r = 0; r < 3; r++ )
00740       if ( toExtract_thisTurn.resource(r) )
00741          return false;
00742    return true;
00743 }
00744 
00745 Resources MiningStation :: getPlus()
00746 {
00747    return actuallyExtracted;
00748 }
00749 
00750 Resources MiningStation :: getUsage()
00751 {
00752    Resources res;
00753    for ( int r = 0; r < 3; ++r)
00754       res.resource(r) = int( ceil(consumed[r]));
00755    return res;
00756 }
00757 

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