consumeammo.cpp

Go to the documentation of this file.
00001 /*
00002      This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003      Copyright (C) 1994-2010  Martin Bickel  and  Marc Schellenberger
00004  
00005      This program is free software; you can redistribute it and/or modify
00006      it under the terms of the GNU General Public License as published by
00007      the Free Software Foundation; either version 2 of the License, or
00008      (at your option) any later version.
00009  
00010      This program is distributed in the hope that it will be useful,
00011      but WITHOUT ANY WARRANTY; without even the implied warranty of
00012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013      GNU General Public License for more details.
00014  
00015      You should have received a copy of the GNU General Public License
00016      along with this program; see the file COPYING. If not, write to the 
00017      Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
00018      Boston, MA  02111-1307  USA
00019 */
00020 
00021 
00022 
00023 #include "consumeammo.h"
00024 #include "action-registry.h"
00025 
00026 #include "../vehicle.h"
00027 #include "../gamemap.h"
00028 
00029 #include "consumeresource.h"
00030      
00031      
00032 ConsumeAmmo::ConsumeAmmo( ContainerBase* veh, int ammoType, int slot, int count )
00033    : ContainerAction( veh ), produceAmmo(false), produced(0)
00034 {
00035    this->ammoType = ammoType;
00036    this->slot = slot;
00037    this->count = count;
00038    
00039    resultingAmmount = -1;
00040 }
00041 
00042       
00043 ASCString ConsumeAmmo::getDescription() const
00044 {
00045    ASCString res = "Consume " + ASCString::toString(count) + " pieces of ammo ";
00046    if ( slot >= 0 ) 
00047       res += "from slot " + ASCString::toString(slot);
00048    
00049    if ( getContainer() ) 
00050       res += " from unit " + getContainer()->getName();
00051    return  res;
00052 }
00053       
00054 static const int consumeAmmoStreamVersion = 2;      
00055       
00056 void ConsumeAmmo::readData ( tnstream& stream ) 
00057 {
00058    int version = stream.readInt();
00059    if ( version == 1 ) {
00060       int vehicleID = stream.readInt();
00061       setID( vehicleID );
00062    } else {
00063       if ( version >   consumeAmmoStreamVersion )
00064          throw tinvalidversion ( "ConsumeAmmo", consumeAmmoStreamVersion, version );
00065    
00066       ContainerAction::readData( stream );
00067    }
00068       
00069    ammoType = stream.readInt();
00070    slot = stream.readInt();
00071    count = stream.readInt();
00072    resultingAmmount = stream.readInt();
00073    
00074    if ( version >= 2 ) {
00075       produceAmmo = stream.readInt();  
00076       produced = stream.readInt();
00077    }
00078    
00079 };
00080       
00081       
00082 void ConsumeAmmo::writeData ( tnstream& stream ) const
00083 {
00084    stream.writeInt( consumeAmmoStreamVersion  );
00085    ContainerAction::writeData( stream );
00086    stream.writeInt( ammoType );
00087    stream.writeInt( slot );
00088    stream.writeInt( count );
00089    stream.writeInt( resultingAmmount );
00090    stream.writeInt( produceAmmo ); 
00091    stream.writeInt( produced );
00092 };
00093 
00094 void ConsumeAmmo::setAmmoProduction( bool prod )
00095 {
00096    produceAmmo = prod;  
00097 }
00098 
00099 
00100 GameActionID ConsumeAmmo::getID() const
00101 {
00102    return ActionRegistry::ConsumeAmmo;
00103 }
00104 
00105 int ConsumeAmmo::produce( int num, const Context& context, bool queryOnly )
00106 {
00107    if ( !produceAmmo )
00108       return 0;
00109    
00110    if ( !getContainer()->baseType->hasFunction( ContainerBaseType::AmmoProduction )  ) 
00111       return 0;
00112    
00113    Resources needed ( ammoProductionCost[ammoType][0] * num, ammoProductionCost[ammoType][1] * num, ammoProductionCost[ammoType][2] * num );
00114    Resources avail = getContainer()->getResource(needed, true, 1, context.actingPlayer->getPosition() );
00115    
00116    int producable = num;
00117    for ( int r = 0; r < 3; ++r )
00118       if ( ammoProductionCost[ammoType][r] )
00119          producable = min ( producable, avail.resource(r) / ammoProductionCost[ammoType][r]);
00120    
00121    Resources consumed ( ammoProductionCost[ammoType][0] * producable, ammoProductionCost[ammoType][1] * producable, ammoProductionCost[ammoType][2] * producable );
00122    
00123    if ( !queryOnly ) {
00124       ActionResult res = (new ConsumeResource( getContainer(), consumed))->execute( context );
00125       if ( !res.successful() )
00126          throw res;
00127    }
00128    
00129    return producable;
00130 }
00131 
00132 ActionResult ConsumeAmmo::runAction( const Context& context )
00133 {
00134    ContainerBase* c = getContainer();
00135    
00136    Vehicle* veh = dynamic_cast<Vehicle*>(c);
00137    if ( veh && slot >= 0 ) {
00138       if ( count >= 0 ) {
00139          int toProduce = 0;
00140          if ( veh->ammo[slot] < count ) {
00141             toProduce = count - veh->ammo[slot];
00142             if( produce( toProduce, context, true ) < toProduce )
00143                return ActionResult( 21100, veh);
00144          }
00145          
00146          veh->ammo[slot] -= count - toProduce;
00147          if ( toProduce )
00148             produce( toProduce, context , false );
00149          
00150          produced = toProduce;
00151          
00152          resultingAmmount = veh->ammo[slot];
00153          return ActionResult(0);
00154       } else {
00155          if ( veh->ammo[slot] - count > veh->typ->weapons.weapon[slot].count )
00156             return ActionResult(21104);
00157          
00158          veh->ammo[slot] -= count;
00159          resultingAmmount = veh->ammo[slot];
00160          return ActionResult(0);
00161       }
00162    } else {
00163       if ( count >= 0 ) {
00164          int toProduce = 0;
00165          int gettable = c->getAmmo(ammoType,count, true);
00166          if ( gettable < count ) {
00167             toProduce = count - gettable;
00168             if( produce( toProduce, context, true ) < toProduce )
00169                return ActionResult( 21100, c);
00170          }
00171          
00172          c->getAmmo( ammoType, gettable, false );
00173          if ( toProduce )
00174             produce( toProduce, context , false );
00175          
00176          produced = toProduce;
00177          
00178          resultingAmmount = c->getAmmo(ammoType, maxint, true );
00179          return ActionResult(0);
00180       } else {
00181          c->putAmmo(ammoType, -count, false );
00182          resultingAmmount = c->getAmmo(ammoType, maxint, true );
00183          return ActionResult(0);
00184       }
00185    }
00186 }
00187 
00188 
00189 ActionResult ConsumeAmmo::undoAction( const Context& context )
00190 {
00191    ContainerBase* c = getContainer();
00192    Vehicle* veh = dynamic_cast<Vehicle*>(c);
00193    if ( veh && slot >= 0 ) {
00194       if ( veh->ammo[slot] + count > veh->typ->weapons.weapon[slot].count )
00195          return ActionResult( 21101, veh);
00196    
00197       veh->ammo[slot] += (count - produced);
00198       return ActionResult(0);
00199    } else {
00200       if ( count >= 0 )
00201          c->putAmmo( ammoType, count - produced, false );
00202       else
00203          c->getAmmo( ammoType, -count + produced, false );
00204       return ActionResult(0);
00205    }
00206 }
00207 
00208 ActionResult ConsumeAmmo::postCheck()
00209 {
00210    ContainerBase* c = getContainer();
00211    Vehicle* veh = dynamic_cast<Vehicle*>(c);
00212    if ( veh && slot >= 0 ) {
00213       if ( veh->ammo[slot] != resultingAmmount )
00214          return ActionResult( 21102, veh );  
00215    }
00216    
00217    return ActionResult(0);
00218 }
00219 
00220 
00221 namespace {
00222    const bool r1 = registerAction<ConsumeAmmo> ( ActionRegistry::ConsumeAmmo );
00223 }

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