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

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