2011-01-20 15:56:30 +00:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
2011-12-14 07:40:48 +00:00
// Copyright (C) 2001-2008 Martiño Figueroa
2011-01-20 15:56:30 +00:00
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
# ifndef _GLEST_GAME_MAP_H_
# define _GLEST_GAME_MAP_H_
2012-04-20 01:04:05 +00:00
# ifdef WIN32
# include <winsock2.h>
# include <winsock.h>
# endif
2011-01-20 15:56:30 +00:00
# include "vec.h"
# include "math_util.h"
# include "command_type.h"
# include "logger.h"
# include "object.h"
# include "game_constants.h"
2010-08-31 23:14:15 +00:00
# include "selection.h"
2011-01-20 15:56:30 +00:00
# include <cassert>
2012-04-17 07:51:45 +00:00
# include "unit_type.h"
2012-05-04 21:03:52 +00:00
# include "command.h"
2012-05-05 06:23:09 +00:00
# include "checksum.h"
2011-01-20 15:56:30 +00:00
# include "leak_dumper.h"
namespace Glest { namespace Game {
using Shared : : Graphics : : Vec4f ;
using Shared : : Graphics : : Quad2i ;
using Shared : : Graphics : : Rect2i ;
using Shared : : Graphics : : Vec4f ;
using Shared : : Graphics : : Vec2f ;
using Shared : : Graphics : : Vec2i ;
using Shared : : Graphics : : Texture2D ;
class Tileset ;
class Unit ;
class Resource ;
2010-03-21 05:33:13 +00:00
class TechTree ;
2011-01-20 15:56:30 +00:00
class GameSettings ;
2012-03-12 23:08:22 +00:00
class World ;
2011-01-20 15:56:30 +00:00
// =====================================================
// class Cell
//
/// A map cell that holds info about units present on it
// =====================================================
class Cell {
private :
Unit * units [ fieldCount ] ; //units on this cell
Unit * unitsWithEmptyCellMap [ fieldCount ] ; //units with an empty cellmap on this cell
float height ;
private :
Cell ( Cell & ) ;
void operator = ( Cell & ) ;
public :
Cell ( ) ;
//get
2012-04-17 07:51:45 +00:00
inline Unit * getUnit ( int field ) const { if ( field > = fieldCount ) { throw megaglest_runtime_error ( " Invalid field value " + intToStr ( field ) ) ; } return units [ field ] ; }
inline Unit * getUnitWithEmptyCellMap ( int field ) const { if ( field > = fieldCount ) { throw megaglest_runtime_error ( " Invalid field value " + intToStr ( field ) ) ; } return unitsWithEmptyCellMap [ field ] ; }
inline float getHeight ( ) const { return height ; }
2011-01-20 15:56:30 +00:00
2012-04-17 15:25:31 +00:00
inline void setUnit ( int field , Unit * unit ) { if ( field > = fieldCount ) { throw megaglest_runtime_error ( " Invalid field value " + intToStr ( field ) ) ; } units [ field ] = unit ; }
inline void setUnitWithEmptyCellMap ( int field , Unit * unit ) { if ( field > = fieldCount ) { throw megaglest_runtime_error ( " Invalid field value " + intToStr ( field ) ) ; } unitsWithEmptyCellMap [ field ] = unit ; }
inline void setHeight ( float height ) { this - > height = height ; }
2011-01-20 15:56:30 +00:00
2012-04-17 07:51:45 +00:00
inline bool isFree ( Field field ) const {
bool result = getUnit ( field ) = = NULL | | getUnit ( field ) - > isPutrefacting ( ) ;
2011-09-26 23:55:18 +00:00
2012-04-17 07:51:45 +00:00
if ( result = = false ) {
//printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str());
}
return result ;
}
inline bool isFreeOrMightBeFreeSoon ( Vec2i originPos , Vec2i cellPos , Field field ) const {
bool result = getUnit ( field ) = = NULL | | getUnit ( field ) - > isPutrefacting ( ) ;
if ( result = = false ) {
if ( originPos . dist ( cellPos ) > 5 & & getUnit ( field ) - > getType ( ) - > isMobile ( ) = = true ) {
result = true ;
}
//printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str());
}
return result ;
}
2012-03-12 23:08:22 +00:00
void saveGame ( XmlNode * rootNode , int index ) const ;
void loadGame ( const XmlNode * rootNode , int index , World * world ) ;
2011-01-20 15:56:30 +00:00
} ;
// =====================================================
// class SurfaceCell
//
// A heightmap cell, each surface cell is composed by more than one Cell
// =====================================================
class SurfaceCell {
private :
//geometry
Vec3f vertex ;
Vec3f normal ;
Vec3f color ;
//tex coords
Vec2f fowTexCoord ; //tex coords for TEXTURE1 when multitexturing and fogOfWar
Vec2f surfTexCoord ; //tex coords for TEXTURE0
//surface
int surfaceType ;
const Texture2D * surfaceTexture ;
//object & resource
Object * object ;
//visibility
bool visible [ GameConstants : : maxPlayers + GameConstants : : specialFactions ] ;
bool explored [ GameConstants : : maxPlayers + GameConstants : : specialFactions ] ;
//cache
bool nearSubmerged ;
2012-03-13 15:21:25 +00:00
bool cellChangedFromOriginalMapLoad ;
2011-01-20 15:56:30 +00:00
public :
SurfaceCell ( ) ;
~ SurfaceCell ( ) ;
2011-03-06 22:50:04 +00:00
void end ( ) ; //to kill particles
2011-01-20 15:56:30 +00:00
//get
2012-04-17 15:25:31 +00:00
inline const Vec3f & getVertex ( ) const { return vertex ; }
inline float getHeight ( ) const { return vertex . y ; }
inline const Vec3f & getColor ( ) const { return color ; }
inline const Vec3f & getNormal ( ) const { return normal ; }
inline int getSurfaceType ( ) const { return surfaceType ; }
inline const Texture2D * getSurfaceTexture ( ) const { return surfaceTexture ; }
inline Object * getObject ( ) const { return object ; }
inline Resource * getResource ( ) const { return object = = NULL ? NULL : object - > getResource ( ) ; }
inline const Vec2f & getFowTexCoord ( ) const { return fowTexCoord ; }
inline const Vec2f & getSurfTexCoord ( ) const { return surfTexCoord ; }
inline bool getNearSubmerged ( ) const { return nearSubmerged ; }
2011-01-20 15:56:30 +00:00
2012-04-17 07:51:45 +00:00
inline bool isVisible ( int teamIndex ) const { return visible [ teamIndex ] ; }
inline bool isExplored ( int teamIndex ) const { return explored [ teamIndex ] ; }
2011-01-20 15:56:30 +00:00
//set
2012-04-17 15:25:31 +00:00
inline void setVertex ( const Vec3f & vertex ) { this - > vertex = vertex ; }
inline void setHeight ( float height , bool cellChangedFromOriginalMapLoadValue = false ) ;
inline void setNormal ( const Vec3f & normal ) { this - > normal = normal ; }
inline void setColor ( const Vec3f & color ) { this - > color = color ; }
inline void setSurfaceType ( int surfaceType ) { this - > surfaceType = surfaceType ; }
inline void setSurfaceTexture ( const Texture2D * st ) { this - > surfaceTexture = st ; }
inline void setObject ( Object * object ) { this - > object = object ; }
inline void setFowTexCoord ( const Vec2f & ftc ) { this - > fowTexCoord = ftc ; }
inline void setSurfTexCoord ( const Vec2f & stc ) { this - > surfTexCoord = stc ; }
2011-01-20 15:56:30 +00:00
void setExplored ( int teamIndex , bool explored ) ;
void setVisible ( int teamIndex , bool visible ) ;
2012-04-17 15:25:31 +00:00
inline void setNearSubmerged ( bool nearSubmerged ) { this - > nearSubmerged = nearSubmerged ; }
2011-01-20 15:56:30 +00:00
//misc
void deleteResource ( ) ;
2012-03-13 15:21:25 +00:00
bool decAmount ( int value ) ;
2012-04-17 07:51:45 +00:00
inline bool isFree ( ) const {
bool result = object = = NULL | | object - > getWalkable ( ) ;
if ( result = = false ) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
}
return result ;
}
2012-03-13 15:21:25 +00:00
bool getCellChangedFromOriginalMapLoad ( ) const { return cellChangedFromOriginalMapLoad ; }
2012-03-12 23:08:22 +00:00
void saveGame ( XmlNode * rootNode , int index ) const ;
void loadGame ( const XmlNode * rootNode , int index , World * world ) ;
2011-01-20 15:56:30 +00:00
} ;
// =====================================================
// class Map
//
/// Represents the game map (and loads it from a gbm file)
// =====================================================
2012-05-04 21:03:52 +00:00
class FastAINodeCache {
public :
FastAINodeCache ( Unit * unit ) {
this - > unit = unit ;
}
Unit * unit ;
std : : map < Vec2i , std : : map < Vec2i , bool > > cachedCanMoveSoonList ;
} ;
2011-01-20 15:56:30 +00:00
class Map {
public :
static const int cellScale ; //number of cells per surfaceCell
static const int mapScale ; //horizontal scale of surface
private :
string title ;
float waterLevel ;
float heightFactor ;
2011-02-08 03:50:59 +00:00
float cliffLevel ;
2011-02-25 00:31:42 +00:00
int cameraHeight ;
2011-01-20 15:56:30 +00:00
int w ;
int h ;
int surfaceW ;
int surfaceH ;
2012-09-24 17:13:27 +00:00
int surfaceSize ;
2011-01-20 15:56:30 +00:00
int maxPlayers ;
Cell * cells ;
SurfaceCell * surfaceCells ;
2011-01-09 04:49:21 +00:00
Vec2i * startLocations ;
2011-01-20 15:56:30 +00:00
Checksum checksumValue ;
2011-02-10 00:14:21 +00:00
float maxMapHeight ;
2012-03-10 03:27:25 +00:00
string mapFile ;
2011-01-20 15:56:30 +00:00
private :
Map ( Map & ) ;
void operator = ( Map & ) ;
public :
Map ( ) ;
2011-01-09 04:49:21 +00:00
~ Map ( ) ;
2011-03-06 22:50:04 +00:00
void end ( ) ; //to kill particles
2011-01-20 15:56:30 +00:00
Checksum * getChecksumValue ( ) { return & checksumValue ; }
2011-02-06 01:36:55 +00:00
void init ( Tileset * tileset ) ;
2011-01-20 15:56:30 +00:00
Checksum load ( const string & path , TechTree * techTree , Tileset * tileset ) ;
//get
2012-05-04 14:57:59 +00:00
inline Cell * getCell ( int x , int y , bool errorOnInvalid = true ) const {
2012-04-17 07:51:45 +00:00
int arrayIndex = y * w + x ;
if ( arrayIndex < 0 | | arrayIndex > = getCellArraySize ( ) ) {
2012-05-04 14:57:59 +00:00
if ( errorOnInvalid = = false ) {
return NULL ;
}
2012-04-17 07:51:45 +00:00
//abort();
throw megaglest_runtime_error ( " arrayIndex >= getCellArraySize() , arrayIndex = " + intToStr(arrayIndex) + " w = " + intToStr(w) + " h = " + intToStr(h)) ;
}
else if ( cells = = NULL ) {
2012-05-04 14:57:59 +00:00
if ( errorOnInvalid = = false ) {
return NULL ;
}
2012-04-17 07:51:45 +00:00
throw megaglest_runtime_error ( " cells == NULL " ) ;
}
return & cells [ arrayIndex ] ;
}
inline Cell * getCell ( const Vec2i & pos ) const {
return getCell ( pos . x , pos . y ) ;
}
inline int getCellArraySize ( ) const {
return ( w * h ) ;
}
inline int getSurfaceCellArraySize ( ) const {
2012-09-24 17:13:27 +00:00
//return (surfaceW * surfaceH);
return surfaceSize ;
2012-04-17 07:51:45 +00:00
}
inline SurfaceCell * getSurfaceCell ( int sx , int sy ) const {
int arrayIndex = sy * surfaceW + sx ;
if ( arrayIndex < 0 | | arrayIndex > = getSurfaceCellArraySize ( ) ) {
throw megaglest_runtime_error ( " arrayIndex >= getSurfaceCellArraySize(), arrayIndex = " + intToStr ( arrayIndex ) +
" surfaceW = " + intToStr ( surfaceW ) + " surfaceH = " + intToStr ( surfaceH ) +
" sx: " + intToStr ( sx ) + " sy: " + intToStr ( sy ) ) ;
}
else if ( surfaceCells = = NULL ) {
throw megaglest_runtime_error ( " surfaceCells == NULL " ) ;
}
return & surfaceCells [ arrayIndex ] ;
}
inline SurfaceCell * getSurfaceCell ( const Vec2i & sPos ) const {
return getSurfaceCell ( sPos . x , sPos . y ) ;
}
inline int getW ( ) const { return w ; }
inline int getH ( ) const { return h ; }
inline int getSurfaceW ( ) const { return surfaceW ; }
inline int getSurfaceH ( ) const { return surfaceH ; }
inline int getMaxPlayers ( ) const { return maxPlayers ; }
inline float getHeightFactor ( ) const { return heightFactor ; }
inline float getWaterLevel ( ) const { return waterLevel ; }
inline float getCliffLevel ( ) const { return cliffLevel ; }
inline int getCameraHeight ( ) const { return cameraHeight ; }
inline float getMaxMapHeight ( ) const { return maxMapHeight ; }
2011-01-20 15:56:30 +00:00
Vec2i getStartLocation ( int locationIndex ) const ;
2012-04-17 07:51:45 +00:00
inline bool getSubmerged ( const SurfaceCell * sc ) const { return sc - > getHeight ( ) < waterLevel ; }
inline bool getSubmerged ( const Cell * c ) const { return c - > getHeight ( ) < waterLevel ; }
inline bool getDeepSubmerged ( const SurfaceCell * sc ) const { return sc - > getHeight ( ) < waterLevel - ( 1.5f / heightFactor ) ; }
inline bool getDeepSubmerged ( const Cell * c ) const { return c - > getHeight ( ) < waterLevel - ( 1.5f / heightFactor ) ; }
//float getSurfaceHeight(const Vec2i &pos) const;
2011-01-20 15:56:30 +00:00
//is
2012-04-17 07:51:45 +00:00
inline bool isInside ( int x , int y ) const {
return x > = 0 & & y > = 0 & & x < w & & y < h ;
}
inline bool isInside ( const Vec2i & pos ) const {
return isInside ( pos . x , pos . y ) ;
}
inline bool isInsideSurface ( int sx , int sy ) const {
return sx > = 0 & & sy > = 0 & & sx < surfaceW & & sy < surfaceH ;
}
inline bool isInsideSurface ( const Vec2i & sPos ) const {
return isInsideSurface ( sPos . x , sPos . y ) ;
}
2011-03-29 01:45:10 +00:00
bool isResourceNear ( const Vec2i & pos , const ResourceType * rt , Vec2i & resourcePos , int size , Unit * unit = NULL , bool fallbackToPeersHarvestingSameResource = false , Vec2i * resourceClickPos = NULL ) const ;
2011-01-20 15:56:30 +00:00
//free cells
bool isFreeCell ( const Vec2i & pos , Field field ) const ;
bool isFreeCellOrHasUnit ( const Vec2i & pos , Field field , const Unit * unit ) const ;
bool isAproxFreeCell ( const Vec2i & pos , Field field , int teamIndex ) const ;
bool isFreeCells ( const Vec2i & pos , int size , Field field ) const ;
2011-02-06 18:33:49 +00:00
bool isFreeCellsOrHasUnit ( const Vec2i & pos , int size , Field field , const Unit * unit , const UnitType * munit ) const ;
2011-01-20 15:56:30 +00:00
bool isAproxFreeCells ( const Vec2i & pos , int size , Field field , int teamIndex ) const ;
bool canOccupy ( const Vec2i & pos , Field field , const UnitType * ut , CardinalDir facing ) ;
//unit placement
bool aproxCanMove ( const Unit * unit , const Vec2i & pos1 , const Vec2i & pos2 , std : : map < Vec2i , std : : map < Vec2i , std : : map < int , std : : map < int , std : : map < Field , bool > > > > > * lookupCache = NULL ) const ;
bool canMove ( const Unit * unit , const Vec2i & pos1 , const Vec2i & pos2 , std : : map < Vec2i , std : : map < Vec2i , std : : map < int , std : : map < Field , bool > > > > * lookupCache = NULL ) const ;
2012-09-11 21:16:24 +00:00
void putUnitCells ( Unit * unit , const Vec2i & pos , bool ignoreSkill = false ) ;
2012-09-13 21:50:07 +00:00
void clearUnitCells ( Unit * unit , const Vec2i & pos , bool ignoreSkill = false ) ;
2011-01-20 15:56:30 +00:00
Vec2i computeRefPos ( const Selection * selection ) const ;
Vec2i computeDestPos ( const Vec2i & refUnitPos , const Vec2i & unitPos ,
const Vec2i & commandPos ) const ;
const Unit * findClosestUnitToPos ( const Selection * selection , Vec2i originalBuildPos ,
const UnitType * ut ) const ;
bool isInUnitTypeCells ( const UnitType * ut , const Vec2i & pos , const Vec2i & testPos ) const ;
bool isNextToUnitTypeCells ( const UnitType * ut , const Vec2i & pos , const Vec2i & testPos ) const ;
Vec2i findBestBuildApproach ( const Unit * unit , Vec2i originalBuildPos , const UnitType * ut ) const ;
std : : pair < float , Vec2i > getUnitDistanceToPos ( const Unit * unit , Vec2i pos , const UnitType * ut ) ;
//misc
bool isNextTo ( const Vec2i & pos , const Unit * unit ) const ;
bool isNextTo ( const Vec2i & pos , const Vec2i & nextToPos ) const ;
2011-10-28 05:22:41 +00:00
bool isNextTo ( const Unit * unit1 , const Unit * unit2 ) const ;
2011-01-20 15:56:30 +00:00
void clampPos ( Vec2i & pos ) const ;
void prepareTerrain ( const Unit * unit ) ;
void flatternTerrain ( const Unit * unit ) ;
void computeNormals ( ) ;
void computeInterpolatedHeights ( ) ;
//static
2012-04-17 07:51:45 +00:00
inline static Vec2i toSurfCoords ( const Vec2i & unitPos ) { return unitPos / cellScale ; }
inline static Vec2i toUnitCoords ( const Vec2i & surfPos ) { return surfPos * cellScale ; }
2011-01-20 15:56:30 +00:00
static string getMapPath ( const string & mapName , string scenarioDir = " " , bool errorOnNotFound = true ) ;
2012-04-21 03:42:25 +00:00
inline bool isFreeCellOrMightBeFreeSoon ( Vec2i originPos , const Vec2i & pos , Field field ) const {
return
isInside ( pos ) & &
isInsideSurface ( toSurfCoords ( pos ) ) & &
getCell ( pos ) - > isFreeOrMightBeFreeSoon ( originPos , pos , field ) & &
( field = = fAir | | getSurfaceCell ( toSurfCoords ( pos ) ) - > isFree ( ) ) & &
( field ! = fLand | | getDeepSubmerged ( getCell ( pos ) ) = = false ) ;
}
inline bool isAproxFreeCellOrMightBeFreeSoon ( Vec2i originPos , const Vec2i & pos , Field field , int teamIndex ) const {
if ( isInside ( pos ) & & isInsideSurface ( toSurfCoords ( pos ) ) ) {
const SurfaceCell * sc = getSurfaceCell ( toSurfCoords ( pos ) ) ;
if ( sc - > isVisible ( teamIndex ) ) {
return isFreeCellOrMightBeFreeSoon ( originPos , pos , field ) ;
}
else if ( sc - > isExplored ( teamIndex ) ) {
return field = = fLand ? sc - > isFree ( ) & & ! getDeepSubmerged ( getCell ( pos ) ) : true ;
}
else {
return true ;
}
}
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
return false ;
}
2012-05-04 21:03:52 +00:00
//checks if a unit can move from between 2 cells using only visible cells (for pathfinding)
inline bool aproxCanMoveSoon ( const Unit * unit , const Vec2i & pos1 , const Vec2i & pos2 ) const {
if ( isInside ( pos1 ) = = false | | isInsideSurface ( toSurfCoords ( pos1 ) ) = = false | |
isInside ( pos2 ) = = false | | isInsideSurface ( toSurfCoords ( pos2 ) ) = = false ) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
return false ;
}
int size = unit - > getType ( ) - > getSize ( ) ;
int teamIndex = unit - > getTeam ( ) ;
Field field = unit - > getCurrField ( ) ;
const bool * cachedResult = unit - > getFaction ( ) - > aproxCanMoveSoonCached ( size , field , pos1 , pos2 ) ;
if ( cachedResult ! = NULL ) {
return * cachedResult ;
}
//single cell units
if ( size = = 1 ) {
if ( isAproxFreeCellOrMightBeFreeSoon ( unit - > getPos ( ) , pos2 , field , teamIndex ) = = false ) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
unit - > getFaction ( ) - > addAproxCanMoveSoonCached ( size , field , pos1 , pos2 , false ) ;
return false ;
}
if ( pos1 . x ! = pos2 . x & & pos1 . y ! = pos2 . y ) {
if ( isAproxFreeCellOrMightBeFreeSoon ( unit - > getPos ( ) , Vec2i ( pos1 . x , pos2 . y ) , field , teamIndex ) = = false ) {
//Unit *cellUnit = getCell(Vec2i(pos1.x, pos2.y))->getUnit(field);
//Object * obj = getSurfaceCell(toSurfCoords(Vec2i(pos1.x, pos2.y)))->getObject();
//printf("[%s] Line: %d returning false cell [%s] free [%d] cell unitid = %d object class = %d\n",__FUNCTION__,__LINE__,Vec2i(pos1.x, pos2.y).getString().c_str(),this->isFreeCell(Vec2i(pos1.x, pos2.y),field),(cellUnit != NULL ? cellUnit->getId() : -1),(obj != NULL ? obj->getType()->getClass() : -1));
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
unit - > getFaction ( ) - > addAproxCanMoveSoonCached ( size , field , pos1 , pos2 , false ) ;
return false ;
}
if ( isAproxFreeCellOrMightBeFreeSoon ( unit - > getPos ( ) , Vec2i ( pos2 . x , pos1 . y ) , field , teamIndex ) = = false ) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
unit - > getFaction ( ) - > addAproxCanMoveSoonCached ( size , field , pos1 , pos2 , false ) ;
return false ;
}
}
bool isBadHarvestPos = false ;
if ( unit ! = NULL ) {
Command * command = unit - > getCurrCommand ( ) ;
if ( command ! = NULL ) {
const HarvestCommandType * hct = dynamic_cast < const HarvestCommandType * > ( command - > getCommandType ( ) ) ;
if ( hct ! = NULL & & unit - > isBadHarvestPos ( pos2 ) = = true ) {
isBadHarvestPos = true ;
}
}
}
if ( unit = = NULL | | isBadHarvestPos = = true ) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
unit - > getFaction ( ) - > addAproxCanMoveSoonCached ( size , field , pos1 , pos2 , false ) ;
return false ;
}
unit - > getFaction ( ) - > addAproxCanMoveSoonCached ( size , field , pos1 , pos2 , true ) ;
return true ;
}
//multi cell units
else {
for ( int i = pos2 . x ; i < pos2 . x + size ; + + i ) {
for ( int j = pos2 . y ; j < pos2 . y + size ; + + j ) {
Vec2i cellPos = Vec2i ( i , j ) ;
if ( isInside ( cellPos ) & & isInsideSurface ( toSurfCoords ( cellPos ) ) ) {
if ( getCell ( cellPos ) - > getUnit ( unit - > getCurrField ( ) ) ! = unit ) {
if ( isAproxFreeCellOrMightBeFreeSoon ( unit - > getPos ( ) , cellPos , field , teamIndex ) = = false ) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
unit - > getFaction ( ) - > addAproxCanMoveSoonCached ( size , field , pos1 , pos2 , false ) ;
return false ;
}
}
}
else {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
unit - > getFaction ( ) - > addAproxCanMoveSoonCached ( size , field , pos1 , pos2 , false ) ;
return false ;
}
}
}
bool isBadHarvestPos = false ;
if ( unit ! = NULL ) {
Command * command = unit - > getCurrCommand ( ) ;
if ( command ! = NULL ) {
const HarvestCommandType * hct = dynamic_cast < const HarvestCommandType * > ( command - > getCommandType ( ) ) ;
if ( hct ! = NULL & & unit - > isBadHarvestPos ( pos2 ) = = true ) {
isBadHarvestPos = true ;
}
}
}
if ( unit = = NULL | | isBadHarvestPos = = true ) {
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
unit - > getFaction ( ) - > addAproxCanMoveSoonCached ( size , field , pos1 , pos2 , false ) ;
return false ;
}
}
unit - > getFaction ( ) - > addAproxCanMoveSoonCached ( size , field , pos1 , pos2 , true ) ;
return true ;
}
2011-09-26 23:55:18 +00:00
2012-03-10 03:27:25 +00:00
string getMapFile ( ) const { return mapFile ; }
2012-03-12 23:08:22 +00:00
void saveGame ( XmlNode * rootNode ) const ;
void loadGame ( const XmlNode * rootNode , World * world ) ;
2011-01-20 15:56:30 +00:00
private :
//compute
2011-02-06 01:36:55 +00:00
void smoothSurface ( Tileset * tileset ) ;
2011-01-20 15:56:30 +00:00
void computeNearSubmerged ( ) ;
void computeCellColors ( ) ;
2012-09-15 23:43:31 +00:00
void putUnitCellsPrivate ( Unit * unit , const Vec2i & pos , const UnitType * ut , bool isMorph ) ;
2011-01-20 15:56:30 +00:00
} ;
// ===============================
// class PosCircularIterator
// ===============================
class PosCircularIterator {
private :
Vec2i center ;
int radius ;
const Map * map ;
Vec2i pos ;
public :
PosCircularIterator ( const Map * map , const Vec2i & center , int radius ) ;
bool next ( ) ;
const Vec2i & getPos ( ) ;
} ;
// ===============================
// class PosQuadIterator
// ===============================
class PosQuadIterator {
private :
Quad2i quad ;
Rect2i boundingRect ;
Vec2i pos ;
int step ;
2011-02-25 22:13:11 +00:00
const Map * map ;
2011-01-20 15:56:30 +00:00
public :
2011-02-25 22:13:11 +00:00
PosQuadIterator ( const Map * map , const Quad2i & quad , int step = 1 ) ;
2011-01-20 15:56:30 +00:00
bool next ( ) ;
void skipX ( ) ;
const Vec2i & getPos ( ) ;
} ;
} } //end namespace
# endif