25 #include "../vehicle.h"
26 #include "../mapfield.h"
27 #include "../gamemap.h"
28 #include "../viewcalculation.h"
30 #include "../mapdisplayinterface.h"
73 if ( pos ==
getUnit()->getPosition() )
76 for (
int h = 0; h < 8; ++h )
92 map->
sigCoordinateShift.connect( sigc::mem_fun( *
this, &MoveUnitCommand::changeCoordinates ));
100 MoveUnitCommand :: MoveUnitCommand (
Vehicle* unit )
101 :
UnitCommand ( unit ), flags(0), verticalDirection(0), multiTurnMovement(false), limiter(NULL)
109 bool allow_Height_Change;
124 virtual bool allowHeightChange() { ++hcNum;
if ( simpleMode)
return hcNum <= 1 ;
else return true; };
140 void getMovementFields ( set<MapCoordinate3D>& reachableFields, set<MapCoordinate3D>& reachableFieldsIndirect,
int height );
155 typedef multimap<MapCoordinate, Node* > Fields;
165 if ( h == -1 || height == -1 || h == height ) {
169 reachableFieldsIndirect.insert( node.
h );
173 if ( node.
gval < minMovement ) {
175 minMovement = int (node.
gval);
178 for ( Fields::iterator i = fields.begin(); i != fields.end(); ) {
179 int height = i->second->h.getNumericalHeight();
180 int move = int(i->second->gval);
181 Fields::key_type key = i->first;
183 while ( i != fields.end() && i->first == key ) {
184 if ( i->second->gval < move || ( i->second->gval == move && abs(i->second->h.getNumericalHeight()-orgHeight) < abs(height-orgHeight) ))
185 height = i->second->h.getNumericalHeight();
189 f.
setnum( key.x, key.y, height );
190 reachableFields.insert ( f );
215 pf.getMovementFields ( reachableFields, reachableFieldsIndirect, h );
220 fatalError (
"Inconsistent call to changeheight ");
227 pf.getMovementFields ( reachableFields, reachableFieldsIndirect, h );
237 if ( reachableFields.size() == 0 )
249 this->destination = destination;
259 for ( set<MapCoordinate3D>::iterator i = reachableFields.begin(); i != reachableFields.end(); ++i )
260 if ( destination.
x == i->x && destination.
y == i->y ) {
261 this->destination = *i;
263 multiTurnMovement =
false;
274 this->destination.setnum( destination.
x, destination.
y, -1 );
279 multiTurnMovement =
true;
288 for ( set<MapCoordinate3D>::iterator i = reachableFields.begin(); i != reachableFields.end(); ++i )
289 if ( i->x == pos.
x && i->y == pos.
y )
292 for ( set<MapCoordinate3D>::iterator i = reachableFieldsIndirect.begin(); i != reachableFieldsIndirect.end(); ++i )
293 if ( i->x == pos.
x && i->y == pos.
y )
315 astar->
findPath ( totalPath, destination );
316 if ( totalPath.empty() )
321 if ( ( n->gval <= maxMovement ) && n->canStop) {
360 if ( !multiTurnMovement && ( path.rbegin()->x != destination.
x || path.rbegin()->y != destination.
y ))
381 if ( destDamage < 100 ) {
397 verticalDirection = dir;
407 int version = stream.
readInt();
408 if ( version > moveCommandVersion )
410 destination.
read( stream );
413 verticalDirection = stream.
readInt();
415 multiTurnMovement = stream.
readInt();
417 multiTurnMovement =
false;
423 stream.
writeInt( moveCommandVersion );
424 destination.
write( stream );
426 stream.
writeInt( verticalDirection );
427 stream.
writeInt( multiTurnMovement );
447 s +=
" to " + destination.
toString();
472 vector<MapCoordinate> pos;
473 pos.push_back( destination );
int fieldAccessible(const MapField *field, const Vehicle *vehicle, int uheight, const bool *attacked, bool ignoreVisibility)
void writeData(tnstream &stream) const
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...
const AStar3D::Path & getPath()
the command is totally done
int damage
Damage. 0 is no damage, when damage reaches 100 the container is destroyed.
void readData(tnstream &stream)
the unit will not interrupt the movement if it runs onto a mine of into reaction fire ...
virtual vector< MapCoordinate > getCoordinates() const
this is for informational purposes, so the player can see where a Command has taken place when review...
void move(Vehicle *veh, const MapCoordinate &dest)
ASCString toString(bool coordinates=false) 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...
int getFirstBit(int zahl)
Count the number of zero bits on the LSB side of "zahl".
virtual bool allowHeightChange()
we want only results on a certain level of height
virtual bool allowMovement()
void getMovementFields(set< MapCoordinate3D > &reachableFields, set< MapCoordinate3D > &reachableFieldsIndirect, int height)
searches for all fields that are within the range of maxDist and marks them.
int getNumericalHeight() const
static const int moveCommandVersion
MapCoordinate3D getPosition() const
returns the units position
virtual bool allowLeavingContainer()
storage_t::iterator iterator
ContainerBase * getContainer()
returns a pointer to the ContainerBase of the field or NULL if there is none
The interface for all kinds of IO stream.
a single field of the map
ASCString & format(const charT *pFormat,...)
void write(tnstream &stream) const
The ASCString class provides an abstract way to manipulate strings.
void read(tnstream &stream)
const VehicleType::HeightChangeMethod * getHeightChange(int dir, int height=0) const
returns the method for changing the height in the specified direction, or none if there is none...
int height
the current level of height ( BITMAPPED ! )
bool findPath(const MapCoordinate3D &dest)
searches for a path from the unit's current position to dest
PathFinder(Vehicle *veh, int maxDistance)
ASCString getDescription() const
MapCoordinate3D getPosition3D() const
returns the units position; if inside building then Height is -1
bool longDistAvailable(const MapCoordinate &pos)
ActionResult execute(const Context &context)
static bool descendAvail(Vehicle *eht)
Coordinate on the twodimensional map.
virtual bool allowMovement()
virtual bool allowEnteringContainer()
HeightChangeLimitation(bool allow_Height_Change_)
ASCString getName() const
returns the units name or, if it does not exist, the unit type's name or description ...
void setnum(int _x, int _y, int numericalz)
represents a change of a MapCoordinate
virtual bool allowHeightChange()
ASCString getCommandString() const
void setState(State state)
static bool avail(Vehicle *eht)
MovementLimitation(bool simpleMode_)
void writeData(tnstream &stream) const
virtual bool allowEnteringContainer()
const Vehicle * getUnit() const
GameActionID getID() const
virtual bool allowDocking()
static bool ascendAvail(Vehicle *eht)
MapDisplayInterface * display
void setVerticalDirection(int dir)
defines whether we want to end up either at the same level of height (0), lower(<0), or heigher(>0)
void setDestination(const MapCoordinate &destination)
bool canMove(void) const
can the unit move from its current position (does not check neighbouring fields)
the command is completed this turn, but there is still something to do next turn
void registerOperationLimiter(OperationLimiter *ol)
the search can be restricted to certain operations
virtual void startAction(void)=0
ActionResult searchFields(int height=-1, int capabilities=0)
virtual void stopAction(void)=0
Coordinate on the map including height.
bool constructPath(Path &path, const Node *n)
construct a path from a pointer to a visited node, return false if pointer is NULL, else true
A 3D path finding algorithm, based on the 2D algorithm by Amit J. Patel.
void readData(tnstream &stream)
the unit will not change its height even if that would provide a shortcut
virtual bool allowLeavingContainer()
sigc::signal< void, const MapCoodinateVector & > sigCoordinateShift
called when the map is resized and all coordinates have to be adjusted
int getVerticalDirection() const
const Node * find(const MapCoordinate3D &pos)
virtual bool allowDocking()
void fatalError(const ASCString &string)
bool isFieldReachable(const MapCoordinate &pos, bool direct)
checks if the field can be reached by the unit this turn Precondition: searchFields(int,int) was called
AStar3D::DistanceType gval
int networkid
a unique identification of the unit that is used everywhere in ASC (and not only the network protocol...
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...
ActionResult go(const Context &context)
The map. THE central structure of ASC, which holds everything not globally available together...
MapField * getField(int x, int y)
bool operatable()
checks if the task can still be operated.