/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "hopkins/lines.h" #include "hopkins/graphics.h" #include "hopkins/hopkins.h" #include "common/system.h" #include "common/textconsole.h" namespace Hopkins { int LigneItem::appendToRouteInc(int from, int to, RouteItem *route, int index) { if (to == -1) to = _lineDataEndIdx; for (int i = from; i < to; ++i) route[index++].set(_lineData[2*i], _lineData[2*i+1], _directionRouteInc); return index; } int LigneItem::appendToRouteDec(int from, int to, RouteItem *route, int index) { if (from == -1) from = _lineDataEndIdx - 1; for (int i = from; i > to; --i) route[index++].set(_lineData[2*i], _lineData[2*i+1], _directionRouteDec); return index; } LinesManager::LinesManager() { for (int i = 0; i < MAX_LINES; ++i) { Common::fill((byte *)&_zoneLine[i], (byte *)&_zoneLine[i] + sizeof(LigneZoneItem), 0); Common::fill((byte *)&_lineItem[i], (byte *)&_lineItem[i] + sizeof(LigneItem), 0); } for (int i = 0; i < 4000; ++i) Common::fill((byte *)&_smoothRoute[i], (byte *)&_smoothRoute[i] + sizeof(SmoothItem), 0); for (int i = 0; i < 8001; ++i) _bestRoute[i].set(0, 0, DIR_NONE); for (int i = 0; i < 101; ++i) { Common::fill((byte *)&_segment[i], (byte *)&_segment[i] + sizeof(SegmentItem), 0); Common::fill((byte *)&_squareZone[i], (byte *)&_squareZone[i] + sizeof(SquareZoneItem), 0); } for (int i = 0; i < 105; ++i) { BOBZONE[i] = 0; BOBZONE_FLAG[i] = false; } for (int i = 0; i < 106; ++i) Common::fill((byte *)&ZONEP[i], (byte *)&ZONEP[i] + sizeof(ZonePItem), 0); _linesNumb = 0; _newLineIdx = 0; _newLineDataIdx = 0; _newRouteIdx = 0; _newPosX = 0; _newPosY = 0; _smoothMoveDirection = DIR_NONE; _lastLine = 0; _maxLineIdx = 0; _pathFindingMaxDepth = 0; essai0 = NULL; essai1 = NULL; essai2 = NULL; _lineBuf = (int16 *)g_PTRNUL; _route = (RouteItem *)g_PTRNUL; _currentSegmentId = 0; _largeBuf = g_PTRNUL; } LinesManager::~LinesManager() { _vm->_globals.freeMemory(_largeBuf); } void LinesManager::setParent(HopkinsEngine *vm) { _vm = vm; } /** * Load lines */ void LinesManager::loadLines(const Common::String &file) { resetLines(); _linesNumb = 0; _lastLine = 0; byte *ptr = _vm->_fileManager.loadFile(file); for (int idx = 0; READ_LE_INT16((uint16 *)ptr + (idx * 5)) != -1; idx++) { addLine(idx, (Directions)READ_LE_INT16((uint16 *)ptr + (idx * 5)), READ_LE_INT16((uint16 *)ptr + (idx * 5) + 1), READ_LE_INT16((uint16 *)ptr + (idx * 5) + 2), READ_LE_INT16((uint16 *)ptr + (idx * 5) + 3), READ_LE_INT16((uint16 *)ptr + (idx * 5) + 4)); } initRoute(); _vm->_globals.freeMemory(ptr); } /** * Check Hotspots in Inventory screen * Returns the ID of the hotspot under mouse */ int LinesManager::checkInventoryHotspots(int posX, int posY) { int hotspotId = 0; if (posY >= 120 && posY <= 153) hotspotId = checkInventoryHotspotsRow(posX, 1, false); if (posY >= 154 && posY <= 191) hotspotId = checkInventoryHotspotsRow(posX, 7, false); if (posY >= 192 && posY <= 229) hotspotId = checkInventoryHotspotsRow(posX, 13, false); if (posY >= 230 && posY <= 267) hotspotId = checkInventoryHotspotsRow(posX, 19, false); if (posY >= 268 && posY <= 306) hotspotId = checkInventoryHotspotsRow(posX, 25, true); if (posY >= 268 && posY <= 288 && posX >= _vm->_graphicsManager._scrollOffset + 424 && posX <= _vm->_graphicsManager._scrollOffset + 478) hotspotId = 30; if (posY >= 290 && posY <= 306 && posX >= _vm->_graphicsManager._scrollOffset + 424 && posX <= _vm->_graphicsManager._scrollOffset + 478) hotspotId = 31; if (posY < 114 || posY > 306 || posX < _vm->_graphicsManager._scrollOffset + 152 || posX > _vm->_graphicsManager._scrollOffset + 484) hotspotId = 32; return hotspotId; } /** * Check the hotspots in an inventory line * Returns the hotspot Id under the mouse, if any. */ int LinesManager::checkInventoryHotspotsRow(int posX, int minZoneNum, bool lastRow) { int result = minZoneNum; if (posX >= _vm->_graphicsManager._scrollOffset + 158 && posX < _vm->_graphicsManager._scrollOffset + 208) return result; if (posX >= _vm->_graphicsManager._scrollOffset + 208 && posX < _vm->_graphicsManager._scrollOffset + 266) { result += 1; return result; } if (posX >= _vm->_graphicsManager._scrollOffset + 266 && posX < _vm->_graphicsManager._scrollOffset + 320) { result += 2; return result; } if (posX >= _vm->_graphicsManager._scrollOffset + 320 && posX < _vm->_graphicsManager._scrollOffset + 370) { result += 3; return result; } if (posX >= _vm->_graphicsManager._scrollOffset + 370 && posX < _vm->_graphicsManager._scrollOffset + 424) { result += 4; return result; } if (!lastRow && posX >= _vm->_graphicsManager._scrollOffset + 424 && posX <= _vm->_graphicsManager._scrollOffset + 478) { result += 5; return result; } return 0; } /** * Add Zone Line */ void LinesManager::addZoneLine(int idx, int a2, int a3, int a4, int a5, int bobZoneIdx) { int16 *zoneData; if (a2 == a3 && a3 == a4 && a3 == a5) { BOBZONE_FLAG[bobZoneIdx] = true; BOBZONE[bobZoneIdx] = a3; } else { assert (idx <= MAX_LINES); _zoneLine[idx]._zoneData = (int16 *)_vm->_globals.freeMemory((byte *)_zoneLine[idx]._zoneData); int v8 = abs(a2 - a4); int v9 = abs(a3 - a5); int v20 = 1; if (v8 <= v9) v20 += v9; else v20 += v8; zoneData = (int16 *)_vm->_globals.allocMemory(2 * sizeof(int16) * v20 + (4 * sizeof(int16))); assert(zoneData != (int16 *)g_PTRNUL); _zoneLine[idx]._zoneData = zoneData; int16 *dataP = zoneData; int v23 = 1000 * v8 / v20; int v22 = 1000 * v9 / v20; if (a4 < a2) v23 = -v23; if (a5 < a3) v22 = -v22; int v13 = 1000 * a2; int v16 = 1000 * a3; for (int i = 0; i < v20; i++) { *dataP++ = v13 / 1000; *dataP++ = v16 / 1000; v13 += v23; v16 += v22; } *dataP++ = -1; *dataP++ = -1; _zoneLine[idx]._count = v20; _zoneLine[idx]._bobZoneIdx = bobZoneIdx; } } /** * Add Line */ void LinesManager::addLine(int lineIdx, Directions direction, int a3, int a4, int a5, int a6) { assert (lineIdx <= MAX_LINES); if (_linesNumb < lineIdx) _linesNumb = lineIdx; _lineItem[lineIdx]._lineData = (int16 *)_vm->_globals.freeMemory((byte *)_lineItem[lineIdx]._lineData); int v8 = abs(a3 - a5) + 1; int v34 = abs(a4 - a6) + 1; int v33 = v34; if (v8 > v34) v34 = v8; byte *v10 = _vm->_globals.allocMemory(4 * v34 + 8); assert (v10 != g_PTRNUL); Common::fill(v10, v10 + 4 * v34 + 8, 0); _lineItem[lineIdx]._lineData = (int16 *)v10; int16 *curLineData = _lineItem[lineIdx]._lineData; int v36 = 1000 * v8; int v39 = 1000 * v8 / (v34 - 1); int v37 = 1000 * v33 / (v34 - 1); if (a5 < a3) v39 = -v39; if (a6 < a4) v37 = -v37; int dirX = (int)v39 / 1000; // -1: Left, 0: None, 1: Right int dirY = (int)v37 / 1000; // -1: Up, 0: None, 1: Right if (!dirX) { if (dirY == -1) { _lineItem[lineIdx]._directionRouteInc = DIR_UP; _lineItem[lineIdx]._directionRouteDec = DIR_DOWN; } else if (dirY == 1) { _lineItem[lineIdx]._directionRouteInc = DIR_DOWN; _lineItem[lineIdx]._directionRouteDec = DIR_UP; } // If dirY == 0, no move } else if (dirX == 1) { if (dirY == -1) { _lineItem[lineIdx]._directionRouteInc = DIR_UP_RIGHT; _lineItem[lineIdx]._directionRouteDec = DIR_DOWN_LEFT; } else if (!dirY) { _lineItem[lineIdx]._directionRouteInc = DIR_RIGHT; _lineItem[lineIdx]._directionRouteDec = DIR_LEFT; } else if (dirY == 1) { _lineItem[lineIdx]._directionRouteInc = DIR_DOWN_RIGHT; _lineItem[lineIdx]._directionRouteDec = DIR_UP_LEFT; } } else if (dirX == -1) { if (dirY == 1) { _lineItem[lineIdx]._directionRouteInc = DIR_DOWN_LEFT; _lineItem[lineIdx]._directionRouteDec = DIR_UP_RIGHT; } else if (!dirY) { _lineItem[lineIdx]._directionRouteInc = DIR_LEFT; _lineItem[lineIdx]._directionRouteDec = DIR_RIGHT; } else if (dirY == -1) { _lineItem[lineIdx]._directionRouteInc = DIR_UP_LEFT; _lineItem[lineIdx]._directionRouteDec = DIR_DOWN_RIGHT; } } // Second pass to soften cases where dirY == 0 if (dirX == 1) { if (v37 > 250 && v37 <= 999) { _lineItem[lineIdx]._directionRouteInc = DIR_DOWN_RIGHT; _lineItem[lineIdx]._directionRouteDec = DIR_UP_LEFT; } else if (v37 < -250 && v37 > -1000) { _lineItem[lineIdx]._directionRouteInc = DIR_UP_RIGHT; _lineItem[lineIdx]._directionRouteDec = DIR_DOWN_LEFT; } } else if (dirX == -1) { if (v37 > 250 && v37 <= 999) { _lineItem[lineIdx]._directionRouteInc = DIR_DOWN_LEFT; _lineItem[lineIdx]._directionRouteDec = DIR_UP_RIGHT; } else if (v37 < -250 && v37 > -1000) { // In the original code, the test was on positive values and // was impossible to meet. _lineItem[lineIdx]._directionRouteInc = DIR_UP_LEFT; _lineItem[lineIdx]._directionRouteDec = DIR_DOWN_RIGHT; } } int v40 = v36 / v34; int v38 = 1000 * v33 / v34; if (a5 < a3) v40 = -v40; if (a6 < a4) v38 = -v38; int v24 = 1000 * a3; int v25 = 1000 * a4; int v31 = 1000 * a3 / 1000; int v30 = 1000 * a4 / 1000; int v35 = v34 - 1; for (int v26 = 0; v26 < v35; v26++) { curLineData[0] = v31; curLineData[1] = v30; curLineData += 2; v24 += v40; v25 += v38; v31 = v24 / 1000; v30 = v25 / 1000; } curLineData[0] = a5; curLineData[1] = a6; curLineData += 2; curLineData[0] = -1; curLineData[1] = -1; _lineItem[lineIdx]._lineDataEndIdx = v35 + 1; _lineItem[lineIdx]._direction = direction; ++_linesNumb; } /** * Check collision line */ bool LinesManager::checkCollisionLine(int xp, int yp, int *foundDataIdx, int *foundLineIdx, int startLineIdx, int endLineIdx) { int16 *lineData; int left = xp + 4; int right = xp - 4; int top = yp + 4; int bottom = yp - 4; *foundDataIdx = -1; *foundLineIdx = -1; for (int curLineIdx = startLineIdx; curLineIdx <= endLineIdx; curLineIdx++) { lineData = _lineItem[curLineIdx]._lineData; if (lineData == (int16 *)g_PTRNUL) continue; bool collisionFl = true; int lineStartX = lineData[0]; int lineStartY = lineData[1]; int lineDataIdx = 2 * _lineItem[curLineIdx]._lineDataEndIdx; int lineEndX = lineData[lineDataIdx - 2]; int lineEndY = lineData[lineDataIdx - 1]; if (lineStartX >= lineEndX) { if (right > lineStartX || left < lineEndX) collisionFl = false; } else { // lineStartX < lineEndX if (left < lineStartX || right > lineEndX) collisionFl = false; } if (lineStartY >= lineEndY) { if (bottom > lineStartY || top < lineEndY) collisionFl = false; } else { // lineStartY < lineEndY if (top < lineStartY || bottom > lineEndY) collisionFl = false; } if (!collisionFl) continue; for (int idx = 0; idx < _lineItem[curLineIdx]._lineDataEndIdx; idx++) { int lineX = lineData[0]; int lineY = lineData[1]; lineData += 2; if ((xp == lineX || xp + 1 == lineX) && (yp == lineY || yp + 1 == lineY)) { *foundDataIdx = idx; *foundLineIdx = curLineIdx; return true; } } } return false; } /** * Init route */ void LinesManager::initRoute() { int lineX = _lineItem[0]._lineData[0]; int lineY = _lineItem[0]._lineData[1]; int lineIdx = 1; for (;;) { int curDataIdx = _lineItem[lineIdx]._lineDataEndIdx; int16 *curLineData = _lineItem[lineIdx]._lineData; int curLineX = curLineData[2 * curDataIdx - 2]; int curLineY = curLineData[2 * curDataIdx - 1]; if (_vm->_graphicsManager._maxX == curLineX || _vm->_graphicsManager._maxY == curLineY || _vm->_graphicsManager._minX == curLineX || _vm->_graphicsManager._minY == curLineY || (lineX == curLineX && lineY == curLineY)) break; if (lineIdx == MAX_LINES) error("ERROR - LAST LINE NOT FOUND"); int16 *nextLineData = _lineItem[lineIdx + 1]._lineData; if (nextLineData[0] != curLineX && nextLineData[1] != curLineY) break; ++lineIdx; } _lastLine = lineIdx; for (int idx = 1; idx < MAX_LINES; idx++) { if ((_lineItem[idx]._lineDataEndIdx < _maxLineIdx) && (idx != _lastLine + 1)) { _lineItem[idx]._directionRouteInc = _lineItem[idx - 1]._directionRouteInc; _lineItem[idx]._directionRouteDec = _lineItem[idx - 1]._directionRouteDec; } } } // Avoid int LinesManager::CONTOURNE(int lineIdx, int lineDataIdx, int routeIdx, int destLineIdx, int destLineDataIdx, RouteItem *route) { int curLineIdx = lineIdx; int curLineDataIdx = lineDataIdx; int curRouteIdx = routeIdx; if (lineIdx < destLineIdx) { curRouteIdx = _lineItem[lineIdx].appendToRouteInc(lineDataIdx, -1, route, curRouteIdx); for (int i = lineIdx + 1; i < destLineIdx; i++) curRouteIdx = _lineItem[i].appendToRouteInc(0, -1, route, curRouteIdx); curLineDataIdx = 0; curLineIdx = destLineIdx; } if (curLineIdx > destLineIdx) { curRouteIdx = _lineItem[curLineIdx].appendToRouteDec(curLineDataIdx, 0, route, curRouteIdx); for (int i = curLineIdx - 1; i > destLineIdx; i--) curRouteIdx = _lineItem[i].appendToRouteDec(-1, 0, route, curRouteIdx); curLineDataIdx = _lineItem[destLineIdx]._lineDataEndIdx - 1; curLineIdx = destLineIdx; } if (curLineIdx == destLineIdx) { if (destLineDataIdx >= curLineDataIdx) { curRouteIdx = _lineItem[destLineIdx].appendToRouteInc(curLineDataIdx, destLineDataIdx, route, curRouteIdx); } else { curRouteIdx = _lineItem[destLineIdx].appendToRouteDec(curLineDataIdx, destLineDataIdx, route, curRouteIdx); } } return curRouteIdx; } // Avoid 1 int LinesManager::CONTOURNE1(int lineIdx, int lineDataIdx, int routeIdx, int destLineIdx, int destLineDataIdx, RouteItem *route, int a8, int a9) { int curLineIdx = lineIdx; int curLineDataIdx = lineDataIdx; int curRouteIdx = routeIdx; if (destLineIdx < lineIdx) { curRouteIdx = _lineItem[lineIdx].appendToRouteInc(lineDataIdx, -1, route, curRouteIdx); int v15 = lineIdx + 1; if (v15 == a9 + 1) v15 = a8; while (destLineIdx != v15) { curRouteIdx = _lineItem[v15].appendToRouteInc(0, -1, route, curRouteIdx); ++v15; if (a9 + 1 == v15) v15 = a8; } curLineDataIdx = 0; curLineIdx = destLineIdx; } if (destLineIdx > curLineIdx) { curRouteIdx = _lineItem[curLineIdx].appendToRouteDec(curLineDataIdx, 0, route, curRouteIdx); int v24 = curLineIdx - 1; if (v24 == a8 - 1) v24 = a9; while (destLineIdx != v24) { curRouteIdx = _lineItem[v24].appendToRouteDec(-1, 0, route, curRouteIdx); --v24; if (a8 - 1 == v24) v24 = a9; } curLineDataIdx = _lineItem[destLineIdx]._lineDataEndIdx - 1; curLineIdx = destLineIdx; } if (destLineIdx == curLineIdx) { if (destLineDataIdx >= curLineDataIdx) { curRouteIdx = _lineItem[destLineIdx].appendToRouteInc(curLineDataIdx, destLineDataIdx, route, curRouteIdx); } else { curRouteIdx = _lineItem[destLineIdx].appendToRouteDec(curLineDataIdx, destLineDataIdx, route, curRouteIdx); } } return curRouteIdx; } bool LinesManager::MIRACLE(int fromX, int fromY, int lineIdx, int destLineIdx, int routeIdx) { int v35 = 0; int v36 = 0; int v42 = 0; int v43 = 0; int v44 = 0; int v45 = 0; int v46 = 0; int v47 = 0; int v48 = 0; int v49 = 0; int curX = fromX; int curY = fromY; int curLineIdx = lineIdx; int v7 = routeIdx; int dummyDataIdx; if (checkCollisionLine(fromX, fromY, &dummyDataIdx, &curLineIdx, 0, _linesNumb)) { switch (_lineItem[curLineIdx]._direction) { case DIR_UP: curY -= 2; break; case DIR_UP_RIGHT: curY -= 2; curX += 2; break; case DIR_RIGHT: curX += 2; break; case DIR_DOWN_RIGHT: curY += 2; curX += 2; break; case DIR_DOWN: curY += 2; break; case DIR_DOWN_LEFT: curY += 2; curX -= 2; break; case DIR_LEFT: curX -= 2; break; case DIR_UP_LEFT: curY -= 2; curX -= 2; break; default: break; } } int v41 = curX; int v40 = curY; int v9 = 0; int v10 = v40; for (int i = v40; v40 + 200 > v10; i = v10) { if (checkCollisionLine(v41, i, &v49, &v48, 0, _lastLine) == 1 && v48 <= _lastLine) break; v49 = 0; v48 = -1; ++v9; ++v10; } int v37 = v9; int v12 = 0; int v13 = v40; for (int j = v40; v40 - 200 < v13; j = v13) { if (checkCollisionLine(v41, j, &v47, &v46, 0, _lastLine) == 1 && v46 <= _lastLine) break; v47 = 0; v46 = -1; ++v12; --v13; } int v39 = v12; int v15 = 0; int v16 = v41; for (int k = v41; v41 + 200 > v16; k = v16) { if (checkCollisionLine(k, v40, &v45, &v44, 0, _lastLine) == 1 && v44 <= _lastLine) break; v45 = 0; v44 = -1; ++v15; ++v16; } int v38 = v15; int v18 = 0; int v19 = v41; for (int l = v41; v41 - 200 < v19; l = v19) { if (checkCollisionLine(l, v40, &v43, &v42, 0, _lastLine) == 1 && v42 <= _lastLine) break; v43 = 0; v42 = -1; ++v18; --v19; } if (destLineIdx > curLineIdx) { if (v46 != -1 && v46 <= curLineIdx) v46 = -1; if (v44 != -1 && curLineIdx >= v44) v44 = -1; if (v48 != -1 && curLineIdx >= v48) v48 = -1; if (v42 != -1 && curLineIdx >= v42) v42 = -1; if (v46 != -1 && destLineIdx < v46) v46 = -1; if (v44 != -1 && destLineIdx < v44) v44 = -1; if (v48 != -1 && destLineIdx < v48) v48 = -1; if (v42 != -1 && destLineIdx < v42) v42 = -1; } else if (destLineIdx < curLineIdx) { if (v46 != -1 && v46 >= curLineIdx) v46 = -1; if (v44 != -1 && curLineIdx <= v44) v44 = -1; if (v48 != -1 && curLineIdx <= v48) v48 = -1; if (v42 != -1 && curLineIdx <= v42) v42 = -1; if (v46 != -1 && destLineIdx > v46) v46 = -1; if (v44 != -1 && destLineIdx > v44) v44 = -1; if (v48 != -1 && destLineIdx > v48) v48 = -1; if (v42 != -1 && destLineIdx > v42) v42 = -1; } if (v46 != -1 || v44 != -1 || v48 != -1 || v42 != -1) { Directions newDir = DIR_NONE; if (destLineIdx > curLineIdx) { if (v48 <= v46 && v44 <= v46 && v42 <= v46 && v46 > curLineIdx) newDir = DIR_UP; if (v48 <= v44 && v46 <= v44 && v42 <= v44 && curLineIdx < v44) newDir = DIR_RIGHT; if (v46 <= v48 && v44 <= v48 && v42 <= v48 && curLineIdx < v48) newDir = DIR_DOWN; if (v48 <= v42 && v44 <= v42 && v46 <= v42 && curLineIdx < v42) newDir = DIR_LEFT; } else if (destLineIdx < curLineIdx) { if (v46 == -1) v46 = 1300; if (v44 == -1) v44 = 1300; if (v48 == -1) v48 = 1300; if (v42 == -1) v42 = 1300; if (v46 != 1300 && v48 >= v46 && v44 >= v46 && v42 >= v46 && v46 < curLineIdx) newDir = DIR_UP; if (v44 != 1300 && v48 >= v44 && v46 >= v44 && v42 >= v44 && curLineIdx > v44) newDir = DIR_RIGHT; if (v48 != 1300 && v46 >= v48 && v44 >= v48 && v42 >= v48 && curLineIdx > v48) newDir = DIR_DOWN; if (v42 != 1300 && v48 >= v42 && v44 >= v42 && v46 >= v42 && curLineIdx > v42) newDir = DIR_LEFT; } switch(newDir) { case DIR_UP: v36 = v46; v35 = v47; for (int v22 = 0; v22 < v39; v22++) { if (checkCollisionLine(v41, v40 - v22, &v47, &v46, _lastLine + 1, _linesNumb) && _lastLine < v46) { int v23 = GENIAL(v46, v47, v41, v40 - v22, v41, v40 - v39, v7, &_bestRoute[0]); if (v23 == -1) return false; v7 = v23; if (_newPosY != -1) v22 = _newPosY - v40; } _bestRoute[v7].set(v41, v40 - v22, DIR_UP); v7++; } _newLineIdx = v36; _newLineDataIdx = v35; _newRouteIdx = v7; return true; break; case DIR_RIGHT: v36 = v44; v35 = v45; for (int v31 = 0; v31 < v38; v31++) { if (checkCollisionLine(v31 + v41, v40, &v47, &v46, _lastLine + 1, _linesNumb) && _lastLine < v46) { int v32 = GENIAL(v46, v47, v31 + v41, v40, v38 + v41, v40, v7, &_bestRoute[0]); if (v32 == -1) return false; v7 = v32; if (_newPosX != -1) v31 = _newPosX - v41; } _bestRoute[v7].set(v31 + v41, v40, DIR_RIGHT); v7++; } _newLineIdx = v36; _newLineDataIdx = v35; _newRouteIdx = v7; return true; break; case DIR_DOWN: v36 = v48; v35 = v49; for (int v25 = 0; v25 < v37; v25++) { if (checkCollisionLine(v41, v25 + v40, &v47, &v46, _lastLine + 1, _linesNumb) && _lastLine < v46) { int v26 = GENIAL(v46, v47, v41, v25 + v40, v41, v37 + v40, v7, &_bestRoute[0]); if (v26 == -1) return false; v7 = v26; if (_newPosY != -1) v25 = v40 - _newPosY; } _bestRoute[v7].set(v41, v25 + v40, DIR_DOWN); v7++; } _newLineIdx = v36; _newLineDataIdx = v35; _newRouteIdx = v7; return true; break; case DIR_LEFT: v36 = v42; v35 = v43; for (int v28 = 0; v28 < v18; v28++) { if (checkCollisionLine(v41 - v28, v40, &v47, &v46, _lastLine + 1, _linesNumb) && _lastLine < v46) { int v29 = GENIAL(v46, v47, v41 - v28, v40, v41 - v18, v40, v7, &_bestRoute[0]); if (v29 == -1) return false; v7 = v29; if (_newPosX != -1) v28 = v41 - _newPosX; } _bestRoute[v7].set(v41 - v28, v40, DIR_LEFT); v7++; } _newLineIdx = v36; _newLineDataIdx = v35; _newRouteIdx = v7; return true; break; default: break; } } return false; } int LinesManager::GENIAL(int lineIdx, int dataIdx, int fromX, int fromY, int destX, int destY, int routerIdx, RouteItem *route) { int result = routerIdx; int v80 = -1; ++_pathFindingMaxDepth; if (_pathFindingMaxDepth > 10) { warning("PathFinding - Max depth reached"); route[routerIdx].invalidate(); return -1; } int16 *v10 = _lineItem[lineIdx]._lineData; int v98 = v10[0]; int v97 = v10[1]; int v92 = lineIdx; int v65; bool loopCond = false; for (;;) { int v86 = v92 - 1; int v11 = 2 * _lineItem[v92 - 1]._lineDataEndIdx; int16 *v12 = _lineItem[v92 - 1]._lineData; if (v12 == (int16 *)g_PTRNUL) break; while (v12[v11 - 2] != v98 || v97 != v12[v11 - 1]) { --v86; if (_lastLine - 1 != v86) { v11 = 2 * _lineItem[v86]._lineDataEndIdx; v12 = _lineItem[v86]._lineData; if (v12 != (int16 *)g_PTRNUL) continue; } loopCond = true; break; } if (loopCond) break; v92 = v86; v98 = v12[0]; v97 = v12[1]; } int16 *v13 = _lineItem[lineIdx]._lineData; int v95 = v13[2 * _lineItem[lineIdx]._lineDataEndIdx - 2]; int v93 = v13[2 * _lineItem[lineIdx]._lineDataEndIdx - 1]; int v91 = lineIdx; int foundLineIdx, foundDataIdx; loopCond = false; for (;;) { int v87 = v91 + 1; int v15 = 2 * _lineItem[v91 + 1]._lineDataEndIdx; int16 *v16 = _lineItem[v91 + 1]._lineData; if (v16 == (int16 *)g_PTRNUL) break; int v17; for (;;) { v65 = v15; v17 = v16[v15 - 2]; if (v16[0] == v95 && v93 == v16[1]) break; ++v87; if (v87 != _linesNumb + 1) { v15 = 2 * _lineItem[v87]._lineDataEndIdx; v16 = _lineItem[v87]._lineData; if (v16 != (int16 *)g_PTRNUL) continue; } loopCond = true; break; } if (loopCond) break; v91 = v87; v95 = v17; v93 = v16[v65 - 1]; } int v58 = abs(fromX - destX) + 1; int v85 = abs(fromY - destY) + 1; int v20 = v85; if (v58 > v20) v85 = v58; int v84 = 1000 * v58 / v85; int v83 = 1000 * v20 / v85; int v21 = 1000 * fromX; int v22 = 1000 * fromY; int v82 = fromX; int v81 = fromY; if (destX < fromX) v84 = -v84; if (destY < fromY) v83 = -v83; if (v85 > 800) v85 = 800; Common::fill(&_lineBuf[0], &_lineBuf[1000], 0); int bugLigIdx = 0; for (int v88 = 0; v88 < v85 + 1; v88++) { _lineBuf[bugLigIdx] = v82; _lineBuf[bugLigIdx + 1] = v81; v21 += v84; v22 += v83; v82 = v21 / 1000; v81 = v22 / 1000; bugLigIdx += 2; } bugLigIdx -= 2; int v77 = 0; int v78 = 0; int v79 = 0; for (int v89 = v85 + 1; v89 > 0; v89--) { if (checkCollisionLine(_lineBuf[bugLigIdx], _lineBuf[bugLigIdx + 1], &foundDataIdx, &foundLineIdx, v92, v91) && _lastLine < foundLineIdx) { v80 = foundLineIdx; v77 = foundDataIdx; v78 = _lineBuf[bugLigIdx]; v79 = _lineBuf[bugLigIdx + 1]; break; } bugLigIdx -= 2; } int v66 = 0; int v68 = 0; int v70 = 0; int v72 = 0; for (int i = v92; i <= v91; ++i) { int16 *lineData = _lineItem[i]._lineData; if (lineData == (int16 *)g_PTRNUL) error("error in genial routine"); if (i == v92) { v72 = lineData[2 * _lineItem[i]._lineDataEndIdx - 1]; if (lineData[1] <= lineData[2 * _lineItem[i]._lineDataEndIdx - 1]) v72 = lineData[1]; v70 = lineData[2 * _lineItem[i]._lineDataEndIdx - 1]; if (lineData[1] >= lineData[2 * _lineItem[i]._lineDataEndIdx - 1]) v70 = lineData[1]; v68 = lineData[2 * _lineItem[i]._lineDataEndIdx - 2]; if (lineData[0] <= lineData[2 * _lineItem[i]._lineDataEndIdx - 2]) v68 = lineData[0]; v66 = lineData[2 * _lineItem[i]._lineDataEndIdx - 2]; if (lineData[0] >= lineData[2 * _lineItem[i]._lineDataEndIdx - 2]) v66 = lineData[0]; } else { if (lineData[1] < lineData[2 * _lineItem[i]._lineDataEndIdx - 1] && lineData[1] < v72) v72 = lineData[1]; if (lineData[2 * _lineItem[i]._lineDataEndIdx - 1] < lineData[1] && lineData[2 * _lineItem[i]._lineDataEndIdx - 1] < v72) v72 = lineData[2 * _lineItem[i]._lineDataEndIdx - 1]; if (lineData[1] > lineData[2 * _lineItem[i]._lineDataEndIdx - 1] && lineData[1] > v70) v70 = lineData[1]; if (lineData[2 * _lineItem[i]._lineDataEndIdx - 1] > lineData[1] && lineData[2 * _lineItem[i]._lineDataEndIdx - 1] > v70) v70 = lineData[2 * _lineItem[i]._lineDataEndIdx - 1]; if (lineData[0] < lineData[2 * _lineItem[i]._lineDataEndIdx - 2] && v68 > lineData[0]) v68 = lineData[0]; if (lineData[2 * _lineItem[i]._lineDataEndIdx - 2] < lineData[0] && v68 > lineData[2 * _lineItem[i]._lineDataEndIdx - 2]) v68 = lineData[2 * _lineItem[i]._lineDataEndIdx - 2]; if (lineData[0] > lineData[2 * _lineItem[i]._lineDataEndIdx - 2] && v66 < lineData[0]) v66 = lineData[0]; if (lineData[2 * _lineItem[i]._lineDataEndIdx - 2] > lineData[0] && v66 < lineData[2 * _lineItem[i]._lineDataEndIdx - 2]) v66 = lineData[2 * _lineItem[i]._lineDataEndIdx - 2]; } } int v69 = v68 - 2; int v73 = v72 - 2; int v67 = v66 + 2; int v71 = v70 + 2; if (destX >= v69 && destX <= v67 && destY >= v73 && destY <= v71) { int v34 = destY; int v76 = -1; for (;;) { --v34; if (!checkCollisionLine(destX, v34, &foundDataIdx, &foundLineIdx, v92, v91)) break; v76 = foundLineIdx; if (!v34 || v73 > v34) break; } int v35 = destY; int v75 = -1; for (;;) { ++v35; if (!checkCollisionLine(destX, v35, &foundDataIdx, &foundLineIdx, v92, v91)) break; v75 = foundLineIdx; if (_vm->_globals._characterMaxPosY <= v35 || v71 <= v35) break; } int v36 = destX; int v74 = -1; for (;;) { ++v36; if (!checkCollisionLine(v36, destY, &foundDataIdx, &foundLineIdx, v92, v91)) break; v74 = foundLineIdx; if (_vm->_graphicsManager._maxX <= v36 || v67 <= v36) break; } int v37 = destX; int v38 = -1; for(;;) { --v37; if (!checkCollisionLine(v37, destY, &foundDataIdx, &foundLineIdx, v92, v91)) break; v38 = foundLineIdx; if (v37 <= 0 || v69 >= v37) break; } if (v74 != -1 && v38 != -1 && v76 != -1 && v75 != -1) { route[routerIdx].invalidate(); return -1; } } if (v78 < fromX - 1 || v78 > fromX + 1 || v79 < fromY - 1 || v79 > fromY + 1) { _newPosX = v78; _newPosY = v79; if (lineIdx < v80) { int v43 = 0; int v42 = lineIdx; do { if (v42 == v92 - 1) v42 = v91; ++v43; --v42; if (v42 == v92 - 1) v42 = v91; } while (v80 != v42); if (abs(v80 - lineIdx) == v43) { if (dataIdx > abs(_lineItem[lineIdx]._lineDataEndIdx / 2)) { result = CONTOURNE(lineIdx, dataIdx, routerIdx, v80, v77, route); } else { result = CONTOURNE1(lineIdx, dataIdx, routerIdx, v80, v77, route, v92, v91); } } if (abs(v80 - lineIdx) < v43) result = CONTOURNE(lineIdx, dataIdx, result, v80, v77, route); if (v43 < abs(v80 - lineIdx)) result = CONTOURNE1(lineIdx, dataIdx, result, v80, v77, route, v92, v91); } if (lineIdx > v80) { int v45 = abs(lineIdx - v80); int v47 = lineIdx; int v48 = 0; do { if (v47 == v91 + 1) v47 = v92; ++v48; ++v47; if (v47 == v91 + 1) v47 = v92; } while (v80 != v47); if (v45 == v48) { if (dataIdx > abs(_lineItem[lineIdx]._lineDataEndIdx / 2)) { result = CONTOURNE1(lineIdx, dataIdx, result, v80, v77, route, v92, v91); } else { result = CONTOURNE(lineIdx, dataIdx, result, v80, v77, route); } } if (v45 < v48) result = CONTOURNE(lineIdx, dataIdx, result, v80, v77, route); if (v48 < v45) result = CONTOURNE1(lineIdx, dataIdx, result, v80, v77, route, v92, v91); } if (lineIdx == v80) result = CONTOURNE(lineIdx, dataIdx, result, lineIdx, v77, route); for(;;) { if (!checkCollisionLine(_newPosX, _newPosY, &foundDataIdx, &foundLineIdx, _lastLine + 1, _linesNumb)) break; switch (_lineItem[foundLineIdx]._direction) { case DIR_UP: --_newPosY; break; case DIR_UP_RIGHT: --_newPosY; ++_newPosX; break; case DIR_RIGHT: ++_newPosX; break; case DIR_DOWN_RIGHT: ++_newPosY; ++_newPosX; break; case DIR_DOWN: ++_newPosY; break; case DIR_DOWN_LEFT: ++_newPosY; --_newPosX; break; case DIR_LEFT: --_newPosX; break; case DIR_UP_LEFT: --_newPosY; --_newPosX; break; default: break; } } } else { _newPosX = -1; _newPosY = -1; } return result; } // Avoid 2 RouteItem *LinesManager::PARCOURS2(int fromX, int fromY, int destX, int destY) { int foundLineIdx; int foundDataIdx; int curLineY = 0; int curLineX = 0; int v126[9]; int v131[9]; int collLineDataIdxArr[9]; int collLineIdxArr[9]; int clipDestX = destX; int clipDestY = destY; int curLineIdx = 0; int curLineDataIdx = 0; int lineIdx = 0; int lineDataIdx = 0; Directions newDir = DIR_NONE; int v111 = 0; if (destY <= 24) clipDestY = 25; if (!_vm->_globals._checkDistanceFl) { if (abs(fromX - _vm->_globals._oldRouteFromX) <= 4 && abs(fromY - _vm->_globals._oldRouteFromY) <= 4 && abs(_vm->_globals._oldRouteDestX - destX) <= 4 && abs(_vm->_globals._oldRouteDestY - clipDestY) <= 4) return (RouteItem *)g_PTRNUL; if (abs(fromX - destX) <= 4 && abs(fromY - clipDestY) <= 4) return (RouteItem *)g_PTRNUL; if (_vm->_globals._oldZoneNum > 0 && _vm->_objectsManager._zoneNum > 0 && _vm->_globals._oldZoneNum == _vm->_objectsManager._zoneNum) return (RouteItem *)g_PTRNUL; } _vm->_globals._checkDistanceFl = false; _vm->_globals._oldZoneNum = _vm->_objectsManager._zoneNum; _vm->_globals._oldRouteFromX = fromX; _vm->_globals._oldRouteDestX = destX; _vm->_globals._oldRouteFromY = fromY; _vm->_globals._oldRouteDestY = clipDestY; _pathFindingMaxDepth = 0; int routeIdx = 0; if (destX <= 19) clipDestX = 20; if (clipDestY <= 19) clipDestY = 20; if (clipDestX > _vm->_graphicsManager._maxX - 10) clipDestX = _vm->_graphicsManager._maxX - 10; if (clipDestY > _vm->_globals._characterMaxPosY) clipDestY = _vm->_globals._characterMaxPosY; if (abs(fromX - clipDestX) <= 3 && abs(fromY - clipDestY) <= 3) return (RouteItem *)g_PTRNUL; for (int i = 0; i <= 8; ++i) { collLineIdxArr[i] = -1; collLineDataIdxArr[i] = 0; v131[i] = 1300; v126[i] = 1300; } if (characterRoute(fromX, fromY, clipDestX, clipDestY, -1, -1, 0) == 1) return _bestRoute; int v14 = 0; for (int tmpY = clipDestY; tmpY < _vm->_graphicsManager._maxY; tmpY++, v14++) { if (checkCollisionLine(clipDestX, tmpY, &collLineDataIdxArr[5], &collLineIdxArr[5], 0, _lastLine) && collLineIdxArr[5] <= _lastLine) break; collLineDataIdxArr[5] = 0; collLineIdxArr[5] = -1; } v131[5] = v14; v14 = 0; for (int tmpY = clipDestY; tmpY > _vm->_graphicsManager._minY; tmpY--, v14++) { if (checkCollisionLine(clipDestX, tmpY, &collLineDataIdxArr[1], &collLineIdxArr[1], 0, _lastLine) && collLineIdxArr[1] <= _lastLine) break; collLineDataIdxArr[1] = 0; collLineIdxArr[1] = -1; if (v131[5] < v14 && collLineIdxArr[5] != -1) break; } v131[1] = v14; v14 = 0; for (int tmpX = clipDestX; tmpX < _vm->_graphicsManager._maxX; tmpX++) { if (checkCollisionLine(tmpX, clipDestY, &collLineDataIdxArr[3], &collLineIdxArr[3], 0, _lastLine) && collLineIdxArr[3] <= _lastLine) break; collLineDataIdxArr[3] = 0; collLineIdxArr[3] = -1; ++v14; if (v131[1] < v14 && collLineIdxArr[1] != -1) break; if (v131[5] < v14 && collLineIdxArr[5] != -1) break; } v131[3] = v14; v14 = 0; for (int tmpX = clipDestX; tmpX > _vm->_graphicsManager._minX; tmpX--) { if (checkCollisionLine(tmpX, clipDestY, &collLineDataIdxArr[7], &collLineIdxArr[7], 0, _lastLine) && collLineIdxArr[7] <= _lastLine) break; collLineDataIdxArr[7] = 0; collLineIdxArr[7] = -1; ++v14; if (v131[1] < v14 && collLineIdxArr[1] != -1) break; if (v131[5] < v14 && collLineIdxArr[5] != -1) break; if (v131[3] < v14 && collLineIdxArr[3] != -1) break; } v131[7] = v14; if (collLineIdxArr[1] < 0 || _lastLine < collLineIdxArr[1]) collLineIdxArr[1] = -1; if (collLineIdxArr[3] < 0 || _lastLine < collLineIdxArr[3]) collLineIdxArr[3] = -1; if (collLineIdxArr[5] < 0 || _lastLine < collLineIdxArr[5]) collLineIdxArr[5] = -1; if (collLineIdxArr[7] < 0 || _lastLine < collLineIdxArr[7]) collLineIdxArr[7] = -1; if (collLineIdxArr[1] < 0) v131[1] = 1300; if (collLineIdxArr[3] < 0) v131[3] = 1300; if (collLineIdxArr[5] < 0) v131[5] = 1300; if (collLineIdxArr[7] < 0) v131[7] = 1300; if (collLineIdxArr[1] == -1 && collLineIdxArr[3] == -1 && collLineIdxArr[5] == -1 && collLineIdxArr[7] == -1) return (RouteItem *)g_PTRNUL; if (collLineIdxArr[5] != -1 && v131[1] >= v131[5] && v131[3] >= v131[5] && v131[7] >= v131[5]) { curLineIdx = collLineIdxArr[5]; curLineDataIdx = collLineDataIdxArr[5]; } else if (collLineIdxArr[1] != -1 && v131[5] >= v131[1] && v131[3] >= v131[1] && v131[7] >= v131[1]) { curLineIdx = collLineIdxArr[1]; curLineDataIdx = collLineDataIdxArr[1]; } else if (collLineIdxArr[3] != -1 && v131[1] >= v131[3] && v131[5] >= v131[3] && v131[7] >= v131[3]) { curLineIdx = collLineIdxArr[3]; curLineDataIdx = collLineDataIdxArr[3]; } else if (collLineIdxArr[7] != -1 && v131[5] >= v131[7] && v131[3] >= v131[7] && v131[1] >= v131[7]) { curLineIdx = collLineIdxArr[7]; curLineDataIdx = collLineDataIdxArr[7]; } for (int i = 0; i <= 8; ++i) { collLineIdxArr[i] = -1; collLineDataIdxArr[i] = 0; v131[i] = 1300; v126[i] = 1300; } v14 = 0; for (int tmpY = fromY; tmpY < _vm->_graphicsManager._maxY; tmpY++, v14++) { if (checkCollisionLine(fromX, tmpY, &collLineDataIdxArr[5], &collLineIdxArr[5], 0, _lastLine) && collLineIdxArr[5] <= _lastLine) break; collLineDataIdxArr[5] = 0; collLineIdxArr[5] = -1; } v131[5] = v14 + 1; v14 = 0; for (int tmpY = fromY; tmpY > _vm->_graphicsManager._minY; tmpY--) { if (checkCollisionLine(fromX, tmpY, &collLineDataIdxArr[1], &collLineIdxArr[1], 0, _lastLine) && collLineIdxArr[1] <= _lastLine) break; collLineDataIdxArr[1] = 0; collLineIdxArr[1] = -1; ++v14; if (collLineIdxArr[5] != -1 && v14 > 80) break; } v131[1] = v14 + 1; v14 = 0; for (int tmpX = fromX; tmpX < _vm->_graphicsManager._maxX; tmpX++) { if (checkCollisionLine(tmpX, fromY, &collLineDataIdxArr[3], &collLineIdxArr[3], 0, _lastLine) && collLineIdxArr[3] <= _lastLine) break; collLineDataIdxArr[3] = 0; collLineIdxArr[3] = -1; ++v14; if ((collLineIdxArr[5] != -1 || collLineIdxArr[1] != -1) && (v14 > 100)) break; } v131[3] = v14 + 1; v14 = 0; for (int tmpX = fromX; tmpX > _vm->_graphicsManager._minX; tmpX--) { if (checkCollisionLine(tmpX, fromY, &collLineDataIdxArr[7], &collLineIdxArr[7], 0, _lastLine) && collLineIdxArr[7] <= _lastLine) break; collLineDataIdxArr[7] = 0; collLineIdxArr[7] = -1; ++v14; if ((collLineIdxArr[5] != -1 || collLineIdxArr[1] != -1 || collLineIdxArr[3] != -1) && (v14 > 100)) break; } v131[7] = v14 + 1; if (collLineIdxArr[1] != -1) v126[1] = abs(collLineIdxArr[1] - curLineIdx); if (collLineIdxArr[3] != -1) v126[3] = abs(collLineIdxArr[3] - curLineIdx); if (collLineIdxArr[5] != -1) v126[5] = abs(collLineIdxArr[5] - curLineIdx); if (collLineIdxArr[7] != -1) v126[7] = abs(collLineIdxArr[7] - curLineIdx); if (collLineIdxArr[1] == -1 && collLineIdxArr[3] == -1 && collLineIdxArr[5] == -1 && collLineIdxArr[7] == -1) error("Nearest point not found"); if (collLineIdxArr[1] != -1 && v126[3] >= v126[1] && v126[5] >= v126[1] && v126[7] >= v126[1]) { lineIdx = collLineIdxArr[1]; v111 = v131[1]; newDir = DIR_UP; lineDataIdx = collLineDataIdxArr[1]; } else if (collLineIdxArr[5] != -1 && v126[3] >= v126[5] && v126[1] >= v126[5] && v126[7] >= v126[5]) { lineIdx = collLineIdxArr[5]; v111 = v131[5]; newDir = DIR_DOWN; lineDataIdx = collLineDataIdxArr[5]; } else if (collLineIdxArr[3] != -1 && v126[1] >= v126[3] && v126[5] >= v126[3] && v126[7] >= v126[3]) { lineIdx = collLineIdxArr[3]; v111 = v131[3]; newDir = DIR_RIGHT; lineDataIdx = collLineDataIdxArr[3]; } else if (collLineIdxArr[7] != -1 && v126[1] >= v126[7] && v126[5] >= v126[7] && v126[3] >= v126[7]) { lineIdx = collLineIdxArr[7]; v111 = v131[7]; newDir = DIR_LEFT; lineDataIdx = collLineDataIdxArr[7]; } int v55 = characterRoute(fromX, fromY, clipDestX, clipDestY, lineIdx, curLineIdx, 0); if (v55 == 1) return _bestRoute; if (v55 == 2) { lineIdx = _newLineIdx; lineDataIdx = _newLineDataIdx; routeIdx = _newRouteIdx; } else { if (newDir == DIR_UP) { for (int deltaY = 0; deltaY < v111; deltaY++) { if (checkCollisionLine(fromX, fromY - deltaY, &foundDataIdx, &foundLineIdx, _lastLine + 1, _linesNumb) && _lastLine < foundLineIdx) { int tmpRouteIdx = GENIAL(foundLineIdx, foundDataIdx, fromX, fromY - deltaY, fromX, fromY - v111, routeIdx, _bestRoute); if (tmpRouteIdx == -1) { _bestRoute[routeIdx].invalidate(); return &_bestRoute[0]; } routeIdx = tmpRouteIdx; if (_newPosY != -1) deltaY = fromY - _newPosY; } _bestRoute[routeIdx].set(fromX, fromY - deltaY, DIR_UP); routeIdx++; } } if (newDir == DIR_DOWN) { for (int deltaY = 0; deltaY < v111; deltaY++) { if (checkCollisionLine(fromX, deltaY + fromY, &foundDataIdx, &foundLineIdx, _lastLine + 1, _linesNumb) && _lastLine < foundLineIdx) { int tmpRouteIdx = GENIAL(foundLineIdx, foundDataIdx, fromX, deltaY + fromY, fromX, v111 + fromY, routeIdx, &_bestRoute[0]); if (tmpRouteIdx == -1) { _bestRoute[routeIdx].invalidate(); return &_bestRoute[0]; } routeIdx = tmpRouteIdx; if (_newPosY != -1) deltaY = _newPosY - fromY; } _bestRoute[routeIdx].set(fromX, fromY + deltaY, DIR_DOWN); routeIdx++; } } if (newDir == DIR_LEFT) { for (int deltaX = 0; deltaX < v111; deltaX++) { if (checkCollisionLine(fromX - deltaX, fromY, &foundDataIdx, &foundLineIdx, _lastLine + 1, _linesNumb) && _lastLine < foundLineIdx) { int tmpRouteIdx = GENIAL(foundLineIdx, foundDataIdx, fromX - deltaX, fromY, fromX - v111, fromY, routeIdx, &_bestRoute[0]); if (tmpRouteIdx == -1) { _bestRoute[routeIdx].invalidate(); return &_bestRoute[0]; } routeIdx = tmpRouteIdx; if (_newPosX != -1) deltaX = fromX - _newPosX; } _bestRoute[routeIdx].set(fromX - deltaX, fromY, DIR_LEFT); routeIdx++; } } if (newDir == DIR_RIGHT) { for (int deltaX = 0; deltaX < v111; deltaX++) { if (checkCollisionLine(deltaX + fromX, fromY, &foundDataIdx, &foundLineIdx, _lastLine + 1, _linesNumb) && _lastLine < foundLineIdx) { int tmpRouteIdx = GENIAL(foundLineIdx, foundDataIdx, deltaX + fromX, fromY, v111 + fromX, fromY, routeIdx, &_bestRoute[0]); if (tmpRouteIdx == -1) { _bestRoute[routeIdx].invalidate(); return &_bestRoute[0]; } routeIdx = tmpRouteIdx; if (_newPosX != -1) deltaX = _newPosX - fromX; } _bestRoute[routeIdx].set(fromX + deltaX, fromY, DIR_RIGHT); routeIdx++; } } } bool loopCond; do { loopCond = false; if (lineIdx < curLineIdx) { for (int i = lineDataIdx; _lineItem[lineIdx]._lineDataEndIdx > i; ++i) { curLineX = _lineItem[lineIdx]._lineData[2 * i]; curLineY = _lineItem[lineIdx]._lineData[2 * i + 1]; _bestRoute[routeIdx].set(_lineItem[lineIdx]._lineData[2 * i], _lineItem[lineIdx]._lineData[2 * i + 1], _lineItem[lineIdx]._directionRouteInc); routeIdx++; } for (int idx = lineIdx + 1; idx < curLineIdx; idx++) { for (int dataIdx = 0; _lineItem[idx]._lineDataEndIdx > dataIdx; dataIdx++) { curLineX = _lineItem[idx]._lineData[2 * dataIdx]; curLineY = _lineItem[idx]._lineData[2 * dataIdx + 1]; _bestRoute[routeIdx].set(_lineItem[idx]._lineData[2 * dataIdx], _lineItem[idx]._lineData[2 * dataIdx + 1], _lineItem[idx]._directionRouteInc); routeIdx++; if (_lineItem[idx]._lineDataEndIdx > 30 && dataIdx == _lineItem[idx]._lineDataEndIdx / 2) { int v78 = characterRoute(_lineItem[idx]._lineData[2 * dataIdx], _lineItem[idx]._lineData[2 * dataIdx + 1], clipDestX, clipDestY, idx, curLineIdx, routeIdx); if (v78 == 1) return &_bestRoute[0]; if (v78 == 2 || MIRACLE(curLineX, curLineY, idx, curLineIdx, routeIdx)) { lineIdx = _newLineIdx; lineDataIdx = _newLineDataIdx; routeIdx = _newRouteIdx; loopCond = true; break; } } } if (loopCond) break; int v79 = characterRoute(curLineX, curLineY, clipDestX, clipDestY, idx, curLineIdx, routeIdx); if (v79 == 1) return &_bestRoute[0]; if (v79 == 2 || MIRACLE(curLineX, curLineY, idx, curLineIdx, routeIdx)) { lineIdx = _newLineIdx; lineDataIdx = _newLineDataIdx; routeIdx = _newRouteIdx; loopCond = true; break; } } if (loopCond) continue; lineDataIdx = 0; lineIdx = curLineIdx; } if (lineIdx > curLineIdx) { for (int dataIdx = lineDataIdx; dataIdx > 0; dataIdx--) { curLineX = _lineItem[lineIdx]._lineData[2 * dataIdx]; curLineY = _lineItem[lineIdx]._lineData[2 * dataIdx + 1]; _bestRoute[routeIdx].set(_lineItem[lineIdx]._lineData[2 * dataIdx], _lineItem[lineIdx]._lineData[2 * dataIdx + 1], _lineItem[lineIdx]._directionRouteDec); routeIdx++; } for (int v117 = lineIdx - 1; v117 > curLineIdx; v117--) { for (int dataIdx = _lineItem[v117]._lineDataEndIdx - 1; dataIdx > -1; dataIdx--) { curLineX = _lineItem[v117]._lineData[2 * dataIdx]; curLineY = _lineItem[v117]._lineData[2 * dataIdx + 1]; _bestRoute[routeIdx].set(_lineItem[v117]._lineData[2 * dataIdx], _lineItem[v117]._lineData[2 * dataIdx + 1], _lineItem[v117]._directionRouteDec); routeIdx++; if (_lineItem[v117]._lineDataEndIdx > 30 && dataIdx == _lineItem[v117]._lineDataEndIdx / 2) { int v88 = characterRoute(curLineX, curLineY, clipDestX, clipDestY, v117, curLineIdx, routeIdx); if (v88 == 1) return &_bestRoute[0]; if (v88 == 2 || MIRACLE(curLineX, curLineY, v117, curLineIdx, routeIdx)) { lineIdx = _newLineIdx; lineDataIdx = _newLineDataIdx; routeIdx = _newRouteIdx; loopCond = true; break; } } } if (loopCond) break; int v89 = characterRoute(curLineX, curLineY, clipDestX, clipDestY, v117, curLineIdx, routeIdx); if (v89 == 1) return &_bestRoute[0]; if (v89 == 2 || MIRACLE(curLineX, curLineY, v117, curLineIdx, routeIdx)) { lineIdx = _newLineIdx; lineDataIdx = _newLineDataIdx; routeIdx = _newRouteIdx; loopCond = true; break; } } if (!loopCond) { lineDataIdx = _lineItem[curLineIdx]._lineDataEndIdx - 1; lineIdx = curLineIdx; } } } while (loopCond); if (lineIdx == curLineIdx) { if (lineDataIdx <= curLineDataIdx) { routeIdx = _lineItem[curLineIdx].appendToRouteInc(lineDataIdx, curLineDataIdx, _bestRoute, routeIdx); } else { routeIdx = _lineItem[curLineIdx].appendToRouteDec(lineDataIdx, curLineDataIdx, _bestRoute, routeIdx); } } if (characterRoute(_bestRoute[routeIdx - 1]._x, _bestRoute[routeIdx - 1]._y, clipDestX, clipDestY, -1, -1, routeIdx) != 1) { _bestRoute[routeIdx].invalidate(); } return &_bestRoute[0]; } int LinesManager::characterRoute(int fromX, int fromY, int destX, int destY, int startLineIdx, int endLineIdx, int routeIdx) { int v18; int v19; int v20; int v21; int v22; int v23; int v24; int v33; bool v45; int v54; int v55; Directions newDirection; int v92; int v93; int v94; int v95; int v96; int v97; int v98; int v99; int v100; int v101; int v102; int v103; int v104; int v105; int v106; int v107; int v108; int v109; int v111; int v114; int v115; int v117; int collLineIdx; int collDataIdx = 0; int v140; int v142; bool colResult = false; int curX = fromX; int curY = fromY; int curRouteIdx = routeIdx; bool v136 = false; if (startLineIdx == -1 && endLineIdx == -1) v136 = true; int foundDataIdx; int foundLineIdx = startLineIdx; if (checkCollisionLine(fromX, fromY, &foundDataIdx, &foundLineIdx, 0, _linesNumb)) { switch (_lineItem[foundLineIdx]._direction) { case DIR_UP: curY -= 2; break; case DIR_UP_RIGHT: curY -= 2; curX += 2; break; case DIR_RIGHT: curX += 2; break; case DIR_DOWN_RIGHT: curY += 2; curX += 2; case DIR_DOWN: curY += 2; break; case DIR_DOWN_LEFT: curY += 2; curX -= 2; break; case DIR_LEFT: curX -= 2; break; case DIR_UP_LEFT: curY -= 2; curX -= 2; break; default: break; } } v98 = curX; v97 = curY; v115 = 0; v142 = -1; v140 = -1; collLineIdx = -1; int distX, v10, distY, v12, v13, v14; int repeatFlag = 0; int v143 = 0; int v141 = 0; for (;;) { v111 = curX; v109 = curY; if (destX >= curX - 2 && destX <= curX + 2 && destY >= curY - 2 && destY <= curY + 2) { essai0[v115].invalidate(); goto retLABEL_essai0; } distX = abs(curX - destX); v10 = distX + 1; distY = abs(curY - destY); v107 = distY + 1; if (v10 > v107) v107 = v10; v12 = v107 - 1; assert(v12 != 0); v101 = 1000 * v10 / v12; v99 = 1000 * (distY + 1) / v12; if (destX < curX) v101 = -v101; if (destY < curY) v99 = -v99; v13 = (int16)v101 / 1000; v94 = (int16)v99 / 1000; newDirection = DIR_NONE; if (v94 == -1 && (v101 >= 0 && v101 <= 150)) newDirection = DIR_UP; if (v13 == 1 && (v99 >= -1 && v99 <= 150)) newDirection = DIR_RIGHT; if (v94 == 1 && (v101 >= -150 && v101 <= 150)) newDirection = DIR_DOWN; if (v13 == -1 && (v99 >= -150 && v99 <= 150)) newDirection = DIR_LEFT; if (v94 == -1 && (v101 >= -150 && v101 <= 0)) newDirection = DIR_UP; if (newDirection == DIR_NONE && !checkSmoothMove(curX, v109, destX, destY) && !makeSmoothMove(curX, v109, destX, destY)) { newDirection = _smoothMoveDirection; v14 = 0; for (v14 = 0; _smoothRoute[v14]._posX != -1 && _smoothRoute[v14]._posY != -1; ++v14) { if (checkCollisionLine(_smoothRoute[v14]._posX, _smoothRoute[v14]._posY, &v143, &v142, 0, _linesNumb)) { if (v142 > _lastLine) v142 = -1; break; } essai0[v115].set(_smoothRoute[v14]._posX, _smoothRoute[v14]._posY, newDirection); v115++; if (repeatFlag == 1) { repeatFlag = 2; break; } } if (repeatFlag != 2 && _smoothRoute[v14]._posX != -1 && _smoothRoute[v14]._posY != -1) break; repeatFlag = 1; v18 = v14 - 1; v111 = _smoothRoute[v18]._posX; v109 = _smoothRoute[v18]._posY; } v19 = abs(v111 - destX); v20 = v19 + 1; v95 = abs(v109 - destY); v108 = v95 + 1; if (v20 > (v95 + 1)) v108 = v20; if (v108 <= 10) { essai0[v115].invalidate(); goto retLABEL_essai0; } v21 = v108 - 1; v102 = 1000 * v20 / v21; v100 = 1000 * (v95 + 1) / v21; if (destX < v111) v102 = -v102; if (destY < v109) v100 = -v100; v22 = v102 / 1000; v96 = v100 / 1000; v106 = 1000 * v111; v105 = 1000 * v109; v104 = 1000 * v111 / 1000; v103 = v105 / 1000; if (!(v102 / 1000) && v96 == -1) newDirection = DIR_UP; if (v22 == 1) { if (v96 == -1) newDirection = DIR_UP_RIGHT; if (!v96) newDirection = DIR_RIGHT; if (v96 == 1) newDirection = DIR_DOWN_RIGHT; } if (!v22 && v96 == 1) newDirection = DIR_DOWN; if ((v22 != -1) && (v96 == -1)) { if (v102 >= 0 && v102 < 510) newDirection = DIR_UP; else if (v102 >= 510 && v102 <= 1000) newDirection = DIR_UP_RIGHT; } else { if (v96 == 1) newDirection = DIR_DOWN_LEFT; else if (!v96) newDirection = DIR_LEFT; else if (v96 == -1) { if (v102 >= 0 && v102 < 510) newDirection = DIR_UP; else if (v102 >= 510 && v102 <= 1000) newDirection = DIR_UP_RIGHT; else newDirection = DIR_UP_LEFT; } } if (v22 == 1) { if (v100 >= -1000 && v100 <= -510) newDirection = DIR_UP_RIGHT; if (v100 >= -510 && v100 <= 510) newDirection = DIR_RIGHT; if (v100 >= 510 && v100 <= 1000) newDirection = DIR_DOWN_RIGHT; } if (v96 == 1) { if (v102 >= 510 && v102 <= 1000) newDirection = DIR_DOWN_RIGHT; if (v102 >= -510 && v102 <= 510) newDirection = DIR_DOWN; if (v102 >= -1000 && v102 <= -510) newDirection = DIR_DOWN_LEFT; } if (v22 == -1) { if (v100 >= 510 && v100 <= 1000) newDirection = DIR_DOWN_LEFT; if (v100 >= -510 && v100 <= 510) newDirection = DIR_LEFT; if (v100 >= -1000 && v100 <= -510) newDirection = DIR_UP_LEFT; } if (v96 == -1) { if (v102 >= -1000 && v102 <= -510) newDirection = DIR_UP_LEFT; if (v102 >= -510 && v102 <= 0) newDirection = DIR_UP; } v23 = 0; if (v108 + 1 <= 0) { essai0[v115].invalidate(); goto retLABEL_essai0; } while (!checkCollisionLine(v104, v103, &v143, &v142, 0, _linesNumb)) { essai0[v115].set(v104, v103, newDirection); v106 += v102; v105 += v100; v104 = v106 / 1000; v103 = v105 / 1000; v115++; ++v23; if (v23 >= v108 + 1) { essai0[v115].invalidate(); goto retLABEL_essai0; } } if (_lastLine >= v142) break; v24 = GENIAL(v142, v143, v104, v103, destX, destY, v115, essai0); if (v24 == -1) goto retLABEL_essai0; v115 = v24; if (_newPosX != -1 || _newPosY != -1) { v142 = -1; break; } curX = -1; curY = -1; } essai0[v115].invalidate(); v117 = 0; v33 = v98; v92 = v97; while (true) { if (destX >= v33 - 2 && destX <= v33 + 2 && destY >= v92 - 2 && destY <= v92 + 2) { essai1[v117].invalidate(); goto retLABEL_essai1; } while (v33 != destX) { if (checkCollisionLine(v33, v92, &v141, &v140, 0, _linesNumb)) { if (v140 > _lastLine) v140 = -1; break; } if (v33 < destX) essai1[v117++].set(v33++, v92, DIR_RIGHT); else essai1[v117++].set(v33--, v92, DIR_LEFT); } if (v33 != destX) break; int v43 = v92; while (v43 != destY) { if (checkCollisionLine(destX, v43, &v141, &v140, 0, _linesNumb)) { if (v140 <= _lastLine) break; int v44 = GENIAL(v140, v141, destX, v43, destX, destY, v117, essai1); if (v44 == -1) goto retLABEL_essai1; v117 = v44; if (_newPosX != -1 && _newPosY != -1) break; } if (v43 < destY) essai1[v117++].set(destX, v43++, DIR_DOWN); else essai1[v117++].set(destX, v43--, DIR_UP); } if (v43 == destY) { essai1[v117].invalidate(); goto retLABEL_essai1; } if (v140 <= _lastLine) break; v33 = _newPosX; v92 = _newPosY; v45 = checkCollisionLine(_newPosX, _newPosY, &v141, &v140, 0, _lastLine); if (v45 && v140 <= _lastLine) break; } essai1[v117].invalidate(); v117 = 0; v54 = v98; v93 = v97; while (true) { int v61; v114 = v54; if (destX >= v54 - 2 && destX <= v54 + 2 && destY >= v93 - 2 && destY <= v93 + 2) { essai2[v117].invalidate(); goto retLABEL_essai2; } v55 = v93; while (v55 != destY) { if (checkCollisionLine(v114, v55, &collDataIdx, &collLineIdx, 0, _linesNumb)) { if (collLineIdx > _lastLine) collLineIdx = -1; break; } if (v55 < destY) essai2[v117++].set(v114, v55++, DIR_DOWN); else essai2[v117++].set(v114, v55--, DIR_UP); } if (v55 != destY) break; v61 = v114; while (v61 != destX) { if (checkCollisionLine(v61, destY, &collDataIdx, &collLineIdx, 0, _linesNumb)) { if (collLineIdx <= _lastLine) break; int v62 = GENIAL(collLineIdx, collDataIdx, v61, destY, destX, destY, v117, essai2); if (v62 == -1) { // CHECKME: This goto was to retLABEL_essai1... goto retLABEL_essai2; } v117 = v62; if (_newPosX != -1 && _newPosY != -1) break; } if (v61 < destX) essai2[v117++].set(v61++, destY, DIR_RIGHT); else essai2[v117++].set(v61--, destY, DIR_LEFT); } if (v61 == destX) { collLineIdx = -1; essai2[v117].invalidate(); goto retLABEL_essai2; } if (collLineIdx <= _lastLine) break; v54 = _newPosX; v93 = _newPosY; colResult = checkCollisionLine(_newPosX, _newPosY, &collDataIdx, &collLineIdx, 0, _lastLine); if (colResult && collLineIdx <= _lastLine) break; } essai2[v117].invalidate(); if (!v136) { if (endLineIdx > foundLineIdx) { if (essai0[0]._x != -1 && v142 > foundLineIdx && v140 <= v142 && collLineIdx <= v142 && endLineIdx >= v142) { _newLineIdx = v142; _newLineDataIdx = v143; int i = 0; do { assert(curRouteIdx <= 8000); _bestRoute[curRouteIdx++] = essai0[i++]; } while (essai0[i].isValid()); _newRouteIdx = curRouteIdx; return 2; } if (essai1[0]._x != -1 && foundLineIdx < v140 && collLineIdx <= v140 && v142 <= v140 && endLineIdx >= v140) { _newLineIdx = v140; _newLineDataIdx = v141; int i = 0; do { assert(curRouteIdx <= 8000); _bestRoute[curRouteIdx++] = essai1[i++]; } while (essai1[i].isValid()); _newRouteIdx = curRouteIdx; return 2; } if (essai2[0]._x != -1 && foundLineIdx < collLineIdx && v140 < collLineIdx && v142 < collLineIdx && endLineIdx >= collLineIdx) { _newLineIdx = collLineIdx; _newLineDataIdx = collDataIdx; int i = 0; do { assert(curRouteIdx <= 8000); _bestRoute[curRouteIdx++] = essai2[i++]; } while (essai2[i].isValid()); _newRouteIdx = curRouteIdx; return 2; } } if (endLineIdx < foundLineIdx) { if (v142 == -1) v142 = 1300; if (v140 == -1) v142 = 1300; if (collLineIdx == -1) v142 = 1300; if (essai1[0]._x != -1 && v140 < foundLineIdx && collLineIdx >= v140 && v142 >= v140 && endLineIdx <= v140) { _newLineIdx = v140; _newLineDataIdx = v141; int i = 0; do { assert(curRouteIdx <= 8000); _bestRoute[curRouteIdx++] = essai1[i++]; } while (essai1[i].isValid()); _newRouteIdx = curRouteIdx; return 2; } if (essai2[0]._x != -1 && foundLineIdx > collLineIdx && v140 >= collLineIdx && v142 >= collLineIdx && endLineIdx <= collLineIdx) { _newLineIdx = collLineIdx; _newLineDataIdx = collDataIdx; int i = 0; do { assert(curRouteIdx <= 8000); _bestRoute[curRouteIdx++] = essai2[i++]; } while (essai2[i].isValid()); _newRouteIdx = curRouteIdx; return 2; } // CHECKME: Checking essai0[0]._X might make more sense here? if (essai1[0]._x != -1 && foundLineIdx > v142 && v140 >= v142 && collLineIdx >= v142 && endLineIdx <= v142) { _newLineIdx = v142; _newLineDataIdx = v143; int i = 0; do { assert(curRouteIdx <= 8000); _bestRoute[curRouteIdx++] = essai0[i++]; } while (essai0[i].isValid()); _newRouteIdx = curRouteIdx; return 2; } } } return 0; retLABEL_essai0: if (v115) { int i = 0; do { assert(curRouteIdx <= 8000); _bestRoute[curRouteIdx++] = essai0[i++]; } while (essai0[i].isValid()); } _bestRoute[curRouteIdx].invalidate(); return 1; retLABEL_essai1: if (v117) { int i = 0; do { assert(curRouteIdx <= 8000); _bestRoute[curRouteIdx++] = essai1[i++]; } while (essai1[i].isValid()); } _bestRoute[curRouteIdx].invalidate(); return 1; retLABEL_essai2: if (v117) { int i = 0; do { assert(curRouteIdx <= 8000); _bestRoute[curRouteIdx++] = essai2[i++]; } while (essai2[i].isValid()); } _bestRoute[curRouteIdx].invalidate(); return 1; } RouteItem *LinesManager::cityMapCarRoute(int x1, int y1, int x2, int y2) { RouteItem *result; int arrDelta[10]; int arrDataIdx[10]; int arrLineIdx[10]; int clipX2 = x2; int clipY2 = y2; int superRouteIdx = 0; if (x2 <= 14) clipX2 = 15; if (y2 <= 14) clipY2 = 15; if (clipX2 > _vm->_graphicsManager._maxX - 10) clipX2 = _vm->_graphicsManager._maxX - 10; if (clipY2 > 445) clipY2 = 440; int delta = 0; for (delta = 0; clipY2 + delta < _vm->_graphicsManager._maxY; delta++) { if (checkCollisionLine(clipX2, clipY2 + delta, &arrDataIdx[5], &arrLineIdx[5], 0, _lastLine) && arrLineIdx[5] <= _lastLine) break; arrDataIdx[5] = 0; arrLineIdx[5] = -1; } arrDelta[5] = delta; for (delta = 0; clipY2 - delta > _vm->_graphicsManager._minY; delta++) { if (checkCollisionLine(clipX2, clipY2 - delta , &arrDataIdx[1], &arrLineIdx[1], 0, _lastLine) && arrLineIdx[1] <= _lastLine) break; arrDataIdx[1] = 0; arrLineIdx[1] = -1; if (arrDelta[5] < delta && arrLineIdx[5] != -1) break; } arrDelta[1] = delta; for (delta = 0; clipX2 + delta < _vm->_graphicsManager._maxX; delta++) { if (checkCollisionLine(clipX2 + delta, clipY2, &arrDataIdx[3], &arrLineIdx[3], 0, _lastLine) && arrLineIdx[3] <= _lastLine) break; arrDataIdx[3] = 0; arrLineIdx[3] = -1; if (arrDelta[1] <= delta && arrLineIdx[1] != -1) break; if (arrDelta[5] <= delta && arrLineIdx[5] != -1) break; } arrDelta[3] = delta; for (delta = 0; clipX2 - delta > _vm->_graphicsManager._minX; delta++) { if (checkCollisionLine(clipX2 - delta, clipY2, &arrDataIdx[7], &arrLineIdx[7], 0, _lastLine) && arrLineIdx[7] <= _lastLine) break; arrDataIdx[7] = 0; arrLineIdx[7] = -1; if ((arrDelta[1] <= delta && arrLineIdx[1] != -1) || (arrDelta[3] <= delta && arrLineIdx[3] != -1) || (arrDelta[5] <= delta && arrLineIdx[5] != -1)) break; } arrDelta[7] = delta; int v68 = 0; int v69 = 0; int v72 = 0; int v73 = 0; if (arrLineIdx[1] == -1) arrDelta[1] = 1300; if (arrLineIdx[3] == -1) arrDelta[3] = 1300; if (arrLineIdx[5] == -1) arrDelta[5] = 1300; if (arrLineIdx[7] == -1) arrDelta[7] = 1300; if (arrLineIdx[1] != -1 || arrLineIdx[3] != -1 || arrLineIdx[5] != -1 || arrLineIdx[7] != -1) { bool v23 = false; if (arrLineIdx[5] != -1 && arrDelta[1] >= arrDelta[5] && arrDelta[3] >= arrDelta[5] && arrDelta[7] >= arrDelta[5]) { v73 = arrLineIdx[5]; v72 = arrDataIdx[5]; v23 = true; } if (arrLineIdx[1] != -1 && !v23 && arrDelta[5] >= arrDelta[1] && arrDelta[3] >= arrDelta[1] && arrDelta[7] >= arrDelta[1]) { v73 = arrLineIdx[1]; v72 = arrDataIdx[1]; v23 = true; } if (arrLineIdx[3] != -1 && !v23 && arrDelta[1] >= arrDelta[3] && arrDelta[5] >= arrDelta[3] && arrDelta[7] >= arrDelta[3]) { v73 = arrLineIdx[3]; v72 = arrDataIdx[3]; v23 = true; } if (arrLineIdx[7] != -1 && !v23 && arrDelta[5] >= arrDelta[7] && arrDelta[3] >= arrDelta[7] && arrDelta[1] >= arrDelta[7]) { v73 = arrLineIdx[7]; v72 = arrDataIdx[7]; } for (int v24 = 0; v24 <= 8; v24++) { arrLineIdx[v24] = -1; arrDataIdx[v24] = 0; arrDelta[v24] = 1300; } if (checkCollisionLine(x1, y1, &arrDataIdx[1], &arrLineIdx[1], 0, _lastLine)) { v69 = arrLineIdx[1]; v68 = arrDataIdx[1]; } else if (checkCollisionLine(x1, y1, &arrDataIdx[1], &arrLineIdx[1], 0, _linesNumb)) { int v27 = 0; int v28; for (;;) { v28 = essai2[v27]._x; int v29 = essai2[v27]._y; Directions v66 = essai2[v27]._dir; v27++; if (checkCollisionLine(v28, v29, &arrDataIdx[1], &arrLineIdx[1], 0, _lastLine)) break; _bestRoute[superRouteIdx].set(v28, v29, v66); essai0[superRouteIdx].set(v28, v29, v66); superRouteIdx++; if (v28 == -1) break;; } if (v28 != -1) { v69 = arrLineIdx[1]; v68 = arrDataIdx[1]; } } else { v69 = 1; v68 = 1; superRouteIdx = 0; } bool loopFl = true; while (loopFl) { loopFl = false; if (v69 < v73) { superRouteIdx = _lineItem[v69].appendToRouteInc(v68, _lineItem[v69]._lineDataEndIdx - 2, _bestRoute, superRouteIdx); for (int j = v69 + 1; j < v73; ++j) { if (PLAN_TEST(_lineItem[j]._lineData[0], _lineItem[j]._lineData[1], superRouteIdx, j, v73)) { v69 = _newLineIdx; v68 = _newLineDataIdx; superRouteIdx = _newRouteIdx; loopFl = true; break; } if (_lineItem[j]._lineDataEndIdx - 2 > 0) { superRouteIdx = _lineItem[j].appendToRouteInc(0, _lineItem[j]._lineDataEndIdx - 2, _bestRoute, superRouteIdx); } } if (loopFl) continue; v68 = 0; v69 = v73; } if (v69 > v73) { superRouteIdx = _lineItem[v69].appendToRouteDec(v68, 0, _bestRoute, superRouteIdx); for (int l = v69 - 1; l > v73; --l) { if (PLAN_TEST(_lineItem[l]._lineData[2 * _lineItem[l]._lineDataEndIdx - 2], _lineItem[l]._lineData[2 * _lineItem[l]._lineDataEndIdx - 1], superRouteIdx, l, v73)) { v69 = _newLineIdx; v68 = _newLineDataIdx; superRouteIdx = _newRouteIdx; loopFl = true; break; } superRouteIdx = _lineItem[l].appendToRouteDec(_lineItem[l]._lineDataEndIdx - 2, 0, _bestRoute, superRouteIdx); } if (loopFl) continue; v68 = _lineItem[v73]._lineDataEndIdx - 1; v69 = v73; } if (v69 == v73) { if (v68 <= v72) { superRouteIdx = _lineItem[v73].appendToRouteInc(v68, v72, _bestRoute, superRouteIdx); } else { superRouteIdx = _lineItem[v73].appendToRouteDec(v68, v72, _bestRoute, superRouteIdx); } } } _bestRoute[superRouteIdx].invalidate(); result = &_bestRoute[0]; } else { result = (RouteItem *)g_PTRNUL; } return result; } bool LinesManager::checkSmoothMove(int fromX, int fromY, int destX, int destY) { int foundLineIdx; int foundDataIdx; int distX = abs(fromX - destX) + 1; int distY = abs(fromY - destY) + 1; if (distX > distY) distY = distX; if (distY <= 10) return true; int stepX = 1000 * distX / (distY - 1); int stepY = 1000 * distY / (distY - 1); if (destX < fromX) stepX = -stepX; if (destY < fromY) stepY = -stepY; int smoothPosX = 1000 * fromX; int smoothPosY = 1000 * fromY; int newPosX = fromX; int newPosY = fromY; if (distY + 1 > 0) { int stepCount = 0; while (!checkCollisionLine(newPosX, newPosY, &foundDataIdx, &foundLineIdx, 0, _linesNumb) || foundLineIdx > _lastLine) { smoothPosX += stepX; smoothPosY += stepY; newPosX = smoothPosX / 1000; newPosY = smoothPosY / 1000; ++stepCount; if (stepCount >= distY + 1) return false; } return true; } return false; } bool LinesManager::makeSmoothMove(int fromX, int fromY, int destX, int destY) { int curX = fromX; int curY = fromY; if (fromX > destX && destY > fromY) { int hopkinsIdx = 36; int smoothIdx = 0; int stepCount = 0; while (curX > destX && destY > curY) { int v25 = _vm->_globals._hopkinsItem[hopkinsIdx]._speedX; int v40 = _vm->_globals._hopkinsItem[hopkinsIdx]._speedY; int spriteSize = _vm->_globals._spriteSize[curY]; if (spriteSize < 0) { v25 = _vm->_graphicsManager.zoomOut(v25, -spriteSize); v40 = _vm->_graphicsManager.zoomOut(v40, -spriteSize); } else if (spriteSize > 0) { v25 = _vm->_graphicsManager.zoomIn(v25, spriteSize); v40 = _vm->_graphicsManager.zoomIn(v40, spriteSize); } for (int i = 0; i < v25; i++) { --curX; _smoothRoute[smoothIdx]._posX = curX; if (curY != curY + v40) curY++; _smoothRoute[smoothIdx]._posY = curY; smoothIdx++; } ++hopkinsIdx; if (hopkinsIdx == 48) hopkinsIdx = 36; ++stepCount; } if (stepCount > 5) { _smoothRoute[smoothIdx]._posX = -1; _smoothRoute[smoothIdx]._posY = -1; _smoothMoveDirection = DIR_DOWN_LEFT; return false; } } else if (fromX < destX && destY > fromY) { int hopkinsIdx = 36; int smoothIdx = 0; int stepCount = 0; while (curX < destX && destY > curY) { int v14 = _vm->_globals._hopkinsItem[hopkinsIdx]._speedX; int v39 = _vm->_globals._hopkinsItem[hopkinsIdx]._speedY; int spriteSize = _vm->_globals._spriteSize[curY]; if (spriteSize < 0) { v14 = _vm->_graphicsManager.zoomOut(v14, -spriteSize); v39 = _vm->_graphicsManager.zoomOut(v39, -spriteSize); } else if (spriteSize > 0) { v14 = _vm->_graphicsManager.zoomIn(v14, spriteSize); v39 = _vm->_graphicsManager.zoomIn(v39, spriteSize); } for (int i = 0; i < v14; i++) { ++curX; _smoothRoute[smoothIdx]._posX = curX; if (curY != curY + v39) curY++; _smoothRoute[smoothIdx]._posY = curY; smoothIdx++; } ++hopkinsIdx; if (hopkinsIdx == 48) hopkinsIdx = 36; ++stepCount; } if (stepCount > 5) { _smoothRoute[smoothIdx]._posX = -1; _smoothRoute[smoothIdx]._posY = -1; _smoothMoveDirection = DIR_DOWN_RIGHT; return false; } } else if (fromX > destX && destY < fromY) { int hopkinsIdx = 12; int smoothIdx = 0; int stepCount = 0; while (curX > destX && destY < curY) { int v11 = _vm->_graphicsManager.zoomOut(_vm->_globals._hopkinsItem[hopkinsIdx]._speedX, 25); int v38 = _vm->_graphicsManager.zoomOut(_vm->_globals._hopkinsItem[hopkinsIdx]._speedY, 25); int oldY = curY; for (int v12 = 0; v12 < v11; v12++) { --curX; _smoothRoute[smoothIdx]._posX = curX; if ((uint16)curY != (uint16)oldY + v38) curY--; _smoothRoute[smoothIdx]._posY = curY; smoothIdx++; } ++hopkinsIdx; if (hopkinsIdx == 24) hopkinsIdx = 12; ++stepCount; } if (stepCount > 5) { _smoothRoute[smoothIdx]._posX = -1; _smoothRoute[smoothIdx]._posY = -1; _smoothMoveDirection = DIR_UP_LEFT; return false; } } else if (fromX < destX && destY < fromY) { int hopkinsIdx = 12; int smoothIdx = 0; int stepCount = 0; while (curX < destX && destY < curY) { int oldY = curY; int v7 = _vm->_graphicsManager.zoomOut(_vm->_globals._hopkinsItem[hopkinsIdx]._speedX, 25); int v37 = _vm->_graphicsManager.zoomOut(_vm->_globals._hopkinsItem[hopkinsIdx]._speedY, 25); for (int i = 0; i < v7; i++) { ++curX; _smoothRoute[smoothIdx]._posX = curX; if ((uint16)curY != (uint16)oldY + v37) curY--; _smoothRoute[smoothIdx]._posY = curY; smoothIdx++; } ++hopkinsIdx; if (hopkinsIdx == 24) hopkinsIdx = 12; ++stepCount; } if (stepCount > 5) { _smoothRoute[smoothIdx]._posX = -1; _smoothRoute[smoothIdx]._posY = -1; _smoothMoveDirection = DIR_UP_RIGHT; return false; } } return true; } bool LinesManager::PLAN_TEST(int paramX, int paramY, int superRouteIdx, int a4, int a5) { int v42; int v43; int v44; int v45; int dataIdxTestUp; int dataIdxTestDown; int dataIdxTestLeft; int dataIdxTestRight; int lineIdxTestUp; int lineIdxTestDown; int lineIdxTestLeft; int lineIdxTestRight; int idxTestUp = testLine(paramX, paramY - 2, &v42, &lineIdxTestUp, &dataIdxTestUp); int idxTestDown = testLine(paramX, paramY + 2, &v43, &lineIdxTestDown, &dataIdxTestDown); int idxTestLeft = testLine(paramX - 2, paramY, &v44, &lineIdxTestLeft, &dataIdxTestLeft); int idxTestRight = testLine(paramX + 2, paramY, &v45, &lineIdxTestRight, &dataIdxTestRight); if (idxTestUp == -1 && idxTestDown == -1 && idxTestLeft == -1 && idxTestRight == -1) return false; int v8; if (a4 == -1 || a5 == -1) { if (idxTestUp != -1) v8 = 1; else if (idxTestDown != -1) v8 = 2; else if (idxTestLeft != -1) v8 = 3; else if (idxTestRight != -1) v8 = 4; else return false; } else { int v28 = 100; int v7 = 100; int v35 = 100; int v27 = 100; int v36 = abs(a4 - a5); if (idxTestUp != -1) { v28 = abs(lineIdxTestUp - a5); } if (idxTestDown != -1) { v7 = abs(lineIdxTestDown - a5); } if (idxTestLeft != -1) { v35 = abs(lineIdxTestLeft - a5); } if (idxTestRight != -1) { v27 = abs(lineIdxTestRight - a5); } if (v28 < v36 && v28 <= v7 && v28 <= v35 && v28 <= v27) v8 = 1; else if (v36 > v7 && v28 >= v7 && v35 >= v7 && v27 >= v7) v8 = 2; else if (v35 < v36 && v35 <= v28 && v35 <= v7 && v35 <= v27) v8 = 3; else if (v27 < v36 && v27 <= v28 && v27 <= v7 && v27 <= v35) v8 = 4; else return false; } int v33 = 0; int idxTest = 0; if (v8 == 1) { idxTest = idxTestUp; v33 = v42; _newLineIdx = lineIdxTestUp; _newLineDataIdx = dataIdxTestUp; } else if (v8 == 2) { idxTest = idxTestDown; v33 = v43; _newLineIdx = lineIdxTestDown; _newLineDataIdx = dataIdxTestDown; } else if (v8 == 3) { idxTest = idxTestLeft; v33 = v44; _newLineIdx = lineIdxTestLeft; _newLineDataIdx = dataIdxTestLeft; } else if (v8 == 4) { idxTest = idxTestRight; v33 = v45; _newLineIdx = lineIdxTestRight; _newLineDataIdx = dataIdxTestRight; } int routeIdx = superRouteIdx; if (v33 == 1) { routeIdx = _lineItem[idxTest].appendToRouteInc(0, -1, _bestRoute, routeIdx); } else if (v33 == 2) { routeIdx = _lineItem[idxTest].appendToRouteDec(-1, -1, _bestRoute, routeIdx); } _newRouteIdx = routeIdx; return true; } // Test line int LinesManager::testLine(int paramX, int paramY, int *a3, int *foundLineIdx, int *foundDataIdx) { int16 *lineData; int lineDataEndIdx; int collLineIdx; int collDataIdx; for (int idx = _lastLine + 1; idx < _linesNumb + 1; idx++) { lineData = _lineItem[idx]._lineData; lineDataEndIdx = _lineItem[idx]._lineDataEndIdx; if (lineData[0] == paramX && lineData[1] == paramY) { *a3 = 1; int posX = lineData[2 * (lineDataEndIdx - 1)]; int posY = lineData[2 * (lineDataEndIdx - 1) + 1]; if (_lineItem[idx]._directionRouteInc == DIR_DOWN || _lineItem[idx]._directionRouteInc == DIR_UP) posY += 2; if (_lineItem[idx]._directionRouteInc == DIR_RIGHT || _lineItem[idx]._directionRouteDec == DIR_LEFT) posX += 2; if (!checkCollisionLine(posX, posY, &collDataIdx, &collLineIdx, 0, _lastLine)) error("Error in test line"); *foundLineIdx = collLineIdx; *foundDataIdx = collDataIdx; return idx; } if (lineData[2 * (lineDataEndIdx - 1)] == paramX && lineData[2 * (lineDataEndIdx - 1) + 1] == paramY) { *a3 = 2; int posX = lineData[0]; int posY = lineData[1]; if (_lineItem[idx]._directionRouteInc == DIR_DOWN || _lineItem[idx]._directionRouteInc == DIR_UP) posY -= 2; if (_lineItem[idx]._directionRouteInc == DIR_RIGHT || _lineItem[idx]._directionRouteDec == DIR_LEFT) posX -= 2; if (!checkCollisionLine(posX, posY, &collDataIdx, &collLineIdx, 0, _lastLine)) error("Error in test line"); *foundLineIdx = collLineIdx; *foundDataIdx = collDataIdx; return idx; } } return -1; } int LinesManager::CALC_PROPRE(int idx) { int size = _vm->_globals._spriteSize[idx]; if (_vm->_globals._characterType == 1) { if (size < 0) size = -size; size = 20 * (5 * size - 100) / -80; } else if (_vm->_globals._characterType == 2) { if (size < 0) size = -size; size = 20 * (5 * size - 165) / -67; } int retVal = 25; if (size < 0) retVal = _vm->_graphicsManager.zoomOut(25, -size); else if (size > 0) retVal = _vm->_graphicsManager.zoomIn(25, size); return retVal; } void LinesManager::PACOURS_PROPRE(RouteItem *route) { int routeIdx = 0; Directions oldDir = DIR_NONE; int route0Y = route[0]._y; Directions curDir = route[0]._dir; if (route[0]._x == -1 && route0Y == -1) return; for (;;) { if (oldDir != DIR_NONE && curDir != oldDir) { int oldRouteIdx = routeIdx; int routeCount = 0; int v10 = CALC_PROPRE(route0Y); int curRouteX = route[routeIdx]._x; int curRouteY = route[routeIdx]._y; while (curRouteX != -1 || curRouteY != -1) { int idx = routeIdx; ++routeIdx; ++routeCount; if (route[idx]._dir != curDir) break; curRouteX = route[routeIdx]._x; curRouteY = route[routeIdx]._y; } if (routeCount < v10) { int idx = oldRouteIdx; for (int i = 0; i < routeCount; i++) { route[idx]._dir = oldDir; idx++; } curDir = oldDir; } routeIdx = oldRouteIdx; if (curRouteX == -1 && curRouteY == -1) break; } routeIdx++; oldDir = curDir; route0Y = route[routeIdx]._y; curDir = route[routeIdx]._dir; if (route[routeIdx]._x == -1 && route0Y == -1) break; } } int LinesManager::getMouseZone() { int result; int xp = _vm->_eventsManager._mousePos.x + _vm->_eventsManager._mouseOffset.x; int yp = _vm->_eventsManager._mousePos.y + _vm->_eventsManager._mouseOffset.y; if ((_vm->_eventsManager._mousePos.y + _vm->_eventsManager._mouseOffset.y) > 19) { for (int bobZoneId = 0; bobZoneId <= 48; bobZoneId++) { int bobId = BOBZONE[bobZoneId]; if (bobId && BOBZONE_FLAG[bobZoneId] && _vm->_objectsManager._bob[bobId].field0 && _vm->_objectsManager._bob[bobId]._frameIndex != 250 && !_vm->_objectsManager._bob[bobId]._disabledAnimationFl && xp > _vm->_objectsManager._bob[bobId]._oldX && xp < _vm->_objectsManager._bob[bobId]._oldWidth + _vm->_objectsManager._bob[bobId]._oldX && yp > _vm->_objectsManager._bob[bobId]._oldY) { if (yp < _vm->_objectsManager._bob[bobId]._oldHeight + _vm->_objectsManager._bob[bobId]._oldY) { if (ZONEP[bobZoneId]._spriteIndex == -1) { ZONEP[bobZoneId]._destX = 0; ZONEP[bobZoneId]._destY = 0; } if (!ZONEP[bobZoneId]._destX && !ZONEP[bobZoneId]._destY) { ZONEP[bobZoneId]._destX = _vm->_objectsManager._bob[bobId]._oldWidth + _vm->_objectsManager._bob[bobId]._oldX; ZONEP[bobZoneId]._destY = _vm->_objectsManager._bob[bobId]._oldHeight + _vm->_objectsManager._bob[bobId]._oldY + 6; ZONEP[bobZoneId]._spriteIndex = -1; } return bobZoneId; } } } _currentSegmentId = 0; for (int squareZoneId = 0; squareZoneId <= 99; squareZoneId++) { if (ZONEP[squareZoneId]._enabledFl && _squareZone[squareZoneId]._enabledFl && _squareZone[squareZoneId]._left <= xp && _squareZone[squareZoneId]._right >= xp && _squareZone[squareZoneId]._top <= yp && _squareZone[squareZoneId]._bottom >= yp) { if (_squareZone[squareZoneId]._squareZoneFl) return _zoneLine[_squareZone[squareZoneId]._minZoneLineIdx]._bobZoneIdx; _segment[_currentSegmentId]._minZoneLineIdx = _squareZone[squareZoneId]._minZoneLineIdx; _segment[_currentSegmentId]._maxZoneLineIdx = _squareZone[squareZoneId]._maxZoneLineIdx; ++_currentSegmentId; } } if (!_currentSegmentId) return -1; int colRes1 = 0; for (int yCurrent = yp; yCurrent >= 0; --yCurrent) { colRes1 = checkCollision(xp, yCurrent); if (colRes1 != -1 && ZONEP[colRes1]._enabledFl) break; } if (colRes1 == -1) return -1; int colRes2 = 0; for (int j = yp; j < _vm->_graphicsManager._maxY; ++j) { colRes2 = checkCollision(xp, j); if (colRes2 != -1 && ZONEP[colRes1]._enabledFl) break; } if (colRes2 == -1) return -1; int colRes3 = 0; for (int k = xp; k >= 0; --k) { colRes3 = checkCollision(k, yp); if (colRes3 != -1 && ZONEP[colRes1]._enabledFl) break; } if (colRes3 == -1) return -1; int colRes4 = 0; for (int xCurrent = xp; _vm->_graphicsManager._maxX > xCurrent; ++xCurrent) { colRes4 = checkCollision(xCurrent, yp); if (colRes4 != -1 && ZONEP[colRes1]._enabledFl) break; } if (colRes1 == colRes2 && colRes1 == colRes3 && colRes1 == colRes4) result = colRes1; else result = -1; } else { result = 0; } return result; } int LinesManager::checkCollision(int xp, int yp) { if (_currentSegmentId <= 0) return -1; int xMax = xp + 4; int xMin = xp - 4; for (int idx = 0; idx <= _currentSegmentId; ++idx) { int curZoneLineIdx = _segment[idx]._minZoneLineIdx; if (_segment[idx]._maxZoneLineIdx < curZoneLineIdx) continue; int yMax = yp + 4; int yMin = yp - 4; do { LigneZoneItem *curZoneLine = &_zoneLine[curZoneLineIdx]; int16 *dataP = curZoneLine->_zoneData; if (dataP != (int16 *)g_PTRNUL) { int count = curZoneLine->_count; int startX = dataP[0]; int startY = dataP[1]; int destX = dataP[count * 2 - 2]; int destY = dataP[count * 2 - 1]; bool flag = true; if ((startX < destX && (xMax < startX || xMin > destX)) || (startX >= destX && (xMin > startX || xMax < destX)) || (startY < destY && (yMax < startY || yMin > destY)) || (startY >= destY && (yMin > startY || yMax < destY))) flag = false; if (flag && curZoneLine->_count > 0) { for (int i = 0; i < count; ++i) { int xCheck = *dataP++; int yCheck = *dataP++; if ((xp == xCheck || (xp + 1) == xCheck) && (yp == yCheck)) return curZoneLine->_bobZoneIdx; } } } } while (++curZoneLineIdx <= _segment[idx]._maxZoneLineIdx); } return -1; } // Square Zone void LinesManager::CARRE_ZONE() { for (int idx = 0; idx < 100; ++idx) { SquareZoneItem *curZone = &_squareZone[idx]; curZone->_enabledFl = false; curZone->_squareZoneFl = false; curZone->_left = 1280; curZone->_right = 0; curZone->_top = 460; curZone->_bottom = 0; curZone->_minZoneLineIdx = 401; curZone->_maxZoneLineIdx = 0; } for (int idx = 0; idx < MAX_LINES; ++idx) { int16 *dataP = _zoneLine[idx]._zoneData; if (dataP == (int16 *)g_PTRNUL) continue; SquareZoneItem *curZone = &_squareZone[_zoneLine[idx]._bobZoneIdx]; curZone->_enabledFl = true; if (curZone->_maxZoneLineIdx < idx) curZone->_maxZoneLineIdx = idx; if (curZone->_minZoneLineIdx > idx) curZone->_minZoneLineIdx = idx; for (int i = 0; i < _zoneLine[idx]._count; i++) { int zoneX = *dataP++; int zoneY = *dataP++; if (curZone->_left >= zoneX) curZone->_left = zoneX; if (curZone->_right <= zoneX) curZone->_right = zoneX; if (curZone->_top >= zoneY) curZone->_top = zoneY; if (curZone->_bottom <= zoneY) curZone->_bottom = zoneY; } } for (int idx = 0; idx < 100; idx++) { int zoneWidth = abs(_squareZone[idx]._left - _squareZone[idx]._right); int zoneHeight = abs(_squareZone[idx]._top - _squareZone[idx]._bottom); if (zoneWidth == zoneHeight) _squareZone[idx]._squareZoneFl = true; } } void LinesManager::clearAll() { for (int idx = 0; idx < 105; ++idx) { ZONEP[idx]._destX = 0; ZONEP[idx]._destY = 0; ZONEP[idx]._spriteIndex = 0; } essai0 = (RouteItem *)g_PTRNUL; essai1 = (RouteItem *)g_PTRNUL; essai2 = (RouteItem *)g_PTRNUL; _lineBuf = (int16 *)g_PTRNUL; _route = (RouteItem *)g_PTRNUL; for (int idx = 0; idx < MAX_LINES; ++idx) { _lineItem[idx]._lineDataEndIdx = 0; _lineItem[idx]._direction = DIR_NONE; _lineItem[idx]._directionRouteInc = DIR_NONE; _lineItem[idx]._directionRouteDec = DIR_NONE; _lineItem[idx]._lineData = (int16 *)g_PTRNUL; _zoneLine[idx]._count = 0; _zoneLine[idx]._bobZoneIdx = 0; _zoneLine[idx]._zoneData = (int16 *)g_PTRNUL; } for (int idx = 0; idx < 100; ++idx) _squareZone[idx]._enabledFl = false; // FIXME: Delete these somewhere _vm->_linesManager.essai0 = new RouteItem[8334]; _vm->_linesManager.essai1 = new RouteItem[8334]; _vm->_linesManager.essai2 = new RouteItem[8334]; if (!_vm->_linesManager.essai0) _vm->_linesManager.essai0 = (RouteItem*)g_PTRNUL; if (!_vm->_linesManager.essai1) _vm->_linesManager.essai1 = (RouteItem*)g_PTRNUL; if (!_vm->_linesManager.essai2) _vm->_linesManager.essai2 = (RouteItem*)g_PTRNUL; _largeBuf = _vm->_globals.allocMemory(10000); _vm->_linesManager._lineBuf = (int16 *)(_largeBuf); } /** * Clear all zones and reset nextLine */ void LinesManager::clearAllZones() { for (int idx = 0; idx < MAX_LINES; ++idx) removeZoneLine(idx); } /** * Remove Zone Line */ void LinesManager::removeZoneLine(int idx) { assert (idx <= MAX_LINES); _zoneLine[idx]._zoneData = (int16 *)_vm->_globals.freeMemory((byte *)_zoneLine[idx]._zoneData); } void LinesManager::resetLines() { for (int idx = 0; idx < MAX_LINES; ++idx) { removeLine(idx); _lineItem[idx]._lineDataEndIdx = 0; _lineItem[idx]._lineData = (int16 *)g_PTRNUL; } } // Remove Line void LinesManager::removeLine(int idx) { if (idx > MAX_LINES) error("Attempting to add a line obstacle > MAX_LIGNE."); _lineItem[idx]._lineData = (int16 *)_vm->_globals.freeMemory((byte *)_lineItem[idx]._lineData); } void LinesManager::setMaxLineIdx(int idx) { _maxLineIdx = idx; } void LinesManager::resetLastLine() { _lastLine = 0; } void LinesManager::resetLinesNumb() { _linesNumb = 0; } void LinesManager::enableZone(int idx) { if (BOBZONE[idx]) { BOBZONE_FLAG[idx] = true; } else { ZONEP[idx]._enabledFl = true; } } void LinesManager::disableZone(int idx) { if (BOBZONE[idx]) { BOBZONE_FLAG[idx] = false; } else { ZONEP[idx]._enabledFl = false; } } void LinesManager::checkZone() { int mouseX = _vm->_eventsManager.getMouseX(); int mouseY = _vm->_eventsManager.getMouseY(); int oldMouseY = mouseY; if (_vm->_globals._cityMapEnabledFl || _vm->_eventsManager._startPos.x >= mouseX || (mouseY = _vm->_graphicsManager._scrollOffset + 54, mouseX >= mouseY) || (mouseY = oldMouseY - 1, mouseY < 0 || mouseY > 59)) { if (_vm->_objectsManager._visibleFl) _vm->_objectsManager._eraseVisibleCounter = 4; _vm->_objectsManager._visibleFl = false; } else { _vm->_objectsManager._visibleFl = true; } if (_vm->_objectsManager._forceZoneFl) { _vm->_globals.compteur_71 = 100; _vm->_globals._oldMouseZoneId = -1; _vm->_globals._oldMouseX = -200; _vm->_globals._oldMouseY = -220; _vm->_objectsManager._forceZoneFl = false; } _vm->_globals.compteur_71++; if (_vm->_globals.compteur_71 <= 1) return; if (_vm->_globals._freezeCharacterFl || (_route == (RouteItem *)g_PTRNUL) || _vm->_globals.compteur_71 > 4) { _vm->_globals.compteur_71 = 0; int zoneId; if (_vm->_globals._oldMouseX != mouseX || _vm->_globals._oldMouseY != oldMouseY) { zoneId = getMouseZone(); } else { zoneId = _vm->_globals._oldMouseZoneId; } if (_vm->_globals._oldMouseZoneId != zoneId) { _vm->_graphicsManager.SETCOLOR4(251, 100, 100, 100); _vm->_eventsManager._mouseCursorId = 4; _vm->_eventsManager.changeMouseCursor(4); if (_vm->_globals._forceHideText) { _vm->_fontManager.hideText(5); _vm->_globals._forceHideText = false; return; } } if (zoneId != -1) { if (ZONEP[zoneId]._verbFl1 || ZONEP[zoneId]._verbFl2 || ZONEP[zoneId]._verbFl3 || ZONEP[zoneId]._verbFl4 || ZONEP[zoneId]._verbFl5 || ZONEP[zoneId]._verbFl6 || ZONEP[zoneId]._verbFl7 || ZONEP[zoneId]._verbFl8 || ZONEP[zoneId]._verbFl9 || ZONEP[zoneId]._verbFl10) { if (_vm->_globals._oldMouseZoneId != zoneId) { _vm->_fontManager.initTextBuffers(5, ZONEP[zoneId]._messageId, _vm->_globals._zoneFilename, 0, 430, 0, 0, 252); _vm->_fontManager.showText(5); _vm->_globals._forceHideText = true; } _vm->_globals._hotspotTextColor += 25; if (_vm->_globals._hotspotTextColor > 100) _vm->_globals._hotspotTextColor = 0; _vm->_graphicsManager.SETCOLOR4(251, _vm->_globals._hotspotTextColor, _vm->_globals._hotspotTextColor, _vm->_globals._hotspotTextColor); if (_vm->_eventsManager._mouseCursorId == 4) { if (ZONEP[zoneId]._verbFl1 == 2) { _vm->_eventsManager.changeMouseCursor(16); _vm->_eventsManager._mouseCursorId = 16; _vm->_objectsManager.setVerb(16); } } } else { _vm->_graphicsManager.SETCOLOR4(251, 100, 100, 100); _vm->_eventsManager._mouseCursorId = 4; _vm->_eventsManager.changeMouseCursor(4); } } _vm->_objectsManager._zoneNum = zoneId; _vm->_globals._oldMouseX = mouseX; _vm->_globals._oldMouseY = oldMouseY; _vm->_globals._oldMouseZoneId = zoneId; if (_vm->_globals._freezeCharacterFl && (_vm->_eventsManager._mouseCursorId == 4)) { if (zoneId != -1 && zoneId != 0) _vm->_objectsManager.handleRightButton(); } if ((_vm->_globals._cityMapEnabledFl && zoneId == -1) || !zoneId) { _vm->_objectsManager.setVerb(0); _vm->_eventsManager._mouseCursorId = 0; _vm->_eventsManager.changeMouseCursor(0); } } } } // End of namespace Hopkins