1 /************************************************************************
2  *                                                                      *
3  *  FreeSynd - a remake of the classic Bullfrog game "Syndicate".       *
4  *                                                                      *
5  *   Copyright (C) 2005  Stuart Binge  <skbinge@gmail.com>              *
6  *   Copyright (C) 2005  Joost Peters  <joostp@users.sourceforge.net>   *
7  *   Copyright (C) 2006  Trent Waddington <qg@biodome.org>              *
8  *   Copyright (C) 2006  Tarjei Knapstad <tarjei.knapstad@gmail.com>    *
9  *   Copyright (C) 2010  Bohdan Stelmakh <chamel@users.sourceforge.net> *
10  *                                                                      *
11  *    This program is free software;  you can redistribute it and / or  *
12  *  modify it  under the  terms of the  GNU General  Public License as  *
13  *  published by the Free Software Foundation; either version 2 of the  *
14  *  License, or (at your option) any later version.                     *
15  *                                                                      *
16  *    This program is  distributed in the hope that it will be useful,  *
17  *  but WITHOUT  ANY WARRANTY;  without even  the implied  warranty of  *
18  *  MERCHANTABILITY  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  *
19  *  General Public License for more details.                            *
20  *                                                                      *
21  *    You can view the GNU  General Public License, online, at the GNU  *
22  *  project's  web  site;  see <http://www.gnu.org/licenses/gpl.html>.  *
23  *  The full text of the license is also included in the file COPYING.  *
24  *                                                                      *
25  ************************************************************************/
26 
27 #include "common.h"
28 #include "mission.h"
29 #include "ped.h"
30 #include "pathsurfaces.h"
31 
32 #if 0
33 #include "SDL.h"
34 #define EXECUTION_SPEED_TIME
35 #endif
36 
37 /*!
38  * Sets a destination point for the ped to reach at given speed.
39  * \param m
40  * \param node destination point
41  * \param newSpeed Speed of movement
42  * \return true if destination has been set correctly.
43  */
setDestination(Mission * m,const TilePoint & locT,int newSpeed)44 bool PedInstance::setDestination(Mission *m, const TilePoint &locT, int newSpeed) {
45     // if no speed was set, use ped's default speed
46     speed_ = newSpeed != -1 ? newSpeed : getDefaultSpeed();
47     setDestinationP(m, locT.tx, locT.ty, locT.tz, locT.ox, locT.oy);
48     if (dest_path_.empty()) {
49         // destination was not set -> stop ped
50         speed_ = 0;
51         return false;
52     } else {
53         return true;
54     }
55 }
56 
setDestinationP(Mission * m,int x,int y,int z,int ox,int oy)57 void PedInstance::setDestinationP(Mission *m, int x, int y, int z,
58                                     int ox, int oy)
59 {
60     // NOTE: this is a "flood" algorithm, it expands until it reaches other's
61     // flood point, then it removes unrelated points
62 #ifdef EXECUTION_SPEED_TIME
63     printf("---------------------------");
64     printf("start time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
65 #endif
66     m->get_map()->adjXYZ(x, y, z);
67     dest_path_.clear();
68 
69     if (map_ == -1 || health_ <= 0)
70         return;
71 
72     floodPointDesc *targetd = &(m->mdpoints_[x + y * m->mmax_x_ + z * m->mmax_m_xy]);
73 
74     floodPointDesc *based = &(m->mdpoints_[pos_.tx
75         + pos_.ty * m->mmax_x_ + pos_.tz * m->mmax_m_xy]);
76 
77 #if 0
78 #if _DEBUG
79     printf("target t %x, dirm %x ; base t %x, dirm %x\n", targetd->t,
80         targetd->dirm, based->t, based->dirm);
81     printf("target dirh %x, dirl %x ; base dirh %x, dirl %x\n", targetd->dirh,
82         targetd->dirl, based->dirh, based->dirl);
83     printf("ttwd %X \n",m->mtsurfaces_[x + y * m->mmax_x_
84         + z * m->mmax_m_xy].twd);
85     printf("target pos: x %i; y %i; z %i, ox %i, oy %i\n",
86         x, y, z, ox, oy);
87     //printf("tileAt %x\n", g_App.maps().map(map())->tileAt(x,y,z));
88     printf("base pos: x %i; y %i; z %i, ox %i, oy %i, oz %i\n",
89         pos_.tx, pos_.ty, pos_.tz, pos_.ox, pos_.oy, pos_.oz);
90     printf("zmax %x\n", m->mmax_z_);
91     if ((z - 1)>= 0) {
92         printf("lower twd %i\n", m->mtsurfaces_[x + y * m->mmax_x_
93             + (z - 1) * m->mmax_m_xy].twd);
94     }
95 #endif
96 #endif
97 
98     //return;
99     if(targetd->t == m_fdNonWalkable || map_ == -1 || health_ <= 0) {
100         printf("==== unwalk target: x %i; y %i; z %i, ox %i, oy %i\n",
101             x, y, z, ox, oy);
102         printf("setDestinationP, Movement to nonwalkable postion\n");
103         return;
104     }
105 
106     if(based->t == m_fdNonWalkable) {
107         printf("==== unwalk pos: x %i; y %i; z %i, ox %i, oy %i, oz %i\n",
108             pos_.tx, pos_.ty, pos_.tz, pos_.ox, pos_.oy, pos_.oz);
109         printf("setDestinationP, Movement from nonwalkable postion\n");
110         return;
111     }
112 
113     if (pos_.tx == x && pos_.ty == y && pos_.tz == z) {
114         dest_path_.push_back(TilePoint(x, y, z, ox, oy));
115         return;
116     }
117 #ifdef EXECUTION_SPEED_TIME
118     printf("directions-map copy start %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
119 #endif
120     floodPointDesc *mdpmirror = m->mdpoints_cp_;
121     memcpy((void *)mdpmirror, (void *)m->mdpoints_,
122         m->mmax_m_all * sizeof(floodPointDesc));
123 
124 #ifdef EXECUTION_SPEED_TIME
125     printf("directions-map copy complete %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
126 #endif
127 
128     unsigned char lt;
129     unsigned short blvl = 0, tlvl = 0;
130     // these are all tiles that belong to base and target
131     std::vector <toSetDesc> bv;
132     std::vector <toSetDesc> tv;
133     bv.reserve(8192);
134     tv.reserve(8192);
135     // these are used for setting values through algorithm
136     toSetDesc sadd;
137     floodPointDesc *pfdp;
138     // setup
139     pfdp = &(mdpmirror[pos_.tx + pos_.ty * m->mmax_x_ + pos_.tz * m->mmax_m_xy]);
140     pfdp->t |= m_fdBasePoint;
141     sadd.coords.x = pos_.tx;
142     sadd.coords.y = pos_.ty;
143     sadd.coords.z = pos_.tz;
144     sadd.p = pfdp;
145     bv.push_back(sadd);
146     pfdp = &(mdpmirror[x + y * m->mmax_x_ + z * m->mmax_m_xy]);
147     pfdp->t |= (m_fdTargetPoint | m_fdConstant);
148     sadd.coords.x = x;
149     sadd.coords.y = y;
150     sadd.coords.z = z;
151     sadd.p = pfdp;
152     tv.push_back(sadd);
153     // for setting lvls data
154     lvlNodesDesc ladd;
155     ladd.indxs = 0;
156     ladd.n = 1;
157     // these are number of nodes per lvl and index start for "bv" and "tv"
158     std::vector <lvlNodesDesc> bn;
159     std::vector <lvlNodesDesc> tn;
160     bn.reserve(512);
161     tn.reserve(512);
162     bn.push_back(ladd);
163     tn.push_back(ladd);
164     bool nodeset, lnknr = true;
165 #ifdef EXECUTION_SPEED_TIME
166     printf("data allocation/setup complete %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
167 #endif
168 
169 #ifdef FIND_DEFINED_TILE
170     bool assertion_bool = true;
171     int x_check = 48, y_check = 23, z_check = 6;
172 #endif
173     do {
174         unsigned short mindx = bn[blvl].indxs + bn[blvl].n;
175         unsigned short nlvl = blvl + 1;
176         unsigned int cindx = 0;
177         for (unsigned short i = bn[blvl].indxs; i < mindx; ++i) {
178             toSetDesc bref = bv[i];
179             cindx = bref.coords.x + bref.coords.y * m->mmax_x_
180                 + bref.coords.z * m->mmax_m_xy;
181             if (bref.p->dirh != 0) {
182                 if ((bref.p->dirh & 0x01) == 0x01) {
183                     sadd.p = &(mdpmirror[cindx + m->mmax_x_ + m->mmax_m_xy]);
184                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
185                         sadd.coords.x = bref.coords.x;
186                         sadd.coords.y = bref.coords.y + 1;
187                         sadd.coords.z = bref.coords.z + 1;
188 #ifdef FIND_DEFINED_TILE
189                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
190                             && sadd.coords.z == z_check)
191                             assert(assertion_bool);
192 #endif
193                         sadd.p->lvl = nlvl;
194                         sadd.p->t |= m_fdBasePoint;
195                         bv.push_back(sadd);
196                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
197                         bref.p->t |= m_fdLink;
198                         sadd.p->t |= m_fdLink;
199                         lt = m_fdBasePoint;
200                         lnknr = false;
201                     }
202                 }
203                 if ((bref.p->dirh & 0x04) == 0x04) {
204                     sadd.p = &(mdpmirror[cindx + 1 + m->mmax_m_xy]);
205                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
206                         sadd.coords.x = bref.coords.x + 1;
207                         sadd.coords.y = bref.coords.y;
208                         sadd.coords.z = bref.coords.z + 1;
209 #ifdef FIND_DEFINED_TILE
210                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
211                             && sadd.coords.z == z_check)
212                             assert(assertion_bool);
213 #endif
214                         sadd.p->lvl = nlvl;
215                         sadd.p->t |= m_fdBasePoint;
216                         bv.push_back(sadd);
217                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
218                         bref.p->t |= m_fdLink;
219                         sadd.p->t |= m_fdLink;
220                         lt = m_fdBasePoint;
221                         lnknr = false;
222                     }
223                 }
224                 if ((bref.p->dirh & 0x10) == 0x10) {
225                     sadd.p = &(mdpmirror[cindx - m->mmax_x_ + m->mmax_m_xy]);
226                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
227                         sadd.coords.x = bref.coords.x;
228                         sadd.coords.y = bref.coords.y - 1;
229                         sadd.coords.z = bref.coords.z + 1;
230 #ifdef FIND_DEFINED_TILE
231                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
232                             && sadd.coords.z == z_check)
233                             assert(assertion_bool);
234 #endif
235                         sadd.p->lvl = nlvl;
236                         sadd.p->t |= m_fdBasePoint;
237                         bv.push_back(sadd);
238                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
239                         bref.p->t |= m_fdLink;
240                         sadd.p->t |= m_fdLink;
241                         lt = m_fdBasePoint;
242                         lnknr = false;
243                     }
244                 }
245                 if ((bref.p->dirh & 0x40) == 0x40) {
246                     sadd.p = &(mdpmirror[cindx - 1 + m->mmax_m_xy]);
247                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
248                         sadd.coords.x = bref.coords.x - 1;
249                         sadd.coords.y = bref.coords.y;
250                         sadd.coords.z = bref.coords.z + 1;
251 #ifdef FIND_DEFINED_TILE
252                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
253                             && sadd.coords.z == z_check)
254                             assert(assertion_bool);
255 #endif
256                         sadd.p->lvl = nlvl;
257                         sadd.p->t |= m_fdBasePoint;
258                         bv.push_back(sadd);
259                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
260                         bref.p->t |= m_fdLink;
261                         sadd.p->t |= m_fdLink;
262                         lt = m_fdBasePoint;
263                         lnknr = false;
264                     }
265                 }
266             }
267             if (bref.p->dirl != 0) {
268                 if ((bref.p->dirl & 0x01) == 0x01) {
269                     sadd.p = &(mdpmirror[cindx + m->mmax_x_ - m->mmax_m_xy]);
270                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
271                         sadd.coords.x = bref.coords.x;
272                         sadd.coords.y = bref.coords.y + 1;
273                         sadd.coords.z = bref.coords.z - 1;
274 #ifdef FIND_DEFINED_TILE
275                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
276                             && sadd.coords.z == z_check)
277                             assert(assertion_bool);
278 #endif
279                         sadd.p->lvl = nlvl;
280                         sadd.p->t |= m_fdBasePoint;
281                         bv.push_back(sadd);
282                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
283                         bref.p->t |= m_fdLink;
284                         sadd.p->t |= m_fdLink;
285                         lt = m_fdBasePoint;
286                         lnknr = false;
287                     }
288                 }
289                 if ((bref.p->dirl & 0x04) == 0x04) {
290                     sadd.p = &(mdpmirror[cindx + 1 - m->mmax_m_xy]);
291                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
292                         sadd.coords.x = bref.coords.x + 1;
293                         sadd.coords.y = bref.coords.y;
294                         sadd.coords.z = bref.coords.z - 1;
295 #ifdef FIND_DEFINED_TILE
296                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
297                             && sadd.coords.z == z_check)
298                             assert(assertion_bool);
299 #endif
300                         sadd.p->lvl = nlvl;
301                         sadd.p->t |= m_fdBasePoint;
302                         bv.push_back(sadd);
303                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
304                         bref.p->t |= m_fdLink;
305                         sadd.p->t |= m_fdLink;
306                         lt = m_fdBasePoint;
307                         lnknr = false;
308                     }
309                 }
310                 if ((bref.p->dirl & 0x10) == 0x10) {
311                     sadd.p = &(mdpmirror[cindx - m->mmax_x_ - m->mmax_m_xy]);
312                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
313                         sadd.coords.x = bref.coords.x;
314                         sadd.coords.y = bref.coords.y - 1;
315                         sadd.coords.z = bref.coords.z - 1;
316 #ifdef FIND_DEFINED_TILE
317                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
318                             && sadd.coords.z == z_check)
319                             assert(assertion_bool);
320 #endif
321                         sadd.p->lvl = nlvl;
322                         sadd.p->t |= m_fdBasePoint;
323                         bv.push_back(sadd);
324                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
325                         bref.p->t |= m_fdLink;
326                         sadd.p->t |= m_fdLink;
327                         lt = m_fdBasePoint;
328                         lnknr = false;
329                     }
330                 }
331                 if ((bref.p->dirl & 0x40) == 0x40) {
332                     sadd.p = &(mdpmirror[cindx - 1 - m->mmax_m_xy]);
333                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
334                         sadd.coords.x = bref.coords.x - 1;
335                         sadd.coords.y = bref.coords.y;
336                         sadd.coords.z = bref.coords.z - 1;
337 #ifdef FIND_DEFINED_TILE
338                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
339                             && sadd.coords.z == z_check)
340                             assert(assertion_bool);
341 #endif
342                         sadd.p->lvl = nlvl;
343                         sadd.p->t |= m_fdBasePoint;
344                         bv.push_back(sadd);
345                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
346                         bref.p->t |= m_fdLink;
347                         sadd.p->t |= m_fdLink;
348                         lt = m_fdBasePoint;
349                         lnknr = false;
350                     }
351                 }
352             }
353             if (bref.p->dirm != 0) {
354                 if ((bref.p->dirm & 0x01) == 0x01) {
355                     sadd.p = &(mdpmirror[cindx + m->mmax_x_]);
356                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
357                         sadd.coords.x = bref.coords.x;
358                         sadd.coords.y = bref.coords.y + 1;
359                         sadd.coords.z = bref.coords.z;
360 #ifdef FIND_DEFINED_TILE
361                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
362                             && sadd.coords.z == z_check)
363                             assert(assertion_bool);
364 #endif
365                         sadd.p->lvl = nlvl;
366                         sadd.p->t |= m_fdBasePoint;
367                         bv.push_back(sadd);
368                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
369                         bref.p->t |= m_fdLink;
370                         sadd.p->t |= m_fdLink;
371                         lt = m_fdBasePoint;
372                         lnknr = false;
373                     }
374                 }
375                 if ((bref.p->dirm & 0x02) == 0x02) {
376                     sadd.p = &(mdpmirror[cindx + 1 + m->mmax_x_]);
377                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
378                         sadd.coords.x = bref.coords.x + 1;
379                         sadd.coords.y = bref.coords.y + 1;
380                         sadd.coords.z = bref.coords.z;
381 #ifdef FIND_DEFINED_TILE
382                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
383                             && sadd.coords.z == z_check)
384                             assert(assertion_bool);
385 #endif
386                         sadd.p->lvl = nlvl;
387                         sadd.p->t |= m_fdBasePoint;
388                         bv.push_back(sadd);
389                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
390                         bref.p->t |= m_fdLink;
391                         sadd.p->t |= m_fdLink;
392                         lt = m_fdBasePoint;
393                         lnknr = false;
394                     }
395                 }
396                 if ((bref.p->dirm & 0x04) == 0x04) {
397                     sadd.p = &(mdpmirror[cindx + 1]);
398                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
399                         sadd.coords.x = bref.coords.x + 1;
400                         sadd.coords.y = bref.coords.y;
401                         sadd.coords.z = bref.coords.z;
402 #ifdef FIND_DEFINED_TILE
403                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
404                             && sadd.coords.z == z_check)
405                             assert(assertion_bool);
406 #endif
407                         sadd.p->lvl = nlvl;
408                         sadd.p->t |= m_fdBasePoint;
409                         bv.push_back(sadd);
410                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
411                         bref.p->t |= m_fdLink;
412                         sadd.p->t |= m_fdLink;
413                         lt = m_fdBasePoint;
414                         lnknr = false;
415                     }
416                 }
417                 if ((bref.p->dirm & 0x08) == 0x08) {
418                     sadd.p = &(mdpmirror[cindx + 1 - m->mmax_x_]);
419                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
420                         sadd.coords.x = bref.coords.x + 1;
421                         sadd.coords.y = bref.coords.y - 1;
422                         sadd.coords.z = bref.coords.z;
423 #ifdef FIND_DEFINED_TILE
424                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
425                             && sadd.coords.z == z_check)
426                             assert(assertion_bool);
427 #endif
428                         sadd.p->lvl = nlvl;
429                         sadd.p->t |= m_fdBasePoint;
430                         bv.push_back(sadd);
431                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
432                         bref.p->t |= m_fdLink;
433                         sadd.p->t |= m_fdLink;
434                         lt = m_fdBasePoint;
435                         lnknr = false;
436                     }
437                 }
438                 if ((bref.p->dirm & 0x10) == 0x10) {
439                     sadd.p = &(mdpmirror[cindx - m->mmax_x_]);
440                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
441                         sadd.coords.x = bref.coords.x;
442                         sadd.coords.y = bref.coords.y - 1;
443                         sadd.coords.z = bref.coords.z;
444 #ifdef FIND_DEFINED_TILE
445                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
446                             && sadd.coords.z == z_check)
447                             assert(assertion_bool);
448 #endif
449                         sadd.p->lvl = nlvl;
450                         sadd.p->t |= m_fdBasePoint;
451                         bv.push_back(sadd);
452                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
453                         bref.p->t |= m_fdLink;
454                         sadd.p->t |= m_fdLink;
455                         lt = m_fdBasePoint;
456                         lnknr = false;
457                     }
458                 }
459                 if ((bref.p->dirm & 0x20) == 0x20) {
460                     sadd.p = &(mdpmirror[cindx - 1 - m->mmax_x_]);
461                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
462                         sadd.coords.x = bref.coords.x - 1;
463                         sadd.coords.y = bref.coords.y - 1;
464                         sadd.coords.z = bref.coords.z;
465 #ifdef FIND_DEFINED_TILE
466                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
467                             && sadd.coords.z == z_check)
468                             assert(assertion_bool);
469 #endif
470                         sadd.p->lvl = nlvl;
471                         sadd.p->t |= m_fdBasePoint;
472                         bv.push_back(sadd);
473                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
474                         bref.p->t |= m_fdLink;
475                         sadd.p->t |= m_fdLink;
476                         lt = m_fdBasePoint;
477                         lnknr = false;
478                     }
479                 }
480                 if ((bref.p->dirm & 0x40) == 0x40) {
481                     sadd.p = &(mdpmirror[cindx - 1]);
482                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
483                         sadd.coords.x = bref.coords.x - 1;
484                         sadd.coords.y = bref.coords.y;
485                         sadd.coords.z = bref.coords.z;
486 #ifdef FIND_DEFINED_TILE
487                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
488                             && sadd.coords.z == z_check)
489                             assert(assertion_bool);
490 #endif
491                         sadd.p->lvl = nlvl;
492                         sadd.p->t |= m_fdBasePoint;
493                         bv.push_back(sadd);
494                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
495                         bref.p->t |= m_fdLink;
496                         sadd.p->t |= m_fdLink;
497                         lt = m_fdBasePoint;
498                         lnknr = false;
499                     }
500                 }
501                 if ((bref.p->dirm & 0x80) == 0x80) {
502                     sadd.p = &(mdpmirror[cindx - 1 + m->mmax_x_]);
503                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
504                         sadd.coords.x = bref.coords.x - 1;
505                         sadd.coords.y = bref.coords.y + 1;
506                         sadd.coords.z = bref.coords.z;
507 #ifdef FIND_DEFINED_TILE
508                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
509                             && sadd.coords.z == z_check)
510                             assert(assertion_bool);
511 #endif
512                         sadd.p->lvl = nlvl;
513                         sadd.p->t |= m_fdBasePoint;
514                         bv.push_back(sadd);
515                     } else if ((sadd.p->t & m_fdTargetPoint) != 0){
516                         bref.p->t |= m_fdLink;
517                         sadd.p->t |= m_fdLink;
518                         lt = m_fdBasePoint;
519                         lnknr = false;
520                     }
521                 }
522             }
523         }
524         ladd.indxs = mindx;
525         ladd.n = bv.size() - mindx;
526         if (ladd.n > 0) {
527             nodeset = true;
528             bn.push_back(ladd);
529             ++blvl;
530         } else {
531             nodeset = false;
532             break;
533         }
534         if (!lnknr)
535             break;
536 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
537         mindx = tn[tlvl].indxs + tn[tlvl].n;
538         nlvl = tlvl + 1;
539         for (unsigned short i = tn[tlvl].indxs; i < mindx; ++i) {
540             toSetDesc bref = tv[i];
541             cindx = bref.coords.x + bref.coords.y * m->mmax_x_
542                 + bref.coords.z * m->mmax_m_xy;
543             if (bref.p->dirh != 0) {
544                 if ((bref.p->dirh & 0x01) == 0x01) {
545                     sadd.p = &(mdpmirror[cindx + m->mmax_x_ + m->mmax_m_xy]);
546                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
547                         sadd.coords.x = bref.coords.x;
548                         sadd.coords.y = bref.coords.y + 1;
549                         sadd.coords.z = bref.coords.z + 1;
550 #ifdef FIND_DEFINED_TILE
551                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
552                             && sadd.coords.z == z_check)
553                             assert(assertion_bool);
554 #endif
555                         sadd.p->lvl = nlvl;
556                         sadd.p->t |= m_fdTargetPoint;
557                         tv.push_back(sadd);
558                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
559                         bref.p->t |= m_fdLink;
560                         sadd.p->t |= m_fdLink;
561                         lt = m_fdTargetPoint;
562                         lnknr = false;
563                     }
564                 }
565                 if ((bref.p->dirh & 0x04) == 0x04) {
566                     sadd.p = &(mdpmirror[cindx + 1 + m->mmax_m_xy]);
567                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
568                         sadd.coords.x = bref.coords.x + 1;
569                         sadd.coords.y = bref.coords.y;
570                         sadd.coords.z = bref.coords.z + 1;
571 #ifdef FIND_DEFINED_TILE
572                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
573                             && sadd.coords.z == z_check)
574                             assert(assertion_bool);
575 #endif
576                         sadd.p->lvl = nlvl;
577                         sadd.p->t |= m_fdTargetPoint;
578                         tv.push_back(sadd);
579                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
580                         bref.p->t |= m_fdLink;
581                         sadd.p->t |= m_fdLink;
582                         lt = m_fdTargetPoint;
583                         lnknr = false;
584                     }
585                 }
586                 if ((bref.p->dirh & 0x10) == 0x10) {
587                     sadd.p = &(mdpmirror[cindx - m->mmax_x_ + m->mmax_m_xy]);
588                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
589                         sadd.coords.x = bref.coords.x;
590                         sadd.coords.y = bref.coords.y - 1;
591                         sadd.coords.z = bref.coords.z + 1;
592 #ifdef FIND_DEFINED_TILE
593                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
594                             && sadd.coords.z == z_check)
595                             assert(assertion_bool);
596 #endif
597                         sadd.p->lvl = nlvl;
598                         sadd.p->t |= m_fdTargetPoint;
599                         tv.push_back(sadd);
600                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
601                         bref.p->t |= m_fdLink;
602                         sadd.p->t |= m_fdLink;
603                         lt = m_fdTargetPoint;
604                         lnknr = false;
605                     }
606                 }
607                 if ((bref.p->dirh & 0x40) == 0x40) {
608                     sadd.p = &(mdpmirror[cindx - 1 + m->mmax_m_xy]);
609                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
610                         sadd.coords.x = bref.coords.x - 1;
611                         sadd.coords.y = bref.coords.y;
612                         sadd.coords.z = bref.coords.z + 1;
613 #ifdef FIND_DEFINED_TILE
614                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
615                             && sadd.coords.z == z_check)
616                             assert(assertion_bool);
617 #endif
618                         sadd.p->lvl = nlvl;
619                         sadd.p->t |= m_fdTargetPoint;
620                         tv.push_back(sadd);
621                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
622                         bref.p->t |= m_fdLink;
623                         sadd.p->t |= m_fdLink;
624                         lt = m_fdTargetPoint;
625                         lnknr = false;
626                     }
627                 }
628             }
629             if (bref.p->dirl != 0) {
630                 if ((bref.p->dirl & 0x01) == 0x01) {
631                     sadd.p = &(mdpmirror[cindx + m->mmax_x_ - m->mmax_m_xy]);
632                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
633                         sadd.coords.x = bref.coords.x;
634                         sadd.coords.y = bref.coords.y + 1;
635                         sadd.coords.z = bref.coords.z - 1;
636 #ifdef FIND_DEFINED_TILE
637                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
638                             && sadd.coords.z == z_check)
639                             assert(assertion_bool);
640 #endif
641                         sadd.p->lvl = nlvl;
642                         sadd.p->t |= m_fdTargetPoint;
643                         tv.push_back(sadd);
644                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
645                         bref.p->t |= m_fdLink;
646                         sadd.p->t |= m_fdLink;
647                         lt = m_fdTargetPoint;
648                         lnknr = false;
649                     }
650                 }
651                 if ((bref.p->dirl & 0x04) == 0x04) {
652                     sadd.p = &(mdpmirror[cindx + 1 - m->mmax_m_xy]);
653                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
654                         sadd.coords.x = bref.coords.x + 1;
655                         sadd.coords.y = bref.coords.y;
656                         sadd.coords.z = bref.coords.z - 1;
657 #ifdef FIND_DEFINED_TILE
658                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
659                             && sadd.coords.z == z_check)
660                             assert(assertion_bool);
661 #endif
662                         sadd.p->lvl = nlvl;
663                         sadd.p->t |= m_fdTargetPoint;
664                         tv.push_back(sadd);
665                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
666                         bref.p->t |= m_fdLink;
667                         sadd.p->t |= m_fdLink;
668                         lt = m_fdTargetPoint;
669                         lnknr = false;
670                     }
671                 }
672                 if ((bref.p->dirl & 0x10) == 0x10) {
673                     sadd.p = &(mdpmirror[cindx - m->mmax_x_ - m->mmax_m_xy]);
674                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
675                         sadd.coords.x = bref.coords.x;
676                         sadd.coords.y = bref.coords.y - 1;
677                         sadd.coords.z = bref.coords.z - 1;
678 #ifdef FIND_DEFINED_TILE
679                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
680                             && sadd.coords.z == z_check)
681                             assert(assertion_bool);
682 #endif
683                         sadd.p->lvl = nlvl;
684                         sadd.p->t |= m_fdTargetPoint;
685                         tv.push_back(sadd);
686                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
687                         bref.p->t |= m_fdLink;
688                         sadd.p->t |= m_fdLink;
689                         lt = m_fdTargetPoint;
690                         lnknr = false;
691                     }
692                 }
693                 if ((bref.p->dirl & 0x40) == 0x40) {
694                     sadd.p = &(mdpmirror[cindx - 1 - m->mmax_m_xy]);
695                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
696                         sadd.coords.x = bref.coords.x - 1;
697                         sadd.coords.y = bref.coords.y;
698                         sadd.coords.z = bref.coords.z - 1;
699 #ifdef FIND_DEFINED_TILE
700                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
701                             && sadd.coords.z == z_check)
702                             assert(assertion_bool);
703 #endif
704                         sadd.p->lvl = nlvl;
705                         sadd.p->t |= m_fdTargetPoint;
706                         tv.push_back(sadd);
707                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
708                         bref.p->t |= m_fdLink;
709                         sadd.p->t |= m_fdLink;
710                         lt = m_fdTargetPoint;
711                         lnknr = false;
712                     }
713                 }
714             }
715             if (bref.p->dirm != 0) {
716                 if ((bref.p->dirm & 0x01) == 0x01) {
717                     sadd.p = &(mdpmirror[cindx + m->mmax_x_]);
718                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
719                         sadd.coords.x = bref.coords.x;
720                         sadd.coords.y = bref.coords.y + 1;
721                         sadd.coords.z = bref.coords.z;
722 #ifdef FIND_DEFINED_TILE
723                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
724                             && sadd.coords.z == z_check)
725                             assert(assertion_bool);
726 #endif
727                         sadd.p->lvl = nlvl;
728                         sadd.p->t |= m_fdTargetPoint;
729                         tv.push_back(sadd);
730                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
731                         bref.p->t |= m_fdLink;
732                         sadd.p->t |= m_fdLink;
733                         lt = m_fdTargetPoint;
734                         lnknr = false;
735                     }
736                 }
737                 if ((bref.p->dirm & 0x02) == 0x02) {
738                     sadd.p = &(mdpmirror[cindx + 1 + m->mmax_x_]);
739                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
740                         sadd.coords.x = bref.coords.x + 1;
741                         sadd.coords.y = bref.coords.y + 1;
742                         sadd.coords.z = bref.coords.z;
743 #ifdef FIND_DEFINED_TILE
744                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
745                             && sadd.coords.z == z_check)
746                             assert(assertion_bool);
747 #endif
748                         sadd.p->lvl = nlvl;
749                         sadd.p->t |= m_fdTargetPoint;
750                         tv.push_back(sadd);
751                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
752                         bref.p->t |= m_fdLink;
753                         sadd.p->t |= m_fdLink;
754                         lt = m_fdTargetPoint;
755                         lnknr = false;
756                     }
757                 }
758                 if ((bref.p->dirm & 0x04) == 0x04) {
759                     sadd.p = &(mdpmirror[cindx + 1]);
760                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
761                         sadd.coords.x = bref.coords.x + 1;
762                         sadd.coords.y = bref.coords.y;
763                         sadd.coords.z = bref.coords.z;
764 #ifdef FIND_DEFINED_TILE
765                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
766                             && sadd.coords.z == z_check)
767                             assert(assertion_bool);
768 #endif
769                         sadd.p->lvl = nlvl;
770                         sadd.p->t |= m_fdTargetPoint;
771                         tv.push_back(sadd);
772                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
773                         bref.p->t |= m_fdLink;
774                         sadd.p->t |= m_fdLink;
775                         lt = m_fdTargetPoint;
776                         lnknr = false;
777                     }
778                 }
779                 if ((bref.p->dirm & 0x08) == 0x08) {
780                     sadd.p = &(mdpmirror[cindx + 1 - m->mmax_x_]);
781                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
782                         sadd.coords.x = bref.coords.x + 1;
783                         sadd.coords.y = bref.coords.y - 1;
784                         sadd.coords.z = bref.coords.z;
785 #ifdef FIND_DEFINED_TILE
786                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
787                             && sadd.coords.z == z_check)
788                             assert(assertion_bool);
789 #endif
790                         sadd.p->lvl = nlvl;
791                         sadd.p->t |= m_fdTargetPoint;
792                         tv.push_back(sadd);
793                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
794                         bref.p->t |= m_fdLink;
795                         sadd.p->t |= m_fdLink;
796                         lt = m_fdTargetPoint;
797                         lnknr = false;
798                     }
799                 }
800                 if ((bref.p->dirm & 0x10) == 0x10) {
801                     sadd.p = &(mdpmirror[cindx - m->mmax_x_]);
802                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
803                         sadd.coords.x = bref.coords.x;
804                         sadd.coords.y = bref.coords.y - 1;
805                         sadd.coords.z = bref.coords.z;
806 #ifdef FIND_DEFINED_TILE
807                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
808                             && sadd.coords.z == z_check)
809                             assert(assertion_bool);
810 #endif
811                         sadd.p->lvl = nlvl;
812                         sadd.p->t |= m_fdTargetPoint;
813                         tv.push_back(sadd);
814                     } else if ((sadd.p->t & m_fdBasePoint) != 0) {
815                         bref.p->t |= m_fdLink;
816                         sadd.p->t |= m_fdLink;
817                         lt = m_fdTargetPoint;
818                         lnknr = false;
819                     }
820                 }
821                 if ((bref.p->dirm & 0x20) == 0x20) {
822                     sadd.p = &(mdpmirror[cindx - 1 - m->mmax_x_]);
823                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
824                         sadd.coords.x = bref.coords.x - 1;
825                         sadd.coords.y = bref.coords.y - 1;
826                         sadd.coords.z = bref.coords.z;
827 #ifdef FIND_DEFINED_TILE
828                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
829                             && sadd.coords.z == z_check)
830                             assert(assertion_bool);
831 #endif
832                         sadd.p->lvl = nlvl;
833                         sadd.p->t |= m_fdTargetPoint;
834                         tv.push_back(sadd);
835                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
836                         bref.p->t |= m_fdLink;
837                         sadd.p->t |= m_fdLink;
838                         lt = m_fdTargetPoint;
839                         lnknr = false;
840                     }
841                 }
842                 if ((bref.p->dirm & 0x40) == 0x40) {
843                     sadd.p = &(mdpmirror[cindx - 1]);
844                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
845                         sadd.coords.x = bref.coords.x - 1;
846                         sadd.coords.y = bref.coords.y;
847                         sadd.coords.z = bref.coords.z;
848 #ifdef FIND_DEFINED_TILE
849                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
850                             && sadd.coords.z == z_check)
851                             assert(assertion_bool);
852 #endif
853                         sadd.p->lvl = nlvl;
854                         sadd.p->t |= m_fdTargetPoint;
855                         tv.push_back(sadd);
856                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
857                         bref.p->t |= m_fdLink;
858                         sadd.p->t |= m_fdLink;
859                         lt = m_fdTargetPoint;
860                         lnknr = false;
861                     }
862                 }
863                 if ((bref.p->dirm & 0x80) == 0x80) {
864                     sadd.p = &(mdpmirror[cindx - 1 + m->mmax_x_]);
865                     if ((sadd.p->t & (m_fdWalkable | m_fdBasePoint | m_fdTargetPoint)) == m_fdWalkable) {
866                         sadd.coords.x = bref.coords.x - 1;
867                         sadd.coords.y = bref.coords.y + 1;
868                         sadd.coords.z = bref.coords.z;
869 #ifdef FIND_DEFINED_TILE
870                         if (sadd.coords.x == x_check && sadd.coords.y == y_check
871                             && sadd.coords.z == z_check)
872                             assert(assertion_bool);
873 #endif
874                         sadd.p->lvl = nlvl;
875                         sadd.p->t |= m_fdTargetPoint;
876                         tv.push_back(sadd);
877                     } else if ((sadd.p->t & m_fdBasePoint) != 0){
878                         bref.p->t |= m_fdLink;
879                         sadd.p->t |= m_fdLink;
880                         lt = m_fdTargetPoint;
881                         lnknr = false;
882                     }
883                 }
884             }
885         }
886         ladd.indxs = mindx;
887         ladd.n = tv.size() - mindx;
888         if (ladd.n > 0) {
889             nodeset = true;
890             tn.push_back(ladd);
891             ++tlvl;
892         } else {
893             nodeset = false;
894             break;
895         }
896     } while (lnknr);
897     //printf("bv %i, tv %i\n", bv.size(), tv.size());
898 #ifdef EXECUTION_SPEED_TIME
899     printf("blvl %i, tlvl %i\n",tlvl, blvl);
900     printf("target reached in %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
901 #endif
902     if (!nodeset && lnknr) {
903         return;
904     }
905     if (blvl == bn.size())
906         blvl--;
907     if (tlvl == tn.size())
908         tlvl--;
909     // when link is set data of nlvl is useless, that is why it is removed
910     if (nodeset) {
911         if (lt == m_fdBasePoint) {
912             unsigned short n = bn[blvl].n;
913             std::vector <toSetDesc>::iterator it = bv.begin() + bn[blvl].indxs;
914             for (unsigned short i = 0; i < n; ++i) {
915                 it->p->t ^= m_fdBasePoint;
916                 it->p->lvl = 0;
917                 //bv.erase(it);
918                 ++it;
919             }
920             //bn.pop_back();
921             --blvl;
922         } else {
923             unsigned short n = tn[tlvl].n;
924             std::vector <toSetDesc>::iterator it = tv.begin() + tn[tlvl].indxs;
925             for (unsigned short i = 0; i < n; ++i) {
926                 it->p->t ^= m_fdTargetPoint;
927                 it->p->lvl = 0;
928                 //tv.erase(it);
929                 ++it;
930             }
931             //tn.pop_back();
932             --tlvl;
933         }
934     }
935 
936     // level which created link have also non-link tiles they are useless
937     if (blvl != 0) {
938         unsigned short n = bn[blvl].n;
939         unsigned short nr = 0;
940         std::vector <toSetDesc>::iterator it = bv.begin() + bn[blvl].indxs;
941         for (unsigned short i = 0; i < n; ++i) {
942             if ((it->p->t & m_fdLink) == 0) {
943                 it->p->t ^= m_fdBasePoint;
944                 it->p->lvl = 0;
945                 //bv.erase(it);
946                 ++nr;
947             }
948             ++it;
949         }
950         bn[blvl].n -= nr;
951     }
952 
953     if (tlvl != 0) {
954         unsigned short n = tn[tlvl].n;
955         unsigned short nr = 0;
956         std::vector <toSetDesc>::iterator it = tv.begin() + tn[tlvl].indxs;
957         for (unsigned short i = 0; i < n; ++i) {
958             if ((it->p->t & m_fdLink) == 0) {
959                 it->p->t ^= m_fdTargetPoint;
960                 it->p->lvl = 0;
961                 //tv.erase(it);
962                 ++nr;
963             }
964             ++it;
965         }
966         tn[tlvl].n -= nr;
967     }
968     //printf("bv %i, tv %i\n", bv.size(), tv.size());
969 #ifdef EXECUTION_SPEED_TIME
970     printf("tops removed time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
971 #endif
972 
973     // tiles that have no childs are removed
974     if (blvl > 1) {
975         --blvl;
976         unsigned short indx = bn[blvl].indxs + bn[blvl].n;
977         --indx;
978         do {
979             toSetDesc &bref = bv[indx];
980             uint16 lvl_child = (bref.p->lvl + 1);
981             bool remv = true;
982             if (bref.p->dirh != 0) {
983                 if ((bref.p->dirh & 0x01) == 0x01) {
984                     pfdp = &(mdpmirror[bref.coords.x
985                         + (bref.coords.y + 1) * m->mmax_x_
986                         + (bref.coords.z + 1) * m->mmax_m_xy]);
987                     if (lvl_child == pfdp->lvl)
988                         remv = false;
989                 }
990                 if ((bref.p->dirh & 0x04) == 0x04) {
991                     pfdp = &(mdpmirror[(bref.coords.x + 1)
992                         + bref.coords.y * m->mmax_x_
993                         + (bref.coords.z + 1) * m->mmax_m_xy]);
994                     if (lvl_child == pfdp->lvl)
995                         remv = false;
996                 }
997                 if ((bref.p->dirh & 0x10) == 0x10) {
998                     pfdp = &(mdpmirror[bref.coords.x
999                         + (bref.coords.y - 1) * m->mmax_x_
1000                         + (bref.coords.z + 1) * m->mmax_m_xy]);
1001                     if (lvl_child == pfdp->lvl)
1002                         remv = false;
1003                 }
1004                 if ((bref.p->dirh & 0x40) == 0x40) {
1005                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1006                         + bref.coords.y * m->mmax_x_
1007                         + (bref.coords.z + 1) * m->mmax_m_xy]);
1008                     if (lvl_child == pfdp->lvl)
1009                         remv = false;
1010                 }
1011             }
1012             if (bref.p->dirl != 0) {
1013                 if ((bref.p->dirl & 0x01) == 0x01) {
1014                     pfdp = &(mdpmirror[bref.coords.x
1015                         + (bref.coords.y + 1) * m->mmax_x_
1016                         + (bref.coords.z - 1) * m->mmax_m_xy]);
1017                     if (lvl_child == pfdp->lvl)
1018                         remv = false;
1019                 }
1020                 if ((bref.p->dirl & 0x04) == 0x04) {
1021                     pfdp = &(mdpmirror[(bref.coords.x + 1)
1022                         + bref.coords.y * m->mmax_x_
1023                         + (bref.coords.z - 1) * m->mmax_m_xy]);
1024                     if (lvl_child == pfdp->lvl)
1025                         remv = false;
1026                 }
1027                 if ((bref.p->dirl & 0x10) == 0x10) {
1028                     pfdp = &(mdpmirror[(bref.coords.x)
1029                         + (bref.coords.y - 1) * m->mmax_x_
1030                         + (bref.coords.z - 1) * m->mmax_m_xy]);
1031                     if (lvl_child == pfdp->lvl)
1032                         remv = false;
1033                 }
1034                 if ((bref.p->dirl & 0x40) == 0x40) {
1035                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1036                         + bref.coords.y * m->mmax_x_
1037                         + (bref.coords.z - 1) * m->mmax_m_xy]);
1038                     if (lvl_child == pfdp->lvl)
1039                         remv = false;
1040                 }
1041             }
1042             if (bref.p->dirm != 0) {
1043                 if ((bref.p->dirm & 0x01) == 0x01) {
1044                     pfdp = &(mdpmirror[bref.coords.x
1045                         + (bref.coords.y + 1) * m->mmax_x_
1046                         + bref.coords.z * m->mmax_m_xy]);
1047                     if (lvl_child == pfdp->lvl)
1048                         remv = false;
1049                 }
1050                 if ((bref.p->dirm & 0x02) == 0x02) {
1051                     pfdp = &(mdpmirror[(bref.coords.x + 1)
1052                         + (bref.coords.y + 1) * m->mmax_x_
1053                         + bref.coords.z * m->mmax_m_xy]);
1054                     if (lvl_child == pfdp->lvl)
1055                         remv = false;
1056                 }
1057                 if ((bref.p->dirm & 0x04) == 0x04) {
1058                     pfdp = &(mdpmirror[(bref.coords.x + 1)
1059                         + bref.coords.y * m->mmax_x_
1060                         + bref.coords.z * m->mmax_m_xy]);
1061                     if (lvl_child == pfdp->lvl)
1062                         remv = false;
1063                 }
1064                 if ((bref.p->dirm & 0x08) == 0x08) {
1065                     pfdp = &(mdpmirror[(bref.coords.x + 1)
1066                         + (bref.coords.y - 1) * m->mmax_x_
1067                         + bref.coords.z * m->mmax_m_xy]);
1068                     if (lvl_child == pfdp->lvl)
1069                         remv = false;
1070                 }
1071                 if ((bref.p->dirm & 0x10) == 0x10) {
1072                     pfdp = &(mdpmirror[bref.coords.x
1073                         + (bref.coords.y - 1) * m->mmax_x_
1074                         + bref.coords.z * m->mmax_m_xy]);
1075                     if (lvl_child == pfdp->lvl)
1076                         remv = false;
1077                 }
1078                 if ((bref.p->dirm & 0x20) == 0x20) {
1079                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1080                         + (bref.coords.y - 1) * m->mmax_x_
1081                         + bref.coords.z * m->mmax_m_xy]);
1082                     if (lvl_child == pfdp->lvl)
1083                         remv = false;
1084                 }
1085                 if ((bref.p->dirm & 0x40) == 0x40) {
1086                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1087                         + bref.coords.y * m->mmax_x_
1088                         + bref.coords.z * m->mmax_m_xy]);
1089                     if (lvl_child == pfdp->lvl)
1090                         remv = false;
1091                 }
1092                 if ((bref.p->dirm & 0x80) == 0x80) {
1093                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1094                         + (bref.coords.y + 1) * m->mmax_x_
1095                         + bref.coords.z * m->mmax_m_xy]);
1096                     if (lvl_child == pfdp->lvl)
1097                         remv = false;
1098                 }
1099             }
1100             if (remv) {
1101                 bref.p->t ^= m_fdBasePoint;
1102                 bref.p->lvl = 0;
1103                 //bv.erase(it);
1104             }
1105             --indx;
1106         } while(indx != 0);
1107     }
1108     if (tlvl > 1) {
1109         --tlvl;
1110         unsigned short indx = tn[tlvl].indxs + tn[tlvl].n;
1111         --indx;
1112         do {
1113             toSetDesc &bref = tv[indx];
1114             uint16 lvl_child = (bref.p->lvl + 1);
1115             bool remv = true;
1116             if (bref.p->dirh != 0) {
1117                 if ((bref.p->dirh & 0x01) == 0x01) {
1118                     pfdp = &(mdpmirror[bref.coords.x
1119                         + (bref.coords.y + 1) * m->mmax_x_
1120                         + (bref.coords.z + 1) * m->mmax_m_xy]);
1121                     if (lvl_child == pfdp->lvl)
1122                         remv = false;
1123                 }
1124                 if ((bref.p->dirh & 0x04) == 0x04) {
1125                     pfdp = &(mdpmirror[(bref.coords.x + 1)
1126                         + bref.coords.y * m->mmax_x_
1127                         + (bref.coords.z + 1) * m->mmax_m_xy]);
1128                     if (lvl_child == pfdp->lvl)
1129                         remv = false;
1130                 }
1131                 if ((bref.p->dirh & 0x10) == 0x10) {
1132                     pfdp = &(mdpmirror[bref.coords.x
1133                         + (bref.coords.y - 1) * m->mmax_x_
1134                         + (bref.coords.z + 1) * m->mmax_m_xy]);
1135                     if (lvl_child == pfdp->lvl)
1136                         remv = false;
1137                 }
1138                 if ((bref.p->dirh & 0x40) == 0x40) {
1139                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1140                         + bref.coords.y * m->mmax_x_
1141                         + (bref.coords.z + 1) * m->mmax_m_xy]);
1142                     if (lvl_child == pfdp->lvl)
1143                         remv = false;
1144                 }
1145             }
1146             if (bref.p->dirl != 0) {
1147                 if ((bref.p->dirl & 0x01) == 0x01) {
1148                     pfdp = &(mdpmirror[bref.coords.x
1149                         + (bref.coords.y + 1) * m->mmax_x_
1150                         + (bref.coords.z - 1) * m->mmax_m_xy]);
1151                     if (lvl_child == pfdp->lvl)
1152                         remv = false;
1153                 }
1154                 if ((bref.p->dirl & 0x04) == 0x04) {
1155                     pfdp = &(mdpmirror[(bref.coords.x + 1)
1156                         + bref.coords.y * m->mmax_x_
1157                         + (bref.coords.z - 1) * m->mmax_m_xy]);
1158                     if (lvl_child == pfdp->lvl)
1159                         remv = false;
1160                 }
1161                 if ((bref.p->dirl & 0x10) == 0x10) {
1162                     pfdp = &(mdpmirror[(bref.coords.x)
1163                         + (bref.coords.y - 1) * m->mmax_x_
1164                         + (bref.coords.z - 1) * m->mmax_m_xy]);
1165                     if (lvl_child == pfdp->lvl)
1166                         remv = false;
1167                 }
1168                 if ((bref.p->dirl & 0x40) == 0x40) {
1169                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1170                         + bref.coords.y * m->mmax_x_
1171                         + (bref.coords.z - 1) * m->mmax_m_xy]);
1172                     if (lvl_child == pfdp->lvl)
1173                         remv = false;
1174                 }
1175             }
1176             if (bref.p->dirm != 0) {
1177                 if ((bref.p->dirm & 0x01) == 0x01) {
1178                     pfdp = &(mdpmirror[bref.coords.x
1179                         + (bref.coords.y + 1) * m->mmax_x_
1180                         + bref.coords.z * m->mmax_m_xy]);
1181                     if (lvl_child == pfdp->lvl)
1182                         remv = false;
1183                 }
1184                 if ((bref.p->dirm & 0x02) == 0x02) {
1185                     pfdp = &(mdpmirror[(bref.coords.x + 1)
1186                         + (bref.coords.y + 1) * m->mmax_x_
1187                         + bref.coords.z * m->mmax_m_xy]);
1188                     if (lvl_child == pfdp->lvl)
1189                         remv = false;
1190                 }
1191                 if ((bref.p->dirm & 0x04) == 0x04) {
1192                     pfdp = &(mdpmirror[(bref.coords.x + 1)
1193                         + bref.coords.y * m->mmax_x_
1194                         + bref.coords.z * m->mmax_m_xy]);
1195                     if (lvl_child == pfdp->lvl)
1196                         remv = false;
1197                 }
1198                 if ((bref.p->dirm & 0x08) == 0x08) {
1199                     pfdp = &(mdpmirror[(bref.coords.x + 1)
1200                         + (bref.coords.y - 1) * m->mmax_x_
1201                         + bref.coords.z * m->mmax_m_xy]);
1202                     if (lvl_child == pfdp->lvl)
1203                         remv = false;
1204                 }
1205                 if ((bref.p->dirm & 0x10) == 0x10) {
1206                     pfdp = &(mdpmirror[bref.coords.x
1207                         + (bref.coords.y - 1) * m->mmax_x_
1208                         + bref.coords.z * m->mmax_m_xy]);
1209                     if (lvl_child == pfdp->lvl)
1210                         remv = false;
1211                 }
1212                 if ((bref.p->dirm & 0x20) == 0x20) {
1213                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1214                         + (bref.coords.y - 1) * m->mmax_x_
1215                         + bref.coords.z * m->mmax_m_xy]);
1216                     if (lvl_child == pfdp->lvl)
1217                         remv = false;
1218                 }
1219                 if ((bref.p->dirm & 0x40) == 0x40) {
1220                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1221                         + bref.coords.y * m->mmax_x_
1222                         + bref.coords.z * m->mmax_m_xy]);
1223                     if (lvl_child == pfdp->lvl)
1224                         remv = false;
1225                 }
1226                 if ((bref.p->dirm & 0x80) == 0x80) {
1227                     pfdp = &(mdpmirror[(bref.coords.x - 1)
1228                         + (bref.coords.y + 1) * m->mmax_x_
1229                         + bref.coords.z * m->mmax_m_xy]);
1230                     if (lvl_child == pfdp->lvl)
1231                         remv = false;
1232                 }
1233             }
1234             if (remv) {
1235                 bref.p->t ^= m_fdTargetPoint;
1236                 bref.p->lvl = 0;
1237                 //tv.erase(it);
1238             }
1239             --indx;
1240         } while(indx != 0);
1241     }
1242     //printf("bv %i, tv %i\n", bv.size(), tv.size());
1243 #ifdef EXECUTION_SPEED_TIME
1244     printf("non-related removed time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
1245 #endif
1246 #if 0
1247     bn.clear();
1248     tn.clear();
1249     bv.clear();
1250     tv.clear();
1251 #endif
1252 
1253     // path is created here
1254     WorldPoint ctile;
1255     ctile.x = pos_.tx;
1256     ctile.y = pos_.ty;
1257     ctile.z = pos_.tz;
1258     unsigned char ct = m_fdBasePoint;
1259     bool tnr = true, np = true;
1260     std::vector<TilePoint> cdestpath;
1261     cdestpath.reserve(256);
1262     do {
1263         unsigned char nt = ct;
1264         WorldPoint toadd;
1265         char dist = 5;
1266         pfdp = &(mdpmirror[ctile.x + ctile.y * m->mmax_x_
1267                     + ctile.z * m->mmax_m_xy]);
1268         uint16 lvl_child = ct == m_fdBasePoint ? pfdp->lvl + 1
1269             : pfdp->lvl - 1;
1270         if (pfdp->dirh != 0) {
1271             if ((pfdp->dirh & 0x01) == 0x01) {
1272                 sadd.coords.x = ctile.x;
1273                 sadd.coords.y = ctile.y + 1;
1274                 sadd.coords.z = ctile.z + 1;
1275                 sadd.p = &(mdpmirror[sadd.coords.x
1276                     + sadd.coords.y * m->mmax_x_
1277                     + sadd.coords.z * m->mmax_m_xy]);
1278                 if ((sadd.p->t & ct) != 0) {
1279                     if (lvl_child == sadd.p->lvl) {
1280                         if (3 < dist) {
1281                             toadd = sadd.coords;
1282                             dist = 3;
1283                         }
1284                     }
1285                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1286                     if (0 < dist) {
1287                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1288                         dist = 0;
1289                         toadd = sadd.coords;
1290                     }
1291                 }
1292                 if ((sadd.p->t & m_fdConstant) != 0)
1293                     tnr = false;
1294             }
1295             if ((pfdp->dirh & 0x04) == 0x04) {
1296                 sadd.coords.x = ctile.x + 1;
1297                 sadd.coords.y = ctile.y;
1298                 sadd.coords.z = ctile.z + 1;
1299                 sadd.p = &(mdpmirror[sadd.coords.x
1300                     + sadd.coords.y * m->mmax_x_
1301                     + sadd.coords.z * m->mmax_m_xy]);
1302                 if ((sadd.p->t & ct) != 0) {
1303                     if (lvl_child == sadd.p->lvl) {
1304                         if (3 < dist) {
1305                             toadd = sadd.coords;
1306                             dist = 3;
1307                         }
1308                     }
1309                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1310                     if (0 < dist) {
1311                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1312                         dist = 0;
1313                         toadd = sadd.coords;
1314                     }
1315                 }
1316                 if ((sadd.p->t & m_fdConstant) != 0)
1317                     tnr = false;
1318             }
1319             if ((pfdp->dirh & 0x10) == 0x10) {
1320                 sadd.coords.x = ctile.x;
1321                 sadd.coords.y = ctile.y - 1;
1322                 sadd.coords.z = ctile.z + 1;
1323                 sadd.p = &(mdpmirror[sadd.coords.x
1324                     + sadd.coords.y * m->mmax_x_
1325                     + sadd.coords.z * m->mmax_m_xy]);
1326                 if ((sadd.p->t & ct) != 0) {
1327                     if (lvl_child == sadd.p->lvl) {
1328                         if (3 < dist) {
1329                             toadd = sadd.coords;
1330                             dist = 3;
1331                         }
1332                     }
1333                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1334                     if (0 < dist) {
1335                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1336                         dist = 0;
1337                         toadd = sadd.coords;
1338                     }
1339                 }
1340                 if ((sadd.p->t & m_fdConstant) != 0)
1341                     tnr = false;
1342             }
1343             if ((pfdp->dirh & 0x40) == 0x40) {
1344                 sadd.coords.x = ctile.x - 1;
1345                 sadd.coords.y = ctile.y;
1346                 sadd.coords.z = ctile.z + 1;
1347                 sadd.p = &(mdpmirror[sadd.coords.x
1348                     + sadd.coords.y * m->mmax_x_
1349                     + sadd.coords.z * m->mmax_m_xy]);
1350                 if ((sadd.p->t & ct) != 0) {
1351                     if (lvl_child == sadd.p->lvl) {
1352                         if (3 < dist) {
1353                             toadd = sadd.coords;
1354                             dist = 3;
1355                         }
1356                     }
1357                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1358                     if (0 < dist) {
1359                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1360                         dist = 0;
1361                         toadd = sadd.coords;
1362                     }
1363                 }
1364                 if ((sadd.p->t & m_fdConstant) != 0)
1365                     tnr = false;
1366             }
1367         }
1368         if (pfdp->dirl != 0) {
1369             if ((pfdp->dirl & 0x01) == 0x01) {
1370                 sadd.coords.x = ctile.x;
1371                 sadd.coords.y = ctile.y + 1;
1372                 sadd.coords.z = ctile.z - 1;
1373                 sadd.p = &(mdpmirror[sadd.coords.x
1374                     + sadd.coords.y * m->mmax_x_
1375                     + sadd.coords.z * m->mmax_m_xy]);
1376                 if ((sadd.p->t & ct) != 0) {
1377                     if (lvl_child == sadd.p->lvl) {
1378                         if (3 < dist) {
1379                             toadd = sadd.coords;
1380                             dist = 3;
1381                         }
1382                     }
1383                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1384                     if (0 < dist) {
1385                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1386                         dist = 0;
1387                         toadd = sadd.coords;
1388                     }
1389                 }
1390                 if ((sadd.p->t & m_fdConstant) != 0)
1391                     tnr = false;
1392             }
1393             if ((pfdp->dirl & 0x04) == 0x04) {
1394                 sadd.coords.x = ctile.x + 1;
1395                 sadd.coords.y = ctile.y;
1396                 sadd.coords.z = ctile.z - 1;
1397                 sadd.p = &(mdpmirror[sadd.coords.x
1398                     + sadd.coords.y * m->mmax_x_
1399                     + sadd.coords.z * m->mmax_m_xy]);
1400                 if ((sadd.p->t & ct) != 0) {
1401                     if (lvl_child == sadd.p->lvl) {
1402                         if (3 < dist) {
1403                             toadd = sadd.coords;
1404                             dist = 3;
1405                         }
1406                     }
1407                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1408                     if (0 < dist) {
1409                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1410                         dist = 0;
1411                         toadd = sadd.coords;
1412                     }
1413                 }
1414                 if ((sadd.p->t & m_fdConstant) != 0)
1415                     tnr = false;
1416             }
1417             if ((pfdp->dirl & 0x10) == 0x10) {
1418                 sadd.coords.x = ctile.x;
1419                 sadd.coords.y = ctile.y - 1;
1420                 sadd.coords.z = ctile.z - 1;
1421                 sadd.p = &(mdpmirror[sadd.coords.x
1422                     + sadd.coords.y * m->mmax_x_
1423                     + sadd.coords.z * m->mmax_m_xy]);
1424                 if ((sadd.p->t & ct) != 0) {
1425                     if (lvl_child == sadd.p->lvl) {
1426                         if (3 < dist) {
1427                             toadd = sadd.coords;
1428                             dist = 3;
1429                         }
1430                     }
1431                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1432                     if (0 < dist) {
1433                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1434                         dist = 0;
1435                         toadd = sadd.coords;
1436                     }
1437                 }
1438                 if ((sadd.p->t & m_fdConstant) != 0)
1439                     tnr = false;
1440             }
1441             if ((pfdp->dirl & 0x40) == 0x40) {
1442                 sadd.coords.x = ctile.x - 1;
1443                 sadd.coords.y = ctile.y;
1444                 sadd.coords.z = ctile.z - 1;
1445                 sadd.p = &(mdpmirror[sadd.coords.x
1446                     + sadd.coords.y * m->mmax_x_
1447                     + sadd.coords.z * m->mmax_m_xy]);
1448                 if ((sadd.p->t & ct) != 0) {
1449                     if (lvl_child == sadd.p->lvl) {
1450                         if (3 < dist) {
1451                             toadd = sadd.coords;
1452                             dist = 3;
1453                         }
1454                     }
1455                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1456                     if (0 < dist) {
1457                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1458                         dist = 0;
1459                         toadd = sadd.coords;
1460                     }
1461                 }
1462                 if ((sadd.p->t & m_fdConstant) != 0)
1463                     tnr = false;
1464             }
1465         }
1466         if (pfdp->dirm != 0) {
1467             if ((pfdp->dirm & 0x01) == 0x01) {
1468                 sadd.coords.x = ctile.x;
1469                 sadd.coords.y = ctile.y + 1;
1470                 sadd.coords.z = ctile.z;
1471                 sadd.p = &(mdpmirror[sadd.coords.x
1472                     + sadd.coords.y * m->mmax_x_
1473                     + sadd.coords.z * m->mmax_m_xy]);
1474                 if ((sadd.p->t & ct) != 0) {
1475                     if (lvl_child == sadd.p->lvl) {
1476                         unsigned char twd = m->mtsurfaces_[sadd.coords.x
1477                             + sadd.coords.y * m->mmax_x_
1478                             + sadd.coords.z * m->mmax_m_xy].twd;
1479                         if (twd > 0x00 && twd < 0x05) {
1480                             if (3 < dist) {
1481                                 toadd = sadd.coords;
1482                                 dist = 3;
1483                             }
1484                         } else {
1485                             if (1 < dist) {
1486                                 toadd = sadd.coords;
1487                                 dist = 1;
1488                             }
1489                         }
1490                     }
1491                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1492                     unsigned char twd = m->mtsurfaces_[sadd.coords.x
1493                         + sadd.coords.y * m->mmax_x_
1494                         + sadd.coords.z * m->mmax_m_xy].twd;
1495                     if (twd > 0x00 && twd < 0x05) {
1496                         if (-1 < dist) {
1497                             nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1498                             dist = -1;
1499                             toadd = sadd.coords;
1500                         }
1501                     } else {
1502                         if (-2 < dist) {
1503                             nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1504                             dist = -2;
1505                             toadd = sadd.coords;
1506                         }
1507                     }
1508                 }
1509                 if ((sadd.p->t & m_fdConstant) != 0)
1510                     tnr = false;
1511             }
1512             if ((pfdp->dirm & 0x02) == 0x02) {
1513                 sadd.coords.x = ctile.x + 1;
1514                 sadd.coords.y = ctile.y + 1;
1515                 sadd.coords.z = ctile.z;
1516                 sadd.p = &(mdpmirror[sadd.coords.x
1517                     + sadd.coords.y * m->mmax_x_
1518                     + sadd.coords.z * m->mmax_m_xy]);
1519                 if ((sadd.p->t & ct) != 0) {
1520                     if (lvl_child == sadd.p->lvl) {
1521                         if (2 < dist) {
1522                             toadd = sadd.coords;
1523                             dist = 2;
1524                         }
1525                     }
1526                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1527                     if (-1 < dist) {
1528                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1529                         dist = -1;
1530                         toadd = sadd.coords;
1531                     }
1532                 }
1533                 if ((sadd.p->t & m_fdConstant) != 0)
1534                     tnr = false;
1535             }
1536             if ((pfdp->dirm & 0x04) == 0x04) {
1537                 sadd.coords.x = ctile.x + 1;
1538                 sadd.coords.y = ctile.y;
1539                 sadd.coords.z = ctile.z;
1540                 sadd.p = &(mdpmirror[sadd.coords.x
1541                     + sadd.coords.y * m->mmax_x_
1542                     + sadd.coords.z * m->mmax_m_xy]);
1543                 if ((sadd.p->t & ct) != 0) {
1544                     if (lvl_child== sadd.p->lvl) {
1545                         unsigned char twd = m->mtsurfaces_[sadd.coords.x
1546                             + sadd.coords.y * m->mmax_x_
1547                             + sadd.coords.z * m->mmax_m_xy].twd;
1548                         if (twd > 0x00 && twd < 0x05) {
1549                             if (3 < dist) {
1550                                 toadd = sadd.coords;
1551                                 dist = 3;
1552                             }
1553                         } else {
1554                             if (1 < dist) {
1555                                 toadd = sadd.coords;
1556                                 dist = 1;
1557                             }
1558                         }
1559                     }
1560                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1561                     unsigned char twd = m->mtsurfaces_[sadd.coords.x
1562                         + sadd.coords.y * m->mmax_x_
1563                         + sadd.coords.z * m->mmax_m_xy].twd;
1564                     if (twd > 0x00 && twd < 0x05) {
1565                         if (-1 < dist) {
1566                             nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1567                             dist = -1;
1568                             toadd = sadd.coords;
1569                         }
1570                     } else {
1571                         if (-2 < dist) {
1572                             nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1573                             dist = -2;
1574                             toadd = sadd.coords;
1575                         }
1576                     }
1577                 }
1578                 if ((sadd.p->t & m_fdConstant) != 0)
1579                     tnr = false;
1580             }
1581             if ((pfdp->dirm & 0x08) == 0x08) {
1582                 sadd.coords.x = ctile.x + 1;
1583                 sadd.coords.y = ctile.y - 1;
1584                 sadd.coords.z = ctile.z;
1585                 sadd.p = &(mdpmirror[sadd.coords.x
1586                     + sadd.coords.y * m->mmax_x_
1587                     + sadd.coords.z * m->mmax_m_xy]);
1588                 if ((sadd.p->t & ct) != 0) {
1589                     if (lvl_child == sadd.p->lvl) {
1590                         if (2 < dist) {
1591                             toadd = sadd.coords;
1592                             dist = 2;
1593                         }
1594                     }
1595                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1596                     if (-1 < dist) {
1597                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1598                         dist = -1;
1599                         toadd = sadd.coords;
1600                     }
1601                 }
1602                 if ((sadd.p->t & m_fdConstant) != 0)
1603                     tnr = false;
1604             }
1605             if ((pfdp->dirm & 0x10) == 0x10) {
1606                 sadd.coords.x = ctile.x;
1607                 sadd.coords.y = ctile.y - 1;
1608                 sadd.coords.z = ctile.z;
1609                 sadd.p = &(mdpmirror[sadd.coords.x
1610                     + sadd.coords.y * m->mmax_x_
1611                     + sadd.coords.z * m->mmax_m_xy]);
1612                 if ((sadd.p->t & ct) != 0) {
1613                     if (lvl_child == sadd.p->lvl) {
1614                         unsigned char twd = m->mtsurfaces_[sadd.coords.x
1615                             + sadd.coords.y * m->mmax_x_
1616                             + sadd.coords.z * m->mmax_m_xy].twd;
1617                         if (twd > 0x00 && twd < 0x05) {
1618                             if (3 < dist) {
1619                                 toadd = sadd.coords;
1620                                 dist = 3;
1621                             }
1622                         } else {
1623                             if (1 < dist) {
1624                                 toadd = sadd.coords;
1625                                 dist = 1;
1626                             }
1627                         }
1628                     }
1629                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1630                     unsigned char twd = m->mtsurfaces_[sadd.coords.x
1631                         + sadd.coords.y * m->mmax_x_
1632                         + sadd.coords.z * m->mmax_m_xy].twd;
1633                     if (twd > 0x00 && twd < 0x05) {
1634                         if (-1 < dist) {
1635                             nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1636                             dist = -1;
1637                             toadd = sadd.coords;
1638                         }
1639                     } else {
1640                         if (-2 < dist) {
1641                             nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1642                             dist = -2;
1643                             toadd = sadd.coords;
1644                         }
1645                     }
1646                 }
1647                 if ((sadd.p->t & m_fdConstant) != 0)
1648                     tnr = false;
1649             }
1650             if ((pfdp->dirm & 0x20) == 0x20) {
1651                 sadd.coords.x = ctile.x - 1;
1652                 sadd.coords.y = ctile.y - 1;
1653                 sadd.coords.z = ctile.z;
1654                 sadd.p = &(mdpmirror[sadd.coords.x
1655                     + sadd.coords.y * m->mmax_x_
1656                     + sadd.coords.z * m->mmax_m_xy]);
1657                 if ((sadd.p->t & ct) != 0) {
1658                     if (lvl_child == sadd.p->lvl) {
1659                         if (2 < dist) {
1660                             toadd = sadd.coords;
1661                             dist = 2;
1662                         }
1663                     }
1664                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1665                     if (-1 < dist) {
1666                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1667                         dist = -1;
1668                         toadd = sadd.coords;
1669                     }
1670                 }
1671                 if ((sadd.p->t & m_fdConstant) != 0)
1672                     tnr = false;
1673             }
1674             if ((pfdp->dirm & 0x40) == 0x40) {
1675                 sadd.coords.x = ctile.x - 1;
1676                 sadd.coords.y = ctile.y;
1677                 sadd.coords.z = ctile.z;
1678                 sadd.p = &(mdpmirror[sadd.coords.x
1679                     + sadd.coords.y * m->mmax_x_
1680                     + sadd.coords.z * m->mmax_m_xy]);
1681                 if ((sadd.p->t & ct) != 0) {
1682                     if (lvl_child == sadd.p->lvl) {
1683                         unsigned char twd = m->mtsurfaces_[sadd.coords.x
1684                             + sadd.coords.y * m->mmax_x_
1685                             + sadd.coords.z * m->mmax_m_xy].twd;
1686                         if (twd > 0x00 && twd < 0x05) {
1687                             if (3 < dist) {
1688                                 toadd = sadd.coords;
1689                                 dist = 3;
1690                             }
1691                         } else {
1692                             if (1 < dist) {
1693                                 toadd = sadd.coords;
1694                                 dist = 1;
1695                             }
1696                         }
1697                     }
1698                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1699                     unsigned char twd = m->mtsurfaces_[sadd.coords.x
1700                         + sadd.coords.y * m->mmax_x_
1701                         + sadd.coords.z * m->mmax_m_xy].twd;
1702                     if (twd > 0x00 && twd < 0x05) {
1703                         if (-1 < dist) {
1704                             nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1705                             dist = -1;
1706                             toadd = sadd.coords;
1707                         }
1708                     } else {
1709                         if (-2 < dist) {
1710                             nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1711                             dist = -2;
1712                             toadd = sadd.coords;
1713                         }
1714                     }
1715                 }
1716                 if ((sadd.p->t & m_fdConstant) != 0)
1717                     tnr = false;
1718             }
1719             if ((pfdp->dirm & 0x80) == 0x80) {
1720                 sadd.coords.x = ctile.x - 1;
1721                 sadd.coords.y = ctile.y + 1;
1722                 sadd.coords.z = ctile.z;
1723                 sadd.p = &(mdpmirror[sadd.coords.x
1724                     + sadd.coords.y * m->mmax_x_
1725                     + sadd.coords.z * m->mmax_m_xy]);
1726                 if ((sadd.p->t & ct) != 0) {
1727                     if (lvl_child == sadd.p->lvl) {
1728                         if (2 < dist) {
1729                             toadd = sadd.coords;
1730                             dist = 2;
1731                         }
1732                     }
1733                 } else if(np && (sadd.p->t & (m_fdBasePoint | m_fdTargetPoint)) != 0) {
1734                     if (-1 < dist) {
1735                         nt = sadd.p->t & (m_fdBasePoint | m_fdTargetPoint);
1736                         dist = -1;
1737                         toadd = sadd.coords;
1738                     }
1739                 }
1740                 if ((sadd.p->t & m_fdConstant) != 0)
1741                     tnr = false;
1742             }
1743         }
1744         if (dist < 1) {
1745             np = false;
1746             ct = nt;
1747         }
1748         cdestpath.push_back(TilePoint(toadd.x, toadd.y, toadd.z));
1749         // this assert might save from memory fill up,
1750         assert(ctile.x != toadd.x || ctile.y != toadd.y || ctile.z != toadd.z);
1751         //if(toadd.x == 49 && toadd.y == 86 && toadd.z == 1)
1752             //toadd.x = 49;
1753         //if(ctile.x == toadd.x && ctile.y == toadd.y && ctile.z == toadd.z)
1754             //ctile = toadd;
1755         ctile = toadd;
1756     } while (tnr);
1757 #ifdef EXECUTION_SPEED_TIME
1758     printf("path creation time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
1759 #endif
1760 
1761     // TODO: smoother path
1762     // stairs to surface, surface to stairs correction
1763     if (!cdestpath.empty()) {
1764         TilePoint prvpn = TilePoint(pos_.tx, pos_.ty, pos_.tz, pos_.ox, pos_.oy);
1765         for (std::vector <TilePoint>::iterator it = cdestpath.begin();
1766             it != cdestpath.end(); ++it) {
1767             std::vector <TilePoint>::iterator fit = it + 1;
1768             bool modified = false;
1769             unsigned char twd = m->mtsurfaces_[prvpn.tx
1770                 + prvpn.ty * m->mmax_x_
1771                 + prvpn.tz * m->mmax_m_xy].twd;
1772             unsigned char twdn = m->mtsurfaces_[it->tx
1773                 + it->ty * m->mmax_x_
1774                 + it->tz * m->mmax_m_xy].twd;
1775             char xf = prvpn.tx - it->tx;
1776             char yf = prvpn.ty - it->ty;
1777             char zf = prvpn.tz - it->tz;
1778             if (twd > 0x0 && twd < 0x05) {
1779                 if (twdn > 0x0 && twdn < 0x05) {
1780                     dest_path_.push_back(*it);
1781                 } else {
1782                     switch (twd) {
1783                         case 0x01:
1784                             if (zf == -1) {
1785                                 if (xf == 0) {
1786                                     dest_path_.push_back(*it);
1787                                     break;
1788                                 }
1789                                 if (xf == 1) {
1790                                     prvpn.ox = 0;
1791                                     prvpn.oy = 0;
1792                                     dest_path_.push_back(prvpn);
1793                                     it->ox = 255;
1794                                     it->oy = 0;
1795                                     dest_path_.push_back(*it);
1796                                     modified = true;
1797                                     break;
1798                                 }
1799                                 if (xf == -1) {
1800                                     prvpn.ox = 255;
1801                                     prvpn.oy = 0;
1802                                     dest_path_.push_back(prvpn);
1803                                     it->ox = 0;
1804                                     it->oy = 0;
1805                                     dest_path_.push_back(*it);
1806                                     modified = true;
1807                                     break;
1808                                 }
1809                             }
1810                             if (zf == 0) {
1811                                 if (xf == 0) {
1812                                     dest_path_.push_back(*it);
1813                                     break;
1814                                 }
1815                                 if (xf == 1) {
1816                                     prvpn.ox = 0;
1817                                     prvpn.oy = 255;
1818                                     dest_path_.push_back(prvpn);
1819                                     it->ox = 255;
1820                                     it->oy = 255;
1821                                     dest_path_.push_back(*it);
1822                                     modified = true;
1823                                     break;
1824                                 }
1825                                 if (xf == -1) {
1826                                     prvpn.ox = 255;
1827                                     prvpn.oy = 255;
1828                                     dest_path_.push_back(prvpn);
1829                                     it->ox = 0;
1830                                     it->oy = 255;
1831                                     dest_path_.push_back(*it);
1832                                     modified = true;
1833                                     break;
1834                                 }
1835                             }
1836                             if (zf == 1)
1837                                 dest_path_.push_back(*it);
1838                             break;
1839                         case 0x02:
1840                             if (zf == -1) {
1841                                 if (xf == 0) {
1842                                     dest_path_.push_back(*it);
1843                                     break;
1844                                 }
1845                                 if (xf == 1) {
1846                                     prvpn.ox = 0;
1847                                     prvpn.oy = 255;
1848                                     dest_path_.push_back(prvpn);
1849                                     it->ox = 255;
1850                                     it->oy = 255;
1851                                     dest_path_.push_back(*it);
1852                                     modified = true;
1853                                     break;
1854                                 }
1855                                 if (xf == -1) {
1856                                     prvpn.ox = 255;
1857                                     prvpn.oy = 255;
1858                                     dest_path_.push_back(prvpn);
1859                                     it->ox = 0;
1860                                     it->oy = 255;
1861                                     dest_path_.push_back(*it);
1862                                     modified = true;
1863                                     break;
1864                                 }
1865                             }
1866                             if (zf == 0) {
1867                                 if (xf == 0) {
1868                                     dest_path_.push_back(*it);
1869                                     break;
1870                                 }
1871                                 if (xf == 1) {
1872                                     prvpn.ox = 0;
1873                                     prvpn.oy = 0;
1874                                     dest_path_.push_back(prvpn);
1875                                     it->ox = 255;
1876                                     it->oy = 0;
1877                                     dest_path_.push_back(*it);
1878                                     modified = true;
1879                                     break;
1880                                 }
1881                                 if (xf == -1) {
1882                                     prvpn.ox = 255;
1883                                     prvpn.oy = 0;
1884                                     dest_path_.push_back(prvpn);
1885                                     it->ox = 0;
1886                                     it->oy = 0;
1887                                     dest_path_.push_back(*it);
1888                                     modified = true;
1889                                     break;
1890                                 }
1891                             }
1892                             if (zf == 1)
1893                                 dest_path_.push_back(*it);
1894                             break;
1895                         case 0x03:
1896                             if (zf == -1) {
1897                                 if (yf == 0) {
1898                                     dest_path_.push_back(*it);
1899                                     break;
1900                                 }
1901                                 if (yf == 1) {
1902                                     prvpn.ox = 255;
1903                                     prvpn.oy = 0;
1904                                     dest_path_.push_back(prvpn);
1905                                     it->ox = 255;
1906                                     it->oy = 255;
1907                                     dest_path_.push_back(*it);
1908                                     modified = true;
1909                                     break;
1910                                 }
1911                                 if (yf == -1) {
1912                                     prvpn.ox = 255;
1913                                     prvpn.oy = 255;
1914                                     dest_path_.push_back(prvpn);
1915                                     it->ox = 255;
1916                                     it->oy = 0;
1917                                     dest_path_.push_back(*it);
1918                                     modified = true;
1919                                     break;
1920                                 }
1921                             }
1922                             if (zf == 0) {
1923                                 if (yf == 0) {
1924                                     dest_path_.push_back(*it);
1925                                     break;
1926                                 }
1927                                 if (yf == 1) {
1928                                     prvpn.ox = 0;
1929                                     prvpn.oy = 255;
1930                                     dest_path_.push_back(prvpn);
1931                                     it->ox = 255;
1932                                     it->oy = 255;
1933                                     dest_path_.push_back(*it);
1934                                     modified = true;
1935                                     break;
1936                                 }
1937                                 if (yf == -1) {
1938                                     prvpn.ox = 255;
1939                                     prvpn.oy = 255;
1940                                     dest_path_.push_back(prvpn);
1941                                     it->ox = 0;
1942                                     it->oy = 255;
1943                                     dest_path_.push_back(*it);
1944                                     modified = true;
1945                                     break;
1946                                 }
1947                             }
1948                             if (zf == 1)
1949                                 dest_path_.push_back(*it);
1950                             break;
1951                         case 0x04:
1952                             if (zf == -1) {
1953                                 if (yf == 0) {
1954                                     dest_path_.push_back(*it);
1955                                     break;
1956                                 }
1957                                 if (yf == 1) {
1958                                     prvpn.ox = 0;
1959                                     prvpn.oy = 0;
1960                                     dest_path_.push_back(prvpn);
1961                                     it->ox = 0;
1962                                     it->oy = 255;
1963                                     dest_path_.push_back(*it);
1964                                     modified = true;
1965                                     break;
1966                                 }
1967                                 if (yf == -1) {
1968                                     prvpn.ox = 0;
1969                                     prvpn.oy = 255;
1970                                     dest_path_.push_back(prvpn);
1971                                     it->ox = 0;
1972                                     it->oy = 0;
1973                                     dest_path_.push_back(*it);
1974                                     modified = true;
1975                                     break;
1976                                 }
1977                             }
1978                             if (zf == 0) {
1979                                 if (yf == 0) {
1980                                     dest_path_.push_back(*it);
1981                                     break;
1982                                 }
1983                                 if (yf == 1) {
1984                                     prvpn.ox = 255;
1985                                     prvpn.oy = 0;
1986                                     dest_path_.push_back(prvpn);
1987                                     it->ox = 255;
1988                                     it->oy = 255;
1989                                     dest_path_.push_back(*it);
1990                                     modified = true;
1991                                     break;
1992                                 }
1993                                 if (yf == -1) {
1994                                     prvpn.ox = 255;
1995                                     prvpn.oy = 255;
1996                                     dest_path_.push_back(prvpn);
1997                                     it->ox = 255;
1998                                     it->oy = 0;
1999                                     dest_path_.push_back(*it);
2000                                     modified = true;
2001                                     break;
2002                                 }
2003                             }
2004                             if (zf == 1)
2005                                 dest_path_.push_back(*it);
2006                             break;
2007                     }
2008                 }
2009             } else {
2010                 if (twdn > 0x0 && twdn < 0x05) {
2011                     switch (twdn) {
2012                         case 0x01:
2013                             if (zf == 1) {
2014                                 if (xf == 0) {
2015                                     dest_path_.push_back(*it);
2016                                     break;
2017                                 }
2018                                 if (xf == -1) {
2019                                     prvpn.ox = 255;
2020                                     prvpn.oy = 0;
2021                                     dest_path_.push_back(prvpn);
2022                                     it->ox = 0;
2023                                     it->oy = 0;
2024                                     dest_path_.push_back(*it);
2025                                     modified = true;
2026                                     break;
2027                                 }
2028                                 if (xf == 1) {
2029                                     prvpn.ox = 0;
2030                                     prvpn.oy = 0;
2031                                     dest_path_.push_back(prvpn);
2032                                     it->ox = 255;
2033                                     it->oy = 0;
2034                                     dest_path_.push_back(*it);
2035                                     modified = true;
2036                                     break;
2037                                 }
2038                             }
2039                             if (zf == 0) {
2040                                 if (xf == 0) {
2041                                     dest_path_.push_back(*it);
2042                                     break;
2043                                 }
2044                                 if (xf == -1) {
2045                                     prvpn.ox = 255;
2046                                     prvpn.oy = 255;
2047                                     dest_path_.push_back(prvpn);
2048                                     it->ox = 0;
2049                                     it->oy = 255;
2050                                     dest_path_.push_back(*it);
2051                                     modified = true;
2052                                     break;
2053                                 }
2054                                 if (xf == 1) {
2055                                     prvpn.ox = 0;
2056                                     prvpn.oy = 255;
2057                                     dest_path_.push_back(prvpn);
2058                                     it->ox = 255;
2059                                     it->oy = 255;
2060                                     dest_path_.push_back(*it);
2061                                     modified = true;
2062                                     break;
2063                                 }
2064                             }
2065                             if (zf == -1)
2066                                 dest_path_.push_back(*it);
2067                             break;
2068                         case 0x02:
2069                             if (zf == 1) {
2070                                 if (xf == 0) {
2071                                     dest_path_.push_back(*it);
2072                                     break;
2073                                 }
2074                                 if (xf == -1) {
2075                                     prvpn.ox = 255;
2076                                     prvpn.oy = 255;
2077                                     dest_path_.push_back(prvpn);
2078                                     it->ox = 0;
2079                                     it->oy = 255;
2080                                     dest_path_.push_back(*it);
2081                                     modified = true;
2082                                     break;
2083                                 }
2084                                 if (xf == 1) {
2085                                     prvpn.ox = 0;
2086                                     prvpn.oy = 255;
2087                                     dest_path_.push_back(prvpn);
2088                                     it->ox = 255;
2089                                     it->oy = 255;
2090                                     dest_path_.push_back(*it);
2091                                     modified = true;
2092                                     break;
2093                                 }
2094                             }
2095                             if (zf == 0) {
2096                                 if (xf == 0) {
2097                                     dest_path_.push_back(*it);
2098                                     break;
2099                                 }
2100                                 if (xf == -1) {
2101                                     prvpn.ox = 255;
2102                                     prvpn.oy = 0;
2103                                     dest_path_.push_back(prvpn);
2104                                     it->ox = 0;
2105                                     it->oy = 0;
2106                                     dest_path_.push_back(*it);
2107                                     modified = true;
2108                                     break;
2109                                 }
2110                                 if (xf == 1) {
2111                                     prvpn.ox = 0;
2112                                     prvpn.oy = 0;
2113                                     dest_path_.push_back(prvpn);
2114                                     it->ox = 255;
2115                                     it->oy = 0;
2116                                     dest_path_.push_back(*it);
2117                                     modified = true;
2118                                     break;
2119                                 }
2120                             }
2121                             if (zf == -1)
2122                                 dest_path_.push_back(*it);
2123                             break;
2124                         case 0x03:
2125                             if (zf == 1) {
2126                                 if (yf == 0) {
2127                                     dest_path_.push_back(*it);
2128                                     break;
2129                                 }
2130                                 if (yf == -1) {
2131                                     prvpn.ox = 255;
2132                                     prvpn.oy = 255;
2133                                     dest_path_.push_back(prvpn);
2134                                     it->ox = 255;
2135                                     it->oy = 0;
2136                                     dest_path_.push_back(*it);
2137                                     modified = true;
2138                                     break;
2139                                 }
2140                                 if (yf == 1) {
2141                                     prvpn.ox = 255;
2142                                     prvpn.oy = 0;
2143                                     dest_path_.push_back(prvpn);
2144                                     it->ox = 255;
2145                                     it->oy = 255;
2146                                     dest_path_.push_back(*it);
2147                                     modified = true;
2148                                     break;
2149                                 }
2150                             }
2151                             if (zf == 0) {
2152                                 if (yf == 0) {
2153                                     dest_path_.push_back(*it);
2154                                     break;
2155                                 }
2156                                 if (yf == -1) {
2157                                     prvpn.ox = 255;
2158                                     prvpn.oy = 255;
2159                                     dest_path_.push_back(prvpn);
2160                                     it->ox = 255;
2161                                     it->oy = 0;
2162                                     dest_path_.push_back(*it);
2163                                     modified = true;
2164                                     break;
2165                                 }
2166                                 if (yf == 1) {
2167                                     prvpn.ox = 255;
2168                                     prvpn.oy = 0;
2169                                     dest_path_.push_back(prvpn);
2170                                     it->ox = 255;
2171                                     it->oy = 255;
2172                                     dest_path_.push_back(*it);
2173                                     modified = true;
2174                                     break;
2175                                 }
2176                             }
2177                             if (zf == -1)
2178                                 dest_path_.push_back(*it);
2179                             break;
2180                         case 0x04:
2181                             if (zf == 1) {
2182                                 if (yf == 0) {
2183                                     dest_path_.push_back(*it);
2184                                     break;
2185                                 }
2186                                 if (yf == -1) {
2187                                     prvpn.ox = 0;
2188                                     prvpn.oy = 255;
2189                                     dest_path_.push_back(prvpn);
2190                                     it->ox = 0;
2191                                     it->oy = 0;
2192                                     dest_path_.push_back(*it);
2193                                     modified = true;
2194                                     break;
2195                                 }
2196                                 if (yf == 1) {
2197                                     prvpn.ox = 0;
2198                                     prvpn.oy = 0;
2199                                     dest_path_.push_back(prvpn);
2200                                     it->ox = 0;
2201                                     it->oy = 255;
2202                                     dest_path_.push_back(*it);
2203                                     modified = true;
2204                                     break;
2205                                 }
2206                             }
2207                             if (zf == 0) {
2208                                 if (yf == 0) {
2209                                     dest_path_.push_back(*it);
2210                                     break;
2211                                 }
2212                                 if (yf == -1) {
2213                                     prvpn.ox = 255;
2214                                     prvpn.oy = 255;
2215                                     dest_path_.push_back(prvpn);
2216                                     it->ox = 255;
2217                                     it->oy = 0;
2218                                     dest_path_.push_back(*it);
2219                                     modified = true;
2220                                     break;
2221                                 }
2222                                 if (yf == 1) {
2223                                     prvpn.ox = 255;
2224                                     prvpn.oy = 0;
2225                                     dest_path_.push_back(prvpn);
2226                                     it->ox = 255;
2227                                     it->oy = 255;
2228                                     dest_path_.push_back(*it);
2229                                     modified = true;
2230                                     break;
2231                                 }
2232                             }
2233                             if (zf == -1)
2234                                 dest_path_.push_back(*it);
2235                             break;
2236                     }
2237                 } else {
2238                     dest_path_.push_back(*it);
2239                 }
2240             }
2241             prvpn = *it;
2242             if (fit == cdestpath.end()) {
2243                 if (modified) {
2244                     dest_path_.push_back(TilePoint(x,y,z,ox,oy));
2245                 } else {
2246                     // untill correct smoothing implemented this
2247                     // will prevent walking on non-walkable tile
2248                     if (xf == -1 && yf == -1) {
2249                         dest_path_.back().ox = 0;
2250                         dest_path_.back().oy = 0;
2251                         dest_path_.push_back(prvpn);
2252                     }
2253                     if (xf == 1 && yf == -1) {
2254                         dest_path_.back().ox = 255;
2255                         dest_path_.back().oy = 0;
2256                         dest_path_.push_back(prvpn);
2257                     }
2258                     if (xf == 1 && yf == 1) {
2259                         dest_path_.back().ox = 255;
2260                         dest_path_.back().oy = 255;
2261                         dest_path_.push_back(prvpn);
2262                     }
2263                     if (xf == -1 && yf == 1) {
2264                         dest_path_.back().ox = 0;
2265                         dest_path_.back().oy = 255;
2266                         dest_path_.push_back(prvpn);
2267                     }
2268                     dest_path_.back().ox = ox;
2269                     dest_path_.back().oy = oy;
2270                 }
2271             }
2272         }
2273     }
2274 #ifdef EXECUTION_SPEED_TIME
2275     printf("smoothing time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
2276 #endif
2277 
2278 #if 0
2279     for (std::list <TilePoint>::iterator it = dest_path_.begin();
2280         it != dest_path_.end(); ++it) {
2281         printf("x %i, y %i, z %i\n", it->tileX(),it->tileY(),it->tileZ());
2282     }
2283 #endif
2284 #ifdef EXECUTION_SPEED_TIME
2285     dest_path_.clear();
2286     printf("+++++++++++++++++++++++++++");
2287     printf("end time %i.%i\n", SDL_GetTicks()/1000, SDL_GetTicks()%1000);
2288 #endif
2289 }
2290 
movementP(Mission * m,int elapsed)2291 bool PedInstance::movementP(Mission *m, int elapsed)
2292 {
2293     bool updated = false;
2294     int used_time = elapsed;
2295 
2296     while ((!dest_path_.empty()) && used_time != 0) {
2297         int nxtTileX = dest_path_.front().tx;
2298         int nxtTileY = dest_path_.front().ty;
2299         int nxtTileZ = dest_path_.front().tz;
2300         if (hold_on_.wayFree != 0 && hold_on_.pathBlocker->isPathBlocker()) {
2301             if (hold_on_.xadj || hold_on_.yadj) {
2302                 if(abs(hold_on_.tilex - nxtTileX) <= hold_on_.xadj
2303                     && abs(hold_on_.tiley - nxtTileY) <= hold_on_.yadj
2304                     && hold_on_.tilez == nxtTileZ)
2305                 {
2306                     if (hold_on_.wayFree == 1)
2307                         return updated;
2308                     // hold_on_.wayFree == 2
2309                     dest_path_.clear();
2310                     speed_ = 0;
2311                     return updated;
2312                 }
2313             } else {
2314                 if (hold_on_.tilex == nxtTileX && hold_on_.tiley == nxtTileY
2315                     && hold_on_.tilez == nxtTileZ)
2316                 {
2317                     if (hold_on_.wayFree == 1)
2318                         return updated;
2319                     // hold_on_.wayFree == 2
2320                     dest_path_.clear();
2321                     speed_ = 0;
2322                     return updated;
2323                 }
2324             }
2325         } else
2326             hold_on_.wayFree = 0;
2327         // TODO: not ignore Z, if tile is stairs diffz is wrong
2328         int adx =
2329              nxtTileX * 256 + dest_path_.front().ox;
2330         int ady =
2331              nxtTileY * 256 + dest_path_.front().oy;
2332         int atx = pos_.tx * 256 + pos_.ox;
2333         int aty = pos_.ty * 256 + pos_.oy;
2334         int diffx = adx - atx, diffy = ady - aty;
2335 
2336         if (abs(diffx) < 16 && abs(diffy) < 16) {
2337             // TODO: maybe something better? then using diffx/diffy?
2338             // for this check
2339             pos_.oy = dest_path_.front().oy;
2340             pos_.ox = dest_path_.front().ox;
2341             pos_.tz = nxtTileZ;
2342             pos_.ty = nxtTileY;
2343             pos_.tx = nxtTileX;
2344             dest_path_.pop_front();
2345             if (dest_path_.empty())
2346                 speed_ = 0;
2347             updated = true;
2348         } else {
2349             setDirection(diffx, diffy, &dir_);
2350 
2351             int dx = 0, dy = 0;
2352             double d = sqrt((double)(diffx * diffx + diffy * diffy));
2353             // object will not move over a distance he can actually move
2354             double avail_time_use = (d / (double)speed_) * 1000.0;
2355             // correcting time availiable for this distance to time
2356             // we can use
2357             if (avail_time_use > used_time)
2358                 avail_time_use = used_time;
2359 
2360             if (abs(diffx) > 0)
2361                 // dx = diffx * (speed_ * used_time / 1000) / d;
2362                 dx = (int)((diffx * (speed_ * avail_time_use) / d) / 1000);
2363             if (abs(diffy) > 0)
2364                 // dy = diffy * (speed_ * used_time / 1000) / d;
2365                 dy = (int)((diffy * (speed_ * avail_time_use) / d) / 1000);
2366 
2367             if (dx || dy) {
2368                 int prv_time = used_time;
2369                 if (dx) {
2370                     used_time -= (int)(((double) dx * 1000.0 * d)
2371                         / (double)(diffx * speed_));
2372                 } else if (dy) {
2373                     used_time -= (int)(((double) dy * 1000.0 * d)
2374                         / (double)(diffy * speed_));
2375                 } else
2376                     used_time = 0;
2377                 if (used_time < 0 || prv_time == used_time)
2378                     used_time = 0;
2379             } else
2380                 used_time = 0;
2381 
2382             updatePlacement(pos_.ox + dx, pos_.oy + dy);
2383             // TODO : what obstacles? cars? doors are already
2384             // setting stop signal, reuse it?
2385 #if 0
2386             if (updatePlacement(pos_.ox + dx, pos_.oy + dy)) {
2387                 ;
2388             } else {
2389                 // TODO: avoid obstacles.
2390                 speed_ = 0;
2391             }
2392 #endif
2393             if(nxtTileX == pos_.tx && nxtTileY == pos_.ty)
2394                 pos_.tz = nxtTileZ;
2395 
2396             if(nxtTileX == pos_.tx && nxtTileY == pos_.ty
2397                 && nxtTileZ == pos_.tz
2398                 && dest_path_.front().ox == pos_.ox
2399                 && dest_path_.front().oy == pos_.oy)
2400             {
2401                 dest_path_.pop_front();
2402             }
2403             if (dest_path_.size() == 0)
2404                 speed_ = 0;
2405 
2406             updated = true;
2407         }
2408 
2409         if ((state_ & pa_smFollowing) != 0) {
2410             // TODO: too big elapsed makes ped move to close to target
2411             // possible solution will be to use movedir like movement
2412             // and calculate distance at every step, but it is
2413             // a high cpu consuming
2414             if (!dest_path_.empty()) {
2415                 WorldPoint wpt(dest_path_.back());
2416                 double dist_cur = distanceToPosition(wpt);
2417                 if (dist_cur < (double)dist_to_pos_) {
2418                     dest_path_.clear();
2419                     speed_ = 0;
2420                 }
2421             }
2422         }
2423 
2424         offzOnStairs(m->mtsurfaces_[pos_.tx + pos_.ty * m->mmax_x_
2425             + pos_.tz * m->mmax_m_xy].twd);
2426     }
2427 #ifdef _DEBUG
2428     if (dest_path_.empty() && speed_) {
2429         printf("Was running at speed %i, destination unknown\n", speed_);
2430         speed_ = 0;
2431     }
2432 #endif
2433 
2434     return updated;
2435 }
2436 
2437 /*! \returns bitmask :
2438  * 0b(1) - success, 1b(2) - bounced, 2b(4) - need bounce (for bounce forbidden),
2439  * 3b(8) - non-walkable tile as base, 4b(16) - wrong direction,
2440  * 5b(32) - dist passed set, 6b(64) -  bouncing restored original dir
2441  * (loop is possible)
2442  */
moveToDir(Mission * m,int elapsed,DirMoveType & dir_move,int dir,int t_posx,int t_posy,int * dist,bool set_dist)2443 uint8 PedInstance::moveToDir(Mission* m, int elapsed, DirMoveType &dir_move,
2444     int dir, int t_posx, int t_posy, int* dist, bool set_dist)
2445 {
2446     // TODO: better non-posiotional random walking
2447     floodPointDesc *based = &(m->mdpoints_[pos_.tx
2448         + pos_.ty * m->mmax_x_ + pos_.tz * m->mmax_m_xy]);
2449     if (based->t == m_fdNonWalkable) {
2450         printf("==== unwalk pos: x %i; y %i; z %i, ox %i, oy %i, oz %i\n",
2451             pos_.tx, pos_.ty, pos_.tz, pos_.ox, pos_.oy, pos_.oz);
2452         printf("moveToDir, Movement from nonwalkable postion\n");
2453         return 8;
2454     }
2455 
2456     // TODO: set safewalk need, somewhere
2457     bool check_safe_walk = dir_move.safe_walk;
2458 
2459     // TODO: find safewalk tile and use normal pathfinding
2460     // to get there
2461     if ((based->t & m_fdSafeWalk) == 0)
2462         check_safe_walk = false;
2463     bool move_to_pos = false;
2464     if (dir == -1) {
2465         if (t_posx != -1 && t_posy != -1) {
2466             setDirection(t_posx - pos_.tx * 256 - pos_.ox,
2467                 t_posy - pos_.ty * 256 - pos_.oy, &dir);
2468             if (dir == -1)
2469                 return 16;
2470             move_to_pos = true;
2471             if (dir_move.dir_modifier == 0)
2472                 dir_move.dir_orig = dir;
2473         } else {
2474             dir = dir_;
2475             dir_move.dir_orig = dir;
2476         }
2477     }
2478 
2479     double dist_curr = (elapsed * speed_) / 1000.0;
2480     if (dist == NULL || (dist && *dist == 0)) {
2481          if (dist_to_pos_ > 0 && (int)dist_curr > dist_to_pos_)
2482              dist_curr = (double) dist_to_pos_;
2483     } else if ((int) dist_curr > (*dist))
2484         dist_curr = (double)(*dist);
2485     bool should_bounce = dir_move.bounce;
2486 
2487     if (dir_move.dir_modifier != 0) {
2488         dir = dir_move.dir_last;
2489     }
2490     double dist_total = 0;
2491     uint8 move_mask = 1;
2492 
2493     while ((int)dist_curr > 0) {
2494         bool need_bounce = false;
2495         double diffx = 0.0, diffy = 0.0;
2496         if (dir == 0) {
2497             diffy = 1.0;
2498         } else if (dir == 64) {
2499             diffx = 1.0;
2500         } else if (dir == 128) {
2501             diffy = -1.0;
2502         } else if (dir == 192) {
2503             diffx = -1.0;
2504         } else if (dir < 64) {
2505             diffx = sin((dir / 128.0) * PI);
2506             diffy = cos((dir / 128.0) * PI);
2507         } else if (dir < 128) {
2508             int dirn = dir % 64;
2509             diffy = -sin((dirn / 128.0) * PI);
2510             diffx = cos((dirn / 128.0) * PI);
2511         } else if (dir < 192) {
2512             int dirn = dir % 64;
2513             diffx = -sin((dirn / 128.0) * PI);
2514             diffy = -cos((dirn / 128.0) * PI);
2515         } else if (dir < 256) {
2516             int dirn = dir % 64;
2517             diffy = sin((dirn / 128.0) * PI);
2518             diffx = -cos((dirn / 128.0) * PI);
2519         }
2520 
2521         double posx = (double)(pos_.tx * 256 + pos_.ox);
2522         double posy = (double)(pos_.ty * 256 + pos_.oy);
2523         floodPointDesc *fpd = &(m->mdpoints_[pos_.tx + pos_.ty * m->mmax_x_ +
2524             pos_.tz * m->mmax_m_xy]);
2525         double dist_passsed = 0;
2526         double dist_inc = sqrt(diffx * diffx + diffy * diffy);
2527 
2528         do {
2529             double px = posx + diffx;
2530             double py = posy + diffy;
2531             int tilenx = diffx >= 0.0 ? ((int)ceil(px)) / 256
2532                 : ((int)floor(px)) / 256;
2533             int tileny = diffy >= 0.0 ? ((int)ceil(py)) / 256
2534                 : ((int)floor(py)) / 256;
2535             if (tilenx < 0 ||  tileny < 0 || tilenx >= m->mmax_x_
2536                 || tileny >= m->mmax_y_)
2537             {
2538                 need_bounce = true;
2539                 break;
2540             }
2541             if (pos_.tx != tilenx || pos_.ty != tileny) {
2542                 // TODO: check for stairs and offset should be correct,
2543                 // to avoid jumping on top of stairs
2544                 int32 dec_z = 0;
2545                 if (tilenx - pos_.tx == 0) {
2546                     if (tileny - pos_.ty > 0) {
2547                         if ((fpd->dirh & 0x01) == 0x01) {
2548                             ++pos_.tz;
2549                             --dec_z;
2550                         } else if ((fpd->dirl & 0x01) == 0x01) {
2551                             --pos_.tz;
2552                             ++dec_z;
2553                         } else if ((fpd->dirm & 0x01) != 0x01) {
2554                             need_bounce = true;
2555                             break;
2556                         }
2557                     } else {
2558                         if ((fpd->dirh & 0x10) == 0x10) {
2559                             ++pos_.tz;
2560                             --dec_z;
2561                         } else if ((fpd->dirl & 0x10) == 0x10) {
2562                             --pos_.tz;
2563                             ++dec_z;
2564                         } else if ((fpd->dirm & 0x10) != 0x10) {
2565                             need_bounce = true;
2566                             break;
2567                         }
2568                     }
2569                 } else if (tileny - pos_.ty == 0) {
2570                     if (tilenx - pos_.tx > 0) {
2571                         if ((fpd->dirh & 0x04) == 0x04) {
2572                             ++pos_.tz;
2573                             --dec_z;
2574                         } else if ((fpd->dirl & 0x04) == 0x04) {
2575                             --pos_.tz;
2576                             ++dec_z;
2577                         } else if ((fpd->dirm & 0x04) != 0x04) {
2578                             need_bounce = true;
2579                             break;
2580                         }
2581                     } else {
2582                         if ((fpd->dirh & 0x40) == 0x40) {
2583                             ++pos_.tz;
2584                             --dec_z;
2585                         } else if ((fpd->dirl & 0x40) == 0x40) {
2586                             --pos_.tz;
2587                             ++dec_z;
2588                         } else if ((fpd->dirm & 0x40) != 0x40) {
2589                             need_bounce = true;
2590                             break;
2591                         }
2592                     }
2593                 } else if (tileny - pos_.ty > 0) {
2594                     if (tilenx - pos_.tx > 0) {
2595                         if ((fpd->dirm & 0x02) != 0x02) {
2596                             need_bounce = true;
2597                             break;
2598                         }
2599                     } else {if ((fpd->dirm & 0x80) != 0x80) {
2600                             need_bounce = true;
2601                             break;
2602                         }
2603                     }
2604                 } else {
2605                     // (tileny - pos_.ty < 0)
2606                     if (tilenx - pos_.tx > 0) {
2607                         if ((fpd->dirm & 0x08) != 0x08) {
2608                             need_bounce = true;
2609                             break;
2610                         }
2611                     } else {if ((fpd->dirm & 0x20) != 0x20) {
2612                             need_bounce = true;
2613                             break;
2614                         }
2615                     }
2616                 }
2617 
2618 #if 0
2619 #ifdef _DEBUG
2620                 if (getDebugID() == 8) {
2621                     printf("x %i, y %i, z %i\n", pos_.tx, pos_.ty, pos_.tz + dec_z);
2622                     printf("nx %i, ny %i, nz %i\n", tilenx, tileny, pos_.tz);
2623                 }
2624 #endif
2625 #endif
2626 
2627                 floodPointDesc *fpd_prv = fpd;
2628                 fpd = &(m->mdpoints_[tilenx + tileny * m->mmax_x_
2629                     + pos_.tz * m->mmax_m_xy]);
2630                 if (check_safe_walk && (fpd->t & m_fdSafeWalk) == 0) {
2631                     pos_.tz += dec_z;
2632                     need_bounce = true;
2633                     break;
2634                 }
2635 
2636                 pos_.tx = tilenx;
2637                 pos_.ty = tileny;
2638                 if (dir_move.dir_modifier != 0) {
2639                     dist_passsed += dist_inc;
2640                     posx = px;
2641                     posy = py;
2642                     if (move_to_pos) {
2643                         dir_move.on_new_tile = true;
2644                         // avoiding direction recovery where tile is same as
2645                         // the one that forced us to bounce
2646                         if (fpd_prv->dirh != fpd->dirh
2647                             || fpd_prv->dirm != fpd->dirm
2648                             || fpd_prv->dirl != fpd->dirl)
2649                         {
2650                             if (dir_move.dir_modifier < 3) {
2651                                 dir_move.dir_modifier = 0;
2652                                 dir_move.dir_last = -1;
2653                                 dir = dir_move.dir_orig;
2654                             } else {
2655                                 dir_move.dir_modifier -= 2;
2656                                 // & 0x00C0 = ((% 256) / 64) * 64
2657                                 dir = (256 + dir - dir_move.modifier_value) & 0x00C0;
2658                                 dir_move.dir_last = dir;
2659                             }
2660                         }
2661                     } else {
2662                         int rand_inc = rand();
2663                         if ((rand_inc & 0x00FF) < 32) {
2664                             dir_move.dir_last = -1;
2665                             dir_move.dir_modifier = 0;
2666                             // & 0x003F = % 64, & 0x00FF = % 256
2667                             dir = (256 + dir + (rand_inc & 0x003F) - 32) & 0x00FF;
2668                         }
2669                     }
2670                     break;
2671                 }
2672             }
2673             dist_passsed += dist_inc;
2674             posx = px;
2675             posy = py;
2676         } while (dist_passsed < dist_curr);
2677 
2678         if (diffx >= 0.0)
2679             // & 0x00FF = % 256
2680             pos_.ox = ((int)ceil(posx)) & 0x00FF;
2681         else
2682             pos_.ox = ((int)floor(posx)) & 0x00FF;
2683         if (diffy >= 0.0)
2684             pos_.oy = ((int)ceil(posy)) & 0x00FF;
2685         else
2686             pos_.oy = ((int)floor(posy)) & 0x00FF;
2687 
2688         dist_curr -= dist_passsed;
2689         if (set_dist)
2690             dist_total += dist_passsed;
2691 
2692         if (need_bounce && should_bounce) {
2693             move_mask |= 2;
2694             if (move_to_pos) {
2695                 if (dir_move.dir_modifier == 0) {
2696                     dir_move.modifier_value = 64;
2697                     dir_move.modifier_value *= getClosestDirs(dir_move.dir_orig,
2698                         dir_move.dir_closest, dir_move.dir_closer);;
2699                     dir_move.dir_modifier = 1;
2700                     dir = dir_move.dir_closest;
2701                     dir_move.dir_last = dir_move.dir_closest;
2702                     dir_move.on_new_tile = false;
2703                 } else if (dir_move.dir_modifier == 1) {
2704                     if (dir_move.on_new_tile) {
2705                         dir_move.dir_modifier += 2;
2706                         // & 0x00C0 = ((% 256) / 64) * 64
2707                         // dir based on closest
2708                         dir = (256 + dir + dir_move.modifier_value) & 0x00C0;
2709                     } else {
2710                         dir_move.modifier_value *= -1;
2711                         dir_move.dir_modifier = 4;
2712                         dir = dir_move.dir_closer;
2713                         dir_move.dir_last = dir_move.dir_closer;
2714                     }
2715                     dir_move.dir_last = dir;
2716 
2717                 // dir based on closest
2718                 } else if (dir_move.dir_modifier == 3) {
2719                     dir = (256 + dir + dir_move.modifier_value) & 0x00C0;
2720                     dir_move.dir_last = dir;
2721                     dir_move.dir_modifier += 2;
2722                 } else if (dir_move.dir_modifier == 5) {
2723                     dir = (256 + dir + dir_move.modifier_value) & 0x00C0;
2724                     dir_move.dir_last = dir;
2725                     dir_move.dir_modifier += 2;
2726 
2727                 // dir based on closer
2728                 } else if (dir_move.dir_modifier == 2) {
2729                     dir = dir_move.dir_closer;
2730                     dir_move.dir_last = dir_move.dir_closer;
2731                     dir_move.dir_modifier += 2;
2732                 } else if (dir_move.dir_modifier == 4) {
2733                     dir = (256 + dir + dir_move.modifier_value) & 0x00C0;
2734                     dir_move.dir_last = dir;
2735                     dir_move.dir_modifier += 2;
2736                 } else if (dir_move.dir_modifier == 6) {
2737                     dir = (256 + dir + dir_move.modifier_value) & 0x00C0;
2738                     dir_move.dir_last = dir;
2739                     dir_move.dir_modifier += 2;
2740                 } else if (dir_move.dir_modifier == 8) {
2741                     dir = (256 + dir + dir_move.modifier_value) & 0x00C0;
2742                     dir_move.dir_last = dir;
2743                     dir_move.dir_modifier += 2;
2744                 } else {
2745                     dir_move.dir_modifier = 0;
2746                     dir_move.dir_last = -1;
2747                     dir = dir_move.dir_orig;
2748                     move_mask |= 64;
2749                     break;
2750                 }
2751             } else if (dir_move.dir_modifier) {
2752                 if (dir_move.dir_modifier == 2)
2753                     dir_move.dir_last += 64;
2754                 if (dir_move.dir_modifier == 3) {
2755                     dir_move.dir_last += (256 - 64);
2756                 }
2757                 dir_move.dir_last &= 0x00FF;
2758                 dir = dir_move.dir_last;
2759                 --dir_move.dir_modifier;
2760             } else {
2761                 dir_move.dir_last = (dir_move.dir_last + 64) & 0x00FF;
2762                 dir = dir_move.dir_last;
2763                 dir_move.dir_modifier = 1;
2764             }
2765             setDirection(dir);
2766         } else if (!move_to_pos && dir_move.dir_modifier != 0) {
2767             setDirection(dir);
2768             if (dir_move.dir_modifier == 1) {
2769                 ++dir_move.dir_modifier;
2770                 dir_move.dir_last += (256 - 64);
2771             }
2772             if (dir_move.dir_modifier == 2) {
2773                 ++dir_move.dir_modifier;
2774                 dir_move.dir_last += 128;
2775             }
2776             if (dir_move.dir_modifier == 3) {
2777                 ++dir_move.dir_modifier;
2778                 dir_move.dir_last += (256 - 64);
2779             }
2780             if (dir_move.dir_modifier == 3) {
2781                 dir_move.dir_modifier = 0;
2782                 dir_move.dir_last += (256 - 64);
2783             }
2784             // &0x00FF = % 256
2785             dir_move.dir_last &= 0x00FF;
2786             dir = dir_move.dir_last;
2787         } else {
2788             setDirection(dir);
2789             if (need_bounce) {
2790                 move_mask ^= 1;
2791                 move_mask |= 4;
2792                 break;
2793             }
2794         }
2795     }
2796     offzOnStairs(m->mtsurfaces_[pos_.tx + pos_.ty * m->mmax_x_
2797         + pos_.tz * m->mmax_m_xy].twd);
2798     if (set_dist && dist != NULL)
2799         *dist = (int)dist_total;
2800 
2801     return move_mask;
2802 }
2803 
getClosestDirs(int dir,int & closest,int & closer)2804 inline int PedInstance::getClosestDirs(int dir, int& closest, int& closer) {
2805     // & 0x003F = % 64
2806     int mod = dir & 0x003F;
2807     if (mod == 0) {
2808         // & 0x00C0 = ((% 256) / 64) * 64
2809         closest = (dir + 64) & 0x00C0;
2810         closer = (256 + dir - 64) & 0x00C0;
2811         return 1;
2812     } else {
2813         if (mod < 32) {
2814             closest = dir & 0x00C0;
2815             closer = (dir + 64) & 0x00C0;
2816             return -1;
2817         } else {
2818             closest = (dir + 64) & 0x00C0;
2819             closer = dir & 0x00C0;
2820         }
2821     }
2822     return 1;
2823 }
2824