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