2005-04-05 18:08:02 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
|
|
|
* Copyright (C) 2004 Ivan Dubrov
|
|
|
|
* Copyright (C) 2004-2005 The ScummVM project
|
|
|
|
*
|
|
|
|
* 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
|
2005-04-09 19:19:54 +00:00
|
|
|
* along with this program; if not, write to the Free Software
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2005-04-05 18:08:02 +00:00
|
|
|
*
|
|
|
|
* $Header$
|
|
|
|
*
|
|
|
|
*/
|
2005-04-05 15:07:40 +00:00
|
|
|
#include "gob/gob.h"
|
|
|
|
#include "gob/map.h"
|
|
|
|
#include "gob/video.h"
|
|
|
|
#include "gob/util.h"
|
|
|
|
#include "gob/dataio.h"
|
|
|
|
#include "gob/inter.h"
|
|
|
|
#include "gob/goblin.h"
|
|
|
|
#include "gob/sound.h"
|
2005-04-09 19:32:29 +00:00
|
|
|
#include "gob/scenery.h"
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
namespace Gob {
|
|
|
|
|
2005-06-22 19:32:10 +00:00
|
|
|
int8 map_passMap[28][26]; // [y][x]
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 map_itemsMap[28][26]; // [y][x]
|
|
|
|
|
|
|
|
Map_Point map_wayPoints[40];
|
|
|
|
int16 map_nearestWayPoint = 0;
|
|
|
|
int16 map_nearestDest = 0;
|
|
|
|
|
|
|
|
int16 map_curGoblinX;
|
|
|
|
int16 map_curGoblinY;
|
|
|
|
int16 map_destX;
|
|
|
|
int16 map_destY;
|
|
|
|
|
|
|
|
Map_ItemPos map_itemPoses[40];
|
2005-06-22 19:32:10 +00:00
|
|
|
int8 map_loadFromAvo;
|
2005-04-05 15:07:40 +00:00
|
|
|
char map_sourceFile[15];
|
2005-04-11 20:04:14 +00:00
|
|
|
static char *map_avoDataPtr;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
This should fix a crash which could happen when placing several objects too
close to each other on the ground. (Happened to me on the first level after
destroying the voodoo doll, where I'd drop the banana, the soap and the
false nose close to each other on the ground after using them.)
Reasoning behind the change:
From what I understand, map_itemsMap[] contains information for each "cell"
of the map about which objects are there. Each cell can contain two objects
which are stored in the upper and lower byte of a 16-bit word.
When dropping an object, it is written into map_itemsMap[], but not just to
the indicated cell but also to a few of the surrounding ones. Presumably to
make it easier to pick it up afterwards.
When writing an object to a cell, we check if one of the bytes is already
occupied. If it is, write to the other byte. Otherwise, write to that byte.
(If both bytes are occupied, one will be overwritten.)
The old code assumed that if one byte was free at position (x,y) the same
byte would automatically be the free one in the surrounding cells. This
could cause bad values in the array, since the item was added to an
existing value, rather than replacing it.
This new code makes the check for each cell that is modified. (It also gets
rid of some code duplication.)
svn-id: r17851
2005-04-28 10:34:48 +00:00
|
|
|
void map_placeItem(int16 x, int16 y, int16 id) {
|
|
|
|
if ((map_itemsMap[y][x] & 0xff00) != 0)
|
|
|
|
map_itemsMap[y][x] = (map_itemsMap[y][x] & 0xff00) | id;
|
|
|
|
else
|
|
|
|
map_itemsMap[y][x] = (map_itemsMap[y][x] & 0x00ff) | (id << 8);
|
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
enum {
|
|
|
|
kLeft = (1 << 0),
|
|
|
|
kUp = (1 << 1),
|
|
|
|
kRight = (1 << 2),
|
|
|
|
kDown = (1 << 3)
|
|
|
|
};
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
int16 map_getDirection(int16 x0, int16 y0, int16 x1, int16 y1) {
|
|
|
|
int16 dir = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (x0 == x1 && y0 == y1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (x1 < 0 || x1 > 25 || y1 < 0 || y1 > 27)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (y1 > y0)
|
2005-07-10 13:37:03 +00:00
|
|
|
dir |= kDown;
|
2005-04-05 15:07:40 +00:00
|
|
|
else if (y1 < y0)
|
2005-07-10 13:37:03 +00:00
|
|
|
dir |= kUp;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (x1 > x0)
|
2005-07-10 13:37:03 +00:00
|
|
|
dir |= kRight;
|
2005-04-05 15:07:40 +00:00
|
|
|
else if (x1 < x0)
|
2005-07-10 13:37:03 +00:00
|
|
|
dir |= kLeft;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (map_passMap[y0][x0] == 3 && (dir & kUp)) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (map_passMap[y0 - 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirN;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (map_passMap[y0][x0] == 3 && (dir & kDown)) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (map_passMap[y0 + 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirS;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (map_passMap[y0][x0] == 6 && (dir & kUp)) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (map_passMap[y0 - 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirN;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (map_passMap[y0][x0] == 6 && (dir & kDown)) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (map_passMap[y0 + 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirS;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (dir == kLeft) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (x0 - 1 >= 0 && map_passMap[y0][x0 - 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirW;
|
2005-04-05 15:07:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (dir == kRight) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (x0 + 1 < 26 && map_passMap[y0][x0 + 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirE;
|
2005-04-05 15:07:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (dir == kUp) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (y0 - 1 >= 0 && map_passMap[y0 - 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirN;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (y0 - 1 >= 0 && x0 - 1 >= 0
|
|
|
|
&& map_passMap[y0 - 1][x0 - 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirNW;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (y0 - 1 >= 0 && x0 + 1 < 26
|
|
|
|
&& map_passMap[y0 - 1][x0 + 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirNE;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (dir == kDown) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (y0 + 1 < 28 && map_passMap[y0 + 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirS;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (y0 + 1 < 28 && x0 - 1 >= 0
|
|
|
|
&& map_passMap[y0 + 1][x0 - 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirSW;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (y0 + 1 < 28 && x0 + 1 < 26
|
|
|
|
&& map_passMap[y0 + 1][x0 + 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirSE;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (dir == (kRight | kUp)) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (y0 - 1 >= 0 && x0 + 1 < 26
|
|
|
|
&& map_passMap[y0 - 1][x0 + 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirNE;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (y0 - 1 >= 0 && map_passMap[y0 - 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirN;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (x0 + 1 < 26 && map_passMap[y0][x0 + 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirE;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (dir == (kRight | kDown)) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (x0 + 1 < 26 && y0 + 1 < 28
|
|
|
|
&& map_passMap[y0 + 1][x0 + 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirSE;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (y0 + 1 < 28 && map_passMap[y0 + 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirS;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (x0 + 1 < 26 && map_passMap[y0][x0 + 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirE;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (dir == (kLeft | kUp)) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (x0 - 1 >= 0 && y0 - 1 >= 0
|
|
|
|
&& map_passMap[y0 - 1][x0 - 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirNW;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (y0 - 1 >= 0 && map_passMap[y0 - 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirN;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (x0 - 1 >= 0 && map_passMap[y0][x0 - 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirW;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (dir == (kLeft | kDown)) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (x0 - 1 >= 0 && y0 + 1 < 28
|
|
|
|
&& map_passMap[y0 + 1][x0 - 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirSW;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (y0 + 1 < 28 && map_passMap[y0 + 1][x0] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirS;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (x0 - 1 >= 0 && map_passMap[y0][x0 - 1] != 0)
|
2005-07-10 13:37:03 +00:00
|
|
|
return kDirW;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
int16 map_findNearestWayPoint(int16 x, int16 y) {
|
|
|
|
int16 nearestWayPoint = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 length;
|
|
|
|
int16 i;
|
|
|
|
int16 tmp;
|
|
|
|
|
|
|
|
length = 30000;
|
|
|
|
|
|
|
|
for (i = 0; i < 40; i++) {
|
|
|
|
if (map_wayPoints[i].x < 0 ||
|
|
|
|
map_wayPoints[i].x > 25 ||
|
|
|
|
map_wayPoints[i].y < 0 || map_wayPoints[i].y > 27)
|
2005-07-10 13:37:03 +00:00
|
|
|
return -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
tmp = ABS(x - map_wayPoints[i].x) + ABS(y - map_wayPoints[i].y);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (tmp <= length) {
|
2005-07-10 13:37:03 +00:00
|
|
|
nearestWayPoint = i;
|
2005-04-05 15:07:40 +00:00
|
|
|
length = tmp;
|
|
|
|
}
|
|
|
|
}
|
2005-07-10 13:37:03 +00:00
|
|
|
|
|
|
|
return nearestWayPoint;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
void map_findNearestToGob(void) {
|
|
|
|
int16 wayPoint = map_findNearestWayPoint(map_curGoblinX, map_curGoblinY);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (wayPoint != -1)
|
|
|
|
map_nearestWayPoint = wayPoint;
|
|
|
|
}
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
void map_findNearestToDest(void) {
|
|
|
|
int16 wayPoint = map_findNearestWayPoint(map_destX, map_destY);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
if (wayPoint != -1)
|
|
|
|
map_nearestDest = wayPoint;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int16 map_checkDirectPath(int16 x0, int16 y0, int16 x1, int16 y1) {
|
|
|
|
uint16 dir;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
dir = map_getDirection(x0, y0, x1, y1);
|
|
|
|
|
|
|
|
if (x0 == x1 && y0 == y1)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (dir == 0)
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
switch (dir) {
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirNW:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0--;
|
|
|
|
y0--;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirN:
|
2005-04-05 15:07:40 +00:00
|
|
|
y0--;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirNE:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0++;
|
|
|
|
y0--;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirW:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0--;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirE:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0++;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirSW:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0--;
|
|
|
|
y0++;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirS:
|
2005-04-05 15:07:40 +00:00
|
|
|
y0++;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirSE:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0++;
|
|
|
|
y0++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int16 map_checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1) {
|
|
|
|
uint16 dir;
|
|
|
|
int16 curX;
|
|
|
|
int16 curY;
|
|
|
|
int16 nextLink;
|
|
|
|
|
|
|
|
curX = x0;
|
|
|
|
curY = y0;
|
|
|
|
dir = 0;
|
|
|
|
|
|
|
|
nextLink = 1;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
if (x0 == curX && y0 == curY)
|
|
|
|
nextLink = 1;
|
|
|
|
|
|
|
|
if (nextLink != 0) {
|
|
|
|
if (map_checkDirectPath(x0, y0, x1, y1) == 1)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
nextLink = 0;
|
|
|
|
if (i0 > i1) {
|
|
|
|
curX = map_wayPoints[i0].x;
|
|
|
|
curY = map_wayPoints[i0].y;
|
|
|
|
i0--;
|
|
|
|
} else if (i0 < i1) {
|
|
|
|
curX = map_wayPoints[i0].x;
|
|
|
|
curY = map_wayPoints[i0].y;
|
|
|
|
i0++;
|
|
|
|
} else if (i0 == i1) {
|
|
|
|
curX = map_wayPoints[i0].x;
|
|
|
|
curY = map_wayPoints[i0].y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i0 == i1 && map_wayPoints[i0].x == x0
|
|
|
|
&& map_wayPoints[i0].y == y0) {
|
|
|
|
if (map_checkDirectPath(x0, y0, x1, y1) == 1)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
dir = map_getDirection(x0, y0, curX, curY);
|
|
|
|
switch (dir) {
|
|
|
|
case 0:
|
|
|
|
return 0;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirNW:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0--;
|
|
|
|
y0--;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirN:
|
2005-04-05 15:07:40 +00:00
|
|
|
y0--;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirNE:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0++;
|
|
|
|
y0--;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirW:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0--;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirE:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0++;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirSW:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0--;
|
|
|
|
y0++;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirS:
|
2005-04-05 15:07:40 +00:00
|
|
|
y0++;
|
|
|
|
break;
|
|
|
|
|
2005-07-10 13:37:03 +00:00
|
|
|
case kDirSE:
|
2005-04-05 15:07:40 +00:00
|
|
|
x0++;
|
|
|
|
y0++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-18 09:57:44 +00:00
|
|
|
void map_optimizePoints(void) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 i;
|
|
|
|
|
|
|
|
if (map_nearestWayPoint < map_nearestDest) {
|
|
|
|
for (i = map_nearestWayPoint; i <= map_nearestDest; i++) {
|
2005-12-18 09:57:44 +00:00
|
|
|
if (map_checkDirectPath(map_curGoblinX, map_curGoblinY,
|
2005-04-05 15:07:40 +00:00
|
|
|
map_wayPoints[i].x, map_wayPoints[i].y) == 1)
|
|
|
|
map_nearestWayPoint = i;
|
|
|
|
}
|
|
|
|
} else if (map_nearestWayPoint > map_nearestDest) {
|
|
|
|
for (i = map_nearestWayPoint; i >= map_nearestDest; i--) {
|
2005-12-18 09:57:44 +00:00
|
|
|
if (map_checkDirectPath(map_curGoblinX, map_curGoblinY,
|
2005-04-05 15:07:40 +00:00
|
|
|
map_wayPoints[i].x, map_wayPoints[i].y) == 1)
|
|
|
|
map_nearestWayPoint = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void map_loadDataFromAvo(char *dest, int16 size) {
|
|
|
|
memcpy(dest, map_avoDataPtr, size);
|
|
|
|
map_avoDataPtr += size;
|
|
|
|
}
|
|
|
|
|
2005-04-11 20:38:17 +00:00
|
|
|
uint16 map_loadFromAvo_LE_UINT16() {
|
|
|
|
uint16 tmp = READ_LE_UINT16(map_avoDataPtr);
|
|
|
|
map_avoDataPtr += 2;
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2005-04-05 15:07:40 +00:00
|
|
|
void map_loadItemToObject(void) {
|
|
|
|
int16 flag;
|
|
|
|
int16 count;
|
|
|
|
int16 i;
|
|
|
|
|
2005-04-11 20:41:00 +00:00
|
|
|
flag = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
if (flag == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
map_avoDataPtr += 1456;
|
2005-04-11 20:41:00 +00:00
|
|
|
count = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
map_avoDataPtr += 20;
|
2005-04-11 20:41:00 +00:00
|
|
|
gob_itemToObject[i] = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
map_avoDataPtr += 5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void map_loadMapObjects(char *avjFile) {
|
|
|
|
int16 i;
|
|
|
|
char avoName[128];
|
|
|
|
int16 handle;
|
|
|
|
char item;
|
|
|
|
int16 soundCount;
|
|
|
|
int16 tmp;
|
|
|
|
char *savedPtr;
|
|
|
|
char *savedPtr2;
|
|
|
|
char *savedPtr3;
|
|
|
|
int16 state;
|
|
|
|
int16 col;
|
|
|
|
int32 flag;
|
|
|
|
Gob_State *pState;
|
|
|
|
char buf[128];
|
|
|
|
char sndNames[20][14];
|
|
|
|
char *dataBuf;
|
|
|
|
int16 x;
|
|
|
|
int16 y;
|
|
|
|
int16 count2;
|
|
|
|
int16 count3;
|
|
|
|
|
|
|
|
strcpy(avoName, map_sourceFile);
|
|
|
|
strcat(avoName, ".avo");
|
|
|
|
|
|
|
|
handle = data_openData(avoName);
|
|
|
|
if (handle >= 0) {
|
|
|
|
map_loadFromAvo = 1;
|
|
|
|
data_closeData(handle);
|
2005-11-22 13:17:08 +00:00
|
|
|
map_avoDataPtr = data_getData(avoName);
|
2005-04-05 15:07:40 +00:00
|
|
|
dataBuf = map_avoDataPtr;
|
|
|
|
map_loadDataFromAvo((char *)map_passMap, 28 * 26);
|
|
|
|
|
|
|
|
for (y = 0; y < 28; y++) {
|
|
|
|
for (x = 0; x < 26; x++) {
|
|
|
|
map_loadDataFromAvo(&item, 1);
|
|
|
|
map_itemsMap[y][x] = item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < 40; i++) {
|
2005-04-11 20:41:00 +00:00
|
|
|
map_wayPoints[i].x = map_loadFromAvo_LE_UINT16();
|
|
|
|
map_wayPoints[i].y = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
map_loadDataFromAvo((char *)map_itemPoses, szMap_ItemPos * 20);
|
|
|
|
} else {
|
|
|
|
map_loadFromAvo = 0;
|
2005-11-22 13:17:08 +00:00
|
|
|
map_avoDataPtr = data_getData(avjFile);
|
2005-04-05 15:07:40 +00:00
|
|
|
dataBuf = map_avoDataPtr;
|
|
|
|
}
|
|
|
|
|
|
|
|
map_avoDataPtr += 32;
|
|
|
|
map_avoDataPtr += 76;
|
|
|
|
map_avoDataPtr += 4;
|
|
|
|
map_avoDataPtr += 20;
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
2005-04-11 20:41:00 +00:00
|
|
|
tmp = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
map_avoDataPtr += tmp * 14;
|
|
|
|
}
|
|
|
|
|
2005-04-11 20:41:00 +00:00
|
|
|
soundCount = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
savedPtr = map_avoDataPtr;
|
|
|
|
|
|
|
|
map_avoDataPtr += 14 * soundCount;
|
|
|
|
map_avoDataPtr += 4;
|
|
|
|
map_avoDataPtr += 24;
|
|
|
|
|
2005-04-11 20:41:00 +00:00
|
|
|
count2 = map_loadFromAvo_LE_UINT16();
|
|
|
|
count3 = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
savedPtr2 = map_avoDataPtr;
|
|
|
|
map_avoDataPtr += count2 * 8;
|
|
|
|
|
|
|
|
savedPtr3 = map_avoDataPtr;
|
|
|
|
map_avoDataPtr += count3 * 8;
|
|
|
|
|
2005-04-11 20:41:00 +00:00
|
|
|
gob_gobsCount = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
for (i = 0; i < gob_gobsCount; i++) {
|
|
|
|
gob_goblins[i] = (Gob_Object *)malloc(sizeof(Gob_Object));
|
|
|
|
|
|
|
|
gob_goblins[i]->xPos = READ_LE_UINT16(savedPtr2);
|
|
|
|
savedPtr2 += 2;
|
|
|
|
|
|
|
|
gob_goblins[i]->yPos = READ_LE_UINT16(savedPtr2);
|
|
|
|
savedPtr2 += 2;
|
|
|
|
|
|
|
|
gob_goblins[i]->order = READ_LE_UINT16(savedPtr2);
|
|
|
|
savedPtr2 += 2;
|
|
|
|
|
|
|
|
gob_goblins[i]->state = READ_LE_UINT16(savedPtr2);
|
|
|
|
savedPtr2 += 2;
|
|
|
|
|
|
|
|
if (i == 3)
|
2005-04-11 20:04:14 +00:00
|
|
|
gob_goblins[i]->stateMach = (Gob_StateLine *)malloc(szGob_StateLine * 70);
|
2005-04-05 15:07:40 +00:00
|
|
|
else
|
2005-04-11 20:04:14 +00:00
|
|
|
gob_goblins[i]->stateMach = (Gob_StateLine *)malloc(szGob_StateLine * 40);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
// FIXME: All is wrong further. We should unwind calls to map_loadDataFromAvo()
|
|
|
|
map_loadDataFromAvo((char *)gob_goblins[i]->stateMach, 40 * szGob_StateLine);
|
|
|
|
map_avoDataPtr += 160;
|
|
|
|
gob_goblins[i]->multObjIndex = *map_avoDataPtr;
|
|
|
|
map_avoDataPtr += 2;
|
|
|
|
|
|
|
|
gob_goblins[i]->realStateMach = gob_goblins[i]->stateMach;
|
|
|
|
for (state = 0; state < 40; state++) {
|
|
|
|
for (col = 0; col < 6; col++) {
|
|
|
|
if (gob_goblins[i]->stateMach[state][col] == 0)
|
|
|
|
continue;
|
|
|
|
|
2005-04-11 20:38:17 +00:00
|
|
|
Gob_State *tmpState = (Gob_State *)malloc(sizeof(Gob_State));
|
|
|
|
gob_goblins[i]->stateMach[state][col] = tmpState;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->animation = map_loadFromAvo_LE_UINT16();
|
|
|
|
tmpState->layer = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
map_avoDataPtr += 8;
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->unk0 = map_loadFromAvo_LE_UINT16();
|
|
|
|
tmpState->unk1 = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
map_avoDataPtr += 2;
|
|
|
|
if (READ_LE_UINT32(map_avoDataPtr) != 0) {
|
|
|
|
map_avoDataPtr += 4;
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->sndItem = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
|
|
|
map_avoDataPtr += 6;
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->sndItem = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->freq = map_loadFromAvo_LE_UINT16();
|
|
|
|
tmpState->repCount = map_loadFromAvo_LE_UINT16();
|
2005-05-01 10:15:30 +00:00
|
|
|
tmpState->sndFrame = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pState = (Gob_State *)malloc(sizeof(Gob_State));
|
|
|
|
gob_goblins[0]->stateMach[39][0] = pState;
|
|
|
|
pState->animation = 0;
|
|
|
|
pState->layer = 98;
|
|
|
|
pState->unk0 = 0;
|
|
|
|
pState->unk1 = 0;
|
|
|
|
pState->sndItem = -1;
|
|
|
|
|
|
|
|
pState = (Gob_State *) malloc(sizeof(Gob_State));
|
|
|
|
gob_goblins[1]->stateMach[39][0] = pState;
|
|
|
|
pState->animation = 0;
|
|
|
|
pState->layer = 99;
|
|
|
|
pState->unk0 = 0;
|
|
|
|
pState->unk1 = 0;
|
|
|
|
pState->sndItem = -1;
|
|
|
|
|
|
|
|
pState = (Gob_State *) malloc(sizeof(Gob_State));
|
|
|
|
gob_goblins[2]->stateMach[39][0] = pState;
|
|
|
|
pState->animation = 0;
|
|
|
|
pState->layer = 100;
|
|
|
|
pState->unk0 = 0;
|
|
|
|
pState->unk1 = 0;
|
|
|
|
pState->sndItem = -1;
|
|
|
|
|
2005-05-01 10:15:30 +00:00
|
|
|
gob_goblins[2]->stateMach[10][0]->sndFrame = 13;
|
|
|
|
gob_goblins[2]->stateMach[11][0]->sndFrame = 13;
|
|
|
|
gob_goblins[2]->stateMach[28][0]->sndFrame = 13;
|
|
|
|
gob_goblins[2]->stateMach[29][0]->sndFrame = 13;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-05-01 10:15:30 +00:00
|
|
|
gob_goblins[1]->stateMach[10][0]->sndFrame = 13;
|
|
|
|
gob_goblins[1]->stateMach[11][0]->sndFrame = 13;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
for (state = 40; state < 70; state++) {
|
|
|
|
pState = (Gob_State *)malloc(sizeof(Gob_State));
|
|
|
|
gob_goblins[3]->stateMach[state][0] = pState;
|
|
|
|
gob_goblins[3]->stateMach[state][1] = 0;
|
|
|
|
|
|
|
|
pState->animation = 9;
|
|
|
|
pState->layer = state - 40;
|
|
|
|
pState->sndItem = -1;
|
2005-05-01 10:15:30 +00:00
|
|
|
pState->sndFrame = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2005-04-11 20:38:17 +00:00
|
|
|
gob_objCount = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
for (i = 0; i < gob_objCount; i++) {
|
|
|
|
gob_objects[i] =
|
|
|
|
(Gob_Object *) malloc(sizeof(Gob_Object));
|
|
|
|
|
|
|
|
gob_objects[i]->xPos = READ_LE_UINT16(savedPtr3);
|
|
|
|
savedPtr3 += 2;
|
|
|
|
|
|
|
|
gob_objects[i]->yPos = READ_LE_UINT16(savedPtr3);
|
|
|
|
savedPtr3 += 2;
|
|
|
|
|
|
|
|
gob_objects[i]->order = READ_LE_UINT16(savedPtr3);
|
|
|
|
savedPtr3 += 2;
|
|
|
|
|
|
|
|
gob_objects[i]->state = READ_LE_UINT16(savedPtr3);
|
|
|
|
savedPtr3 += 2;
|
|
|
|
|
2005-04-11 20:04:14 +00:00
|
|
|
gob_objects[i]->stateMach = (Gob_StateLine *)malloc(szGob_StateLine * 40);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
map_loadDataFromAvo((char *)gob_objects[i]->stateMach, 40 * szGob_StateLine);
|
|
|
|
map_avoDataPtr += 160;
|
|
|
|
gob_objects[i]->multObjIndex = *map_avoDataPtr;
|
|
|
|
map_avoDataPtr += 2;
|
|
|
|
|
|
|
|
gob_objects[i]->realStateMach = gob_objects[i]->stateMach;
|
|
|
|
for (state = 0; state < 40; state++) {
|
|
|
|
for (col = 0; col < 6; col++) {
|
|
|
|
if (gob_objects[i]->stateMach[state][col] == 0)
|
|
|
|
continue;
|
|
|
|
|
2005-04-11 20:38:17 +00:00
|
|
|
Gob_State *tmpState = (Gob_State *)malloc(sizeof(Gob_State));
|
|
|
|
gob_objects[i]->stateMach[state][col] = tmpState;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->animation = map_loadFromAvo_LE_UINT16();
|
|
|
|
tmpState->layer = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
map_avoDataPtr += 8;
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->unk0 = map_loadFromAvo_LE_UINT16();
|
|
|
|
tmpState->unk1 = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
map_avoDataPtr += 2;
|
|
|
|
if (READ_LE_UINT32(map_avoDataPtr) != 0) {
|
|
|
|
map_avoDataPtr += 4;
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->sndItem = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
|
|
|
map_avoDataPtr += 6;
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->sndItem = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
2005-04-11 20:38:17 +00:00
|
|
|
tmpState->freq = map_loadFromAvo_LE_UINT16();
|
|
|
|
tmpState->repCount = map_loadFromAvo_LE_UINT16();
|
2005-05-01 10:15:30 +00:00
|
|
|
tmpState->sndFrame = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gob_objects[10] = (Gob_Object *)malloc(sizeof(Gob_Object));
|
|
|
|
memset(gob_objects[10], 0, sizeof(Gob_Object));
|
|
|
|
|
2005-04-11 20:04:14 +00:00
|
|
|
gob_objects[10]->stateMach = (Gob_StateLine *)malloc(szGob_StateLine * 40);
|
|
|
|
memset(gob_objects[10]->stateMach, 0, szGob_StateLine * 40);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
pState = (Gob_State *)malloc(sizeof(Gob_State));
|
|
|
|
gob_objects[10]->stateMach[0][0] = pState;
|
|
|
|
|
|
|
|
memset(pState, 0, sizeof(Gob_State));
|
|
|
|
pState->animation = 9;
|
|
|
|
pState->layer = 27;
|
|
|
|
pState->unk0 = 0;
|
|
|
|
pState->unk1 = 0;
|
|
|
|
pState->sndItem = -1;
|
2005-05-01 10:15:30 +00:00
|
|
|
pState->sndFrame = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
gob_placeObject(gob_objects[10], 1);
|
|
|
|
|
|
|
|
gob_objects[10]->realStateMach = gob_objects[10]->stateMach;
|
|
|
|
gob_objects[10]->type = 1;
|
|
|
|
gob_objects[10]->unk14 = 1;
|
|
|
|
|
2005-04-11 20:38:17 +00:00
|
|
|
state = map_loadFromAvo_LE_UINT16();
|
2005-04-05 15:07:40 +00:00
|
|
|
for (i = 0; i < state; i++) {
|
|
|
|
map_avoDataPtr += 30;
|
|
|
|
|
2005-04-11 20:44:33 +00:00
|
|
|
map_loadDataFromAvo((char *)&flag, 4);
|
2005-04-05 15:07:40 +00:00
|
|
|
map_avoDataPtr += 56;
|
|
|
|
|
|
|
|
if (flag != 0)
|
|
|
|
map_avoDataPtr += 30;
|
|
|
|
}
|
|
|
|
|
|
|
|
map_loadDataFromAvo((char *)&tmp, 2);
|
|
|
|
map_avoDataPtr += 48;
|
|
|
|
map_loadItemToObject();
|
|
|
|
map_avoDataPtr = savedPtr;
|
|
|
|
|
|
|
|
for (i = 0; i < soundCount; i++) {
|
|
|
|
map_loadDataFromAvo(buf, 14);
|
|
|
|
strcat(buf, ".SND");
|
|
|
|
strcpy(sndNames[i], buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(dataBuf);
|
|
|
|
|
|
|
|
gob_soundData[14] = snd_loadSoundData("diamant1.snd");
|
|
|
|
|
|
|
|
for (i = 0; i < soundCount; i++) {
|
|
|
|
handle = data_openData(sndNames[i]);
|
|
|
|
if (handle < 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
data_closeData(handle);
|
|
|
|
gob_soundData[i] = snd_loadSoundData(sndNames[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void map_loadMapsInitGobs(void) {
|
|
|
|
int16 layer;
|
|
|
|
int16 i;
|
|
|
|
|
|
|
|
if (map_loadFromAvo == 0)
|
|
|
|
error("map_load: Loading .pas/.pos files is not supported!");
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
gob_nextLayer(gob_goblins[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
|
|
|
|
layer =
|
|
|
|
gob_goblins[i]->stateMach[gob_goblins[i]->state][0]->layer;
|
|
|
|
|
|
|
|
scen_updateAnim(layer, 0, gob_goblins[i]->animation, 0,
|
|
|
|
gob_goblins[i]->xPos, gob_goblins[i]->yPos, 0);
|
|
|
|
|
|
|
|
gob_goblins[i]->yPos = (gob_gobPositions[i].y + 1) * 6 -
|
|
|
|
(scen_toRedrawBottom - scen_animTop);
|
|
|
|
|
|
|
|
gob_goblins[i]->xPos = gob_gobPositions[i].x * 12 -
|
|
|
|
(scen_toRedrawLeft - scen_animLeft);
|
|
|
|
|
|
|
|
gob_goblins[i]->order = scen_toRedrawBottom / 24 + 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
gob_currentGoblin = 0;
|
|
|
|
gob_pressedMapX = gob_gobPositions[0].x;
|
|
|
|
gob_pressedMapY = gob_gobPositions[0].y;
|
|
|
|
gob_pathExistence = 0;
|
|
|
|
|
|
|
|
gob_goblins[0]->doAnim = 0;
|
|
|
|
gob_goblins[1]->doAnim = 1;
|
|
|
|
gob_goblins[2]->doAnim = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // End of namespace Gob
|