00001
00002
00003
00004
00005
00006
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
00113
00114
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
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 if ( harvestOnPosition(pos ) )
00224
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
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
00327
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
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
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
00700 resourceFactor = resource_material_factor;
00701 fieldResource = &fld->material;
00702 } else {
00703
00704 resourceFactor = resource_fuel_factor;
00705 fieldResource = &fld->fuel;
00706 }
00707
00708 float perc = 1;
00709
00710
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 )
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