Advanced Strategic Command
changeunitmovement.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 <cmath>
23 
24 #include "changeunitmovement.h"
25 #include "changeunitproperty.h"
26 #include "action-registry.h"
27 
28 #include "../vehicle.h"
29 #include "../gamemap.h"
30 
31 
32 ChangeUnitMovement::ChangeUnitMovement( Vehicle* veh, int movement, bool delta, Recursivity recursive )
33  : UnitAction( veh->getMap(), veh->networkid ), originalMovement(-1), resultingMovement(-1)
34 {
35  this->movement = movement;
36  this->delta = delta;
37  this->recursive = recursive;
38 }
39 
40 
42 {
43  ASCString res = "Change movement ";
44  if ( getUnit(false) )
45  res += " of unit " + getUnit(false)->getName();
46 
47  if ( delta )
48  res += " by ";
49  else
50  res += " to ";
51  res += ASCString::toString(movement) + " points ";
52  return res;
53 }
54 
55 static const int changeUnitMovementStreamVersion = 2;
56 
58 {
59  UnitAction::readData( stream );
60  int version = stream.readInt();
61  if ( version < 1 || version > changeUnitMovementStreamVersion )
62  throw tinvalidversion ( "ChangeUnitMovement", changeUnitMovementStreamVersion, version );
63 
64  movement = stream.readInt();
65  delta = stream.readInt();
66  originalMovement = stream.readInt();
67  resultingMovement = stream.readInt();
68  if ( version >= 2 )
69  recursive = (Recursivity) stream.readInt();
70  else
71  recursive = NORMAL;
72 };
73 
74 
76 {
77  UnitAction::writeData( stream );
79  stream.writeInt( movement );
80  stream.writeInt( delta );
81  stream.writeInt( originalMovement );
82  stream.writeInt( resultingMovement );
83  stream.writeInt( (int) recursive );
84 };
85 
86 
88 {
90 }
91 
92 void ChangeUnitMovement::decreaseMovement( Vehicle* veh, float fraction, const Context& context )
93 {
94  if ( recursive != NONE )
95  if ( veh->typ->movement[ getFirstBit ( veh->height ) ] ) {
96  float cargoFraction = fraction;
97  if ( veh->cargoNestingDepth() == 0 && veh->typ->cargoMovementDivisor != 0 && recursive == NORMAL )
98  cargoFraction /= veh->typ->cargoMovementDivisor;
99 
100  for ( Vehicle::Cargo::const_iterator i = veh->getCargo().begin(); i != veh->getCargo().end(); ++i )
101  if ( *i )
102  decreaseMovement( *i, cargoFraction, context );
103  }
104 
105  float f = float(veh->maxMovement()) * fraction;
106  float f2 = ceil(f);
107  if ( fabs ( f-f2) > 0.999 )
108  f2 -= 1;
109 
110  int i = int( f2 );
111  int newMovement = veh->getMovement(false,false) - i;
112 
113  (new ChangeUnitProperty(veh, ChangeUnitProperty::Movement, newMovement ))->execute( context );
114 }
115 
116 
118 {
119  Vehicle* veh = getUnit();
120 
121  originalMovement = veh->getMovement( false, false );
122 
123  float fraction;
124  if ( delta ) {
125  fraction = float(movement) / float( veh->maxMovement());
126  } else {
127  fraction = float(originalMovement - movement) / float( veh->maxMovement());
128  }
129 
130  decreaseMovement( veh, fraction, context );
131 
132  resultingMovement = veh->getMovement( false, false );
133  return ActionResult(0);
134 }
135 
136 
138 {
139  return ActionResult(0);
140 }
141 
143 {
144  if ( getUnit()->getMovement( false, false ) != originalMovement )
145  throw ActionResult( 21103, getUnit() );
146 
147  return ActionResult(0);
148 }
149 
151 {
152  if ( getUnit()->getMovement( false, false ) != resultingMovement )
153  throw ActionResult( 21103, getUnit() );
154 
155  return ActionResult(0);
156 }
157 
158 
159 namespace {
160  const bool r1 = registerAction<ChangeUnitMovement> ( ActionRegistry::ChangeUnitMovement );
161 }
virtual void readData(tnstream &stream)
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
ASCString getDescription() const
int maxMovement() const
the maximum distance that the unit can drive in a single turn on the current level of height ...
Definition: vehicle.cpp:1069
int GameActionID
Definition: action.h:35
virtual void writeData(tnstream &stream) const
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
double cargoMovementDivisor
if a transport moves the movement for the units inside a transport is decreased by 1/n of the tranpor...
Definition: vehicletype.h:194
int getFirstBit(int zahl)
Count the number of zero bits on the LSB side of "zahl".
Definition: misc.cpp:45
static const int changeUnitMovementStreamVersion
void writeData(tnstream &stream) const
Definition: unitaction.cpp:75
virtual ActionResult runAction(const Context &context)
The interface for all kinds of IO stream.
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
vector< int > movement
the distance a unit can travel each round. One value for each of the 8 levels of height ...
Definition: vehicletype.h:203
int height
the current level of height ( BITMAPPED ! )
Definition: vehicle.h:118
virtual ActionResult undoAction(const Context &context)
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
ActionResult execute(const Context &context)
Definition: action.cpp:41
virtual ActionResult preCheck()
preCheck is called before an action is redone and should check the preconditions for the action...
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 ActionResult postCheck()
postCheck is called after an action has been redone and should check that the state of the map is exa...
the loaded units get their movement changed too, by the normal fraction (loaded units less than carri...
const VehicleType * typ
Definition: vehicle.h:83
virtual GameActionID getID() const
const Cargo & getCargo() const
int getMovement(bool checkFuel=true, bool checkRF=true) const
returns the movement points the unit has left for this turn. CheckFuel should almost always be true...
Definition: vehicle.cpp:558
only the unit itself gets its movement changed
void readData(tnstream &stream)
Definition: unitaction.cpp:65
int cargoNestingDepth()
returns the nesting depth of the cargo. The unit standing on the field is 0, its cargo is 1...