Advanced Strategic Command
servicing.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Advanced Strategic Command; http://www.asc-hq.de
3  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; see the file COPYING. If not, write to the
17  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  Boston, MA 02111-1307 USA
19 */
20 
21 #include <sigc++/sigc++.h>
22 
23 #include "servicing.h"
24 
25 #include "../vehicle.h"
26 #include "../spfst.h"
27 #include "../containercontrols.h"
28 #include "../gameoptions.h"
29 
30 #include "consumeresource.h"
31 #include "consumeammo.h"
32 
33 #include "context.h"
34 
36 
38 {
39  if ( target->getOwner() == target->getMap()->actplayer )
40  return NONE;
41 
42  if ( target->getMap()->player[target->getMap()->actplayer].diplomacy.isAllied( target->getOwner() ))
43  return NONE;
44 
45  if ( target->getMap()->player[target->getMap()->actplayer].diplomacy.getState( target->getOwner() ) >= PEACE )
46  return GET;
47 
48  return ALL;
49 }
50 
51 
52 
54 {
55  this->container = container;
56  orgAmount = available = container->getResource( Resources( maxint, maxint, maxint), true );
57  storagelimit = container->putResource( Resources( maxint, maxint, maxint), true );
58  for ( int r = 0; r < 3; ++r )
59  if ( maxint - available.resource(r) > storagelimit.resource(r))
60  storagelimit.resource(r) += available.resource(r);
61  else
62  storagelimit.resource(r) = maxint;
63 };
64 
66 {
67  return container;
68 };
69 
71 {
72  return available;
73 }
74 
75 
78  if ( limit == ALL )
79  return Resources();
80 
81  if ( limit == GET ) {
82  Resources res = available - orgAmount;
83  for ( int r = 0; r < resourceTypeNum; ++r )
84  if ( res.resource(r) < 0 )
85  res.resource(r) = 0;
86 
87  return res;
88  }
89 
90  return available;
91 };
92 
94  if( getTransferLimitation( container ) == ALL )
95  return available;
96  else
97  return storagelimit;
98 };
99 
100 bool ResourceWatch::putResource( int resourcetype, int amount )
101 {
102  Resources rr = available;
103  rr.resource(resourcetype) += amount;
104 
105  for ( int r = 0; r < resourceTypeNum; ++r)
106  if ( rr.resource(r) > storagelimit.resource(r))
107  return false;
108  available = rr;
109  sigChanged( resourcetype );
110  return true;
111 }
112 
113 
114 bool ResourceWatch::getResource( int resourcetype, int amount )
115 {
116  if ( available.resource(resourcetype) >= amount ) {
117  available.resource(resourcetype) -= amount;
118  sigChanged( resourcetype );
119  return true;
120  }
121  return false;
122 }
123 
125 {
126  bool b = true;
127  for ( int r = 0; r < resourceTypeNum; ++r)
128  if ( res.resource(r) > 0 )
129  if ( !getResource( r, res.resource(r) ))
130  b = false;
131  return b;
132 }
133 
134 
135 
137  {
138  assert( unit == source.getContainer() || unit == dest.getContainer() );
139  if ( unit == source.getContainer() )
140  return source;
141  else
142  return dest;
143  }
144 
146  {
147  return getResourceWatch ( opposingContainer( unit ));
148  }
149 
151  {
152  assert( unit == source.getContainer() || unit == dest.getContainer() );
153  if ( unit == dest.getContainer() )
154  return source.getContainer();
155  else
156  return dest.getContainer();
157  }
158 
159  void Transferrable::show( const ContainerBase* unit )
160  {
161  assert( unit == source.getContainer() || unit == dest.getContainer() );
162  if ( unit == dest.getContainer() )
164  else
166  }
167 
168 
169  Transferrable::Transferrable( ResourceWatch& s, ResourceWatch& d ) : source( s ) , dest( d ) {};
170 
172  {
173  return source.getContainer();
174  }
175 
177  {
178  return dest.getContainer();
179  }
180 
181  bool Transferrable::setDestAmount( long amount )
182  {
183  return setAmount( getDstContainer(), amount ) == amount;
184  }
185 
187  {
188  show( source.getContainer() );
189  show( dest.getContainer() );
190  }
191 
192  int Transferrable::setAmount( ContainerBase* target, int newamount )
193  {
194  transfer( target, newamount - getAmount( target ) );
195  return getAmount( target );
196  }
197 
199  {
200  setAmount( target, getMax( target, true ));
201  }
202 
203 
205  {
206  setAmount( target, 0 );
207  }
208 
209 
210 
212  private:
213  int ammoType;
214  int sourceAmmo;
215  int destAmmo;
216  map<const ContainerBase*,int> produced;
217  map<const ContainerBase*,int> orgAmmo;
218  bool& allowAmmoProduction;
219 
220 
221  int& getAmmo( const ContainerBase* unit );
222  int put( ContainerBase* c, int toPut, bool queryOnly );
223  int get( ContainerBase* c, int toGet, bool queryOnly );
224  void executeTransfer( ContainerBase* from, ContainerBase* to, int amount, const Context& context );
225 
226  public:
227  AmmoTransferrable( int ammo, ResourceWatch& src, ResourceWatch& dst, bool& allowProduction );
228  ASCString getName();
229 
230  int getID();
231  int getMax( ContainerBase* c, bool avail );
232  int getMin( ContainerBase* c, bool avail );
233  int getAmount ( const ContainerBase* target );
234  int transfer( ContainerBase* target, int delta );
235  bool isExchangable() const;
236  void commit( const Context& context );
237  };
238 
240  private:
241  int resourceType;
242  bool exchangable;
243  void warn();
244  void srcChanged( int res );
245  void dstChanged( int res );
246  void executeTransfer( ContainerBase* from, ContainerBase* to, int amount, const Context& context );
247  public:
248  ResourceTransferrable( int resource, ResourceWatch& src, ResourceWatch& dst, bool isExchangable = true );
249  ASCString getName();
250  int getID();
251  int getMax( ContainerBase* c, bool avail );
252  int getMin( ContainerBase* c, bool avail );
253  int getAmount ( const ContainerBase* target );
254  int getAvail ( const ContainerBase* target );
255  int transfer( ContainerBase* target, int delta );
256  bool isExchangable() const;
257  void commit(const Context& context);
258  };
259 
260 
261 
262 
263 
264  void ResourceTransferrable::warn()
265  {
266  warningMessage( "Inconsistency in ResourceTransfer");
267  };
268 
269  void ResourceTransferrable::srcChanged( int res )
270  {
271  if ( res == resourceType ) {
272  show( source.getContainer() );
273  }
274  }
275 
276  void ResourceTransferrable::dstChanged( int res )
277  {
278  if ( res == resourceType ) {
279  show( dest.getContainer() );
280  }
281  }
282 
283 
284  void ResourceTransferrable::executeTransfer( ContainerBase* from, ContainerBase* to, int amount, const Context& context )
285  {
286  if ( amount == 0 )
287  return;
288 
289  if ( amount < 0 )
290  executeTransfer( to, from, -amount, context );
291  else
292  if ( amount > 0 ) {
293  Resources r;
294  r.resource(resourceType) = amount;
295 
296  ActionResult res = (new ConsumeResource( from, r ))->execute( context );
297  if ( !res.successful() )
298  throw res;
299 
300  res = (new ConsumeResource( to, -r))->execute( context );
301  if ( !res.successful() )
302  throw res;
303 
304  }
305  }
306 
307 
308 ResourceTransferrable::ResourceTransferrable( int resource, ResourceWatch& src, ResourceWatch& dst, bool isExchangable )
309  : Transferrable( src, dst ), resourceType ( resource ), exchangable( isExchangable )
310  {
311  source.sigChanged.connect( sigc::mem_fun( *this, &ResourceTransferrable::srcChanged ));
312  dest.sigChanged.connect( sigc::mem_fun( *this, &ResourceTransferrable::dstChanged ));
313  };
314 
316  {
317  return Resources::name( resourceType );
318  }
319 
321  {
322  return resourceType + 1000;
323  };
324 
326  {
327  if ( avail ) {
328  int needed = getResourceWatch( c ).limit().resource(resourceType) - getAvail( c );
329  int av = min ( needed, getOpposingResourceWatch( c ).avail().resource(resourceType) );
330 
331  return getAvail( c ) + av;
332  } else
333  return getResourceWatch( c ).limit().resource(resourceType);
334  }
335 
337  {
338  if ( avail ) {
339  int space = getOpposingResourceWatch( c ).limit().resource(resourceType) - getOpposingResourceWatch( c ).avail().resource(resourceType);
340  if ( space > getAvail( c ) )
341  return 0;
342  else
343  return getAvail( c ) - space;
344  } else
345  return 0;
346  }
347 
349  {
350  return getResourceWatch( target ).amount().resource(resourceType);
351  }
352 
354  {
355  return getResourceWatch( target ).avail().resource(resourceType);
356  }
357 
359  {
360  if ( delta < 0 )
361  return transfer( opposingContainer( target ), -delta );
362  else {
363  delta = min( delta, getOpposingResourceWatch( target ).avail().resource(resourceType) );
364  delta = min( delta, getResourceWatch( target ).limit().resource(resourceType) - getAvail( target ));
365  getOpposingResourceWatch( target ).getResource( resourceType, delta );
366  getResourceWatch( target ).putResource(resourceType, delta);
367  return delta;
368  }
369  }
370 
372  {
373  return exchangable;
374  }
375 
377  {
378  ContainerBase* target = dest.getContainer();
379  executeTransfer( source.getContainer(), target, getAmount( target ) - target->getResource( maxint, resourceType, true ), context );
380  }
381 
382 
383 
384 
385 
386 
387 
388 
389 
390  int& AmmoTransferrable::getAmmo( const ContainerBase* unit )
391  {
392  assert( unit == source.getContainer() || unit == dest.getContainer() );
393  if ( unit == source.getContainer() )
394  return sourceAmmo;
395  else
396  return destAmmo;
397  }
398 
399  int AmmoTransferrable::put( ContainerBase* c, int toPut, bool queryOnly )
400  {
402 
403  if ( limit == ALL )
404  return 0;
405 
406  int undoProduction = min( toPut, produced[c]);
407  if ( undoProduction > 0 ) {
408  if ( !queryOnly ) {
409  for ( int r = 0; r < resourceTypeNum; ++r )
410  getResourceWatch( c ).putResource( r, ammoProductionCost[ammoType][r] * undoProduction );
411 
412  produced[c] -= undoProduction;
413  }
414  }
415  toPut -= undoProduction;
416 
417  toPut = min( toPut, c->maxAmmo(ammoType) - getAmmo( c ));
418 
419  if( !queryOnly ) {
420  getAmmo(c) += toPut;
421  show(c);
422  }
423 
424  return toPut + undoProduction;
425  }
426 
427  int AmmoTransferrable::get( ContainerBase* c, int toGet, bool queryOnly )
428  {
430 
431  if ( limit == ALL )
432  return 0;
433 
434  int gettable;
435 
436  if ( limit == GET ) {
437  gettable = getAmmo(c) - orgAmmo[c];
438  if ( gettable < 0 )
439  gettable = 0;
440  } else
441  gettable = getAmmo( c );
442 
443  int got = min ( toGet, gettable);
444  int toProduce = toGet - got;
445 
446  if ( allowAmmoProduction && toProduce > 0 && weaponAmmo[ammoType] && c->baseType->hasFunction(ContainerBaseType::AmmoProduction) ) {
447  for ( int r = 0; r < resourceTypeNum; ++r ) {
448  if ( ammoProductionCost[ammoType][r] ) {
449  int produceable = getResourceWatch(c).avail().resource(r) / ammoProductionCost[ammoType][r];
450  if ( produceable < toProduce )
451  toProduce = produceable;
452  }
453  }
454  if ( !queryOnly ) {
455  Resources res;
456  for ( int r = 0; r < resourceTypeNum; ++r )
457  res.resource(r) = ammoProductionCost[ammoType][r] * toProduce;
458 
459  getResourceWatch( c ).getResources( res );
460  produced[c] += toProduce;
461 
462  getAmmo(c) -= got;
463  }
464  got += toProduce;
465  } else {
466  if ( !queryOnly ) {
467  getAmmo(c) -= got;
468  show( c );
469  }
470 
471  }
472  return got;
473  }
474 
475 
476  void AmmoTransferrable::executeTransfer( ContainerBase* from, ContainerBase* to, int amount, const Context& context )
477  {
478  if ( amount < 0 )
479  executeTransfer( to, from, -amount, context );
480  else
481  if ( amount > 0 ) {
482  auto_ptr<ConsumeAmmo> ca1 ( new ConsumeAmmo( from, ammoType, -1, amount ));
483  ca1->setAmmoProduction( allowAmmoProduction );
484 
485  ActionResult res = ca1->execute( context );
486  if( res.successful() )
487  ca1.release();
488  else
489  throw res;
490 
491  auto_ptr<ConsumeAmmo> ca2 ( new ConsumeAmmo( to, ammoType, -1, -amount ));
492  res = ca2->execute( context );
493  if( res.successful() )
494  ca2.release();
495  else
496  throw res;
497  }
498  }
499 
500  AmmoTransferrable::AmmoTransferrable( int ammo, ResourceWatch& src, ResourceWatch& dst, bool& allowProduction ) : Transferrable( src, dst ), ammoType ( ammo ), allowAmmoProduction( allowProduction )
501  {
502  sourceAmmo = src.getContainer()->getAmmo( ammoType, maxint, true );
503  destAmmo = dst.getContainer()->getAmmo( ammoType, maxint, true );
504 
505  orgAmmo[src.getContainer()] = sourceAmmo;
506  orgAmmo[dst.getContainer()] = destAmmo;
507  };
508 
510  {
511  return cwaffentypen[ ammoType ];
512  }
513 
515  {
516  // the AI depends on this value and ID scheme!
517  return ammoType + 2000;
518  };
519 
521  {
522  if ( avail ) {
523  int needed = c->maxAmmo( ammoType ) - getAmount( c );
524  int av = get( opposingContainer( c ), needed, true );
525  return getAmount( c ) + av;
526  } else
527  return c->maxAmmo( ammoType );
528  }
529 
531  {
532  if ( avail ) {
533  int storable = opposingContainer(c)->maxAmmo(ammoType) - getAmmo( opposingContainer(c) );
534  int transferable = min( getAmmo(c), storable );
535  return getAmmo(c) - transferable;
536  } else
537  return 0;
538  }
539 
541  {
542  return getAmmo( target );
543  }
544 
545  int AmmoTransferrable::transfer( ContainerBase* target, int delta )
546  {
547  if ( delta < 0 )
548  return transfer( opposingContainer( target ), -delta );
549  else {
550  delta = min( delta, put( target, delta, true ));
551  int got = get( opposingContainer( target ), delta, false );
552  put( target, got, false );
553  return got;
554  }
555  }
556 
558  {
559  return true;
560  };
561 
562  void AmmoTransferrable::commit( const Context& context )
563  {
564  executeTransfer( source.getContainer(), dest.getContainer(), destAmmo - orgAmmo[dest.getContainer()], context );
565  }
566 
567 
568 
569 
571 {
572  Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
573  if ( !srcVehicle )
574  return NULL;
575 
576  const SingleWeapon* serviceWeapon = NULL;
577  for (int i = 0; i < srcVehicle->typ->weapons.count ; i++)
578  if ( srcVehicle->typ->weapons.weapon[i].service() )
579  serviceWeapon = &srcVehicle->typ->weapons.weapon[i];
580 
581  return serviceWeapon;
582 }
583 
584 bool ServiceChecker::serviceWeaponFits( ContainerBase* dest )
585 {
586  const SingleWeapon* serviceWeapon = getServiceWeapon();
587  if ( serviceWeapon )
588  if ( (ignoreChecks & ignoreHeight) || (serviceWeapon->sourceheight & source->getHeight()) )
589  if ( (ignoreChecks & ignoreHeight) || (serviceWeapon->targ & dest->getHeight() )) {
590  int dist = beeline( source->getPosition(), dest->getPosition() );
591  if ( (ignoreChecks & ignoreDistance) || (serviceWeapon->mindistance <= dist && serviceWeapon->maxdistance >= dist) )
592  if ( serviceWeapon->targetingAccuracy[dest->baseType->getMoveMalusType()] > 0 )
593  if ( (ignoreChecks & ignoreHeight) || (serviceWeapon->efficiency[6+getheightdelta(source,dest)] > 0 ))
595  return true;
596 
597  }
598 
599  return false;
600 }
601 
602 ServiceChecker :: ServiceChecker( ContainerBase* src, int skipChecks ) : source(src), ignoreChecks( skipChecks )
603 {
604 }
605 
606 
608 {
609  MapCoordinate spos = source->getPosition();
610  MapCoordinate dpos = dest->getPosition();
611  bool externalTransfer = spos != dpos;
612 
613  if ( source->isBuilding() && dest->isBuilding() )
614  return;
615 
616  if ( getTransferLimitation( dest ) == ALL )
617  return;
618 
619 
621  return;
622 
626 
627 
628  for ( int r = 0; r < resourceTypeNum; r++ ) {
629  if ( externalTransfer ) {
630  Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
631  if ( !srcVehicle ) {// it's a building
632  Building* bld = dynamic_cast<Building*>(source);
633  assert(bld);
634  bool active = source->baseType->hasFunction( resourceVehicleFunctions[r] ) || dest->baseType->hasFunction( resourceVehicleFunctions[r] );
635  if ( (ignoreChecks & ignoreHeight) || (bld->typ->externalloadheight & dest->getHeight()) )
636  if ( (ignoreChecks & ignoreDistance) || beeline(source->getPosition(), dest->getPosition()) < 20 )
637  resource( dest, r, active );
638  } else {
639  if ( serviceWeaponFits( dest )) {
640  bool active = source->baseType->hasFunction( resourceVehicleFunctions[r] ) || dest->baseType->hasFunction( resourceVehicleFunctions[r] );
641  resource( dest, r, active );
642  }
643  }
644 
645  } else {
646  bool active = (source->getStorageCapacity().resource(r) || source->isBuilding() )
647  && (dest->getStorageCapacity().resource(r) || dest->isBuilding());
648  resource( dest, r, active );
649  }
650  }
651 
652  /* it is important that the ammo transfers are in front of the resource transfers, because ammo production affects resource amounts
653  and their prelimarny commitment would cause inconsistencies */
654 
655  for ( int a = 0; a < weaponTypeNum; ++a ) {
656  if ( source->maxAmmo( a ) && dest->maxAmmo( a )) {
657  if ( weaponAmmo[a] ) {
658  if ( externalTransfer ) {
660  Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
661  if ( !srcVehicle ) {// it's a building
662  Building* bld = dynamic_cast<Building*>(source);
663  assert(bld);
664  if ( (ignoreChecks & ignoreHeight) || (bld->typ->externalloadheight & dest->getHeight()) )
665  if ( (ignoreChecks & ignoreDistance) || beeline(source->getPosition(), dest->getPosition()) < 20 )
666  ammo(dest, a);
667  } else {
668  if ( serviceWeaponFits( dest ) )
669  ammo(dest, a);
670  }
671  }
672  } else {
673  ammo(dest, a);
674  }
675  }
676  }
677  }
678 
679 
680 
681  if ( externalTransfer ) {
682  Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
683  if ( srcVehicle ) {// it's a unit
685  if ( serviceWeaponFits( dest ) && dest->damage > 0 ) {
686  repair( dest );
687  }
688  }
689 
690  } else {
692  repair( dest );
693  }
694 
695 
696 
697 }
698 
699 
700 
701 void ServiceTargetSearcher::fieldChecker( const MapCoordinate& pos )
702 {
703  MapField* fld = gamemap->getField( pos );
704  if ( fld && fld->getContainer() )
705  check( fld->getContainer() );
706 }
707 
708 void ServiceTargetSearcher::addTarget( ContainerBase* target )
709 {
710  if ( find( targets.begin(), targets.end(), target ) == targets.end() )
711  targets.push_back( target );
712 }
713 
715 {
716  if ( checks & checkAmmo )
717  addTarget ( dest );
718 }
719 
720 void ServiceTargetSearcher::resource( ContainerBase* dest, int type, bool active )
721 {
722  if ( checks & checkResources )
723  if ( active )
724  addTarget ( dest );
725 }
726 
728 {
729  if ( checks & checkRepair )
730  addTarget ( dest );
731 }
732 
733 
734 ServiceTargetSearcher::ServiceTargetSearcher( ContainerBase* src, int checkFlags ) : ServiceChecker( src ), checks ( checkFlags )
735 {
736  gamemap = src->getMap();
737 }
738 
739 
741 {
742  Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
743  if ( srcVehicle ) {
744  if ( srcVehicle->attacked )
745  return false;
746 
747 
749  if ( source->getMap()->getField( source->getPosition() )->unitHere( srcVehicle )) {
750  const SingleWeapon* weap = getServiceWeapon();
751  if( weap )
756  return true;
757 
758  }
759  } else {
761  // if ( source->getStorageCapacity().energy )
762  return true;
763 
765  // if ( source->getStorageCapacity().material )
766  return true;
767 
769  // if ( source->getStorageCapacity().fuel )
770  return true;
771 
772  }
773  return false;
774 }
775 
776 
778 {
779  Vehicle* srcVehicle = dynamic_cast<Vehicle*>(source);
780  if ( srcVehicle ) {
781  if ( source->getMap()->getField( source->getPosition() )->unitHere( srcVehicle )) {
782  const SingleWeapon* weap = getServiceWeapon();
783  if( weap )
784  circularFieldIterator(source->getMap(), source->getPosition(), weap->maxdistance / maxmalq, (weap->mindistance + maxmalq - 1) / maxmalq, FieldIterationFunctor( this, &ServiceTargetSearcher::fieldChecker ) );
785  }
786  } else
787  circularFieldIterator(source->getMap(), source->getPosition(), 1, 1, FieldIterationFunctor( this, &ServiceTargetSearcher::fieldChecker ) );
788 
789  for ( ContainerBase::Cargo::const_iterator i = source->getCargo().begin(); i != source->getCargo().end(); ++i )
790  if ( *i )
791  check( *i );
792 };
793 
794 
795 
796 void TransferHandler::ammo( ContainerBase* dest, int type )
797 {
798  transfers.push_back ( new AmmoTransferrable( type, sourceRes, destRes, allowProduction ));
799 }
800 
801 void TransferHandler::resource( ContainerBase* dest, int type, bool active )
802 {
803  transfers.push_back( new ResourceTransferrable( type, sourceRes, destRes, active ));
804 }
805 
806 TransferHandler::TransferHandler( ContainerBase* src, ContainerBase* dst, int flags ) : ServiceChecker( src, flags ), sourceRes( src ), destRes( dst ), source(src), dest(dst)
807 {
808  allowProduction = CGameOptions::Instance()->autoproduceammunition ;
809 
810  if ( dest->getMap()->player[dest->getMap()->actplayer].diplomacy.getState( dest->getOwner() ) <= TRUCE )
811  return;
812 
813  check( dst );
814 };
815 
817 {
818  if ( ammoProductionPossible() ) {
819  allowProduction = allow;
820  updateRanges();
821  return true;
822  } else
823  return false;
824 }
825 
826 
828 {
829  if ( allowProduction != CGameOptions::Instance()->autoproduceammunition ) {
830  CGameOptions::Instance()->autoproduceammunition = allowProduction ;
832  }
833 }
834 
836 {
838 }
839 
841 {
842  return transfers;
843 }
844 
846 {
847  for ( Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
848  if ( (*i)->isExchangable())
849  (*i)->fill( dest );
850 }
851 
853 {
854  for ( Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
855  if ( (*i)->isExchangable())
856  if ( dynamic_cast<AmmoTransferrable*>(*i))
857  (*i)->fill( dest );
858 }
859 
861 {
862  for ( Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
863  if ( (*i)->isExchangable())
864  if ( dynamic_cast<ResourceTransferrable*>(*i))
865  (*i)->fill( dest );
866 }
867 
868 
870 {
871  for ( Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
872  (*i)->empty( dest );
873 
874 }
875 
876 
877 bool TransferHandler::commit( const Context& context )
878 {
879  for ( Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
880  (*i)->commit( context );
881 
882  return true;
883 }
884 
885 
886 
DiplomaticStates getState(PlayerID towardsPlayer) const
Definition: player.cpp:92
void fillDestAmmo()
Definition: servicing.cpp:852
bool ammoProductionPossible()
Definition: servicing.cpp:835
int transfer(ContainerBase *target, int delta)
Definition: servicing.cpp:358
void fill(ContainerBase *target)
Definition: servicing.cpp:198
sigc::signal< void, int > sigChanged
Definition: servicing.h:38
Player & getPlayer(PlayerID p)
Definition: gamemap.h:257
bool service(void) const
virtual int putResource(int amount, int resourcetype, bool queryonly, int scope=1, int player=-1)=0
scope: 0 = local 1 = resource network 2 = global in all buildings 3 = map wide pool( used only intern...
virtual int getMoveMalusType() const =0
const BuildingType * typ
Definition: buildings.h:48
static const int checkAmmo
Definition: servicing.h:139
int damage
Damage. 0 is no damage, when damage reaches 100 the container is destroyed.
int getAmount(const ContainerBase *target)
Definition: servicing.cpp:540
bool putResource(int resourcetype, int amount)
Definition: servicing.cpp:100
#define weaponTypeNum
Definition: vehicletype.h:63
TransferHandler(ContainerBase *src, ContainerBase *dst, int flags=0)
Definition: servicing.cpp:806
int externalloadheight
bitmapped: units on these levels of height may be refuelled when standing next to the buildings entry...
Definition: buildingtype.h:93
int getheightdelta(const ContainerBase *c1, const ContainerBase *c2)
calculate the height difference between two levels of height.
Definition: spfst.cpp:393
static const int checkRepair
Definition: servicing.h:141
static const int checkResources
Definition: servicing.h:140
UnitWeapon weapons
The weapons.
Definition: vehicletype.h:248
Resources getStorageCapacity() const
returns the local storage capacity for the given resource, which depends on the resource mode of the ...
int sourceheight
the weapon can be shot from these levels of height (bitmapped)
Definition: vehicletype.h:108
int efficiency[13]
the targeting accuracy of the weapon over different height differences between the attacking unit and...
Definition: vehicletype.h:132
DiplomaticStateVector diplomacy
Definition: player.h:209
int targ
the weapon can attack targets at these levels of height (bitmapped)
Definition: vehicletype.h:105
bool hasFunction(ContainerFunctions function) const
void check(ContainerBase *dest)
Definition: servicing.cpp:607
int getOwner() const
returns the number of the player this vehicle/building belongs to
void repair(ContainerBase *dest)
Definition: servicing.cpp:727
int getAmount(const ContainerBase *target)
Definition: servicing.cpp:348
int getAvail(const ContainerBase *target)
Definition: servicing.cpp:353
virtual int getAmount(const ContainerBase *target)=0
const char * cwaffentypen[weaponTypeNum]
Definition: vehicletype.cpp:71
AmmoTransferrable(int ammo, ResourceWatch &src, ResourceWatch &dst, bool &allowProduction)
Definition: servicing.cpp:500
virtual void resource(ContainerBase *dest, int type, bool active)=0
ResourceTransferrable(int resource, ResourceWatch &src, ResourceWatch &dst, bool isExchangable=true)
Definition: servicing.cpp:308
void ammo(ContainerBase *dest, int type)
Definition: servicing.cpp:796
bool getResource(int resourcetype, int amount)
Definition: servicing.cpp:114
int transfer(ContainerBase *target, int delta)
Definition: servicing.cpp:545
bool commit(const Context &context)
Definition: servicing.cpp:877
int ignoreChecks
Definition: servicing.h:99
void warningMessage(const ASCString &str)
virtual bool isBuilding() const =0
const Resources limit()
Definition: servicing.cpp:93
const bool weaponAmmo[weaponTypeNum]
Definition: vehicletype.cpp:92
const Resources amount()
Definition: servicing.cpp:70
#define chhochfliegend
Definition: typen.h:416
ContainerBase * source
Definition: servicing.h:98
Definition: player.h:53
SingleWeapon weapon[16]
Definition: vehicletype.h:170
ContainerBase * getContainer()
returns a pointer to the ContainerBase of the field or NULL if there is none
Definition: mapfield.cpp:331
void show(const ContainerBase *unit)
Definition: servicing.cpp:159
a single field of the map
Definition: mapfield.h:26
static const char * name(int r)
Definition: typen.cpp:190
virtual int transfer(ContainerBase *target, int delta)=0
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
void ammo(ContainerBase *dest, int type)
Definition: servicing.cpp:714
bool autoproduceammunition
produce required ammo upon refuelling
Definition: gameoptions.h:191
int beeline(const Vehicle *a, const Vehicle *b)
returns the distance between the units a and b
sigc::signal< void, const std::string & > sigSourceAmount
Definition: servicing.h:83
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
class Vehicle::ReactionFire reactionfire
#define maxmalq
Constants that specify the layout of ASC.
Definition: typen.h:429
ServiceTargetSearcher(ContainerBase *src, int checkFlags)
Definition: servicing.cpp:734
int getMax(ContainerBase *c, bool avail)
get maximum amount for that unit.
Definition: servicing.cpp:325
virtual int getResource(int amount, int resourcetype, bool queryonly, int scope=1, int player=-1)=0
void setChanged(bool flag=true)
Definition: gameoptions.h:272
int mindistance
the minimal distance the weapon can shoot
Definition: vehicletype.h:114
TransferLimitation getTransferLimitation(const ContainerBase *target)
Definition: servicing.cpp:37
const int resourceTypeNum
The number of different resources that ASC uses.
Definition: typen.h:77
ContainerBase * getContainer()
Definition: servicing.cpp:65
#define chtieffliegend
Definition: typen.h:414
int getMin(ContainerBase *c, bool avail)
Definition: servicing.cpp:530
virtual void ammo(ContainerBase *dest, int type)=0
const int ammoProductionCost[weaponTypeNum][3]
Definition: vehicletype.cpp:75
Coordinate on the twodimensional map.
Definition: typen.h:202
void circularFieldIterator(GameMap *gamemap, const MapCoordinate &center, int startDist, int stopDist, FieldIterationFunctor functor)
ASCString getName()
Definition: servicing.cpp:509
ResourceWatch & source
Definition: servicing.h:50
ServiceChecker(ContainerBase *src, int skipChecks=0)
Definition: servicing.cpp:602
bool isExchangable() const
Definition: servicing.cpp:371
void commit(const Context &context)
Definition: servicing.cpp:376
virtual int getHeight() const =0
returns the bitmapped level of height. Only one bit will be set, of course
int maxdistance
the maximum distance the weapon can shoot
Definition: vehicletype.h:111
bool isExchangable() const
Definition: servicing.cpp:557
ContainerBase * getDstContainer()
Definition: servicing.cpp:176
A single weapon of a #Vehicletype.
Definition: vehicletype.h:100
const SingleWeapon * getServiceWeapon()
Definition: servicing.cpp:570
void fillDestResource()
Definition: servicing.cpp:860
int targetingAccuracy[cmovemalitypenum]
the effectiveness of the weapon against different targets.
Definition: vehicletype.h:137
signed char actplayer
the player who is currently making his moves (may be human or AI)
Definition: gamemap.h:232
bool successful() const
Player player[9]
Definition: gamemap.h:253
static CGameOptions * Instance()
returns the only Instance
Definition: gameoptions.cpp:38
int setAmount(ContainerBase *target, int newamount)
Definition: servicing.cpp:192
const Resources avail()
Definition: servicing.cpp:76
ResourceWatch(ContainerBase *container)
Definition: servicing.cpp:53
int & resource(int type)
Definition: typen.h:105
Definition: player.h:53
sigc::signal< bool > updateRanges
Definition: servicing.h:185
const VehicleType * typ
Definition: vehicle.h:83
bool isAllied(PlayerID towardsPlayer) const
Definition: player.h:82
virtual int getAmmo(int type, int num, bool queryOnly)=0
bool attacked
did the unit already attack this turn
Definition: vehicle.h:109
void resource(ContainerBase *dest, int type, bool active)
Definition: servicing.cpp:801
const ContainerBaseType * baseType
the type descriping all non-instance specific properties of the container
Definition: containerbase.h:80
void resource(ContainerBase *dest, int type, bool active)
Definition: servicing.cpp:720
#define maxint
Definition: typen.h:462
ContainerBase * getSrcContainer()
Definition: servicing.cpp:171
GameMap * getMap() const
The parent class of Vehicle and Building; The name Container originates from Battle Isle...
Definition: containerbase.h:40
int getMin(ContainerBase *c, bool avail)
Definition: servicing.cpp:336
An actual building on the map, which references a BuildingType Buildings have an owner,.
Definition: buildings.h:38
const T & min(const T &a, const T &b, const T &c)
Definition: misc.h:80
Status getStatus() const
for each player that can still be attacked one bit is set
Definition: vehicle.h:155
static const int ignoreDistance
Definition: servicing.h:111
bool getResources(Resources res)
Definition: servicing.cpp:124
Resources are basically the currency of ASC.
Definition: typen.h:97
virtual int maxAmmo(int type) const =0
void showAll()
Definition: servicing.cpp:186
Transfers & getTransfers()
Definition: servicing.cpp:840
void empty(ContainerBase *target)
Definition: servicing.cpp:204
ResourceWatch & dest
Definition: servicing.h:51
virtual void repair(ContainerBase *dest)=0
ResourceWatch & getResourceWatch(const ContainerBase *unit)
Definition: servicing.cpp:136
const Cargo & getCargo() const
Transferrable(ResourceWatch &s, ResourceWatch &d)
Definition: servicing.cpp:169
sigc::signal< void, const std::string & > sigDestAmount
Definition: servicing.h:84
bool setDestAmount(long amount)
Definition: servicing.cpp:181
virtual int getMax(ContainerBase *c, bool avail)=0
get maximum amount for that unit.
ResourceWatch & getOpposingResourceWatch(const ContainerBase *unit)
Definition: servicing.cpp:145
int getMax(ContainerBase *c, bool avail)
get maximum amount for that unit.
Definition: servicing.cpp:520
bool allowAmmoProduction(bool allow)
Definition: servicing.cpp:816
static const int ignoreHeight
Definition: servicing.h:110
ContainerBase * opposingContainer(const ContainerBase *unit)
Definition: servicing.cpp:150
#define chfliegend
Definition: typen.h:415
int getID()
the id is used to identify the transferrable when serializng to disk. In each service operation...
Definition: servicing.cpp:320
int getID()
the id is used to identify the transferrable when serializng to disk. In each service operation...
Definition: servicing.cpp:514
Loki::Functor< void, LOKI_TYPELIST_1(const MapCoordinate &) > FieldIterationFunctor
Definition: mapalgorithms.h:43
TransferLimitation
Definition: servicing.cpp:35
void commit(const Context &context)
Definition: servicing.cpp:562
MapField * getField(int x, int y)
Definition: gamemap.h:465
virtual MapCoordinate3D getPosition() const =0