00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 }