scummvm/engines/gob/map_v1.cpp
Sven Hesse 34dae22c1a More goblin handling functions, now the deactivated goblin shows
his boredom. It's the wrong goblin that's deactivated, though.
Also, the entering animation is still missing (now nothing is drawn
instead).

svn-id: r22979
2006-06-07 18:49:20 +00:00

425 lines
11 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004 Ivan Dubrov
* Copyright (C) 2004-2006 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
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/stdafx.h"
#include "common/endian.h"
#include "gob/gob.h"
#include "gob/map.h"
#include "gob/dataio.h"
#include "gob/goblin.h"
#include "gob/sound.h"
#include "gob/scenery.h"
#include "gob/mult.h"
namespace Gob {
Map_v1::Map_v1(GobEngine *vm) : Map(vm) {
int i;
int j;
_mapWidth = 26;
_mapHeight = 28;
_passMap = new int8[_mapHeight * _mapWidth];
_itemsMap = new int16*[_mapHeight];
for (i = 0; i < _mapHeight; i++) {
_itemsMap[i] = new int16[_mapWidth];
for (j = 0; j < _mapWidth; j++) {
setPass(j, i, 0);
_itemsMap[i][j] = 0;
}
}
_wayPointsCount = 40;
_wayPoints = new Point[40];
for (i = 0; i < 40; i++) {
_wayPoints[i].x = 0;
_wayPoints[i].y = 0;
_wayPoints[i].field_2 = 0;
}
}
Map_v1::~Map_v1() {
int i;
_mapWidth = 26;
_mapHeight = 28;
if (_passMap)
delete[] _passMap;
if (_itemsMap) {
for (i = 0; i < _mapHeight; i++)
delete[] _itemsMap[i];
delete[] _itemsMap;
}
if (_wayPoints)
delete[] _wayPoints;
}
void Map_v1::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;
Goblin::Gob_State *pState;
char buf[128];
char sndNames[20][14];
char *dataBuf;
int16 x;
int16 y;
int16 count2;
int16 count3;
strcpy(avoName, _sourceFile);
strcat(avoName, ".avo");
handle = _vm->_dataio->openData(avoName);
if (handle >= 0) {
_loadFromAvo = 1;
_vm->_dataio->closeData(handle);
_avoDataPtr = _vm->_dataio->getData(avoName);
dataBuf = _avoDataPtr;
loadDataFromAvo((char *)_passMap, _mapHeight * _mapWidth);
for (y = 0; y < _mapHeight; y++) {
for (x = 0; x < _mapWidth; x++) {
loadDataFromAvo(&item, 1);
_itemsMap[y][x] = item;
}
}
for (i = 0; i < 40; i++) {
_wayPoints[i].x = loadFromAvo_LE_UINT16();
_wayPoints[i].y = loadFromAvo_LE_UINT16();
}
loadDataFromAvo((char *)_itemPoses, szMap_ItemPos * 20);
} else {
_loadFromAvo = 0;
_avoDataPtr = _vm->_dataio->getData(avjFile);
dataBuf = _avoDataPtr;
}
_avoDataPtr += 32;
_avoDataPtr += 76;
_avoDataPtr += 4;
_avoDataPtr += 20;
for (i = 0; i < 3; i++) {
tmp = loadFromAvo_LE_UINT16();
_avoDataPtr += tmp * 14;
}
soundCount = loadFromAvo_LE_UINT16();
savedPtr = _avoDataPtr;
_avoDataPtr += 14 * soundCount;
_avoDataPtr += 4;
_avoDataPtr += 24;
count2 = loadFromAvo_LE_UINT16();
count3 = loadFromAvo_LE_UINT16();
savedPtr2 = _avoDataPtr;
_avoDataPtr += count2 * 8;
savedPtr3 = _avoDataPtr;
_avoDataPtr += count3 * 8;
_vm->_goblin->_gobsCount = loadFromAvo_LE_UINT16();
for (i = 0; i < _vm->_goblin->_gobsCount; i++) {
_vm->_goblin->_goblins[i] = new Goblin::Gob_Object;
_vm->_goblin->_goblins[i]->xPos = READ_LE_UINT16(savedPtr2);
savedPtr2 += 2;
_vm->_goblin->_goblins[i]->yPos = READ_LE_UINT16(savedPtr2);
savedPtr2 += 2;
_vm->_goblin->_goblins[i]->order = READ_LE_UINT16(savedPtr2);
savedPtr2 += 2;
_vm->_goblin->_goblins[i]->state = READ_LE_UINT16(savedPtr2);
savedPtr2 += 2;
if (i == 3) {
_vm->_goblin->_goblins[i]->stateMach = new Goblin::Gob_StateLine[70];
memset(_vm->_goblin->_goblins[i]->stateMach, 0, 70 * sizeof(Goblin::Gob_StateLine));
}
else {
_vm->_goblin->_goblins[i]->stateMach = new Goblin::Gob_StateLine[40];
memset(_vm->_goblin->_goblins[i]->stateMach, 0, 40 * sizeof(Goblin::Gob_StateLine));
}
uint32* tempstatedata = new uint32[40*6];
for (state = 0; state < 40; ++state) {
for (col = 0; col < 6; ++col) {
tempstatedata[state*6+col] = READ_LE_UINT32(_avoDataPtr);
_avoDataPtr += 4;
}
}
_avoDataPtr += 160;
_vm->_goblin->_goblins[i]->multObjIndex = *_avoDataPtr;
_avoDataPtr += 2;
_vm->_goblin->_goblins[i]->realStateMach = _vm->_goblin->_goblins[i]->stateMach;
for (state = 0; state < 40; state++) {
for (col = 0; col < 6; col++) {
if (tempstatedata[state*6+col] == 0) {
_vm->_goblin->_goblins[i]->stateMach[state][col] = 0;
continue;
}
Goblin::Gob_State *tmpState = new Goblin::Gob_State;
_vm->_goblin->_goblins[i]->stateMach[state][col] = tmpState;
tmpState->animation = loadFromAvo_LE_UINT16();
tmpState->layer = loadFromAvo_LE_UINT16();
_avoDataPtr += 8;
tmpState->unk0 = loadFromAvo_LE_UINT16();
tmpState->unk1 = loadFromAvo_LE_UINT16();
_avoDataPtr += 2;
if (READ_LE_UINT32(_avoDataPtr) != 0) {
_avoDataPtr += 4;
tmpState->sndItem = loadFromAvo_LE_UINT16();
} else {
_avoDataPtr += 6;
tmpState->sndItem = -1;
}
tmpState->freq = loadFromAvo_LE_UINT16();
tmpState->repCount = loadFromAvo_LE_UINT16();
tmpState->sndFrame = loadFromAvo_LE_UINT16();
}
}
delete[] tempstatedata;
}
pState = new Goblin::Gob_State;
_vm->_goblin->_goblins[0]->stateMach[39][0] = pState;
pState->animation = 0;
pState->layer = 98;
pState->unk0 = 0;
pState->unk1 = 0;
pState->sndItem = -1;
pState = new Goblin::Gob_State;
_vm->_goblin->_goblins[1]->stateMach[39][0] = pState;
pState->animation = 0;
pState->layer = 99;
pState->unk0 = 0;
pState->unk1 = 0;
pState->sndItem = -1;
pState = new Goblin::Gob_State;
_vm->_goblin->_goblins[2]->stateMach[39][0] = pState;
pState->animation = 0;
pState->layer = 100;
pState->unk0 = 0;
pState->unk1 = 0;
pState->sndItem = -1;
_vm->_goblin->_goblins[2]->stateMach[10][0]->sndFrame = 13;
_vm->_goblin->_goblins[2]->stateMach[11][0]->sndFrame = 13;
_vm->_goblin->_goblins[2]->stateMach[28][0]->sndFrame = 13;
_vm->_goblin->_goblins[2]->stateMach[29][0]->sndFrame = 13;
_vm->_goblin->_goblins[1]->stateMach[10][0]->sndFrame = 13;
_vm->_goblin->_goblins[1]->stateMach[11][0]->sndFrame = 13;
for (state = 40; state < 70; state++) {
pState = new Goblin::Gob_State;
_vm->_goblin->_goblins[3]->stateMach[state][0] = pState;
_vm->_goblin->_goblins[3]->stateMach[state][1] = 0;
pState->animation = 9;
pState->layer = state - 40;
pState->sndItem = -1;
pState->sndFrame = 0;
}
_vm->_goblin->_objCount = loadFromAvo_LE_UINT16();
for (i = 0; i < _vm->_goblin->_objCount; i++) {
_vm->_goblin->_objects[i] = new Goblin::Gob_Object;
_vm->_goblin->_objects[i]->xPos = READ_LE_UINT16(savedPtr3);
savedPtr3 += 2;
_vm->_goblin->_objects[i]->yPos = READ_LE_UINT16(savedPtr3);
savedPtr3 += 2;
_vm->_goblin->_objects[i]->order = READ_LE_UINT16(savedPtr3);
savedPtr3 += 2;
_vm->_goblin->_objects[i]->state = READ_LE_UINT16(savedPtr3);
savedPtr3 += 2;
_vm->_goblin->_objects[i]->stateMach = new Goblin::Gob_StateLine[40];
uint32* tempstatedata = new uint32[40*6];
for (state = 0; state < 40; ++state) {
for (col = 0; col < 6; ++col) {
tempstatedata[state*6+col] = READ_LE_UINT32(_avoDataPtr);
_avoDataPtr += 4;
}
}
_avoDataPtr += 160;
_vm->_goblin->_objects[i]->multObjIndex = *_avoDataPtr;
_avoDataPtr += 2;
_vm->_goblin->_objects[i]->realStateMach = _vm->_goblin->_objects[i]->stateMach;
for (state = 0; state < 40; state++) {
for (col = 0; col < 6; col++) {
if (tempstatedata[state*6+col] == 0) {
_vm->_goblin->_objects[i]->stateMach[state][col] = 0;
continue;
}
Goblin::Gob_State *tmpState = new Goblin::Gob_State;
_vm->_goblin->_objects[i]->stateMach[state][col] = tmpState;
tmpState->animation = loadFromAvo_LE_UINT16();
tmpState->layer = loadFromAvo_LE_UINT16();
_avoDataPtr += 8;
tmpState->unk0 = loadFromAvo_LE_UINT16();
tmpState->unk1 = loadFromAvo_LE_UINT16();
_avoDataPtr += 2;
if (READ_LE_UINT32(_avoDataPtr) != 0) {
_avoDataPtr += 4;
tmpState->sndItem = loadFromAvo_LE_UINT16();
} else {
_avoDataPtr += 6;
tmpState->sndItem = -1;
}
tmpState->freq = loadFromAvo_LE_UINT16();
tmpState->repCount = loadFromAvo_LE_UINT16();
tmpState->sndFrame = loadFromAvo_LE_UINT16();
}
}
delete[] tempstatedata;
}
_vm->_goblin->_objects[10] = new Goblin::Gob_Object;
memset(_vm->_goblin->_objects[10], 0, sizeof(Goblin::Gob_Object));
_vm->_goblin->_objects[10]->stateMach = new Goblin::Gob_StateLine[40];
for (state = 0; state < 40; ++state)
for (col = 0; col < 6; ++col)
_vm->_goblin->_objects[10]->stateMach[state][col] = 0;
pState = new Goblin::Gob_State;
_vm->_goblin->_objects[10]->stateMach[0][0] = pState;
memset(pState, 0, sizeof(Goblin::Gob_State));
pState->animation = 9;
pState->layer = 27;
pState->unk0 = 0;
pState->unk1 = 0;
pState->sndItem = -1;
pState->sndFrame = 0;
_vm->_goblin->placeObject(_vm->_goblin->_objects[10], 1, 0, 0, 0, 0);
_vm->_goblin->_objects[10]->realStateMach = _vm->_goblin->_objects[10]->stateMach;
_vm->_goblin->_objects[10]->type = 1;
_vm->_goblin->_objects[10]->unk14 = 1;
state = loadFromAvo_LE_UINT16();
for (i = 0; i < state; i++) {
_avoDataPtr += 30;
loadDataFromAvo((char *)&flag, 4);
_avoDataPtr += 56;
if (flag != 0)
_avoDataPtr += 30;
}
loadDataFromAvo((char *)&tmp, 2);
_avoDataPtr += 48;
loadItemToObject();
_avoDataPtr = savedPtr;
for (i = 0; i < soundCount; i++) {
loadDataFromAvo(buf, 14);
strcat(buf, ".SND");
strcpy(sndNames[i], buf);
}
delete[] dataBuf;
_vm->_goblin->_soundData[14] = _vm->_snd->loadSoundData("diamant1.snd");
for (i = 0; i < soundCount; i++) {
handle = _vm->_dataio->openData(sndNames[i]);
if (handle < 0)
continue;
_vm->_dataio->closeData(handle);
_vm->_goblin->_soundData[i] = _vm->_snd->loadSoundData(sndNames[i]);
}
}
void Map_v1::optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) {
int16 i;
if (_nearestWayPoint < _nearestDest) {
for (i = _nearestWayPoint; i <= _nearestDest; i++) {
if (checkDirectPath(0, _curGoblinX, _curGoblinY,
_wayPoints[i].x, _wayPoints[i].y) == 1)
_nearestWayPoint = i;
}
} else if (_nearestWayPoint > _nearestDest) {
for (i = _nearestWayPoint; i >= _nearestDest; i--) {
if (checkDirectPath(0, _curGoblinX, _curGoblinY,
_wayPoints[i].x, _wayPoints[i].y) == 1)
_nearestWayPoint = i;
}
}
}
void Map_v1::findNearestToGob(Mult::Mult_Object *obj) {
int16 wayPoint = findNearestWayPoint(_curGoblinX, _curGoblinY);
if (wayPoint != -1)
_nearestWayPoint = wayPoint;
}
void Map_v1::findNearestToDest(Mult::Mult_Object *obj) {
int16 wayPoint = findNearestWayPoint(_destX, _destY);
if (wayPoint != -1)
_nearestDest = wayPoint;
}
} // End of namespace Gob