Advanced Strategic Command
unitfieldregistration.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 "unitfieldregistration.h"
23 #include "action-registry.h"
24 
25 #include "../vehicle.h"
26 #include "../gamemap.h"
27 #include "../viewcalculation.h"
28 
30  : UnitAction( vehicle->getMap(), vehicle->networkid)
31 {
32  this->operation= operation;
33  this->position = pos;
34  if ( carrier )
35  carrierID = carrier->getIdentification();
36  else
37  carrierID = 0;
38 }
39 
40 
41 ASCString UnitFieldRegistration::getOpName() const
42 {
43  switch ( operation ) {
44  case RegisterOnField: return "RegisterOnField";
45  case UnregisterOnField: return "UnregisterOnField";
46  case AddView: return "AddView";
47  case RemoveView: return "RemoveView";
48  case Position: return "Position";
49  case Position3D: return "Position3D";
50  case RegisterInCarrier: return "CarrierRegistration";
51  case UnRegisterFromCarrier: return "CarrierUnregistration";
52  }
53  return "";
54 }
55 
57 {
58  ASCString res = getOpName();
59  if ( getUnit(false) )
60  res += " " + getUnit(false)->getName();
61 
62  if ( position.valid() )
63  res += " " + position.toString();
64 
65  return res;
66 }
67 
68 static const int unitFieldRegistrationVersion = 2;
69 
71 {
72  UnitAction::readData( stream );
73  int version = stream.readInt();
74  if ( version < 1 || version > unitFieldRegistrationVersion )
75  throw tinvalidversion ( "UnitFieldRegistration", unitFieldRegistrationVersion, version );
76 
77  operation = (Operation) stream.readInt();
78  position.read( stream );
79  previousPosition.read( stream );
80  stream.readInt();
81  stream.readInt();
82 
83  if ( version >= 2 )
84  carrierID = stream.readInt();
85  else
86  carrierID = 0;
87 };
88 
89 
91 {
92  UnitAction::writeData( stream );
93  stream.writeInt( unitFieldRegistrationVersion );
94  stream.writeInt( (int) operation );
95  position.write( stream );
96  previousPosition.write( stream );
97  stream.writeInt( 0 ); // dummy
98  stream.writeInt( 0 ); // dummy
99  stream.writeInt( carrierID );
100 };
101 
102 
104 {
106 }
107 
109 {
110  Vehicle* veh = getUnit();
111 
112  MapField* fld = getMap()->getField( position );
113 
114  switch ( operation ) {
115  case RegisterOnField:
116  if ( fld->getContainer() )
117  fld->getContainer()->addToCargo( veh );
118  else
119  fld->vehicle = veh;
120  break;
121 
122  case RegisterInCarrier:
123  {
124  ContainerBase* carrier = getMap()->getContainer( carrierID );
125  if ( !carrier )
126  throw ActionResult( 21303 );
127  carrier->addToCargo( veh );
128  break;
129  }
130 
132  {
133  ContainerBase* carrier = getMap()->getContainer( carrierID );
134  if ( !carrier )
135  throw ActionResult( 21303 );
136  if ( !carrier->removeUnitFromCargo( veh ))
137  throw ActionResult( 21302, veh );
138  break;
139  }
140 
141  case UnregisterOnField:
142  if ( fld->getContainer() && fld->getContainer() != veh ) {
143  if ( !fld->getContainer()->removeUnitFromCargo( veh ))
144  throw ActionResult( 21302, veh );
145  } else {
146  if ( fld->vehicle != veh )
147  throw ActionResult( 21301, veh );
148  fld->vehicle = NULL;
149  }
150  break;
151 
152  case AddView:
153  veh->addview();
154  break;
155 
156  case RemoveView:
157  veh->removeview();
158  break;
159 
160  case Position3D:
161  previousPosition = veh->getPosition();
162  veh->xpos = position.x;
163  veh->ypos = position.y;
164  veh->height = position.getBitmappedHeight();
165  break;
166 
167  case Position:
168  previousPosition = veh->getPosition();
169  veh->xpos = position.x;
170  veh->ypos = position.y;
171  break;
172  }
173 
174  if ( operation == Position3D || operation == Position ) {
175  for ( Vehicle::Cargo::const_iterator i = veh->getCargo().begin(); i != veh->getCargo().end(); ++i )
176  if ( *i ) {
177  auto_ptr<UnitFieldRegistration> ufr4 ( new UnitFieldRegistration( *i, position, Position ));
178  ActionResult res = ufr4->execute( context );
179  if ( !res.successful() )
180  return res;
181  else
182  ufr4.release();
183  }
184  }
185 
186  return ActionResult(0);
187 }
188 
189 
191 {
192  Vehicle* veh = getUnit();
193 
194  MapField* fld = getMap()->getField( position );
195 
196  switch ( operation ) {
197  case UnregisterOnField:
198  if ( fld->getContainer() )
199  fld->getContainer()->addToCargo( veh );
200  else
201  fld->vehicle = veh;
202  break;
203 
204  case RegisterInCarrier:
205  {
206  ContainerBase* carrier = getMap()->getContainer( carrierID );
207  if ( !carrier )
208  throw ActionResult( 21303 );
209 
210  if ( !carrier->removeUnitFromCargo( veh ))
211  throw ActionResult( 21302, veh );
212 
213  break;
214  }
215 
217  {
218  ContainerBase* carrier = getMap()->getContainer( carrierID );
219  if ( !carrier )
220  throw ActionResult( 21303 );
221 
222  carrier->addToCargo( veh );
223  break;
224  }
225 
226  case RegisterOnField:
227  if ( fld->getContainer() && fld->getContainer() != veh ) {
228  if ( !fld->getContainer()->removeUnitFromCargo( veh ))
229  throw ActionResult( 21302, veh );
230  } else {
231  if ( fld->vehicle != veh )
232  throw ActionResult( 21301, veh );
233  fld->vehicle = NULL;
234  }
235  break;
236 
237  case RemoveView:
238  veh->addview();
239  break;
240 
241  case AddView:
242  veh->removeview();
243  break;
244 
245  case Position3D:
246  veh->xpos = previousPosition.x;
247  veh->ypos = previousPosition.y;
248  veh->height = previousPosition.getBitmappedHeight();
249  break;
250 
251  case Position:
252  veh->xpos = previousPosition.x;
253  veh->ypos = previousPosition.y;
254  break;
255 
256  }
257 
258  return ActionResult(0);
259 }
260 
262 {
263  if ( operation == Position || operation == Position3D ) {
264  if ( getUnit()->xpos != previousPosition.x || getUnit()->ypos != previousPosition.y )
265  return ActionResult( 21206, getUnit() );
266  }
267  return ActionResult(0);
268 }
269 
271 {
272  return ActionResult(0);
273 }
274 
275 
276 
277 namespace {
278  const bool r1 = registerAction<UnitFieldRegistration> ( ActionRegistry::UnitFieldRegistration );
279 }
280 
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
Vehicle * vehicle
Definition: mapfield.h:89
bool valid() const
Definition: typen.h:221
ASCString toString(bool coordinates=false) const
Definition: typen.cpp:314
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
void writeData(tnstream &stream) const
Definition: unitaction.cpp:75
ContainerBase * getContainer(int nwid)
Definition: gamemap.cpp:1231
virtual int getIdentification() const =0
MapCoordinate3D getPosition() const
returns the units position
Definition: vehicle.cpp:1552
GameMap * getMap()
Definition: action.h:92
ContainerBase * getContainer()
returns a pointer to the ContainerBase of the field or NULL if there is none
Definition: mapfield.cpp:331
The interface for all kinds of IO stream.
a single field of the map
Definition: mapfield.h:26
void write(tnstream &stream) const
Definition: typen.h:253
virtual ActionResult postCheck()
postCheck is called after an action has been redone and should check that the state of the map is exa...
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
void read(tnstream &stream)
Definition: typen.h:254
int height
the current level of height ( BITMAPPED ! )
Definition: vehicle.h:118
UnitFieldRegistration(Vehicle *vehicle, const MapCoordinate3D &pos, Operation operation, ContainerBase *carrier=0)
Vehicle * getUnit(bool dontThrow=false)
Definition: unitaction.cpp:47
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 readData(tnstream &stream)
void removeview()
removes the units view to the map.
Definition: vehicle.cpp:1006
virtual ActionResult runAction(const Context &context)
bool successful() const
static const int unitFieldRegistrationVersion
virtual ActionResult undoAction(const Context &context)
virtual GameActionID getID() const
int xpos
the position on the map
Definition: vehicle.h:124
virtual void writeData(tnstream &stream) const
int getBitmappedHeight() const
Definition: typen.h:241
void addToCargo(Vehicle *veh, int position=-1)
adds the unit to the cargo
Coordinate on the map including height.
Definition: typen.h:238
The parent class of Vehicle and Building; The name Container originates from Battle Isle...
Definition: containerbase.h:40
bool removeUnitFromCargo(Vehicle *veh, bool recursive=false)
removes the given unit from the container.
virtual ActionResult preCheck()
preCheck is called before an action is redone and should check the preconditions for the action...
const Cargo & getCargo() const
int ypos
Definition: vehicle.h:124
ASCString getDescription() const
void readData(tnstream &stream)
Definition: unitaction.cpp:65
void addview()
adds the units view to the map.
Definition: vehicle.cpp:990
MapField * getField(int x, int y)
Definition: gamemap.h:465