Advanced Strategic Command
trainunitcommand.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 #include "trainunitcommand.h"
23 
24 #include "../vehicle.h"
25 #include "../mapfield.h"
26 #include "../gamemap.h"
27 #include "../viewcalculation.h"
28 #include "../spfst.h"
29 #include "../mapdisplayinterface.h"
30 #include "action-registry.h"
31 #include "../itemrepository.h"
32 #include "../containercontrols.h"
33 #include "consumeammo.h"
34 #include "changeunitproperty.h"
35 
36 bool TrainUnitCommand :: avail ( const ContainerBase* carrier, const Vehicle* unit )
37 {
38  if ( !carrier || !unit )
39  return false;
40 
41  if ( carrier->getMap()->getgameparameter( cgp_bi3_training ) )
42  return false;
43 
44  if ( !carrier->findUnit( unit->networkid, false ) )
45  return false;
46 
47  if ( unit->getCarrier() != carrier )
48  return false;
49 
51  if( unit->getExperience_offensive() >= maxExp
52  && unit->getExperience_defensive() >= maxExp )
53  return false;
54 
55  if ( unit->attacked )
56  return false;
57 
58 
60  return false;
61 
62  int num = 0;
63  int numsh = 0;
64  for (int i = 0; i < unit->typ->weapons.count; i++ )
65  if ( unit->typ->weapons.weapon[i].shootable() && (unit->typ->weapons.weapon[i].count > 0 )) {
66  if ( unit->ammo[i] )
67  numsh++;
68  else
69  num++;
70  }
71 
72  if ( num == 0 && numsh > 0 )
73  return true;
74  else
75  return false;
76 }
77 
78 
79 
80 TrainUnitCommand :: TrainUnitCommand ( ContainerBase* container )
81  : ContainerCommand ( container ), unitID(-1)
82 {
83 
84 }
85 
86 
87 
88 
89 
91 {
92  if ( getState() != SetUp )
93  return ActionResult(22000);
94 
95  Vehicle* unit = getMap()->getUnit( unitID );
96  if ( !unit )
97  return ActionResult( 22100 );
98 
99  if ( !avail( getContainer(), unit ))
100  return ActionResult( 22101 );
101 
104 
106  if ( newexp_o > maxexp )
107  newexp_o = maxexp;
108 
109  if ( newexp_d > maxexp )
110  newexp_d = maxexp;
111 
112  if ( newexp_o >= unit->getExperience_offensive() ) {
113  auto_ptr<ChangeUnitProperty> train ( new ChangeUnitProperty( unit, ChangeUnitProperty::ExperienceOffensive, newexp_o ));
114  ActionResult res = train->execute( context );
115  if ( res.successful() )
116  train.release();
117  }
118 
119  if ( newexp_d >= unit->getExperience_defensive() ) {
120  auto_ptr<ChangeUnitProperty> train ( new ChangeUnitProperty( unit, ChangeUnitProperty::ExperienceDefensive, newexp_d ));
121  ActionResult res = train->execute( context );
122  if ( res.successful() )
123  train.release();
124  }
125 
126  auto_ptr<ChangeUnitProperty> train2 ( new ChangeUnitProperty( unit, ChangeUnitProperty::AttackedFlag, 1 ));
127  ActionResult res = train2->execute( context );
128  if ( res.successful() )
129  train2.release();
130 
131  auto_ptr<ChangeUnitProperty> move ( new ChangeUnitProperty( unit, ChangeUnitProperty::Movement, 0 ));
132  res = move->execute( context );
133  if ( res.successful() )
134  move.release();
135 
136 
137  for (int i = 0; i < unit->typ->weapons.count; i++ ) {
138  if ( unit->typ->weapons.weapon[i].shootable() && (unit->typ->weapons.weapon[i].count > 0 )) {
139  auto_ptr<ConsumeAmmo> consumer ( new ConsumeAmmo( unit, unit->typ->weapons.weapon[i].getScalarWeaponType(), i, 1 ));
140  res = consumer->execute( context );
141  if ( res.successful() )
142  consumer.release();
143  else
144  break;
145  }
146  }
147 
148 
149  if ( res.successful() )
150  setState( Finished );
151  else
152  setState( Failed );
153 
154  return res;
155 }
156 
157 
158 
159 static const int TrainUnitCommandVersion = 1;
160 
162 {
163  ContainerCommand::readData( stream );
164  int version = stream.readInt();
165  if ( version > TrainUnitCommandVersion )
166  throw tinvalidversion ( "TrainUnitCommand", TrainUnitCommandVersion, version );
167  unitID = stream.readInt();
168 }
169 
171 {
172  ContainerCommand::writeData( stream );
174  stream.writeInt( unitID );
175 }
176 
178 {
179  unitID = unit->networkid;
180  setState( SetUp );
181 }
182 
183 
185 {
186  ASCString c;
187  c.format("trainUnit ( map, %d, %d )", getContainerID(), unitID );
188  return c;
189 
190 }
191 
193 {
195 }
196 
198 {
199  ASCString s = "Train ";
200 
201  if ( getMap()->getUnit( unitID ))
202  s += getMap()->getUnit( unitID )->getName();
203  else
204  s += "unit id " + ASCString::toString(unitID);
205 
206  return s;
207 }
208 
209 namespace
210 {
211  const bool r1 = registerAction<TrainUnitCommand> ( ActionRegistry::TrainUnitCommand );
212 }
213 
Vehicle * findUnit(int nwid, bool recursive=true) const
searches for a the unit in carrier and optionally all inner carriers
void writeData(tnstream &stream) const
int getExperience_defensive() const
Definition: vehicle.cpp:258
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
the command is totally done
Definition: command.h:120
void move(Vehicle *veh, const MapCoordinate &dest)
int ammo[16]
Definition: vehicle.h:87
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
UnitWeapon weapons
The weapons.
Definition: vehicletype.h:248
bool shootable(void) const
bool hasFunction(ContainerFunctions function) const
State getState() const
Definition: command.h:125
int count
amount of ammunition the unit having this weapon can carry
Definition: vehicletype.h:117
void readData(tnstream &stream)
GameMap * getMap()
Definition: action.h:92
SingleWeapon weapon[16]
Definition: vehicletype.h:170
The interface for all kinds of IO stream.
ASCString & format(const charT *pFormat,...)
Definition: ascstring.cpp:78
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
int getContainerID() const
int getScalarWeaponType(void) const
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
ActionResult go(const Context &context)
ASCString getName() const
returns the units name or, if it does not exist, the unit type's name or description ...
Definition: vehicle.cpp:1569
ASCString getCommandString() const
ASCString getDescription() const
void setState(State state)
Definition: command.cpp:44
bool successful() const
static const int TrainUnitCommandVersion
Vehicle * getUnit(int x, int y, int nwid)
Definition: gamemap.cpp:1215
void writeData(tnstream &stream) const
int getgameparameter(GameParameter num) const
Definition: gamemap.cpp:1047
GameActionID getID() const
const int maxunitexperience
The maximum experience value of a Vehicle.
Definition: typen.h:73
ContainerBase * getCarrier() const
if this is a unit and it is inside a building or transport, returns the transport. NULL otherwise.
ContainerBase * getContainer(bool dontThrow=false)
const VehicleType * typ
Definition: vehicle.h:83
bool attacked
did the unit already attack this turn
Definition: vehicle.h:109
static bool avail(const ContainerBase *carrier, const Vehicle *unit)
const ContainerBaseType * baseType
the type descriping all non-instance specific properties of the container
Definition: containerbase.h:80
GameMap * getMap() const
void readData(tnstream &stream)
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
int networkid
a unique identification of the unit that is used everywhere in ASC (and not only the network protocol...
Definition: vehicle.h:140
void setUnit(Vehicle *unit)
int getExperience_offensive() const
Definition: vehicle.cpp:253