Advanced Strategic Command
putminecommand.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 "putminecommand.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 "../viewcalculation.h"
33 
34 #include "changeunitmovement.h"
35 #include "spawnmine.h"
36 #include "consumeammo.h"
37 #include "removemine.h"
38 
40 {
41  if ( unit )
42  if (unit->getOwner() == unit->getMap()->actplayer)
44  if ( !unit->attacked )
45  return true;
46  return false;
47 }
48 
49 
50 PutMineCommand :: PutMineCommand ( Vehicle* unit )
51  : UnitCommand ( unit ), mode(Build)
52 {
53  object = cmantitankmine;
54  putMines = false;
55  removeMines = false;
56 
57  weaponNum = -1;
58 
59  for ( int i = 0; i < unit->typ->weapons.count; i++)
60  if ((unit->typ->weapons.weapon[i].getScalarWeaponType() == cwminen) && unit->typ->weapons.weapon[i].shootable() && (unit->typ->weapons.weapon[i].sourceheight & unit->height) ) {
62  removeMines = true;
63 
64  if (unit->ammo[i] > 0)
65  putMines = true;
66 
67  weaponNum = i;
68  }
69 }
70 
71 
72 vector<MapCoordinate> PutMineCommand::getFields()
73 {
74  vector<MapCoordinate> fields = objectsRemovable;
75 
76  for ( map<MapCoordinate,vector<MineTypes> > ::iterator i = objectsCreatable.begin(); i != objectsCreatable.end(); ++i )
77  if ( find(fields.begin(), fields.end(), i->first) == fields.end() )
78  fields.push_back ( i->first );
79  return fields;
80 }
81 
82 const vector<MineTypes>& PutMineCommand::getCreatableMines( const MapCoordinate& pos )
83 {
84  return objectsCreatable[pos];
85 }
86 
88 {
89  return find( objectsRemovable.begin(), objectsRemovable.end(), pos) != objectsRemovable.end();
90 }
91 
93 {
94  if ( !getUnit() )
95  return ActionResult(201);
96 
97  if (getUnit()->getMovement() < mineputmovedecrease)
98  return ActionResult( 119 );
99 
100 
101  objectsCreatable.clear();
102  objectsRemovable.clear();
103 
104  if ( weaponNum >= 0 )
105  circularFieldIterator( getMap(), getUnit()->getPosition(), getUnit()->typ->weapons.weapon[weaponNum].maxdistance/10, getUnit()->typ->weapons.weapon[weaponNum].mindistance/10, FieldIterationFunctor( this, &PutMineCommand::fieldChecker ));
106 
107  if ( objectsRemovable.size() + objectsCreatable.size() ) {
109  return ActionResult(0);
110  } else
111  return ActionResult(21504);
112 }
113 
114 void PutMineCommand :: fieldChecker( const MapCoordinate& pos )
115 {
116  MapField* fld = getMap()->getField(pos);
117  if ( !fld )
118  return;
119 
120  if ( fld->vehicle || fld->building )
121  return;
122 
123  if ( fieldvisiblenow( getMap()->getField(pos)) ) {
124 
125  if ( removeMines && !fld->mines.empty() && fld->getVisibility( getUnit()->getOwner() ) == visible_all) {
126  objectsRemovable.push_back( pos );
127  }
128 
129  if (putMines && (fld->mines.empty() || fld->mineowner() == getUnit()->getOwner()) && fld->mines.size() < getMap()->getgameparameter ( cgp_maxminesonfield )) {
130  if ( (fld->bdt & (getTerrainBitType( cbwater ).flip())).any() ) {
131  objectsCreatable[pos].push_back( cmantipersonnelmine );
132  objectsCreatable[pos].push_back( cmantitankmine );
133  }
134  if ( (fld->typ->art & getTerrainBitType(cbwater2)).any()
135  || (fld->typ->art & getTerrainBitType(cbwater3)).any() )
136  objectsCreatable[pos].push_back( cmmooredmine );
137 
138  if ( (fld->bdt & getTerrainBitType(cbwater0)).any()
139  || (fld->bdt & getTerrainBitType(cbwater1)).any()
140  || (fld->bdt & getTerrainBitType(cbwater2)).any()
141  || (fld->bdt & getTerrainBitType(cbwater3)).any()
142  || (fld->bdt & getTerrainBitType(cbriver)).any() )
143  objectsCreatable[pos].push_back( cmfloatmine );
144 
145  }
146  }
147 }
148 
149 
151 {
152  MapField* fld = getMap()->getField(target);
153 
154  if( !fld )
155  throw ActionResult(21002);
156 
157  this->target = target;
158  this->object = mineType;
159 
160  mode = Build;
161 
162 
163  setState( SetUp );
164 }
165 
167 {
168  MapField* fld = getMap()->getField(target);
169 
170  if( !fld )
171  throw ActionResult(21002);
172 
173  this->target = target;
174  mode = Remove;
175 
176  setState( SetUp );
177 }
178 
179 
181 {
182  MapCoordinate targetPosition;
183 
184  if ( getState() != SetUp )
185  return ActionResult(22000);
186 
187  searchFields();
188 
189  int strength = getUnit()->typ->weapons.weapon[weaponNum].maxstrength;
190 
191  ActionResult res(0);
192  if ( mode == Build ) {
193  res = (new SpawnMine(getMap(), target, object, getUnit()->getOwner(), MineBasePunch[object-1] * strength / 64 ))->execute( context );
194 
195  computeview( getMap(), 0, false, &context );
196 
197  if ( res.successful() )
198  res = (new ConsumeAmmo( getUnit(), getUnit()->typ->weapons.weapon[weaponNum].getScalarWeaponType(), weaponNum, 1 ))->execute(context);
199  } else
200  res = (new RemoveMine(getMap(), target, 0 ))->execute( context );
201 
202 
203  if ( res.successful() )
204  res = (new ChangeUnitMovement( getUnit(), mineputmovedecrease, true ))->execute(context);
205 
206  if ( res.successful() )
207  setState( Finished );
208  else
209  setState( Failed );
210 
211  if( context.display && fieldvisiblenow( getMap()->getField(target), context.viewingPlayer ))
212  context.display->displayMap();
213  return res;
214 
215 }
216 
217 static const int putObjectCommandVersion = 1;
218 
220 {
221  UnitCommand::readData( stream );
222  int version = stream.readInt();
223  if ( version > putObjectCommandVersion )
224  throw tinvalidversion ( "PutMineCommand", putObjectCommandVersion, version );
225  target.read( stream );
226  object = (MineTypes) stream.readInt();
227  mode = (Mode) stream.readInt();
228  putMines = stream.readInt();
229  removeMines = stream.readInt();;
230  weaponNum = stream.readInt();
231 
232 }
233 
234 void PutMineCommand :: writeData ( tnstream& stream ) const
235 {
236  UnitCommand::writeData( stream );
237  stream.writeInt( putObjectCommandVersion );
238  target.write( stream );
239  stream.writeInt( object );
240  stream.writeInt( mode );
241  stream.writeInt( putMines );
242  stream.writeInt( removeMines );
243  stream.writeInt( weaponNum );
244 
245 }
246 
248 {
249  ASCString c;
250  if ( mode == Build )
251  c.format("unitPutMine ( map, %d, asc.MapCoordinate(%d, %d), %d )", getUnitID(), target.x, target.y, (int)object );
252  else
253  c.format("unitRemoveMine ( map, %d, asc.MapCoordinate(%d, %d) )", getUnitID(), target.x, target.y );
254  return c;
255 
256 }
257 
259 {
261 }
262 
264 {
265  ASCString s = "Put Mine";
266  if ( getUnit() ) {
267  s += " by " + getUnit()->getName();
268  }
269  s += " on " + target.toString();
270  return s;
271 }
272 
273 namespace
274 {
275 const bool r1 = registerAction<PutMineCommand> ( ActionRegistry::PutMineCommand );
276 }
277 
ASCString getDescription() const
TerrainType::Weather * typ
the terraintype of the field
Definition: mapfield.h:38
void setCreationTarget(const MapCoordinate &target, MineTypes mineType)
void writeData(tnstream &stream) const
Definition: unitcommand.cpp:67
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 computeview(GameMap *gamemap, int player_fieldcount_mask, bool disableShareView, const Context *context)
completely computes the view
int GameActionID
Definition: action.h:35
const vector< MineTypes > & getCreatableMines(const MapCoordinate &pos)
the command is totally done
Definition: command.h:120
int getUnitID() const
Definition: unitcommand.h:37
Vehicle * vehicle
Definition: mapfield.h:89
int ammo[16]
Definition: vehicle.h:87
void setRemovalTarget(const MapCoordinate &target)
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
static const int putObjectCommandVersion
UnitWeapon weapons
The weapons.
Definition: vehicletype.h:248
ActionResult go(const Context &context)
int sourceheight
the weapon can be shot from these levels of height (bitmapped)
Definition: vehicletype.h:108
bool shootable(void) const
bool hasFunction(ContainerFunctions function) const
ActionResult searchFields()
int getOwner() const
returns the number of the player this vehicle/building belongs to
GameActionID getID() const
State getState() const
Definition: command.h:125
static bool avail(Vehicle *eht)
void read(tnstream &stream)
Definition: typen.h:213
int mineowner(void)
the player who placed the mines on this field.
Definition: mapfield.cpp:454
GameMap * getMap()
Definition: action.h:92
SingleWeapon weapon[16]
Definition: vehicletype.h:170
ASCString toString(bool coordinates=false) const
Definition: typen.cpp:304
The interface for all kinds of IO stream.
a single field of the map
Definition: mapfield.h:26
ASCString & format(const charT *pFormat,...)
Definition: ascstring.cpp:78
TerrainBits art
the properties defining which unit can move onto this field and which not
Definition: terraintype.h:125
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
void writeData(tnstream &stream) const
int height
the current level of height ( BITMAPPED ! )
Definition: vehicle.h:118
const int mineputmovedecrease
the movement cost for putting mines on the map
Definition: typen.h:485
int getScalarWeaponType(void) const
bool fieldvisiblenow(const MapField *pe, Vehicle *veh, int player)
{@
Definition: spfst.cpp:399
MineTypes
Definition: objects.h:70
ActionResult execute(const Context &context)
Definition: action.cpp:41
TerrainBits getTerrainBitType(TerrainBitTypes tbt)
void write(tnstream &stream) const
Definition: typen.h:212
Coordinate on the twodimensional map.
Definition: typen.h:202
void circularFieldIterator(GameMap *gamemap, const MapCoordinate &center, int startDist, int stopDist, FieldIterationFunctor functor)
ASCString getName() const
returns the units name or, if it does not exist, the unit type's name or description ...
Definition: vehicle.cpp:1569
virtual void displayMap(void)=0
const int MineBasePunch[cminenum]
Definition: objects.cpp:39
void setState(State state)
Definition: command.cpp:44
int viewingPlayer
Definition: context.h:40
signed char actplayer
the player who is currently making his moves (may be human or AI)
Definition: gamemap.h:232
bool successful() const
#define cwminen
Definition: vehicletype.h:67
MapDisplayInterface * display
Definition: context.h:39
TerrainBits bdt
the terraintype properties. They determine which units can move over the field. This variable is reca...
Definition: mapfield.h:161
MineContainer mines
Definition: mapfield.h:117
vector< MapCoordinate > getFields()
int getgameparameter(GameParameter num) const
Definition: gamemap.cpp:1047
ASCString getCommandString() const
void readData(tnstream &stream)
const VehicleType * typ
Definition: vehicle.h:83
bool attacked
did the unit already attack this turn
Definition: vehicle.h:109
Building * building
Definition: mapfield.h:102
void readData(tnstream &stream)
Definition: unitcommand.cpp:52
GameMap * getMap() const
int maxstrength
strength of the weapon when fired over the minimal distance
Definition: vehicletype.h:120
VisibilityStates getVisibility(int actplayer)
Definition: mapfield.h:240
bool getRemovableMines(const MapCoordinate &pos)
Loki::Functor< void, LOKI_TYPELIST_1(const MapCoordinate &) > FieldIterationFunctor
Definition: mapalgorithms.h:43
const Vehicle * getUnit() const
Definition: unitcommand.cpp:26
MapField * getField(int x, int y)
Definition: gamemap.h:465