Advanced Strategic Command
consumeammo.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 
22 
23 #include "consumeammo.h"
24 #include "action-registry.h"
25 
26 #include "../vehicle.h"
27 #include "../gamemap.h"
28 
29 #include "consumeresource.h"
30 
31 
32 ConsumeAmmo::ConsumeAmmo( ContainerBase* veh, int ammoType, int slot, int count )
33  : ContainerAction( veh ), produceAmmo(false), produced(0)
34 {
35  this->ammoType = ammoType;
36  this->slot = slot;
37  this->count = count;
38 
39  resultingAmmount = -1;
40 }
41 
42 
44 {
45  ASCString res = "Consume " + ASCString::toString(count) + " pieces of ammo ";
46  if ( slot >= 0 )
47  res += "from slot " + ASCString::toString(slot);
48 
49  if ( getContainer() )
50  res += " from unit " + getContainer()->getName();
51  return res;
52 }
53 
54 static const int consumeAmmoStreamVersion = 2;
55 
57 {
58  int version = stream.readInt();
59  if ( version == 1 ) {
60  int vehicleID = stream.readInt();
61  setID( vehicleID );
62  } else {
63  if ( version > consumeAmmoStreamVersion )
64  throw tinvalidversion ( "ConsumeAmmo", consumeAmmoStreamVersion, version );
65 
66  ContainerAction::readData( stream );
67  }
68 
69  ammoType = stream.readInt();
70  slot = stream.readInt();
71  count = stream.readInt();
72  resultingAmmount = stream.readInt();
73 
74  if ( version >= 2 ) {
75  produceAmmo = stream.readInt();
76  produced = stream.readInt();
77  }
78 
79 };
80 
81 
82 void ConsumeAmmo::writeData ( tnstream& stream ) const
83 {
86  stream.writeInt( ammoType );
87  stream.writeInt( slot );
88  stream.writeInt( count );
89  stream.writeInt( resultingAmmount );
90  stream.writeInt( produceAmmo );
91  stream.writeInt( produced );
92 };
93 
95 {
96  produceAmmo = prod;
97 }
98 
99 
101 {
103 }
104 
105 int ConsumeAmmo::produce( int num, const Context& context, bool queryOnly )
106 {
107  if ( !produceAmmo )
108  return 0;
109 
110  if ( !getContainer()->baseType->hasFunction( ContainerBaseType::AmmoProduction ) )
111  return 0;
112 
113  Resources needed ( ammoProductionCost[ammoType][0] * num, ammoProductionCost[ammoType][1] * num, ammoProductionCost[ammoType][2] * num );
114  Resources avail = getContainer()->getResource(needed, true, 1, context.actingPlayer->getPosition() );
115 
116  int producable = num;
117  for ( int r = 0; r < 3; ++r )
118  if ( ammoProductionCost[ammoType][r] )
119  producable = min ( producable, avail.resource(r) / ammoProductionCost[ammoType][r]);
120 
121  Resources consumed ( ammoProductionCost[ammoType][0] * producable, ammoProductionCost[ammoType][1] * producable, ammoProductionCost[ammoType][2] * producable );
122 
123  if ( !queryOnly ) {
124  ActionResult res = (new ConsumeResource( getContainer(), consumed))->execute( context );
125  if ( !res.successful() )
126  throw res;
127  }
128 
129  return producable;
130 }
131 
133 {
135 
136  Vehicle* veh = dynamic_cast<Vehicle*>(c);
137  if ( veh && slot >= 0 ) {
138  if ( count >= 0 ) {
139  int toProduce = 0;
140  if ( veh->ammo[slot] < count ) {
141  toProduce = count - veh->ammo[slot];
142  if( produce( toProduce, context, true ) < toProduce )
143  return ActionResult( 21100, veh);
144  }
145 
146  veh->ammo[slot] -= count - toProduce;
147  if ( toProduce )
148  produce( toProduce, context , false );
149 
150  produced = toProduce;
151 
152  resultingAmmount = veh->ammo[slot];
153  return ActionResult(0);
154  } else {
155  if ( veh->ammo[slot] - count > veh->typ->weapons.weapon[slot].count )
156  return ActionResult(21104);
157 
158  veh->ammo[slot] -= count;
159  resultingAmmount = veh->ammo[slot];
160  return ActionResult(0);
161  }
162  } else {
163  if ( count >= 0 ) {
164  int toProduce = 0;
165  int gettable = c->getAmmo(ammoType,count, true);
166  if ( gettable < count ) {
167  toProduce = count - gettable;
168  if( produce( toProduce, context, true ) < toProduce )
169  return ActionResult( 21100, c);
170  }
171 
172  c->getAmmo( ammoType, gettable, false );
173  if ( toProduce )
174  produce( toProduce, context , false );
175 
176  produced = toProduce;
177 
178  resultingAmmount = c->getAmmo(ammoType, maxint, true );
179  return ActionResult(0);
180  } else {
181  c->putAmmo(ammoType, -count, false );
182  resultingAmmount = c->getAmmo(ammoType, maxint, true );
183  return ActionResult(0);
184  }
185  }
186 }
187 
188 
190 {
192  Vehicle* veh = dynamic_cast<Vehicle*>(c);
193  if ( veh && slot >= 0 ) {
194  if ( veh->ammo[slot] + count > veh->typ->weapons.weapon[slot].count )
195  return ActionResult( 21101, veh);
196 
197  veh->ammo[slot] += (count - produced);
198  return ActionResult(0);
199  } else {
200  if ( count >= 0 )
201  c->putAmmo( ammoType, count - produced, false );
202  else
203  c->getAmmo( ammoType, -count + produced, false );
204  return ActionResult(0);
205  }
206 }
207 
209 {
211  Vehicle* veh = dynamic_cast<Vehicle*>(c);
212  if ( veh && slot >= 0 ) {
213  if ( veh->ammo[slot] != resultingAmmount )
214  return ActionResult( 21102, veh );
215  }
216 
217  return ActionResult(0);
218 }
219 
220 
221 namespace {
222  const bool r1 = registerAction<ConsumeAmmo> ( ActionRegistry::ConsumeAmmo );
223 }
void writeData(tnstream &stream) const
Player * actingPlayer
Definition: context.h:37
virtual void readData(tnstream &stream)
Definition: consumeammo.cpp:56
virtual void writeInt(int i)
Writes a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is p...
Definition: basestrm.cpp:363
int GameActionID
Definition: action.h:35
int ammo[16]
Definition: vehicle.h:87
virtual ASCString getName() const =0
virtual int readInt(void)
Reads a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is pe...
Definition: basestrm.cpp:284
int getPosition() const
Definition: player.h:112
UnitWeapon weapons
The weapons.
Definition: vehicletype.h:248
virtual void writeData(tnstream &stream) const
Definition: consumeammo.cpp:82
void setID(int id)
should usually not be called, the ID should only be set through the constructor
int count
amount of ammunition the unit having this weapon can carry
Definition: vehicletype.h:117
SingleWeapon weapon[16]
Definition: vehicletype.h:170
The interface for all kinds of IO stream.
virtual GameActionID getID() const
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
virtual int getResource(int amount, int resourcetype, bool queryonly, int scope=1, int player=-1)=0
ActionResult execute(const Context &context)
Definition: action.cpp:41
const int ammoProductionCost[weaponTypeNum][3]
Definition: vehicletype.cpp:75
virtual ActionResult postCheck()
postCheck is called after an action has been redone and should check that the state of the map is exa...
void setAmmoProduction(bool prod)
specifies if ammo shall be produced if there is not enough ammo available and the container has ammo ...
Definition: consumeammo.cpp:94
bool successful() const
virtual ActionResult runAction(const Context &context)
int & resource(int type)
Definition: typen.h:105
const VehicleType * typ
Definition: vehicle.h:83
ContainerBase * getContainer(bool dontThrow=false)
virtual int getAmmo(int type, int num, bool queryOnly)=0
virtual ActionResult undoAction(const Context &context)
#define maxint
Definition: typen.h:462
The parent class of Vehicle and Building; The name Container originates from Battle Isle...
Definition: containerbase.h:40
const T & min(const T &a, const T &b, const T &c)
Definition: misc.h:80
Resources are basically the currency of ASC.
Definition: typen.h:97
static const int consumeAmmoStreamVersion
Definition: consumeammo.cpp:54
ASCString getDescription() const
Definition: consumeammo.cpp:43
virtual int putAmmo(int type, int num, bool queryOnly)=0
void readData(tnstream &stream)