From: <be...@us...> - 2017-05-13 11:09:44
|
Revision: 1026 http://sourceforge.net/p/freesynd/code/1026 Author: benblan Date: 2017-05-13 11:09:41 +0000 (Sat, 13 May 2017) Log Message: ----------- Rework of pedpathfinding for better readability Modified Paths: -------------- freesynd/trunk/src/common.h freesynd/trunk/src/ia/actions.cpp freesynd/trunk/src/map.cpp freesynd/trunk/src/map.h freesynd/trunk/src/model/position.h freesynd/trunk/src/pathsurfaces.h freesynd/trunk/src/ped.cpp freesynd/trunk/src/ped.h freesynd/trunk/src/pedpathfinding.cpp Modified: freesynd/trunk/src/common.h =================================================================== --- freesynd/trunk/src/common.h 2017-05-08 13:41:38 UTC (rev 1025) +++ freesynd/trunk/src/common.h 2017-05-13 11:09:41 UTC (rev 1026) @@ -162,6 +162,33 @@ static const uint8 kColorBlue = 15; /*! Color constant : Dark Green */ static const uint8 kColorDarkGreen = 16; + + /*! + * Turn bits given by mask on in the given bitfield. + * \param bitfield the bitfield to update + * \param mask The bitmask to apply + */ + inline void setBitsWithMask(uint32 *bitfield, const uint32 mask) { + *bitfield |= mask; + } + + /*! + * Return true is bits identified by mask are set in the bitfield + * \param bitfield the bitfield to query + * \param mask The bitmask to apply + */ + inline bool isBitsOnWithMask(const uint32 bitfield, const uint32 mask) { + return (bitfield & mask) != 0; + } + + /*! + * Return true is bits identified by mask are set in the bitfield + * \param bitfield 8 bits bitfield to query + * \param mask 8 bits bitmask to apply + */ + inline bool isBitsOnWithMask(const uint8 bitfield, const uint8 mask) { + return (bitfield & mask) != 0; + } }; inline void boxify(int &left, int &width, int x1, int x2) @@ -178,7 +205,4 @@ int y; }; -#define IS_FLAG_SET(field, flags) (field & flags) != 0 -#define SET_FLAG(field, flags) field |= flags - #endif Modified: freesynd/trunk/src/ia/actions.cpp =================================================================== --- freesynd/trunk/src/ia/actions.cpp 2017-05-08 13:41:38 UTC (rev 1025) +++ freesynd/trunk/src/ia/actions.cpp 2017-05-13 11:09:41 UTC (rev 1026) @@ -430,7 +430,6 @@ setFailed(); } else { if (pPed->speed() != 0) { - //IS_FLAG_SET(pPed->stateMasks(), PedInstance::pa_smWalking) if (pPed->isCloseTo(pTarget_, kFollowDistance)) { // We reached the target so stop moving temporarily pPed->clearDestination(); Modified: freesynd/trunk/src/map.cpp =================================================================== --- freesynd/trunk/src/map.cpp 2017-05-08 13:41:38 UTC (rev 1025) +++ freesynd/trunk/src/map.cpp 2017-05-13 11:09:41 UTC (rev 1026) @@ -33,13 +33,9 @@ #include "gfx/tilemanager.h" #include "gfx/screen.h" -#if 0 -#define EXECUTION_SPEED_TIME -#endif - -Map::Map(TileManager * tileManager, uint16 i_id) : tile_manager_(tileManager) +Map::Map(TileManager * tileManager, uint16 anId) : tile_manager_(tileManager) { - i_id_ = i_id; + id_ = anId; a_tiles_ = NULL; } @@ -50,7 +46,7 @@ bool Map::loadMap(uint8 * mapData) { - LOG(Log::k_FLG_GFX, "Map", "loadMap", ("Loading Map %d.", i_id_)); + LOG(Log::k_FLG_GFX, "Map", "loadMap", ("Loading Map %d.", id_)); max_x_ = READ_LE_UINT32(mapData + 0); max_y_ = READ_LE_UINT32(mapData + 4); max_z_ = READ_LE_UINT32(mapData + 8); @@ -130,6 +126,24 @@ } } +void Map::clip(TilePoint *pPoint) { + if (pPoint->tx < 0) { + pPoint->tx = 0; + } else if (pPoint->tx >= maxX()) { + pPoint->tx = maxX() - 1; + } + + if (pPoint->ty < 0) { + pPoint->ty = 0; + } else if (pPoint->ty >= maxY()) { + pPoint->ty = maxY() - 1; + } + + if (pPoint->tz < 0 || pPoint->tz >= maxZ()) { + pPoint->tz = 0; + } +} + float scalexPx = 256.0f; float scalexPy = 256.0f; float scaleyPx = 256.0f; Modified: freesynd/trunk/src/map.h =================================================================== --- freesynd/trunk/src/map.h 2017-05-08 13:41:38 UTC (rev 1025) +++ freesynd/trunk/src/map.h 2017-05-13 11:09:41 UTC (rev 1026) @@ -28,8 +28,6 @@ #include "common.h" #include "model/position.h" -#define NUM_MAPS 59 - class Tile; class TileManager; class MapObject; @@ -40,12 +38,12 @@ */ class Map { public: - Map(TileManager *tileManager, uint16 i_id); + Map(TileManager *tileManager, uint16 anId); ~Map(); bool loadMap(uint8 *mapData); - uint16 id() { return i_id_; } + uint16 id() { return id_; } int width() { return map_width_; } int height() { return map_height_; } void mapDimensions(int *x, int *y, int *z); @@ -53,6 +51,8 @@ void adjXYZ(int &x, int &y, int &z); //! Clip x and y to map dimensions. void clip(Point2D *point); + //! Clip x, y and z to map dimensions. + void clip(TilePoint *point); //! Converts a Map tile position to a screen position void tileToScreenPoint(int x, int y, int z, int pX, int pY, Point2D *pScp); @@ -74,7 +74,7 @@ protected: /*! Every map has a unique ID which is used to identify the name of the file containing map data.*/ - uint16 i_id_; + uint16 id_; int max_x_, max_y_, max_z_; Tile **a_tiles_; TileManager *tile_manager_; Modified: freesynd/trunk/src/model/position.h =================================================================== --- freesynd/trunk/src/model/position.h 2017-05-08 13:41:38 UTC (rev 1025) +++ freesynd/trunk/src/model/position.h 2017-05-13 11:09:41 UTC (rev 1026) @@ -28,6 +28,9 @@ #ifndef MODEL_POSITION_H_ #define MODEL_POSITION_H_ +#include <iostream> +#include <sstream> + /*! * This a convenient structure to store a position * in map tile coordinates. @@ -107,6 +110,13 @@ int b = other.tx | (other.ty << 16); return a < b; } + + void toString(std::string *buffer) const { + std::ostringstream out; + + out << "(" << tx << ", " << ty << ", " << tz << " - " << ox << ", " << oy << ", " << oz << ")"; + buffer->append(out.str()); + } }; /*! Modified: freesynd/trunk/src/pathsurfaces.h =================================================================== --- freesynd/trunk/src/pathsurfaces.h 2017-05-08 13:41:38 UTC (rev 1025) +++ freesynd/trunk/src/pathsurfaces.h 2017-05-13 11:09:41 UTC (rev 1026) @@ -31,7 +31,8 @@ unsigned char twd; }surfaceDesc; - typedef struct { + class floodPointDesc { + public: // mapFloodDesc // 0 - not defined, 0b - base point, 1b - target point, // 2b - link (when base point reaches target point or vice versa), @@ -45,13 +46,42 @@ // 0x10 = (x, y - 1, z); 0x20 = (x - 1, y - 1, z); // 0x40 = (x - 1, y, z); 0x80 = (x - 1, y + 1, z) // can be combined 0x01 | 0x02; 0x01 | 0x10 | 0x40 etc. - unsigned char dirh; - unsigned char dirm; - unsigned char dirl; + uint8 dirh; + uint8 dirm; + uint8 dirl; unsigned short lvl; - }floodPointDesc; + bool isDirectionUpContains(uint8 bmDirection) { + return fs_cmn::isBitsOnWithMask(dirh, bmDirection); + } + + bool isDirectionGroundContains(uint8 bmDirection) { + return fs_cmn::isBitsOnWithMask(dirm, bmDirection); + } + + bool isDirectionDownContains(uint8 bmDirection) { + return fs_cmn::isBitsOnWithMask(dirl, bmDirection); + } + + //! In path finding, identify the direction to North + static const uint8 kBMaskDirNorth; + //! In path finding, identify the direction to North-East + static const uint8 kBMaskDirNorthEast; + //! In path finding, identify the direction to East + static const uint8 kBMaskDirEast; + //! In path finding, identify the direction to South-East + static const uint8 kBMaskDirSouthEast; + //! In path finding, identify the direction to South + static const uint8 kBMaskDirSouth; + //! In path finding, identify the direction to South-West + static const uint8 kBMaskDirSouthWest; + //! In path finding, identify the direction to West + static const uint8 kBMaskDirWest; + //! In path finding, identify the direction to North-West + static const uint8 kBMaskDirNorthWest; + }; + typedef enum { m_fdNotDefined = 0, m_fdBasePoint = 1, Modified: freesynd/trunk/src/ped.cpp =================================================================== --- freesynd/trunk/src/ped.cpp 2017-05-08 13:41:38 UTC (rev 1025) +++ freesynd/trunk/src/ped.cpp 2017-05-13 11:09:41 UTC (rev 1026) @@ -347,7 +347,7 @@ setDrawnAnim(PedInstance::ad_HitAnim); } else if ((state_ & pa_smHitByLaser) != 0) { setDrawnAnim(PedInstance::ad_VaporizeAnim); - } else if (IS_FLAG_SET(state_, pa_smHitByPersuadotron)) { + } else if (fs_cmn::isBitsOnWithMask(state_, pa_smHitByPersuadotron)) { setDrawnAnim(PedInstance::ad_PersuadedAnim); } #ifdef _DEBUG @@ -634,7 +634,7 @@ void PedInstance::setEnergyActivated(bool isActivated) { if (isActivated) { - SET_FLAG(desc_state_, pd_smShieldProtected); + fs_cmn::setBitsWithMask(&desc_state_, pd_smShieldProtected); } else { desc_state_ &= pd_smAll ^ pd_smShieldProtected; } @@ -1616,7 +1616,7 @@ */ void PedInstance::handlePersuadedBy(PedInstance *pAgent) { pAgent->addPersuaded(this); - SET_FLAG(desc_state_, pd_smControlled); + fs_cmn::setBitsWithMask(&desc_state_, pd_smControlled); setObjGroupID(pAgent->objGroupID()); owner_ = pAgent; setPanicImmuned(); Modified: freesynd/trunk/src/ped.h =================================================================== --- freesynd/trunk/src/ped.h 2017-05-08 13:41:38 UTC (rev 1025) +++ freesynd/trunk/src/ped.h 2017-05-13 11:09:41 UTC (rev 1026) @@ -194,9 +194,9 @@ //! Returns the ped's behaviour Behaviour & behaviour() { return behaviour_; } //! Return true if ped has escaped the map - bool hasEscaped() { return IS_FLAG_SET(desc_state_, pd_smEscaped); } + bool hasEscaped() { return fs_cmn::isBitsOnWithMask(desc_state_, pd_smEscaped); } //! Indicate that the ped has escaped - void escape() { SET_FLAG(desc_state_, pd_smEscaped); } + void escape() { fs_cmn::setBitsWithMask(&desc_state_, pd_smEscaped); } //! Return true if ped don't panic bool isPanicImmuned() { return panicImmuned_; } //! Tells the ped not to panic @@ -364,7 +364,7 @@ void commitSuicide(); //! Return true if ped has activated his energy shield - bool isEnergyShieldActivated() { return IS_FLAG_SET(desc_state_, pd_smShieldProtected); } + bool isEnergyShieldActivated() { return fs_cmn::isBitsOnWithMask(desc_state_, pd_smShieldProtected); } void setEnergyActivated(bool status); //! Return the damage after applying protection of Mod @@ -378,7 +378,7 @@ // Persuasion //************************************* //! Return true if ped is persuaded - bool isPersuaded() { return IS_FLAG_SET(desc_state_, pd_smControlled); } + bool isPersuaded() { return fs_cmn::isBitsOnWithMask(desc_state_, pd_smControlled); } //! Returns true if this ped can persuade that ped bool canPersuade(PedInstance *pOtherPed, const int persuadotronRange); //! Return owner of persuaded @@ -659,7 +659,8 @@ private: inline int getClosestDirs(int dir, int& closest, int& closer); - void buildDestinationPath(Mission *m, std::vector<TilePoint> &cdestpath, int x, int y, int z, int ox, int oy); + void createPath(Mission *m, floodPointDesc *mdpmirror, std::vector<TilePoint> &cdestpath); + void buildFinalDestinationPath(Mission *m, std::vector<TilePoint> &cdestpath, const TilePoint &destinationPt); protected: enum pedDescStateMasks { Modified: freesynd/trunk/src/pedpathfinding.cpp =================================================================== --- freesynd/trunk/src/pedpathfinding.cpp 2017-05-08 13:41:38 UTC (rev 1025) +++ freesynd/trunk/src/pedpathfinding.cpp 2017-05-13 11:09:41 UTC (rev 1026) @@ -29,6 +29,7 @@ #include "ped.h" #include "pathsurfaces.h" #include "gfx/tile.h" +#include "utils/log.h" #if 0 #include "SDL.h" @@ -35,6 +36,15 @@ #define EXECUTION_SPEED_TIME #endif +const uint8 floodPointDesc::kBMaskDirNorth = 0x10; +const uint8 floodPointDesc::kBMaskDirNorthEast = 0x08; +const uint8 floodPointDesc::kBMaskDirEast = 0x04; +const uint8 floodPointDesc::kBMaskDirSouth = 0x01; +const uint8 floodPointDesc::kBMaskDirSouthEast = 0x02; +const uint8 floodPointDesc::kBMaskDirSouthWest = 0x80; +const uint8 floodPointDesc::kBMaskDirWest = 0x40; +const uint8 floodPointDesc::kBMaskDirNorthWest = 0x20; + /*! * Sets a destination point for the ped to reach at given speed. * \param m @@ -42,16 +52,17 @@ * \param newSpeed Speed of movement * \return true if destination has been set correctly. */ -//bool PedInstance::setDestination(Mission *m, const TilePoint &locT, int newSpeed) { bool PedInstance::initMovementToDestination(Mission *m, const TilePoint &destinationPt, int newSpeed) { - // if no speed was set, use ped's default speed - speed_ = newSpeed != -1 ? newSpeed : getDefaultSpeed(); - int x = destinationPt.tx; - int y = destinationPt.ty; - int z = destinationPt.tz; - int ox = destinationPt.ox; - int oy = destinationPt.oy; + dest_path_.clear(); + + if (health_ <= 0) { + return false; + } + + TilePoint clippedDestPt(destinationPt); + m->get_map()->clip(&clippedDestPt); + // NOTE: this is a "flood" algorithm, it expands until it reaches other's // flood point, then it removes unrelated points #ifdef EXECUTION_SPEED_TIME @@ -58,13 +69,9 @@ printf("---------------------------"); printf("start time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000); #endif - m->get_map()->adjXYZ(x, y, z); - dest_path_.clear(); - if (health_ <= 0) - return false; - floodPointDesc *targetd = &(m->mdpoints_[x + y * m->mmax_x_ + z * m->mmax_m_xy]); + floodPointDesc *targetd = &(m->mdpoints_[clippedDestPt.tx + clippedDestPt.ty * m->mmax_x_ + clippedDestPt.tz * m->mmax_m_xy]); floodPointDesc *based = &(m->mdpoints_[pos_.tx + pos_.ty * m->mmax_x_ + pos_.tz * m->mmax_m_xy]); @@ -90,23 +97,23 @@ #endif #endif - //return; if(targetd->t == m_fdNonWalkable) { - printf("==== unwalk target: x %i; y %i; z %i, ox %i, oy %i\n", - x, y, z, ox, oy); - printf("setDestinationP, Movement to nonwalkable postion\n"); + std::string posAsStr; + clippedDestPt.toString(&posAsStr); + LOG(Log::k_FLG_GAME, "PedInstance", "initMovementToDestination", ("Ped %d : Movement to nonwalkable position %s", id_, posAsStr.c_str())); return false; } if(based->t == m_fdNonWalkable) { - printf("==== unwalk pos: x %i; y %i; z %i, ox %i, oy %i, oz %i\n", - pos_.tx, pos_.ty, pos_.tz, pos_.ox, pos_.oy, pos_.oz); - printf("setDestinationP, Movement from nonwalkable postion\n"); + std::string posAsStr; + position().toString(&posAsStr); + LOG(Log::k_FLG_GAME, "PedInstance", "initMovementToDestination", ("Ped %d : Movement from nonwalkable position %s", id_, posAsStr.c_str())); return false; } - if (pos_.tx == x && pos_.ty == y && pos_.tz == z) { - dest_path_.push_back(TilePoint(x, y, z, ox, oy)); + if (sameTile(clippedDestPt)) { + // TODO : check if this case can be removed to follow the regular + // path finding even if costly return false; } #ifdef EXECUTION_SPEED_TIME @@ -138,11 +145,11 @@ sadd.coords.z = pos_.tz; sadd.p = pfdp; bv.push_back(sadd); - pfdp = &(mdpmirror[x + y * m->mmax_x_ + z * m->mmax_m_xy]); + pfdp = &(mdpmirror[clippedDestPt.tx + clippedDestPt.ty * m->mmax_x_ + clippedDestPt.tz * m->mmax_m_xy]); pfdp->t |= (m_fdTargetPoint | m_fdConstant); - sadd.coords.x = x; - sadd.coords.y = y; - sadd.coords.z = z; + sadd.coords.x = clippedDestPt.tx; + sadd.coords.y = clippedDestPt.ty; + sadd.coords.z = clippedDestPt.tz; sadd.p = pfdp; tv.push_back(sadd); // for setting lvls data @@ -1238,35 +1245,66 @@ #ifdef EXECUTION_SPEED_TIME printf("non-related removed time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000); #endif + + // path is created here + std::vector<TilePoint> cdestpath; + cdestpath.reserve(256); + + createPath(m, mdpmirror, cdestpath); + +#ifdef EXECUTION_SPEED_TIME + printf("path creation time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000); +#endif + + // TODO: smoother path + // stairs to surface, surface to stairs correction + if (!cdestpath.empty()) { + buildFinalDestinationPath(m, cdestpath, clippedDestPt); + } + + if (dest_path_.empty()) { + // destination was not set -> stop ped + speed_ = 0; + return false; + } else { + // if no speed was set, use ped's default speed + speed_ = newSpeed != -1 ? newSpeed : getDefaultSpeed(); + return true; + } + #if 0 - bn.clear(); - tn.clear(); - bv.clear(); - tv.clear(); + for (std::list <TilePoint>::iterator it = dest_path_.begin(); + it != dest_path_.end(); ++it) { + printf("x %i, y %i, z %i\n", it->tileX(),it->tileY(),it->tileZ()); + } #endif +#ifdef EXECUTION_SPEED_TIME + dest_path_.clear(); + printf("+++++++++++++++++++++++++++"); + printf("end time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000); +#endif +} - // path is created here - WorldPoint ctile; - ctile.x = pos_.tx; - ctile.y = pos_.ty; - ctile.z = pos_.tz; +void PedInstance::createPath(Mission *m, floodPointDesc *mdpmirror, std::vector<TilePoint> &pathToDestination) { + TilePoint currentTile(pos_.tx, pos_.ty, pos_.tz); unsigned char ct = m_fdBasePoint; bool tnr = true, np = true; - std::vector<TilePoint> cdestpath; - cdestpath.reserve(256); + floodPointDesc *pfdp; + toSetDesc sadd; + do { unsigned char nt = ct; + char dist = 5; WorldPoint toadd; - char dist = 5; - pfdp = &(mdpmirror[ctile.x + ctile.y * m->mmax_x_ - + ctile.z * m->mmax_m_xy]); + pfdp = &(mdpmirror[currentTile.tx + currentTile.ty * m->mmax_x_ + + currentTile.tz * m->mmax_m_xy]); uint16 lvl_child = ct == m_fdBasePoint ? pfdp->lvl + 1 : pfdp->lvl - 1; if (pfdp->dirh != 0) { - if ((pfdp->dirh & 0x01) == 0x01) { - sadd.coords.x = ctile.x; - sadd.coords.y = ctile.y + 1; - sadd.coords.z = ctile.z + 1; + if (pfdp->isDirectionUpContains(floodPointDesc::kBMaskDirSouth)) { + sadd.coords.x = currentTile.tx; + sadd.coords.y = currentTile.ty + 1; + sadd.coords.z = currentTile.tz + 1; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1287,10 +1325,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirh & 0x04) == 0x04) { - sadd.coords.x = ctile.x + 1; - sadd.coords.y = ctile.y; - sadd.coords.z = ctile.z + 1; + if (pfdp->isDirectionUpContains(floodPointDesc::kBMaskDirEast)) { + sadd.coords.x = currentTile.tx + 1; + sadd.coords.y = currentTile.ty; + sadd.coords.z = currentTile.tz + 1; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1311,10 +1349,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirh & 0x10) == 0x10) { - sadd.coords.x = ctile.x; - sadd.coords.y = ctile.y - 1; - sadd.coords.z = ctile.z + 1; + if (pfdp->isDirectionUpContains(floodPointDesc::kBMaskDirNorth)) { + sadd.coords.x = currentTile.tx; + sadd.coords.y = currentTile.ty - 1; + sadd.coords.z = currentTile.tz + 1; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1335,10 +1373,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirh & 0x40) == 0x40) { - sadd.coords.x = ctile.x - 1; - sadd.coords.y = ctile.y; - sadd.coords.z = ctile.z + 1; + if (pfdp->isDirectionUpContains(floodPointDesc::kBMaskDirWest)) { + sadd.coords.x = currentTile.tx - 1; + sadd.coords.y = currentTile.ty; + sadd.coords.z = currentTile.tz + 1; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1361,10 +1399,10 @@ } } if (pfdp->dirl != 0) { - if ((pfdp->dirl & 0x01) == 0x01) { - sadd.coords.x = ctile.x; - sadd.coords.y = ctile.y + 1; - sadd.coords.z = ctile.z - 1; + if (pfdp->isDirectionDownContains(floodPointDesc::kBMaskDirSouth)) { + sadd.coords.x = currentTile.tx; + sadd.coords.y = currentTile.ty + 1; + sadd.coords.z = currentTile.tz - 1; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1385,10 +1423,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirl & 0x04) == 0x04) { - sadd.coords.x = ctile.x + 1; - sadd.coords.y = ctile.y; - sadd.coords.z = ctile.z - 1; + if (pfdp->isDirectionDownContains(floodPointDesc::kBMaskDirEast)) { + sadd.coords.x = currentTile.tx + 1; + sadd.coords.y = currentTile.ty; + sadd.coords.z = currentTile.tz - 1; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1409,10 +1447,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirl & 0x10) == 0x10) { - sadd.coords.x = ctile.x; - sadd.coords.y = ctile.y - 1; - sadd.coords.z = ctile.z - 1; + if (pfdp->isDirectionDownContains(floodPointDesc::kBMaskDirNorth)) { + sadd.coords.x = currentTile.tx; + sadd.coords.y = currentTile.ty - 1; + sadd.coords.z = currentTile.tz - 1; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1433,10 +1471,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirl & 0x40) == 0x40) { - sadd.coords.x = ctile.x - 1; - sadd.coords.y = ctile.y; - sadd.coords.z = ctile.z - 1; + if (pfdp->isDirectionDownContains(floodPointDesc::kBMaskDirWest)) { + sadd.coords.x = currentTile.tx - 1; + sadd.coords.y = currentTile.ty; + sadd.coords.z = currentTile.tz - 1; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1459,10 +1497,10 @@ } } if (pfdp->dirm != 0) { - if ((pfdp->dirm & 0x01) == 0x01) { - sadd.coords.x = ctile.x; - sadd.coords.y = ctile.y + 1; - sadd.coords.z = ctile.z; + if (pfdp->isDirectionGroundContains(floodPointDesc::kBMaskDirSouth)) { + sadd.coords.x = currentTile.tx; + sadd.coords.y = currentTile.ty + 1; + sadd.coords.z = currentTile.tz; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1504,10 +1542,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirm & 0x02) == 0x02) { - sadd.coords.x = ctile.x + 1; - sadd.coords.y = ctile.y + 1; - sadd.coords.z = ctile.z; + if (pfdp->isDirectionGroundContains(floodPointDesc::kBMaskDirSouthEast)) { + sadd.coords.x = currentTile.tx + 1; + sadd.coords.y = currentTile.ty + 1; + sadd.coords.z = currentTile.tz; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1528,10 +1566,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirm & 0x04) == 0x04) { - sadd.coords.x = ctile.x + 1; - sadd.coords.y = ctile.y; - sadd.coords.z = ctile.z; + if (pfdp->isDirectionGroundContains(floodPointDesc::kBMaskDirEast)) { + sadd.coords.x = currentTile.tx + 1; + sadd.coords.y = currentTile.ty; + sadd.coords.z = currentTile.tz; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1573,10 +1611,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirm & 0x08) == 0x08) { - sadd.coords.x = ctile.x + 1; - sadd.coords.y = ctile.y - 1; - sadd.coords.z = ctile.z; + if (pfdp->isDirectionGroundContains(floodPointDesc::kBMaskDirNorthEast)) { + sadd.coords.x = currentTile.tx + 1; + sadd.coords.y = currentTile.ty - 1; + sadd.coords.z = currentTile.tz; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1597,10 +1635,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirm & 0x10) == 0x10) { - sadd.coords.x = ctile.x; - sadd.coords.y = ctile.y - 1; - sadd.coords.z = ctile.z; + if (pfdp->isDirectionGroundContains(floodPointDesc::kBMaskDirNorth)) { + sadd.coords.x = currentTile.tx; + sadd.coords.y = currentTile.ty - 1; + sadd.coords.z = currentTile.tz; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1642,10 +1680,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirm & 0x20) == 0x20) { - sadd.coords.x = ctile.x - 1; - sadd.coords.y = ctile.y - 1; - sadd.coords.z = ctile.z; + if (pfdp->isDirectionGroundContains(floodPointDesc::kBMaskDirNorthWest)) { + sadd.coords.x = currentTile.tx - 1; + sadd.coords.y = currentTile.ty - 1; + sadd.coords.z = currentTile.tz; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1666,10 +1704,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirm & 0x40) == 0x40) { - sadd.coords.x = ctile.x - 1; - sadd.coords.y = ctile.y; - sadd.coords.z = ctile.z; + if (pfdp->isDirectionGroundContains(floodPointDesc::kBMaskDirWest)) { + sadd.coords.x = currentTile.tx - 1; + sadd.coords.y = currentTile.ty; + sadd.coords.z = currentTile.tz; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1711,10 +1749,10 @@ if ((sadd.p->t & m_fdConstant) != 0) tnr = false; } - if ((pfdp->dirm & 0x80) == 0x80) { - sadd.coords.x = ctile.x - 1; - sadd.coords.y = ctile.y + 1; - sadd.coords.z = ctile.z; + if (pfdp->isDirectionGroundContains(floodPointDesc::kBMaskDirSouthWest)) { + sadd.coords.x = currentTile.tx - 1; + sadd.coords.y = currentTile.ty + 1; + sadd.coords.z = currentTile.tz; sadd.p = &(mdpmirror[sadd.coords.x + sadd.coords.y * m->mmax_x_ + sadd.coords.z * m->mmax_m_xy]); @@ -1740,50 +1778,17 @@ np = false; ct = nt; } - cdestpath.push_back(TilePoint(toadd.x, toadd.y, toadd.z)); + pathToDestination.push_back(TilePoint(toadd.x, toadd.y, toadd.z)); // this assert might save from memory fill up, - assert(ctile.x != toadd.x || ctile.y != toadd.y || ctile.z != toadd.z); - //if(toadd.x == 49 && toadd.y == 86 && toadd.z == 1) - //toadd.x = 49; - //if(ctile.x == toadd.x && ctile.y == toadd.y && ctile.z == toadd.z) - //ctile = toadd; - ctile = toadd; + assert(currentTile.tx != toadd.x || currentTile.ty != toadd.y || currentTile.tz != toadd.z); + + currentTile.tx = toadd.x; + currentTile.ty = toadd.y; + currentTile.tz = toadd.z; } while (tnr); -#ifdef EXECUTION_SPEED_TIME - printf("path creation time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000); -#endif - - // TODO: smoother path - // stairs to surface, surface to stairs correction - if (!cdestpath.empty()) { - buildDestinationPath(m, cdestpath, x, y, z, ox, oy); - } - - if (dest_path_.empty()) { - // destination was not set -> stop ped - speed_ = 0; - return false; - } else { - return true; - } -#ifdef EXECUTION_SPEED_TIME - printf("smoothing time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000); -#endif - -#if 0 - for (std::list <TilePoint>::iterator it = dest_path_.begin(); - it != dest_path_.end(); ++it) { - printf("x %i, y %i, z %i\n", it->tileX(),it->tileY(),it->tileZ()); - } -#endif -#ifdef EXECUTION_SPEED_TIME - dest_path_.clear(); - printf("+++++++++++++++++++++++++++"); - printf("end time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000); -#endif } -void PedInstance::buildDestinationPath(Mission *m, std::vector<TilePoint> &cdestpath, int x, int y, int z, int ox, int oy) { +void PedInstance::buildFinalDestinationPath(Mission *m, std::vector<TilePoint> &cdestpath, const TilePoint &destinationPt) { TilePoint prvpn = TilePoint(pos_.tx, pos_.ty, pos_.tz, pos_.ox, pos_.oy); for (std::vector <TilePoint>::iterator it = cdestpath.begin(); it != cdestpath.end(); ++it) { @@ -2261,38 +2266,42 @@ dest_path_.push_back(*it); } } - prvpn = *it; - if (fit == cdestpath.end()) { - if (modified) { - dest_path_.push_back(TilePoint(x,y,z,ox,oy)); - } else { - // untill correct smoothing implemented this - // will prevent walking on non-walkable tile - if (xf == -1 && yf == -1) { - dest_path_.back().ox = 0; - dest_path_.back().oy = 0; - dest_path_.push_back(prvpn); - } - if (xf == 1 && yf == -1) { - dest_path_.back().ox = 255; - dest_path_.back().oy = 0; - dest_path_.push_back(prvpn); - } - if (xf == 1 && yf == 1) { - dest_path_.back().ox = 255; - dest_path_.back().oy = 255; - dest_path_.push_back(prvpn); - } - if (xf == -1 && yf == 1) { - dest_path_.back().ox = 0; - dest_path_.back().oy = 255; - dest_path_.push_back(prvpn); - } - dest_path_.back().ox = ox; - dest_path_.back().oy = oy; + prvpn = *it; + if (fit == cdestpath.end()) { + if (modified) { + dest_path_.push_back(TilePoint(destinationPt)); + } else { + // untill correct smoothing implemented this + // will prevent walking on non-walkable tile + if (xf == -1 && yf == -1) { + dest_path_.back().ox = 0; + dest_path_.back().oy = 0; + dest_path_.push_back(prvpn); } + if (xf == 1 && yf == -1) { + dest_path_.back().ox = 255; + dest_path_.back().oy = 0; + dest_path_.push_back(prvpn); + } + if (xf == 1 && yf == 1) { + dest_path_.back().ox = 255; + dest_path_.back().oy = 255; + dest_path_.push_back(prvpn); + } + if (xf == -1 && yf == 1) { + dest_path_.back().ox = 0; + dest_path_.back().oy = 255; + dest_path_.push_back(prvpn); + } + dest_path_.back().ox = destinationPt.ox; + dest_path_.back().oy = destinationPt.oy; } } + } + +#ifdef EXECUTION_SPEED_TIME + printf("smoothing time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000); +#endif } bool PedInstance::doMove(int elapsed, Mission *pMission) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |