mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 06:08:35 +00:00
2f00e8d279
Makes it a bit clearer to understand its purpose
788 lines
19 KiB
C++
788 lines
19 KiB
C++
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "chewy/movclass.h"
|
|
#include "chewy/defines.h"
|
|
#include "chewy/globals.h"
|
|
|
|
namespace Chewy {
|
|
|
|
#define LEFT_VECT -1
|
|
#define RIGHT_VECT 1
|
|
#define MOV_START 0
|
|
#define MOV_FOUND 1
|
|
#define MOV_UNPASSABLE 2
|
|
#define Y_DOWN 1
|
|
#define Y_UP 2
|
|
#define SOURCE_COL 14
|
|
#define DEST_COL 19
|
|
#define CHECK_COL 255
|
|
#define MIN_COL 8
|
|
#define UNBEGEHBAR_COL 3
|
|
#define CONNECT_COL 15
|
|
#define CUR_COL 13
|
|
#define S_OBEN 0
|
|
#define S_RECHTS 1
|
|
#define S_UNTEN 2
|
|
#define S_LINKS 3
|
|
#define MOV_X 1
|
|
#define MOV_Y 2
|
|
|
|
MovClass::MovClass() {
|
|
_vecTbl[0] = -40;
|
|
_vecTbl[1] = 1;
|
|
_vecTbl[2] = 40;
|
|
_vecTbl[3] = -1;
|
|
}
|
|
|
|
MovClass::~MovClass() {
|
|
}
|
|
|
|
void MovClass::goto_xy(GotoPkt *gp) {
|
|
const int16 width = _G(room)->_barriers->getWidth();
|
|
_gpkt = gp;
|
|
_agv.AutoGo = false;
|
|
_agv.Continue = false;
|
|
_vecTbl[0] = -width;
|
|
_vecTbl[2] = width;
|
|
_plotDelay = 20;
|
|
calc_xy();
|
|
_plotDelay = 0;
|
|
|
|
int16 start_feld = get_feld_nr(_gpkt->Sx, _gpkt->Sy);
|
|
int16 ziel_feld = get_feld_nr(_gpkt->Dx, _gpkt->Dy);
|
|
int16 tmp = ziel_feld;
|
|
calc_go(start_feld, &ziel_feld);
|
|
|
|
if (tmp != ziel_feld) {
|
|
get_mov_line();
|
|
if (_gml.MLineFeld != -1) {
|
|
calc_mov_line_xit(_gml.MLineFeld);
|
|
if (_mle.FNr != -1) {
|
|
_agv.AutoGo = true;
|
|
_agv.Start = 0;
|
|
_agv.LastFeld = -1;
|
|
_agv.AkKnoten = 0;
|
|
start_feld = get_feld_nr(_gpkt->Sx, _gpkt->Sy);
|
|
ziel_feld = _gml.MLineFeld;
|
|
calc_go(start_feld, &ziel_feld);
|
|
if (_gml.MLineFeld != ziel_feld) {
|
|
_agv.PktAnz = 2;
|
|
} else {
|
|
_agv.PktAnz = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int16 MovClass::calc_auto_go(int16 x, int16 y, int16 *auto_x, int16 *auto_y) {
|
|
int16 ret = -1;
|
|
|
|
const int16 width = _G(room)->_barriers->getWidth();
|
|
const int16 height = _G(room)->_barriers->getHeight();
|
|
if (_agv.AutoGo == true) {
|
|
const byte *data = _G(room)->_barriers->getData();
|
|
const byte *buffer = data + 6;
|
|
buffer += (width * height) * _gpkt->AkMovEbene;
|
|
if (!_agv.Start) {
|
|
_agv.Start = _agv.PktAnz;
|
|
if (_agv.PktAnz == 1) {
|
|
_agv.Start = 3;
|
|
get_feld_xy(_gml.MLineFeld, &_agv.X_End, &_agv.Y_End);
|
|
_agv.AkFeld = _gml.MLineFeld;
|
|
} else {
|
|
get_feld_xy(_gml.GotoFeld, &_agv.X_End, &_agv.Y_End);
|
|
_agv.AkFeld = _gml.GotoFeld;
|
|
}
|
|
*auto_x = _agv.X_End + 4;
|
|
*auto_y = _agv.Y_End + 4;
|
|
ret = true;
|
|
} else {
|
|
if (get_feld_nr(x, y) == _agv.AkFeld) {
|
|
if (_agv.Start == 2) {
|
|
_agv.Start = 3;
|
|
get_feld_xy(_gml.GotoFeld, &_agv.X_End, &_agv.Y_End);
|
|
*auto_x = _agv.X_End + 4;
|
|
*auto_y = _agv.Y_End + 4;
|
|
ret = true;
|
|
} else if (_agv.Start == 3) {
|
|
if (_agv.LastFeld == -1) {
|
|
_agv.LastFeld = _gml.MLineFeld;
|
|
_agv.AkFeld = _gml.MLineFeld + _mle.Direction;
|
|
if (buffer[_agv.AkFeld] == MOV_LINE_KNOTEN) {
|
|
_feld1knoten = true;
|
|
} else
|
|
_feld1knoten = false;
|
|
get_feld_xy(_agv.AkFeld, &_agv.X_End, &_agv.Y_End);
|
|
*auto_x = _agv.X_End + 4;
|
|
*auto_y = _agv.Y_End + 4;
|
|
ret = true;
|
|
} else if (get_feld_nr(x, y) == _agv.AkFeld) {
|
|
if (_agv.AkFeld == _mle.FNr) {
|
|
_agv.AutoGo = false;
|
|
*auto_x = _gpkt->Dx;
|
|
*auto_y = _gpkt->Dy;
|
|
ret = true;
|
|
} else {
|
|
int16 ok = 0;
|
|
if (_feld1knoten) {
|
|
_feld1knoten = false;
|
|
_agv.LastFeld = _agv.AkFeld;
|
|
_agv.AkFeld = _mle.KnPkt[_agv.AkKnoten];
|
|
++_agv.AkKnoten;
|
|
if (_agv.AkFeld != -1)
|
|
ok = 1;
|
|
} else {
|
|
for (int16 i = 0; i < 4 && !ok; i++) {
|
|
if (buffer[_agv.AkFeld + _vecTbl[i]] == MOV_LINE_IDX) {
|
|
if (_agv.AkFeld + _vecTbl[i] != _agv.LastFeld) {
|
|
_agv.LastFeld = _agv.AkFeld;
|
|
_agv.AkFeld += _vecTbl[i];
|
|
ok = 1;
|
|
}
|
|
} else if (buffer[_agv.AkFeld + _vecTbl[i]] == MOV_LINE_KNOTEN) {
|
|
if (_agv.AkFeld + _vecTbl[i] != _agv.LastFeld) {
|
|
_agv.LastFeld = _agv.AkFeld + _vecTbl[i];
|
|
_agv.AkFeld = _mle.KnPkt[_agv.AkKnoten];
|
|
++_agv.AkKnoten;
|
|
if (_agv.AkFeld == -1)
|
|
ok = 0;
|
|
else
|
|
ok = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (ok) {
|
|
get_feld_xy(_agv.AkFeld, &_agv.X_End, &_agv.Y_End);
|
|
*auto_x = _agv.X_End + 4;
|
|
*auto_y = _agv.Y_End + 4;
|
|
} else {
|
|
_agv.AutoGo = false;
|
|
*auto_x = _gpkt->Dx;
|
|
*auto_y = _gpkt->Dy;
|
|
}
|
|
ret = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[] data;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void MovClass::stop_auto_go() {
|
|
_agv.AutoGo = false;
|
|
_agv.Continue = true;
|
|
}
|
|
|
|
void MovClass::continue_auto_go() {
|
|
_agv.AutoGo = _agv.Continue;
|
|
}
|
|
|
|
bool MovClass::auto_go_status() {
|
|
return _agv.AutoGo;
|
|
}
|
|
|
|
void MovClass::calc_xy() {
|
|
int16 xvector = 0;
|
|
int16 yvector = 0;
|
|
|
|
if (!_G(barriers)->getBarrierId(_gpkt->Dx, _gpkt->Dy)) {
|
|
int16 ende = 0;
|
|
int16 count = 0;
|
|
int16 min_x = -1;
|
|
int16 min_y = -1;
|
|
const int16 width = _G(room)->_barriers->getWidth();
|
|
const int16 height = _G(room)->_barriers->getHeight();
|
|
|
|
while (!ende) {
|
|
int16 min_steps = 30000;
|
|
int16 x = _gpkt->Dx - (count + 1) * 8;
|
|
int16 y = _gpkt->Dy - (count + 1) * 8;
|
|
|
|
for (int16 seite = 0; seite < 4; seite++) {
|
|
int16 anz = 2 + (count * 2);
|
|
|
|
switch (seite) {
|
|
case S_OBEN:
|
|
xvector = 8;
|
|
yvector = 0;
|
|
break;
|
|
|
|
case S_RECHTS:
|
|
xvector = 0;
|
|
yvector = 8;
|
|
break;
|
|
|
|
case S_UNTEN:
|
|
xvector = -8;
|
|
yvector = 0;
|
|
break;
|
|
|
|
case S_LINKS:
|
|
xvector = 0;
|
|
yvector = -8;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
for (int16 i = 0; i < anz; i++) {
|
|
if (x >= 0 && x < width * 8 &&
|
|
y >= 0 && y < height * 8) {
|
|
if (_G(barriers)->getBarrierId(x, y)) {
|
|
int16 aksteps = abs(_gpkt->Dx - x);
|
|
aksteps += abs(_gpkt->Dy - y);
|
|
if (aksteps < min_steps) {
|
|
min_steps = aksteps;
|
|
min_x = x;
|
|
min_y = y;
|
|
}
|
|
}
|
|
}
|
|
x += xvector;
|
|
y += yvector;
|
|
}
|
|
}
|
|
|
|
++count;
|
|
if (min_steps != 30000) {
|
|
ende = 1;
|
|
int16 tmp_feld = get_feld_nr(min_x, min_y);
|
|
get_feld_xy(tmp_feld, &_gpkt->Dx, &_gpkt->Dy);
|
|
_gpkt->Dx += 4;
|
|
_gpkt->Dy += 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
short MovClass::calc_go(int16 src_feld, int16 *dst_feld) {
|
|
int16 new_vector = true;
|
|
ObjMov om;
|
|
MovInfo mi;
|
|
|
|
mi.Vorschub = _gpkt->Vorschub;
|
|
get_feld_xy(src_feld, &om.Xypos[0], &om.Xypos[1]);
|
|
get_feld_xy(*dst_feld, &mi.XyzEnd[0], &mi.XyzEnd[1]);
|
|
mi.XyzStart[0] = om.Xypos[0];
|
|
mi.XyzStart[1] = om.Xypos[1];
|
|
get_mov_vector(mi.XyzStart, mi.XyzEnd, mi.Vorschub, &om);
|
|
bool endFl = false;
|
|
int16 mov_ok = 0;
|
|
int16 steps = 0;
|
|
int16 abbruch = MOV_START;
|
|
|
|
while (!endFl && !abbruch) {
|
|
if (om.Count > 0) {
|
|
--om.Count;
|
|
int16 tmpx = om.Xyvo[0];
|
|
int16 tmpy = om.Xyvo[1];
|
|
int16 tmpz = om.Xyvo[2];
|
|
om.Xyna[0][0] += om.Xyna[0][1];
|
|
if (om.Xyna[0][1] < 0) {
|
|
if (om.Xyna[0][0] < -1000) {
|
|
om.Xyna[0][0] += 1000;
|
|
--tmpx;
|
|
}
|
|
} else if (om.Xyna[0][0] > 1000) {
|
|
om.Xyna[0][0] -= 1000;
|
|
++tmpx;
|
|
}
|
|
om.Xyna[1][0] += om.Xyna[1][1];
|
|
if (om.Xyna[1][1] < 0) {
|
|
if (om.Xyna[1][0] < -1000) {
|
|
om.Xyna[1][0] += 1000;
|
|
--tmpy;
|
|
}
|
|
} else if (om.Xyna[1][0] > 1000) {
|
|
om.Xyna[1][0] -= 1000;
|
|
++tmpy;
|
|
}
|
|
om.Xyna[2][0] += om.Xyna[2][1];
|
|
if (om.Xyna[2][1] < 0) {
|
|
if (om.Xyna[2][0] < -1000) {
|
|
om.Xyna[2][0] += 1000;
|
|
}
|
|
} else if (om.Xyna[2][0] > 1000) {
|
|
om.Xyna[2][0] -= 1000;
|
|
}
|
|
|
|
tmpz = 0;
|
|
if (!_G(barriers)->getBarrierId(om.Xypos[0] + tmpx + tmpz,
|
|
om.Xypos[1] + tmpy + tmpz)) {
|
|
|
|
if (!_G(barriers)->getBarrierId(om.Xypos[0] + tmpx + tmpz,
|
|
om.Xypos[1] + tmpz)) {
|
|
|
|
if (!_G(barriers)->getBarrierId(om.Xypos[0] + tmpz,
|
|
om.Xypos[1] + tmpy + tmpz)) {
|
|
|
|
abbruch = MOV_UNPASSABLE;
|
|
} else {
|
|
if (!tmpy) {
|
|
abbruch = MOV_UNPASSABLE;
|
|
} else if (abs(om.Xypos[1] - mi.XyzEnd[1]) <= abs(tmpy)) {
|
|
abbruch = MOV_FOUND;
|
|
} else {
|
|
mov_ok = MOV_Y;
|
|
}
|
|
}
|
|
} else {
|
|
if (!tmpx) {
|
|
abbruch = MOV_UNPASSABLE;
|
|
} else if (abs(om.Xypos[0] - mi.XyzEnd[0]) <= abs(tmpx)) {
|
|
abbruch = MOV_FOUND;
|
|
} else {
|
|
mov_ok = MOV_X;
|
|
}
|
|
}
|
|
} else {
|
|
++steps;
|
|
om.Xypos[0] += tmpx;
|
|
om.Xypos[1] += tmpy;
|
|
om.Xypos[2] += tmpz;
|
|
if (new_vector) {
|
|
new_vector = false;
|
|
mi.XyzStart[0] = om.Xypos[0];
|
|
mi.XyzStart[1] = om.Xypos[1];
|
|
get_mov_vector(mi.XyzStart, mi.XyzEnd, mi.Vorschub, &om);
|
|
}
|
|
if (om.Count == 0) {
|
|
|
|
abbruch = MOV_FOUND;
|
|
}
|
|
}
|
|
|
|
if (mov_ok) {
|
|
++steps;
|
|
if (mov_ok == MOV_X)
|
|
om.Xypos[0] += tmpx;
|
|
else
|
|
om.Xypos[1] += tmpy;
|
|
om.Xypos[2] += tmpz;
|
|
mi.XyzStart[0] = om.Xypos[0];
|
|
mi.XyzStart[1] = om.Xypos[1];
|
|
get_mov_vector(mi.XyzStart, mi.XyzEnd, mi.Vorschub, &om);
|
|
if (mov_ok == MOV_X) {
|
|
if (om.Xyvo[0] != 0)
|
|
new_vector = true;
|
|
} else {
|
|
if (om.Xyvo[1] != 0)
|
|
new_vector = true;
|
|
}
|
|
if (om.Count == 0) {
|
|
|
|
abbruch = MOV_FOUND;
|
|
}
|
|
mov_ok = false;
|
|
}
|
|
} else
|
|
endFl = true;
|
|
}
|
|
if (abbruch == MOV_UNPASSABLE)
|
|
*dst_feld = get_feld_nr(om.Xypos[0], om.Xypos[1]);
|
|
|
|
return steps;
|
|
}
|
|
|
|
void MovClass::get_mov_line() {
|
|
const int16 width = _G(room)->_barriers->getWidth();
|
|
const int16 height = _G(room)->_barriers->getHeight();
|
|
const int16 level = _G(room)->_barriers->getLevel();
|
|
const byte *data = _G(room)->_barriers->getData();
|
|
const byte *buffer = data + 6;
|
|
int16 ak_steps;
|
|
|
|
_gml.GotoFeld = -1;
|
|
_gml.MLineFeld = -1;
|
|
|
|
if (level > 1) {
|
|
buffer += (width * height) * _gpkt->AkMovEbene;
|
|
int16 start_feld = get_feld_nr(_gpkt->Sx, _gpkt->Sy);
|
|
int16 ende = 0;
|
|
int16 count = 0;
|
|
int16 min_steps = 30000;
|
|
int16 count_vect = width;
|
|
int16 y_richtung = Y_DOWN;
|
|
while (!ende) {
|
|
|
|
int16 tmp_feld = start_feld + count * count_vect;
|
|
if (_G(barriers)->getBarrierId(tmp_feld, data + 6)) {
|
|
int16 abbruch = 0;
|
|
int16 vector = 0;
|
|
while ((tmp_feld % width) < (width - 1) && !abbruch)
|
|
{
|
|
if (_G(barriers)->getBarrierId(tmp_feld + vector, data + 6)) {
|
|
tmp_feld += vector;
|
|
if (buffer[tmp_feld] == MOV_LINE_IDX) {
|
|
ak_steps = abs((tmp_feld % width) - (start_feld % width));
|
|
ak_steps += abs((tmp_feld / width) - (start_feld / width));
|
|
if (ak_steps < min_steps) {
|
|
min_steps = ak_steps;
|
|
_gml.GotoFeld = start_feld + count * count_vect;
|
|
_gml.MLineFeld = tmp_feld;
|
|
}
|
|
}
|
|
vector = RIGHT_VECT;
|
|
} else {
|
|
abbruch = MOV_UNPASSABLE;
|
|
}
|
|
}
|
|
|
|
tmp_feld = start_feld + count * count_vect;
|
|
vector = LEFT_VECT;
|
|
abbruch = 0;
|
|
while ((tmp_feld % width) > 0 && !abbruch) {
|
|
if (_G(barriers)->getBarrierId(tmp_feld + vector, data + 6)) {
|
|
tmp_feld += vector;
|
|
if (buffer[tmp_feld] == MOV_LINE_IDX) {
|
|
ak_steps = abs((tmp_feld % width) - (start_feld % width));
|
|
ak_steps += abs((tmp_feld / width) - (start_feld / width));
|
|
if (ak_steps < min_steps) {
|
|
min_steps = ak_steps;
|
|
_gml.GotoFeld = start_feld + count * count_vect;
|
|
_gml.MLineFeld = tmp_feld;
|
|
}
|
|
}
|
|
} else {
|
|
abbruch = MOV_UNPASSABLE;
|
|
}
|
|
}
|
|
++count;
|
|
} else {
|
|
if (y_richtung == Y_DOWN) {
|
|
|
|
y_richtung = Y_UP;
|
|
count = 1;
|
|
count_vect = -_G(room)->_barriers->getWidth();
|
|
} else
|
|
ende = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[] data;
|
|
}
|
|
|
|
void MovClass::calc_mov_line_xit(int16 start_feld) {
|
|
const int16 width = _G(room)->_barriers->getWidth();
|
|
const int16 height = _G(room)->_barriers->getHeight();
|
|
const int16 level = _G(room)->_barriers->getLevel();
|
|
const byte *data = _G(room)->_barriers->getData();
|
|
int16 tmp_feld;
|
|
int16 i;
|
|
int16 dest_steps;
|
|
|
|
int16 k;
|
|
int16 TmpKnPkt[MAX_KNOTEN_PKT];
|
|
int16 dir_unerreicht = 0;
|
|
int16 KnPkt_unrreicht[MAX_KNOTEN_PKT];
|
|
int16 feld_unerreicht = 0;
|
|
int16 knoten_felder[MAX_KNOTEN_PKT][6];
|
|
|
|
for (i = 0; i < MAX_KNOTEN_PKT; i++)
|
|
TmpKnPkt[i] = -1;
|
|
if (level > 1) {
|
|
memset(knoten_felder, -1, MAX_KNOTEN_PKT * 6);
|
|
const byte *buffer = data + 6;
|
|
buffer += (width * height) * _gpkt->AkMovEbene;
|
|
_mle.Steps = 30000;
|
|
int16 min_step_unerreicht = 30000;
|
|
_mle.FNr = -1;
|
|
int16 ziel_feld = get_feld_nr(_gpkt->Dx, _gpkt->Dy);
|
|
int16 calc_feld = start_feld;
|
|
int16 last_feld = start_feld;
|
|
int16 steps = 0;
|
|
int16 found = 0;
|
|
int16 ak_knoten = -1;
|
|
int16 tbl_dir = 1;
|
|
int16 tbl_ptr = 0;
|
|
int16 knoten_flag = 0;
|
|
|
|
//found_min = 0;
|
|
int16 dir = 30000;
|
|
while (!found) {
|
|
tmp_feld = ziel_feld;
|
|
calc_go(calc_feld, &tmp_feld);
|
|
if (tmp_feld == ziel_feld) {
|
|
dest_steps = abs((ziel_feld % width) - (calc_feld % width));
|
|
dest_steps += abs((ziel_feld / width) - (calc_feld / width));
|
|
if (dest_steps < _mle.Steps) {
|
|
_mle.Steps = dest_steps;
|
|
_mle.FNr = calc_feld;
|
|
if (dir == 30000)
|
|
_mle.Direction = 0;
|
|
else
|
|
_mle.Direction = dir;
|
|
for (i = 0; i < MAX_KNOTEN_PKT; i++)
|
|
_mle.KnPkt[i] = TmpKnPkt[i];
|
|
}
|
|
} else {
|
|
dest_steps = abs((ziel_feld % width) - (tmp_feld % width));
|
|
dest_steps += abs((ziel_feld / width) - (tmp_feld / width));
|
|
if (dest_steps < min_step_unerreicht) {
|
|
min_step_unerreicht = dest_steps;
|
|
feld_unerreicht = tmp_feld;
|
|
if (dir == 30000)
|
|
dir_unerreicht = 0;
|
|
else
|
|
dir_unerreicht = dir;
|
|
for (i = 0; i < MAX_KNOTEN_PKT; i++)
|
|
KnPkt_unrreicht[i] = TmpKnPkt[i];
|
|
}
|
|
}
|
|
int16 ok = 0;
|
|
for (i = 0; i < 4 && !ok; i++) {
|
|
if (buffer[calc_feld + _vecTbl[tbl_ptr + i * tbl_dir]] == MOV_LINE_IDX)
|
|
{
|
|
if (calc_feld + _vecTbl[tbl_ptr + i * tbl_dir] != last_feld)
|
|
{
|
|
last_feld = calc_feld;
|
|
calc_feld += _vecTbl[tbl_ptr + i * tbl_dir];
|
|
++steps;
|
|
ok = 1;
|
|
if (dir == 30000) {
|
|
dir = _vecTbl[tbl_ptr + i * tbl_dir];
|
|
}
|
|
if (knoten_flag) {
|
|
TmpKnPkt[ak_knoten] = calc_feld;
|
|
knoten_felder[ak_knoten][tbl_ptr + i * tbl_dir] = calc_feld;
|
|
knoten_flag = false;
|
|
}
|
|
}
|
|
} else if (buffer[calc_feld + _vecTbl[tbl_ptr + i * tbl_dir]] == MOV_LINE_KNOTEN) {
|
|
if (calc_feld + _vecTbl[tbl_ptr + i * tbl_dir] != last_feld) {
|
|
if (dir == 30000) {
|
|
dir = _vecTbl[tbl_ptr + i * tbl_dir];
|
|
}
|
|
++ak_knoten;
|
|
for (k = 0; k < 6; k++)
|
|
knoten_felder[ak_knoten][k] = -1;
|
|
switch (tbl_ptr + i * tbl_dir) {
|
|
case MLE_UP:
|
|
k = MLE_DOWN;
|
|
break;
|
|
case MLE_RIGHT:
|
|
k = MLE_LEFT;
|
|
break;
|
|
case MLE_LEFT:
|
|
k = MLE_RIGHT;
|
|
break;
|
|
case MLE_DOWN:
|
|
k = MLE_UP;
|
|
break;
|
|
}
|
|
knoten_felder[ak_knoten][k] = calc_feld;
|
|
last_feld = calc_feld;
|
|
calc_feld += _vecTbl[tbl_ptr + i * tbl_dir];
|
|
knoten_felder[ak_knoten][4] = calc_feld;
|
|
++steps;
|
|
knoten_felder[ak_knoten][5] = steps;
|
|
knoten_flag = true;
|
|
ok = 1;
|
|
}
|
|
}
|
|
}
|
|
if (!ok) {
|
|
|
|
if (ak_knoten != -1)
|
|
{
|
|
ok = 0;
|
|
for (i = 0; i < 4 && !ok; i++) {
|
|
if (knoten_felder[ak_knoten][tbl_ptr + i * tbl_dir] == -1) {
|
|
tmp_feld = knoten_felder[ak_knoten][4];
|
|
if (buffer[tmp_feld + _vecTbl[tbl_ptr + i * tbl_dir]] == MOV_LINE_IDX)
|
|
{
|
|
last_feld = knoten_felder[ak_knoten][4];
|
|
calc_feld = tmp_feld + _vecTbl[tbl_ptr + i * tbl_dir];
|
|
|
|
TmpKnPkt[ak_knoten] = calc_feld;
|
|
knoten_felder[ak_knoten][tbl_ptr + i * tbl_dir] = calc_feld;
|
|
steps = knoten_felder[ak_knoten][5];
|
|
ok = 1;
|
|
}
|
|
}
|
|
}
|
|
if (!ok) {
|
|
--ak_knoten;
|
|
}
|
|
} else if (tbl_dir == 1) {
|
|
tbl_dir = -1;
|
|
tbl_ptr = 3;
|
|
dir = 30000;
|
|
//found_min = 0;
|
|
calc_feld = start_feld;
|
|
last_feld = start_feld;
|
|
} else {
|
|
found = 1;
|
|
if (_mle.FNr == -1) {
|
|
_mle.Steps = min_step_unerreicht;
|
|
_mle.FNr = feld_unerreicht;
|
|
_mle.Direction = dir_unerreicht;
|
|
for (i = 0; i < MAX_KNOTEN_PKT; i++)
|
|
_mle.KnPkt[i] = KnPkt_unrreicht[i];
|
|
|
|
get_feld_xy(feld_unerreicht, &_gpkt->Dx, &_gpkt->Dy);
|
|
_gpkt->Dx += 4;
|
|
_gpkt->Dy += 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[] data;
|
|
}
|
|
|
|
int16 MovClass::get_feld_nr(int16 x, int16 y) {
|
|
const int16 width = _G(room)->_barriers->getWidth();
|
|
x >>= 3;
|
|
y >>= 3;
|
|
|
|
return x + (y * width);
|
|
}
|
|
|
|
void MovClass::get_feld_xy(int16 fnr, int16 *x, int16 *y) {
|
|
const int16 width = _G(room)->_barriers->getWidth();
|
|
*x = (fnr % width);
|
|
*y = (fnr / width);
|
|
*x <<= 3;
|
|
*y <<= 3;
|
|
}
|
|
|
|
void MovClass::get_mov_vector(int16 *startXyz, int16 *endXyz, int16 vorschub, ObjMov *om) {
|
|
if (vorschub > 0) {
|
|
int16 x = startXyz[0];
|
|
int16 y = startXyz[1];
|
|
int16 z = startXyz[2];
|
|
int16 x1 = endXyz[0];
|
|
int16 y1 = endXyz[1];
|
|
int16 z1 = endXyz[2];
|
|
om->Xypos[0] = x;
|
|
om->Xypos[1] = y;
|
|
om->Xypos[2] = z;
|
|
x = x - x1;
|
|
y = y - y1;
|
|
z = z - z1;
|
|
|
|
uint8 xvector;
|
|
if (x < 0) {
|
|
xvector = 1;
|
|
--x;
|
|
} else {
|
|
xvector = 0;
|
|
++x;
|
|
}
|
|
|
|
|
|
uint8 yvector;
|
|
if (y < 0) {
|
|
yvector = 1;
|
|
--y;
|
|
} else {
|
|
yvector = 0;
|
|
++y;
|
|
}
|
|
|
|
uint8 zvector;
|
|
if (z < 0) {
|
|
zvector = 1;
|
|
--z;
|
|
} else {
|
|
zvector = 0;
|
|
++z;
|
|
}
|
|
|
|
int16 absx = abs(x);
|
|
int16 absy = abs(y);
|
|
int16 absz = abs(z);
|
|
float xstep;
|
|
float ystep;
|
|
if (absx < absy) {
|
|
xstep = (float)absx / ((float)absy / (float)vorschub);
|
|
ystep = vorschub;
|
|
om->Count = (int16)((float) y / (float)ystep);
|
|
} else {
|
|
xstep = vorschub;
|
|
ystep = (float)absy / ((float)absx / (float)vorschub);
|
|
om->Count = (int16)((float) x / (float)xstep);
|
|
}
|
|
|
|
float zstep;
|
|
om->Count = abs(om->Count);
|
|
if (!om->Count) {
|
|
zstep = (float)absz / 1.0;
|
|
} else
|
|
zstep = (float)absz / ((float)((abs)(om->Count)));
|
|
|
|
if (!xvector)
|
|
xstep = -xstep;
|
|
if (!yvector)
|
|
ystep = -ystep;
|
|
if (!zvector)
|
|
zstep = -zstep;
|
|
|
|
om->Xyvo[0] = (int16)xstep;
|
|
om->Xyvo[1] = (int16)ystep;
|
|
om->Xyvo[2] = (int16)zstep;
|
|
int16 tmp = (int16)((float)xstep * 1000.0);
|
|
om->Xyna[0][1] = tmp - (om->Xyvo[0] * 1000);
|
|
om->Xyna[0][0] = 0;
|
|
tmp = (int16)((float)ystep * 1000.0);
|
|
om->Xyna[1][1] = tmp - (om->Xyvo[1] * 1000);
|
|
om->Xyna[1][0] = 0;
|
|
tmp = (int16)((float)zstep * 1000.0);
|
|
om->Xyna[2][1] = tmp - (om->Xyvo[2] * 1000);
|
|
om->Xyna[2][0] = 0;
|
|
if (!om->Count) {
|
|
startXyz[0] = endXyz[0];
|
|
startXyz[1] = endXyz[1];
|
|
om->Xypos[0] = endXyz[0];
|
|
om->Xypos[1] = endXyz[1];
|
|
}
|
|
} else {
|
|
om->Count = 0;
|
|
|
|
om->Xypos[0] = startXyz[0];
|
|
om->Xypos[1] = startXyz[1];
|
|
om->Xypos[2] = startXyz[2];
|
|
om->Xyvo[0] = 0;
|
|
om->Xyvo[1] = 0;
|
|
om->Xyvo[2] = 0;
|
|
om->Xyna[0][1] = 0;
|
|
om->Xyna[0][0] = 0;
|
|
om->Xyna[1][1] = 0;
|
|
om->Xyna[1][0] = 0;
|
|
om->Xyna[2][1] = 0;
|
|
om->Xyna[2][0] = 0;
|
|
}
|
|
}
|
|
|
|
} // namespace Chewy
|