2005-04-05 18:08:02 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
|
|
|
* Copyright (C) 2004 Ivan Dubrov
|
2006-01-18 17:39:49 +00:00
|
|
|
* Copyright (C) 2004-2006 The ScummVM project
|
2005-04-05 18:08:02 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
*
|
2006-02-11 10:11:37 +00:00
|
|
|
* $URL$
|
|
|
|
* $Id$
|
2005-04-05 18:08:02 +00:00
|
|
|
*
|
|
|
|
*/
|
2005-04-05 15:07:40 +00:00
|
|
|
#include "gob/gob.h"
|
|
|
|
#include "gob/goblin.h"
|
|
|
|
#include "gob/inter.h"
|
|
|
|
#include "gob/global.h"
|
|
|
|
#include "gob/draw.h"
|
|
|
|
#include "gob/video.h"
|
|
|
|
#include "gob/anim.h"
|
|
|
|
#include "gob/scenery.h"
|
|
|
|
#include "gob/map.h"
|
|
|
|
#include "gob/sound.h"
|
|
|
|
#include "gob/game.h"
|
|
|
|
#include "gob/dataio.h"
|
2005-04-13 18:27:29 +00:00
|
|
|
#include "gob/cdrom.h"
|
2006-01-08 20:03:20 +00:00
|
|
|
#include "gob/music.h"
|
2006-05-11 19:43:30 +00:00
|
|
|
#include "gob/mult.h"
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
namespace Gob {
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
Goblin::Goblin(GobEngine *vm) : _vm(vm) {
|
2006-05-11 19:43:30 +00:00
|
|
|
int i;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_goesAtTarget = 0;
|
|
|
|
_readyToAct = 0;
|
|
|
|
_gobAction = 0;
|
|
|
|
_itemIndInPocket = 5;
|
|
|
|
_itemIdInPocket = 2;
|
|
|
|
_itemByteFlag = 0;
|
|
|
|
_destItemId = -1;
|
|
|
|
_destActionItem = 0;
|
|
|
|
_actDestItemDesc = 0;
|
|
|
|
_forceNextState[0] = -1;
|
|
|
|
_forceNextState[1] = -1;
|
|
|
|
_forceNextState[2] = -1;
|
|
|
|
_forceNextState[3] = -1;
|
|
|
|
_forceNextState[4] = -1;
|
|
|
|
_forceNextState[5] = -1;
|
|
|
|
_forceNextState[6] = -1;
|
|
|
|
_forceNextState[7] = 0;
|
|
|
|
_forceNextState[8] = 0;
|
|
|
|
_forceNextState[9] = 0;
|
|
|
|
|
|
|
|
_boreCounter = 0;
|
|
|
|
_positionedGob = 5;
|
|
|
|
|
|
|
|
_noPick = 0;
|
|
|
|
_objList = 0;
|
2006-05-11 19:43:30 +00:00
|
|
|
|
2006-02-03 07:30:29 +00:00
|
|
|
for (i = 0; i < 4; i++)
|
2006-01-07 22:28:54 +00:00
|
|
|
_goblins[i] = 0;
|
|
|
|
_currentGoblin = 0;
|
2006-02-03 07:30:29 +00:00
|
|
|
for (i = 0; i < 16; i++)
|
2006-01-07 22:28:54 +00:00
|
|
|
_soundData[i] = 0;
|
2006-02-03 07:30:29 +00:00
|
|
|
for (i = 0; i < 3; i++) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobPositions[i].x = 0;
|
|
|
|
_gobPositions[i].y = 0;
|
2006-01-03 23:14:39 +00:00
|
|
|
}
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobDestX = 0;
|
|
|
|
_gobDestY = 0;
|
|
|
|
_pressedMapX = 0;
|
|
|
|
_pressedMapY = 0;
|
|
|
|
_pathExistence = 0;
|
|
|
|
|
|
|
|
_some0ValPtr = 0;
|
|
|
|
|
|
|
|
_gobRetVarPtr = 0;
|
|
|
|
_curGobVarPtr = 0;
|
|
|
|
_curGobXPosVarPtr = 0;
|
|
|
|
_curGobYPosVarPtr = 0;
|
|
|
|
_itemInPocketVarPtr = 0;
|
|
|
|
|
|
|
|
_curGobStateVarPtr = 0;
|
|
|
|
_curGobFrameVarPtr = 0;
|
|
|
|
_curGobMultStateVarPtr = 0;
|
|
|
|
_curGobNextStateVarPtr = 0;
|
|
|
|
_curGobScrXVarPtr = 0;
|
|
|
|
_curGobScrYVarPtr = 0;
|
|
|
|
_curGobLeftVarPtr = 0;
|
|
|
|
_curGobTopVarPtr = 0;
|
|
|
|
_curGobRightVarPtr = 0;
|
|
|
|
_curGobBottomVarPtr = 0;
|
|
|
|
_curGobDoAnimVarPtr = 0;
|
|
|
|
_curGobOrderVarPtr = 0;
|
|
|
|
_curGobNoTickVarPtr = 0;
|
|
|
|
_curGobTypeVarPtr = 0;
|
|
|
|
_curGobMaxTickVarPtr = 0;
|
|
|
|
_curGobTickVarPtr = 0;
|
|
|
|
_curGobActStartStateVarPtr = 0;
|
|
|
|
_curGobLookDirVarPtr = 0;
|
|
|
|
_curGobPickableVarPtr = 0;
|
|
|
|
_curGobRelaxVarPtr = 0;
|
|
|
|
_curGobMaxFrameVarPtr = 0;
|
|
|
|
|
|
|
|
_destItemStateVarPtr = 0;
|
|
|
|
_destItemFrameVarPtr = 0;
|
|
|
|
_destItemMultStateVarPtr = 0;
|
|
|
|
_destItemNextStateVarPtr = 0;
|
|
|
|
_destItemScrXVarPtr = 0;
|
|
|
|
_destItemScrYVarPtr = 0;
|
|
|
|
_destItemLeftVarPtr = 0;
|
|
|
|
_destItemTopVarPtr = 0;
|
|
|
|
_destItemRightVarPtr = 0;
|
|
|
|
_destItemBottomVarPtr = 0;
|
|
|
|
_destItemDoAnimVarPtr = 0;
|
|
|
|
_destItemOrderVarPtr = 0;
|
|
|
|
_destItemNoTickVarPtr = 0;
|
|
|
|
_destItemTypeVarPtr = 0;
|
|
|
|
_destItemMaxTickVarPtr = 0;
|
|
|
|
_destItemTickVarPtr = 0;
|
|
|
|
_destItemActStartStVarPtr = 0;
|
|
|
|
_destItemLookDirVarPtr = 0;
|
|
|
|
_destItemPickableVarPtr = 0;
|
|
|
|
_destItemRelaxVarPtr = 0;
|
|
|
|
_destItemMaxFrameVarPtr = 0;
|
|
|
|
|
|
|
|
_destItemType = 0;
|
|
|
|
_destItemState = 0;
|
2006-02-03 07:30:29 +00:00
|
|
|
for (i = 0; i < 20; i++) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_itemToObject[i] = 0;
|
|
|
|
_objects[i] = 0;
|
2006-01-03 23:14:39 +00:00
|
|
|
}
|
2006-01-07 22:28:54 +00:00
|
|
|
_objCount = 0;
|
|
|
|
_gobsCount = 0;
|
2006-05-11 19:43:30 +00:00
|
|
|
|
|
|
|
_soundSlotsCount = 0;
|
|
|
|
for (i = 0; i < 60; i++)
|
|
|
|
_soundSlots[i] = -1;
|
|
|
|
|
|
|
|
warning("GOB2 Stub! _word_2F9C0, _word_2F9BE, _word_2F9BC, _word_2F9BA, _dword_2F9B6, _dword_2F9B2");
|
|
|
|
_word_2F9C0 = 0;
|
|
|
|
_word_2F9BE = 0;
|
|
|
|
_word_2F9BC = 0;
|
|
|
|
_word_2F9BA = 0;
|
|
|
|
_dword_2F9B6 = 0;
|
|
|
|
_dword_2F9B2 = 0;
|
2006-01-03 23:14:39 +00:00
|
|
|
}
|
|
|
|
|
2006-05-31 08:44:14 +00:00
|
|
|
Goblin::~Goblin() {
|
|
|
|
int i, state, col;
|
|
|
|
|
|
|
|
if (_objList)
|
|
|
|
_vm->_util->deleteList(_objList);
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
if (_goblins[i]) {
|
|
|
|
if (_goblins[i]->stateMach) {
|
|
|
|
for (state = 0; state < (i == 3 ? 70 : 40); state++)
|
2006-11-27 14:19:30 +00:00
|
|
|
if (_goblins[i]->stateMach[state])
|
|
|
|
for (col = 0; col < 6; col++)
|
|
|
|
if (_goblins[i]->stateMach[state][col])
|
|
|
|
delete _goblins[i]->stateMach[state][col];
|
2006-05-31 20:19:03 +00:00
|
|
|
delete []_goblins[i]->stateMach;
|
2006-05-31 08:44:14 +00:00
|
|
|
}
|
|
|
|
delete _goblins[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i = 0; i < 20; i++) {
|
|
|
|
if (_objects[i]) {
|
|
|
|
if (_objects[i]->stateMach) {
|
|
|
|
for (state = 0; state < 40; state++)
|
|
|
|
for (col = 0; col < 6; col++)
|
|
|
|
if (_objects[i]->stateMach[state][col])
|
|
|
|
delete _objects[i]->stateMach[state][col];
|
2006-05-31 20:19:03 +00:00
|
|
|
delete []_objects[i]->stateMach;
|
2006-05-31 08:44:14 +00:00
|
|
|
}
|
|
|
|
delete _objects[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < 16; i++)
|
|
|
|
if (_soundData[i]) {
|
|
|
|
if (_soundData[i]->data)
|
|
|
|
delete[] _soundData[i]->data;
|
|
|
|
delete _soundData[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
char Goblin::rotateState(int16 from, int16 to) {
|
2006-01-07 22:28:54 +00:00
|
|
|
return _rotStates[from / 2][to / 2];
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
int16 Goblin::peekGoblin(Gob_Object *_curGob) {
|
2006-01-03 23:14:39 +00:00
|
|
|
Util::ListNode *ptr;
|
2005-04-05 15:07:40 +00:00
|
|
|
Gob_Object *desc;
|
|
|
|
int16 index;
|
|
|
|
int16 i;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
ptr = _objList->pHead;
|
2005-04-05 15:07:40 +00:00
|
|
|
index = 0;
|
|
|
|
while (ptr != 0) {
|
|
|
|
desc = (Gob_Object *) ptr->pData;
|
2006-01-07 22:28:54 +00:00
|
|
|
if (desc != _curGob) {
|
2005-04-05 15:07:40 +00:00
|
|
|
for (i = 0; i < 3; i++) {
|
2006-01-07 22:28:54 +00:00
|
|
|
if (desc != _goblins[i])
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
|
2006-01-04 01:48:15 +00:00
|
|
|
if (_vm->_global->_inter_mouseX < desc->right &&
|
|
|
|
_vm->_global->_inter_mouseX > desc->left &&
|
|
|
|
_vm->_global->_inter_mouseY < desc->bottom &&
|
|
|
|
_vm->_global->_inter_mouseY > desc->top) {
|
2005-04-05 15:07:40 +00:00
|
|
|
index = i + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ptr = ptr->pNext;
|
|
|
|
}
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::initList(void) {
|
2006-01-29 02:27:10 +00:00
|
|
|
_objList = new Util::List;
|
2006-01-07 22:28:54 +00:00
|
|
|
_objList->pHead = 0;
|
|
|
|
_objList->pTail = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::sortByOrder(Util::List *list) {
|
|
|
|
Util::ListNode *ptr;
|
|
|
|
Util::ListNode *ptr2;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
ptr = list->pHead;
|
|
|
|
while (ptr->pNext != 0) {
|
|
|
|
for (ptr2 = ptr->pNext; ptr2 != 0; ptr2 = ptr2->pNext) {
|
2005-06-21 13:14:56 +00:00
|
|
|
Gob_Object *objDesc = (Gob_Object *)ptr->pData;
|
|
|
|
Gob_Object *objDesc2 = (Gob_Object *)ptr2->pData;
|
|
|
|
|
|
|
|
if (objDesc->order <= objDesc2->order) {
|
|
|
|
if (objDesc->order != objDesc2->order)
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
|
2005-06-21 13:14:56 +00:00
|
|
|
if (objDesc->bottom <= objDesc2->bottom) {
|
|
|
|
if (objDesc->bottom != objDesc2->bottom)
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (objDesc != _goblins[_currentGoblin])
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-06-21 13:14:56 +00:00
|
|
|
SWAP(ptr->pData, ptr2->pData);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
ptr = ptr->pNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::playSound(Snd::SoundDesc *snd, int16 repCount, int16 freq) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (snd != 0) {
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_snd->stopSound(0);
|
|
|
|
_vm->_snd->playSample(snd, repCount, freq);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::drawObjects(void) {
|
|
|
|
Util::ListNode *ptr;
|
|
|
|
Util::ListNode *ptr2;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
Gob_Object *objDesc;
|
|
|
|
Gob_Object *gobDesc2;
|
|
|
|
int16 layer;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
ptr = _objList->pHead;
|
|
|
|
for (ptr = _objList->pHead; ptr != 0; ptr = ptr->pNext) {
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc = (Gob_Object *) ptr->pData;
|
|
|
|
|
|
|
|
if (objDesc->type == 3)
|
|
|
|
objDesc->toRedraw = 1;
|
|
|
|
else if (objDesc->type == 1)
|
|
|
|
objDesc->toRedraw = 0;
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
for (ptr = _objList->pHead; ptr != 0; ptr = ptr->pNext) {
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc = (Gob_Object *) ptr->pData;
|
|
|
|
if (objDesc->toRedraw == 0)
|
|
|
|
continue;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_video->drawSprite(_vm->_anim->_animSurf, _vm->_draw->_backSurface,
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->left, objDesc->top, objDesc->right,
|
|
|
|
objDesc->bottom, objDesc->left, objDesc->top, 0);
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_draw->invalidateRect(objDesc->left, objDesc->top,
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->right, objDesc->bottom);
|
|
|
|
|
|
|
|
if (objDesc->type != 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
layer =
|
|
|
|
objDesc->stateMach[objDesc->state][objDesc->stateColumn]->
|
|
|
|
layer;
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_scenery->updateAnim(layer, objDesc->curFrame, objDesc->animation,
|
2005-04-05 15:07:40 +00:00
|
|
|
0, objDesc->xPos, objDesc->yPos, 0);
|
|
|
|
|
2006-01-09 16:10:22 +00:00
|
|
|
if (_vm->_scenery->_toRedrawLeft == -12345) {
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->dirtyLeft = objDesc->left;
|
|
|
|
objDesc->dirtyRight = objDesc->right;
|
|
|
|
objDesc->dirtyTop = objDesc->top;
|
|
|
|
objDesc->dirtyBottom = objDesc->bottom;
|
|
|
|
} else {
|
|
|
|
objDesc->dirtyLeft =
|
2006-01-09 16:10:22 +00:00
|
|
|
MIN(objDesc->left, _vm->_scenery->_toRedrawLeft);
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->dirtyRight =
|
2006-01-09 16:10:22 +00:00
|
|
|
MAX(objDesc->right, _vm->_scenery->_toRedrawRight);
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->dirtyTop =
|
2006-01-09 16:10:22 +00:00
|
|
|
MIN(objDesc->top, _vm->_scenery->_toRedrawTop);
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->dirtyBottom =
|
2006-01-09 16:10:22 +00:00
|
|
|
MAX(objDesc->bottom, _vm->_scenery->_toRedrawBottom);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
objDesc->dirtyLeft = 0;
|
|
|
|
objDesc->dirtyRight = 319;
|
|
|
|
objDesc->dirtyTop = 0;
|
|
|
|
objDesc->dirtyBottom = 199;
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
sortByOrder(_objList);
|
|
|
|
for (ptr = _objList->pHead; ptr != 0; ptr = ptr->pNext) {
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc = (Gob_Object *) ptr->pData;
|
|
|
|
if (objDesc->toRedraw) {
|
|
|
|
layer =
|
|
|
|
objDesc->stateMach[objDesc->state][objDesc->
|
|
|
|
stateColumn]->layer;
|
|
|
|
|
|
|
|
if (objDesc->type == 0) {
|
|
|
|
if (objDesc->visible == 0) {
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_scenery->updateAnim(layer,
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->curFrame,
|
|
|
|
objDesc->animation, 0,
|
|
|
|
objDesc->xPos, objDesc->yPos, 0);
|
|
|
|
|
|
|
|
} else {
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_scenery->updateAnim(layer,
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->curFrame,
|
|
|
|
objDesc->animation, 2,
|
|
|
|
objDesc->xPos, objDesc->yPos, 1);
|
|
|
|
}
|
2006-01-09 16:10:22 +00:00
|
|
|
if (_vm->_scenery->_toRedrawLeft == -12345) {
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->left = 0;
|
|
|
|
objDesc->top = 0;
|
|
|
|
objDesc->right = 0;
|
|
|
|
objDesc->bottom = 0;
|
|
|
|
} else {
|
2006-01-09 16:10:22 +00:00
|
|
|
_vm->_draw->invalidateRect(_vm->_scenery->_toRedrawLeft,
|
|
|
|
_vm->_scenery->_toRedrawTop,
|
|
|
|
_vm->_scenery->_toRedrawRight,
|
|
|
|
_vm->_scenery->_toRedrawBottom);
|
|
|
|
|
|
|
|
objDesc->left = _vm->_scenery->_toRedrawLeft;
|
|
|
|
objDesc->top = _vm->_scenery->_toRedrawTop;
|
|
|
|
objDesc->right = _vm->_scenery->_toRedrawRight;
|
|
|
|
objDesc->bottom = _vm->_scenery->_toRedrawBottom;
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_scenery->updateStatic(objDesc->order);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
objDesc->left = 0;
|
|
|
|
objDesc->top = 0;
|
|
|
|
objDesc->right = 0;
|
|
|
|
objDesc->bottom = 0;
|
|
|
|
objDesc->type = 1;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (objDesc->type == 0 && objDesc->visible != 0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
for (ptr2 = _objList->pHead; ptr2 != 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
ptr2 = ptr2->pNext) {
|
|
|
|
gobDesc2 = (Gob_Object *) ptr2->pData;
|
|
|
|
|
|
|
|
if (gobDesc2->toRedraw == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (objDesc->right < gobDesc2->dirtyLeft)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (gobDesc2->dirtyRight < objDesc->left)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (objDesc->bottom < gobDesc2->dirtyTop)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (gobDesc2->dirtyBottom < objDesc->top)
|
|
|
|
continue;
|
|
|
|
|
2006-01-09 16:10:22 +00:00
|
|
|
_vm->_scenery->_toRedrawLeft = gobDesc2->dirtyLeft;
|
|
|
|
_vm->_scenery->_toRedrawRight = gobDesc2->dirtyRight;
|
|
|
|
_vm->_scenery->_toRedrawTop = gobDesc2->dirtyTop;
|
|
|
|
_vm->_scenery->_toRedrawBottom = gobDesc2->dirtyBottom;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
layer =
|
|
|
|
objDesc->stateMach[objDesc->
|
|
|
|
state][objDesc->stateColumn]->layer;
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_scenery->updateAnim(layer, objDesc->curFrame,
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->animation, 4, objDesc->xPos,
|
|
|
|
objDesc->yPos, 1);
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_scenery->updateStatic(objDesc->order);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
for (ptr = _objList->pHead; ptr != 0; ptr = ptr->pNext) {
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc = (Gob_Object *) ptr->pData;
|
|
|
|
if (objDesc->toRedraw == 0 || objDesc->type == 1)
|
|
|
|
continue;
|
|
|
|
|
2005-05-01 10:15:30 +00:00
|
|
|
Gob_State *state = objDesc->stateMach[objDesc->state][objDesc->stateColumn];
|
|
|
|
int16 sndFrame;
|
|
|
|
int16 sndItem;
|
|
|
|
int16 freq;
|
|
|
|
int16 repCount;
|
|
|
|
|
|
|
|
if (state->sndFrame & 0xff00) {
|
|
|
|
// There are two frames which trigger a sound effect,
|
|
|
|
// so everything has to be encoded in one byte each.
|
|
|
|
// Note that the frequency is multiplied by 100, not -
|
|
|
|
// as I would have thought, 0x100.
|
|
|
|
|
|
|
|
sndFrame = (state->sndFrame >> 8) & 0xff;
|
|
|
|
sndItem = (state->sndItem >> 8) & 0xff;
|
|
|
|
freq = 100 * ((state->freq >> 8) & 0xff);
|
|
|
|
repCount = (state->repCount >> 8) & 0xff;
|
|
|
|
|
|
|
|
if (objDesc->curFrame == sndFrame) {
|
|
|
|
if (sndItem != 0xff) {
|
2006-01-07 22:28:54 +00:00
|
|
|
playSound(_soundData[sndItem],
|
2005-04-05 15:07:40 +00:00
|
|
|
repCount, freq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-01 10:15:30 +00:00
|
|
|
sndFrame = state->sndFrame & 0xff;
|
|
|
|
sndItem = state->sndItem & 0xff;
|
|
|
|
freq = 100 * (state->freq & 0xff);
|
|
|
|
repCount = state->repCount & 0xff;
|
|
|
|
|
|
|
|
if (objDesc->curFrame == sndFrame) {
|
|
|
|
if (sndItem != 0xff) {
|
2006-01-07 22:28:54 +00:00
|
|
|
playSound(_soundData[sndItem],
|
2005-04-05 15:07:40 +00:00
|
|
|
repCount, freq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2005-05-01 10:15:30 +00:00
|
|
|
// There is only one, so frequency etc. are used as is.
|
|
|
|
sndFrame = state->sndFrame;
|
|
|
|
sndItem = state->sndItem;
|
|
|
|
freq = state->freq;
|
|
|
|
repCount = state->repCount;
|
|
|
|
|
|
|
|
if (objDesc->curFrame == sndFrame) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (sndItem != -1) {
|
2006-01-07 22:28:54 +00:00
|
|
|
playSound(_soundData[sndItem],
|
2005-04-05 15:07:40 +00:00
|
|
|
repCount, freq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
// _vm->_scenery->updateAnim(27, 0, 9, 2, 10, 10, 1);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::animateObjects(void) {
|
|
|
|
Util::ListNode *node;
|
2005-04-05 15:07:40 +00:00
|
|
|
Gob_Object *objDesc;
|
2006-01-03 23:14:39 +00:00
|
|
|
Scenery::AnimLayer *pLayer;
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 layer;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
for (node = _objList->pHead; node != 0; node = node->pNext) {
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc = (Gob_Object *) node->pData;
|
|
|
|
if (objDesc->doAnim != 1 || objDesc->type != 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (objDesc->noTick != 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (objDesc->tick < objDesc->maxTick)
|
|
|
|
objDesc->tick++;
|
|
|
|
|
|
|
|
if (objDesc->tick >= objDesc->maxTick) {
|
|
|
|
objDesc->tick = 1;
|
|
|
|
objDesc->curFrame++;
|
|
|
|
|
|
|
|
layer = objDesc->stateMach[objDesc->state][0]->layer;
|
|
|
|
pLayer =
|
2006-06-12 21:33:30 +00:00
|
|
|
&_vm->_scenery->_animations[objDesc->animation].layers[layer];
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (objDesc->curFrame < pLayer->framesCount)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
objDesc->curFrame = 0;
|
|
|
|
|
|
|
|
objDesc->xPos += pLayer->animDeltaX;
|
|
|
|
objDesc->yPos += pLayer->animDeltaY;
|
|
|
|
|
|
|
|
if (objDesc->nextState == -1
|
|
|
|
&& objDesc->multState == -1
|
|
|
|
&& objDesc->unk14 == 0) {
|
|
|
|
objDesc->toRedraw = 0;
|
|
|
|
objDesc->curFrame = pLayer->framesCount - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (objDesc->multState != -1) {
|
|
|
|
if (objDesc->multState > 39) {
|
2006-01-07 22:28:54 +00:00
|
|
|
objDesc->stateMach = _goblins[(int)(objDesc->multObjIndex)]->stateMach;
|
2005-04-05 17:41:37 +00:00
|
|
|
objDesc->state = objDesc->multState - 40;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2005-04-05 17:41:37 +00:00
|
|
|
objDesc->stateMach = objDesc->realStateMach;
|
2005-04-05 15:07:40 +00:00
|
|
|
objDesc->state = objDesc->multState;
|
|
|
|
}
|
|
|
|
objDesc->animation =
|
|
|
|
objDesc->stateMach[objDesc->state][0]->
|
|
|
|
animation;
|
|
|
|
objDesc->multState = -1;
|
|
|
|
} else {
|
|
|
|
if (objDesc->nextState == -1)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
objDesc->stateMach = objDesc->realStateMach;
|
|
|
|
objDesc->state = objDesc->nextState;
|
|
|
|
objDesc->animation =
|
|
|
|
objDesc->stateMach[objDesc->state][0]->
|
|
|
|
animation;
|
|
|
|
objDesc->nextState = -1;
|
|
|
|
}
|
|
|
|
objDesc->toRedraw = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
int16 Goblin::getObjMaxFrame(Gob_Object * objDesc) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 layer;
|
|
|
|
|
|
|
|
layer = objDesc->stateMach[objDesc->state][0]->layer;
|
2006-06-12 21:33:30 +00:00
|
|
|
return _vm->_scenery->_animations[objDesc->animation].layers[layer].framesCount - 1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
int16 Goblin::objIntersected(Gob_Object *obj1, Gob_Object *obj2) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (obj1->type == 1 || obj2->type == 1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (obj1->right < obj2->left)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (obj1->left > obj2->right)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (obj1->bottom < obj2->top)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (obj1->top > obj2->bottom)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::setMultStates(Gob_Object * gobDesc) {
|
2006-01-07 22:28:54 +00:00
|
|
|
gobDesc->stateMach = _goblins[(int)gobDesc->multObjIndex]->stateMach;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
int16 Goblin::nextLayer(Gob_Object *gobDesc) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (gobDesc->nextState == 10)
|
|
|
|
gobDesc->curLookDir = 0;
|
|
|
|
|
|
|
|
if (gobDesc->nextState == 11)
|
|
|
|
gobDesc->curLookDir = 4;
|
|
|
|
|
|
|
|
if (gobDesc->nextState > 39) {
|
2006-01-03 23:14:39 +00:00
|
|
|
setMultStates(gobDesc);
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
|
|
|
gobDesc->stateMach = gobDesc->realStateMach;
|
|
|
|
}
|
|
|
|
|
|
|
|
gobDesc->curFrame = 0;
|
|
|
|
if (gobDesc->nextState > 39)
|
|
|
|
gobDesc->state = gobDesc->nextState - 40;
|
|
|
|
else
|
|
|
|
gobDesc->state = gobDesc->nextState;
|
|
|
|
|
|
|
|
gobDesc->animation = gobDesc->stateMach[gobDesc->state][0]->animation;
|
|
|
|
return gobDesc->stateMach[gobDesc->state][0]->layer;
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::showBoredom(int16 gobIndex) {
|
2005-04-05 15:07:40 +00:00
|
|
|
Gob_Object *gobDesc;
|
|
|
|
int16 frame;
|
|
|
|
int16 frameCount;
|
|
|
|
int16 layer;
|
|
|
|
int16 state;
|
|
|
|
int16 boreFlag;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
gobDesc = _goblins[gobIndex];
|
2005-04-05 15:07:40 +00:00
|
|
|
layer = gobDesc->stateMach[gobDesc->state][0]->layer;
|
|
|
|
|
|
|
|
frameCount =
|
2006-06-12 21:33:30 +00:00
|
|
|
_vm->_scenery->_animations[gobDesc->animation].layers[layer].framesCount;
|
2005-04-05 15:07:40 +00:00
|
|
|
state = gobDesc->state;
|
|
|
|
frame = gobDesc->curFrame;
|
|
|
|
|
|
|
|
gobDesc->noTick = 0;
|
|
|
|
gobDesc->toRedraw = 1;
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
boreFlag = 1 << _vm->_util->getRandom(7);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (gobIndex != _currentGoblin && _vm->_util->getRandom(3) != 0) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (state == 21) {
|
|
|
|
if ((boreFlag & 16) || (boreFlag & 32)) {
|
|
|
|
gobDesc->multState = 92 + gobIndex;
|
|
|
|
} else if (boreFlag & 1) {
|
|
|
|
gobDesc->multState = 86 + gobIndex;
|
|
|
|
} else if (boreFlag & 2) {
|
|
|
|
gobDesc->multState = 80 + gobIndex;
|
|
|
|
} else if (boreFlag & 4) {
|
|
|
|
gobDesc->multState = 89 + gobIndex;
|
|
|
|
} else if (boreFlag & 8) {
|
|
|
|
gobDesc->multState = 104 + gobIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gobDesc->nextState = 21;
|
2005-04-10 17:13:17 +00:00
|
|
|
} else if (state >= 18 && state <= 21 && VAR(59) == 0) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (state == 30 || state == 31) // ???
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (frame != frameCount)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gobDesc->multState = 104 + gobIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// index - goblin to select+1
|
|
|
|
// index==0 - switch to next
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::switchGoblin(int16 index) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 next;
|
|
|
|
int16 tmp;
|
|
|
|
|
2007-01-13 15:35:02 +00:00
|
|
|
debugC(4, kDebugGameFlow, "switchGoblin");
|
2005-04-10 17:13:17 +00:00
|
|
|
if (VAR(59) != 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_goblins[_currentGoblin]->state <= 39 &&
|
|
|
|
_goblins[_currentGoblin]->curFrame != 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (index != 0 && _goblins[index - 1]->type != 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (index == 0)
|
2006-01-07 22:28:54 +00:00
|
|
|
next = (_currentGoblin + 1) % 3;
|
2005-04-05 15:07:40 +00:00
|
|
|
else
|
|
|
|
next = index - 1;
|
|
|
|
|
2006-05-29 18:24:52 +00:00
|
|
|
if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 ||
|
|
|
|
_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_goblins[(_currentGoblin + 1) % 3]->type != 0 &&
|
|
|
|
_goblins[(_currentGoblin + 2) % 3]->type != 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobPositions[_currentGoblin].x = _vm->_map->_curGoblinX;
|
|
|
|
_gobPositions[_currentGoblin].y = _vm->_map->_curGoblinY;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_goblins[_currentGoblin]->doAnim = 1;
|
|
|
|
_goblins[_currentGoblin]->nextState = 21;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
nextLayer(_goblins[_currentGoblin]);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_currentGoblin = next;
|
|
|
|
if (_goblins[_currentGoblin]->type != 0)
|
|
|
|
_currentGoblin = (_currentGoblin + 1) % 3;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_goblins[_currentGoblin]->doAnim = 0;
|
|
|
|
if (_goblins[_currentGoblin]->curLookDir == 4)
|
|
|
|
_goblins[_currentGoblin]->nextState = 18;
|
2005-04-05 15:07:40 +00:00
|
|
|
else
|
2006-01-07 22:28:54 +00:00
|
|
|
_goblins[_currentGoblin]->nextState = 19;
|
2006-01-03 23:14:39 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_goblins[_currentGoblin]->toRedraw = 1;
|
|
|
|
nextLayer(_goblins[_currentGoblin]);
|
2006-01-03 23:14:39 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
tmp = _gobPositions[_currentGoblin].x;
|
|
|
|
_pressedMapX = tmp;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_destX = tmp;
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobDestX = tmp;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_curGoblinX = tmp;
|
2006-01-03 23:14:39 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
tmp = _gobPositions[_currentGoblin].y;
|
|
|
|
_pressedMapY = tmp;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_destY = tmp;
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobDestY = tmp;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_curGoblinY = tmp;
|
2006-01-03 23:14:39 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
*_curGobVarPtr = _currentGoblin;
|
|
|
|
_pathExistence = 0;
|
|
|
|
_readyToAct = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::adjustDest(int16 posX, int16 posY) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 resDelta;
|
|
|
|
int16 resDeltaDir;
|
|
|
|
int16 resDeltaPix;
|
|
|
|
int16 deltaPix;
|
|
|
|
int16 i;
|
|
|
|
|
2006-05-29 18:24:52 +00:00
|
|
|
if (_vm->_map->getPass(_pressedMapX, _pressedMapY) == 0 &&
|
2006-01-07 22:28:54 +00:00
|
|
|
(_gobAction == 0
|
|
|
|
|| _vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0)) {
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
resDelta = -1;
|
|
|
|
resDeltaDir = 0;
|
|
|
|
resDeltaPix = 0;
|
|
|
|
|
|
|
|
for (i = 1;
|
2006-01-07 22:28:54 +00:00
|
|
|
i <= _pressedMapX
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_pressedMapX - i, _pressedMapY) == 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
i++);
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (i <= _pressedMapX) {
|
2005-04-05 15:07:40 +00:00
|
|
|
resDeltaPix = (i - 1) * 12 + (posX % 12) + 1;
|
|
|
|
resDelta = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 1;
|
2006-05-29 18:24:52 +00:00
|
|
|
(i + _pressedMapX) < _vm->_map->_mapWidth
|
|
|
|
&& _vm->_map->getPass(_pressedMapX + i, _pressedMapY) == 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
i++);
|
|
|
|
|
2006-05-29 18:24:52 +00:00
|
|
|
if (_pressedMapX + i < _vm->_map->_mapWidth) {
|
2005-04-05 15:07:40 +00:00
|
|
|
deltaPix = (i * 12) - (posX % 12);
|
|
|
|
if (resDelta == -1 || deltaPix < resDeltaPix) {
|
|
|
|
resDeltaPix = deltaPix;
|
|
|
|
resDelta = i;
|
|
|
|
resDeltaDir = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 1;
|
2006-05-29 18:24:52 +00:00
|
|
|
(i + _pressedMapY) < _vm->_map->_mapHeight
|
|
|
|
&& _vm->_map->getPass(_pressedMapX, _pressedMapY + i) == 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
i++);
|
|
|
|
|
2006-05-29 18:24:52 +00:00
|
|
|
if (_pressedMapY + i < _vm->_map->_mapHeight) {
|
2005-04-05 15:07:40 +00:00
|
|
|
deltaPix = (i * 6) - (posY % 6);
|
|
|
|
if (resDelta == -1 || deltaPix < resDeltaPix) {
|
|
|
|
resDeltaPix = deltaPix;
|
|
|
|
resDelta = i;
|
|
|
|
resDeltaDir = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 1;
|
2006-01-07 22:28:54 +00:00
|
|
|
i <= _pressedMapY
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_pressedMapX, _pressedMapY - i) == 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
i++);
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (i <= _pressedMapY) {
|
2005-04-05 15:07:40 +00:00
|
|
|
deltaPix = (i * 6) + (posY % 6);
|
|
|
|
if (resDelta == -1 || deltaPix < resDeltaPix) {
|
|
|
|
resDeltaPix = deltaPix;
|
|
|
|
resDelta = i;
|
|
|
|
resDeltaDir = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (resDeltaDir) {
|
|
|
|
case 0:
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapX -= resDelta;
|
2005-04-05 15:07:40 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapX += resDelta;
|
2005-04-05 15:07:40 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapY += resDelta;
|
2005-04-05 15:07:40 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapY -= resDelta;
|
2005-04-05 15:07:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2007-02-05 19:48:12 +00:00
|
|
|
_pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->_mapWidth - 1);
|
|
|
|
_pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->_mapHeight - 1);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::adjustTarget(void) {
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_gobAction == 4
|
|
|
|
&& _vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0) {
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_pressedMapY > 0
|
|
|
|
&& _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX] !=
|
2005-04-05 15:07:40 +00:00
|
|
|
0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapY--;
|
2006-05-29 18:24:52 +00:00
|
|
|
} else if (_pressedMapX < _vm->_map->_mapWidth - 1
|
2006-01-07 22:28:54 +00:00
|
|
|
&& _vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] !=
|
2005-04-05 15:07:40 +00:00
|
|
|
0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapX++;
|
2006-05-29 18:24:52 +00:00
|
|
|
} else if (_pressedMapX < _vm->_map->_mapWidth - 1 && _pressedMapY > 0
|
2006-01-07 22:28:54 +00:00
|
|
|
&& _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX +
|
2005-04-05 15:07:40 +00:00
|
|
|
1] != 0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapY--;
|
|
|
|
_pressedMapX++;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
2007-02-05 19:48:12 +00:00
|
|
|
_pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->_mapWidth - 1);
|
|
|
|
_pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->_mapHeight - 1);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::targetDummyItem(Gob_Object *gobDesc) {
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0 &&
|
2006-05-29 18:24:52 +00:00
|
|
|
_vm->_map->getPass(_pressedMapX, _pressedMapY) == 1) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (gobDesc->curLookDir == 0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_itemPoses[0].x = _pressedMapX;
|
|
|
|
_vm->_map->_itemPoses[0].y = _pressedMapY;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemPoses[0].orient = -4;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_itemPoses[0].x = _pressedMapX;
|
|
|
|
_vm->_map->_itemPoses[0].y = _pressedMapY;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemPoses[0].orient = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::targetItem(void) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 tmpX;
|
|
|
|
int16 tmpY;
|
|
|
|
int16 items;
|
|
|
|
int16 layer;
|
|
|
|
int16 tmpPosX;
|
|
|
|
int16 tmpPosY;
|
|
|
|
Gob_Object *itemDesc;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_gobAction == 3 || _gobAction == 4) {
|
|
|
|
items = _vm->_map->_itemsMap[_pressedMapY][_pressedMapX];
|
|
|
|
if (_gobAction == 4 && (items & 0xff00) != 0 &&
|
|
|
|
_objects[_itemToObject[(items & 0xff00) >> 8]]->
|
2005-04-05 15:07:40 +00:00
|
|
|
pickable == 1) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_destItemId = (items & 0xff00) >> 8;
|
|
|
|
_destActionItem = (items & 0xff00) >> 8;
|
|
|
|
_itemByteFlag = 1;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else if ((items & 0xff) == 0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_destItemId = (items & 0xff00) >> 8;
|
|
|
|
_destActionItem = (items & 0xff00) >> 8;
|
|
|
|
_itemByteFlag = 1;
|
|
|
|
} else if (_gobAction == 3 && _currentGoblin == 2 &&
|
2005-04-05 15:07:40 +00:00
|
|
|
(items & 0xff00) != 0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_destItemId = (items & 0xff00) >> 8;
|
|
|
|
_destActionItem = (items & 0xff00) >> 8;
|
|
|
|
_itemByteFlag = 1;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-01-07 22:28:54 +00:00
|
|
|
_destItemId = items & 0xff;
|
|
|
|
_destActionItem = items & 0xff;
|
|
|
|
_itemByteFlag = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapY = _vm->_map->_itemPoses[_destItemId].y;
|
|
|
|
_vm->_map->_destY = _vm->_map->_itemPoses[_destItemId].y;
|
|
|
|
_gobDestY = _vm->_map->_itemPoses[_destItemId].y;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_gobAction == 3 || _destActionItem == 0) {
|
|
|
|
_pressedMapX = _vm->_map->_itemPoses[_destItemId].x;
|
|
|
|
_vm->_map->_destX = _vm->_map->_itemPoses[_destItemId].x;
|
|
|
|
_gobDestX = _vm->_map->_itemPoses[_destItemId].x;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else if ((items & 0xff00) != 0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_vm->_map->_itemPoses[_destItemId].orient == 4) {
|
|
|
|
if ((_vm->_map->_itemsMap[_pressedMapY]
|
|
|
|
[_pressedMapX - 1] & 0xff00) ==
|
|
|
|
(_vm->_map->_itemsMap[_pressedMapY]
|
|
|
|
[_pressedMapX] & 0xff00)) {
|
|
|
|
_pressedMapX--;
|
|
|
|
_vm->_map->_destX = _pressedMapX;
|
|
|
|
_gobDestX = _pressedMapX;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
2006-01-07 22:28:54 +00:00
|
|
|
} else if (_vm->_map->_itemPoses[_destItemId].orient == 0) {
|
|
|
|
|
|
|
|
if ((_vm->_map->_itemsMap[_pressedMapY]
|
|
|
|
[_pressedMapX + 1] & 0xff00) ==
|
|
|
|
(_vm->_map->_itemsMap[_pressedMapY]
|
|
|
|
[_pressedMapX] & 0xff00)) {
|
|
|
|
_pressedMapX++;
|
|
|
|
_vm->_map->_destX = _pressedMapX;
|
|
|
|
_gobDestX = _pressedMapX;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if ((_vm->_map->_itemsMap[_pressedMapY +
|
|
|
|
1][_pressedMapX] & 0xff00) ==
|
|
|
|
(_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] &
|
2005-04-05 15:07:40 +00:00
|
|
|
0xff00)) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapY++;
|
|
|
|
_vm->_map->_destY = _pressedMapY;
|
|
|
|
_gobDestY = _pressedMapY;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
} else {
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_vm->_map->_itemPoses[_destItemId].orient == 4) {
|
|
|
|
if ((_vm->_map->_itemsMap[_pressedMapY]
|
|
|
|
[_pressedMapX - 1]) ==
|
|
|
|
(_vm->_map->_itemsMap[_pressedMapY]
|
|
|
|
[_pressedMapX])) {
|
|
|
|
_pressedMapX--;
|
|
|
|
_vm->_map->_destX = _pressedMapX;
|
|
|
|
_gobDestX = _pressedMapX;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
2006-01-07 22:28:54 +00:00
|
|
|
} else if (_vm->_map->_itemPoses[_destItemId].orient == 0) {
|
|
|
|
|
|
|
|
if ((_vm->_map->_itemsMap[_pressedMapY]
|
|
|
|
[_pressedMapX + 1]) ==
|
|
|
|
(_vm->_map->_itemsMap[_pressedMapY]
|
|
|
|
[_pressedMapX])) {
|
|
|
|
_pressedMapX++;
|
|
|
|
_vm->_map->_destX = _pressedMapX;
|
|
|
|
_gobDestX = _pressedMapX;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-05-31 10:55:57 +00:00
|
|
|
if (_pressedMapY < (_vm->_map->_mapHeight-1)) {
|
|
|
|
if ((_vm->_map->_itemsMap[_pressedMapY +
|
|
|
|
1][_pressedMapX]) ==
|
|
|
|
(_vm->_map->_itemsMap[_pressedMapY][_pressedMapX])) {
|
|
|
|
_pressedMapY++;
|
|
|
|
_vm->_map->_destY = _pressedMapY;
|
|
|
|
_gobDestY = _pressedMapY;
|
|
|
|
}
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_gobAction == 4 && _destActionItem != 0 &&
|
|
|
|
_itemToObject[_destActionItem] != -1 &&
|
|
|
|
_objects[_itemToObject[_destActionItem]]->
|
2005-04-05 15:07:40 +00:00
|
|
|
pickable == 1) {
|
|
|
|
|
|
|
|
itemDesc =
|
2006-01-07 22:28:54 +00:00
|
|
|
_objects[_itemToObject[_destActionItem]];
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
itemDesc->animation =
|
|
|
|
itemDesc->stateMach[itemDesc->state][0]->animation;
|
|
|
|
layer =
|
|
|
|
itemDesc->stateMach[itemDesc->state][itemDesc->
|
|
|
|
stateColumn]->layer;
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_scenery->updateAnim(layer, 0, itemDesc->animation, 0,
|
2005-04-05 15:07:40 +00:00
|
|
|
itemDesc->xPos, itemDesc->yPos, 0);
|
|
|
|
|
2006-01-09 16:10:22 +00:00
|
|
|
tmpX = (_vm->_scenery->_toRedrawRight + _vm->_scenery->_toRedrawLeft) / 2;
|
|
|
|
tmpY = _vm->_scenery->_toRedrawBottom;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
tmpPosY = tmpY / 6;
|
|
|
|
if ((tmpY % 3) < 3 && tmpPosY > 0)
|
|
|
|
tmpPosY--;
|
|
|
|
|
|
|
|
tmpPosX = tmpX / 12;
|
|
|
|
if ((tmpX % 12) < 6 && tmpPosX > 0)
|
|
|
|
tmpPosX--;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_vm->_map->_itemPoses[_destActionItem].orient == 0 ||
|
|
|
|
_vm->_map->_itemPoses[_destActionItem].orient == -1) {
|
2005-04-05 15:07:40 +00:00
|
|
|
tmpPosX++;
|
|
|
|
}
|
|
|
|
|
2006-05-29 18:24:52 +00:00
|
|
|
if (_vm->_map->getPass(tmpPosX, tmpPosY) == 1) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapX = tmpPosX;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_destX = tmpPosX;
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobDestX = tmpPosX;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapY = tmpPosY;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_destY = tmpPosY;
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobDestY = tmpPosY;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-02-05 19:48:12 +00:00
|
|
|
_pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->_mapWidth - 1);
|
|
|
|
_pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->_mapHeight - 1);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::moveFindItem(int16 posX, int16 posY) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 i;
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_gobAction == 3 || _gobAction == 4) {
|
2005-04-05 15:07:40 +00:00
|
|
|
for (i = 0; i < 20; i++) {
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_objects[i] == 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_objects[i]->type != 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_objects[i]->left > posX)
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_objects[i]->right < posX)
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_objects[i]->top > posY)
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_objects[i]->bottom < posY)
|
2005-04-05 15:07:40 +00:00
|
|
|
continue;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_objects[i]->right - _objects[i]->left < 40)
|
2005-04-05 15:07:40 +00:00
|
|
|
posX =
|
2006-01-07 22:28:54 +00:00
|
|
|
(_objects[i]->left +
|
|
|
|
_objects[i]->right) / 2;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_objects[i]->bottom - _objects[i]->top < 40)
|
2005-04-05 15:07:40 +00:00
|
|
|
posY =
|
2006-01-07 22:28:54 +00:00
|
|
|
(_objects[i]->top +
|
|
|
|
_objects[i]->bottom) / 2;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-02-05 19:48:12 +00:00
|
|
|
_pressedMapX = posX / 12;
|
|
|
|
_pressedMapY = posY / 6;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0
|
2005-04-05 15:07:40 +00:00
|
|
|
&& i < 20) {
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_vm->_map->_itemsMap[_pressedMapY +
|
|
|
|
1][_pressedMapX] != 0) {
|
|
|
|
_pressedMapY++;
|
|
|
|
} else if (_vm->_map->_itemsMap[_pressedMapY +
|
|
|
|
1][_pressedMapX + 1] != 0) {
|
|
|
|
_pressedMapX++;
|
|
|
|
_pressedMapY++;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX +
|
2005-04-05 15:07:40 +00:00
|
|
|
1] != 0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapX++;
|
|
|
|
} else if (_vm->_map->_itemsMap[_pressedMapY -
|
|
|
|
1][_pressedMapX + 1] != 0) {
|
|
|
|
_pressedMapX++;
|
|
|
|
_pressedMapY--;
|
|
|
|
} else if (_vm->_map->_itemsMap[_pressedMapY -
|
|
|
|
1][_pressedMapX] != 0) {
|
|
|
|
_pressedMapY--;
|
|
|
|
} else if (_vm->_map->_itemsMap[_pressedMapY -
|
|
|
|
1][_pressedMapX - 1] != 0) {
|
|
|
|
_pressedMapY--;
|
|
|
|
_pressedMapX--;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX -
|
2005-04-05 15:07:40 +00:00
|
|
|
1] != 0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapX--;
|
|
|
|
} else if (_vm->_map->_itemsMap[_pressedMapY +
|
|
|
|
1][_pressedMapX - 1] != 0) {
|
|
|
|
_pressedMapX--;
|
|
|
|
_pressedMapY++;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2006-01-07 22:28:54 +00:00
|
|
|
_pressedMapX = posX / 12;
|
|
|
|
_pressedMapY = posY / 6;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
2007-02-05 19:48:12 +00:00
|
|
|
_pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->_mapWidth - 1);
|
|
|
|
_pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->_mapHeight - 1);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::moveCheckSelect(int16 framesCount, Gob_Object * gobDesc, int16 *pGobIndex,
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 *nextAct) {
|
2006-01-04 01:48:15 +00:00
|
|
|
if (gobDesc->right > _vm->_global->_inter_mouseX &&
|
|
|
|
gobDesc->left < _vm->_global->_inter_mouseX &&
|
|
|
|
gobDesc->bottom > _vm->_global->_inter_mouseY &&
|
2006-01-07 22:28:54 +00:00
|
|
|
gobDesc->bottom - 10 < _vm->_global->_inter_mouseY && _gobAction == 0) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if (gobDesc->curLookDir & 4)
|
|
|
|
*nextAct = 16;
|
|
|
|
else
|
|
|
|
*nextAct = 23;
|
|
|
|
|
|
|
|
gobDesc->curFrame = framesCount - 1;
|
2006-01-07 22:28:54 +00:00
|
|
|
_pathExistence = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-01-03 23:14:39 +00:00
|
|
|
*pGobIndex = peekGoblin(gobDesc);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (*pGobIndex != 0) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_pathExistence = 0;
|
|
|
|
} else if (_vm->_map->_curGoblinX == _pressedMapX &&
|
|
|
|
_vm->_map->_curGoblinY == _pressedMapY) {
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_gobAction != 0)
|
|
|
|
_readyToAct = 1;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_pathExistence = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::moveInitStep(int16 framesCount, int16 action, int16 cont,
|
2005-04-05 15:07:40 +00:00
|
|
|
Gob_Object *gobDesc, int16 *pGobIndex, int16 *pNextAct) {
|
|
|
|
int16 posX;
|
|
|
|
int16 posY;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (cont != 0 && _goesAtTarget == 0 &&
|
|
|
|
_readyToAct == 0 && VAR(59) == 0 &&
|
2005-04-05 15:07:40 +00:00
|
|
|
gobDesc->type != 1 &&
|
|
|
|
gobDesc->state != 10 && gobDesc->state != 11) {
|
|
|
|
if (gobDesc->state >= 40) {
|
|
|
|
gobDesc->curFrame = framesCount - 1;
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobAction = action;
|
|
|
|
_forceNextState[0] = -1;
|
|
|
|
_forceNextState[1] = -1;
|
|
|
|
_forceNextState[2] = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (action == 3) {
|
2006-01-04 01:48:15 +00:00
|
|
|
posX = _vm->_global->_inter_mouseX + 6;
|
|
|
|
posY = _vm->_global->_inter_mouseY + 7;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else if (action == 4) {
|
2006-01-04 01:48:15 +00:00
|
|
|
posX = _vm->_global->_inter_mouseX + 7;
|
|
|
|
posY = _vm->_global->_inter_mouseY + 12;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-01-04 01:48:15 +00:00
|
|
|
posX = _vm->_global->_inter_mouseX;
|
|
|
|
posY = _vm->_global->_inter_mouseY;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
moveFindItem(posX, posY);
|
|
|
|
adjustDest(posX, posY);
|
|
|
|
adjustTarget();
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_destX = _pressedMapX;
|
|
|
|
_gobDestX = _pressedMapX;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_destY = _pressedMapY;
|
|
|
|
_gobDestY = _pressedMapY;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
targetDummyItem(gobDesc);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
targetItem();
|
2006-05-29 18:24:52 +00:00
|
|
|
initiateMove(0);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
moveCheckSelect(framesCount, gobDesc, pGobIndex, pNextAct);
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_readyToAct != 0 &&
|
|
|
|
(_vm->_map->_curGoblinX != _pressedMapX ||
|
|
|
|
_vm->_map->_curGoblinY != _pressedMapY))
|
|
|
|
_readyToAct = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (gobDesc->type == 1) {
|
2006-01-03 23:14:39 +00:00
|
|
|
*pGobIndex = peekGoblin(gobDesc);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::moveTreatRopeStairs(Gob_Object *gobDesc) {
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_currentGoblin != 1)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (gobDesc->nextState == 28
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_forceNextState[0] = 28;
|
|
|
|
_forceNextState[1] = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gobDesc->nextState == 29
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_forceNextState[0] = 29;
|
|
|
|
_forceNextState[1] = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((gobDesc->nextState == 28 || gobDesc->nextState == 29
|
|
|
|
|| gobDesc->nextState == 20)
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4
|
|
|
|
|| gobDesc->curLookDir == 2)
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_forceNextState[0] = 28;
|
|
|
|
_forceNextState[1] = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else if ((gobDesc->curLookDir == 0
|
|
|
|
|| gobDesc->curLookDir == 4
|
|
|
|
|| gobDesc->curLookDir == 6)
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_forceNextState[0] = 29;
|
|
|
|
_forceNextState[1] = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gobDesc->nextState == 8
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_forceNextState[0] = 8;
|
|
|
|
_forceNextState[1] = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gobDesc->nextState == 9
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_forceNextState[0] = 9;
|
|
|
|
_forceNextState[1] = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gobDesc->nextState == 20
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
|
2005-04-05 15:07:40 +00:00
|
|
|
if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4
|
|
|
|
|| gobDesc->curLookDir == 2)
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_forceNextState[0] = 8;
|
|
|
|
_forceNextState[1] = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else if ((gobDesc->curLookDir == 0
|
|
|
|
|| gobDesc->curLookDir == 4
|
|
|
|
|| gobDesc->curLookDir == 6)
|
2006-05-29 18:24:52 +00:00
|
|
|
&& _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_forceNextState[0] = 9;
|
|
|
|
_forceNextState[1] = -1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
int16 Goblin::doMove(Gob_Object *gobDesc, int16 cont, int16 action) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 framesCount;
|
|
|
|
int16 nextAct;
|
|
|
|
int16 gobIndex;
|
|
|
|
int16 layer;
|
|
|
|
|
|
|
|
nextAct = 0;
|
|
|
|
gobIndex = 0;
|
|
|
|
|
|
|
|
layer = gobDesc->stateMach[gobDesc->state][0]->layer;
|
|
|
|
framesCount =
|
2006-06-12 21:33:30 +00:00
|
|
|
_vm->_scenery->_animations[gobDesc->animation].layers[layer].framesCount;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2005-04-10 17:13:17 +00:00
|
|
|
if (VAR(59) == 0 &&
|
2005-04-05 15:07:40 +00:00
|
|
|
gobDesc->state != 30 && gobDesc->state != 31) {
|
|
|
|
gobDesc->order = (gobDesc->bottom) / 24 + 3;
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_positionedGob != _currentGoblin) {
|
|
|
|
_vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
|
|
|
|
_vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_positionedGob = _currentGoblin;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
gobDesc->animation =
|
|
|
|
gobDesc->stateMach[gobDesc->state][gobDesc->stateColumn]->
|
|
|
|
animation;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobStateLayer =
|
2005-04-05 15:07:40 +00:00
|
|
|
gobDesc->stateMach[gobDesc->state][gobDesc->stateColumn]->layer;
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
moveInitStep(framesCount, action, cont, gobDesc, &gobIndex,
|
2005-04-05 15:07:40 +00:00
|
|
|
&nextAct);
|
2006-01-03 23:14:39 +00:00
|
|
|
moveTreatRopeStairs(gobDesc);
|
2006-06-07 18:49:20 +00:00
|
|
|
moveAdvance(0, gobDesc, nextAct, framesCount);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
return gobIndex;
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::zeroObjects(void) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 i;
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
2006-01-07 22:28:54 +00:00
|
|
|
_goblins[i] = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
for (i = 0; i < 20; i++)
|
2006-01-07 22:28:54 +00:00
|
|
|
_objects[i] = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
for (i = 0; i < 16; i++)
|
2006-01-07 22:28:54 +00:00
|
|
|
_soundData[i] = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::freeAllObjects(void) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_util->deleteList(_objList);
|
2006-06-06 15:43:44 +00:00
|
|
|
_objList = 0;
|
2006-01-03 23:14:39 +00:00
|
|
|
freeObjects();
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::loadObjects(char *source) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 i;
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
zeroObjects();
|
2005-04-05 15:07:40 +00:00
|
|
|
for (i = 0; i < 20; i++)
|
2006-01-07 22:28:54 +00:00
|
|
|
_itemToObject[i] = 100;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
freeObjects();
|
|
|
|
initList();
|
2006-01-04 01:23:20 +00:00
|
|
|
strcpy(_vm->_map->_sourceFile, source);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_sourceFile[strlen(_vm->_map->_sourceFile) - 4] = 0;
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_map->loadMapObjects(source);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
for (i = 0; i < _gobsCount; i++)
|
2006-05-11 19:43:30 +00:00
|
|
|
placeObject(_goblins[i], 0, 0, 0, 0, 0);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
for (i = 0; i < _objCount; i++) {
|
2006-05-11 19:43:30 +00:00
|
|
|
placeObject(_objects[i], 1, 0, 0, 0, 0);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
initVarPointers();
|
2006-01-07 22:28:54 +00:00
|
|
|
_actDestItemDesc = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::saveGobDataToVars(int16 xPos, int16 yPos, int16 someVal) {
|
2005-04-05 15:07:40 +00:00
|
|
|
Gob_Object *obj;
|
2006-01-07 22:28:54 +00:00
|
|
|
*_some0ValPtr = someVal;
|
|
|
|
*_curGobXPosVarPtr = xPos;
|
|
|
|
*_curGobYPosVarPtr = yPos;
|
|
|
|
*_itemInPocketVarPtr = _itemIndInPocket;
|
|
|
|
|
|
|
|
obj = _goblins[_currentGoblin];
|
|
|
|
|
|
|
|
*_curGobStateVarPtr = obj->state;
|
|
|
|
*_curGobFrameVarPtr = obj->curFrame;
|
|
|
|
*_curGobMultStateVarPtr = obj->multState;
|
|
|
|
*_curGobNextStateVarPtr = obj->nextState;
|
|
|
|
*_curGobScrXVarPtr = obj->xPos;
|
|
|
|
*_curGobScrYVarPtr = obj->yPos;
|
|
|
|
*_curGobLeftVarPtr = obj->left;
|
|
|
|
*_curGobTopVarPtr = obj->top;
|
|
|
|
*_curGobRightVarPtr = obj->right;
|
|
|
|
*_curGobBottomVarPtr = obj->bottom;
|
|
|
|
*_curGobDoAnimVarPtr = obj->doAnim;
|
|
|
|
*_curGobOrderVarPtr = obj->order;
|
|
|
|
*_curGobNoTickVarPtr = obj->noTick;
|
|
|
|
*_curGobTypeVarPtr = obj->type;
|
|
|
|
*_curGobMaxTickVarPtr = obj->maxTick;
|
|
|
|
*_curGobTickVarPtr = obj->tick;
|
|
|
|
*_curGobActStartStateVarPtr = obj->actionStartState;
|
|
|
|
*_curGobLookDirVarPtr = obj->curLookDir;
|
|
|
|
*_curGobPickableVarPtr = obj->pickable;
|
|
|
|
*_curGobRelaxVarPtr = obj->relaxTime;
|
|
|
|
*_curGobMaxFrameVarPtr = getObjMaxFrame(obj);
|
|
|
|
|
|
|
|
if (_actDestItemDesc == 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
obj = _actDestItemDesc;
|
|
|
|
*_destItemStateVarPtr = obj->state;
|
|
|
|
*_destItemFrameVarPtr = obj->curFrame;
|
|
|
|
*_destItemMultStateVarPtr = obj->multState;
|
|
|
|
*_destItemNextStateVarPtr = obj->nextState;
|
|
|
|
*_destItemScrXVarPtr = obj->xPos;
|
|
|
|
*_destItemScrYVarPtr = obj->yPos;
|
|
|
|
*_destItemLeftVarPtr = obj->left;
|
|
|
|
*_destItemTopVarPtr = obj->top;
|
|
|
|
*_destItemRightVarPtr = obj->right;
|
|
|
|
*_destItemBottomVarPtr = obj->bottom;
|
|
|
|
*_destItemDoAnimVarPtr = obj->doAnim;
|
|
|
|
*_destItemOrderVarPtr = obj->order;
|
|
|
|
*_destItemNoTickVarPtr = obj->noTick;
|
|
|
|
*_destItemTypeVarPtr = obj->type;
|
|
|
|
*_destItemMaxTickVarPtr = obj->maxTick;
|
|
|
|
*_destItemTickVarPtr = obj->tick;
|
|
|
|
*_destItemActStartStVarPtr = obj->actionStartState;
|
|
|
|
*_destItemLookDirVarPtr = obj->curLookDir;
|
|
|
|
*_destItemPickableVarPtr = obj->pickable;
|
|
|
|
*_destItemRelaxVarPtr = obj->relaxTime;
|
|
|
|
*_destItemMaxFrameVarPtr = getObjMaxFrame(obj);
|
|
|
|
|
|
|
|
_destItemState = obj->state;
|
|
|
|
_destItemType = obj->type;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::initVarPointers(void) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_gobRetVarPtr = (int32 *)VAR_ADDRESS(59);
|
|
|
|
_curGobStateVarPtr = (int32 *)VAR_ADDRESS(60);
|
|
|
|
_curGobFrameVarPtr = (int32 *)VAR_ADDRESS(61);
|
|
|
|
_curGobMultStateVarPtr = (int32 *)VAR_ADDRESS(62);
|
|
|
|
_curGobNextStateVarPtr = (int32 *)VAR_ADDRESS(63);
|
|
|
|
_curGobScrXVarPtr = (int32 *)VAR_ADDRESS(64);
|
|
|
|
_curGobScrYVarPtr = (int32 *)VAR_ADDRESS(65);
|
|
|
|
_curGobLeftVarPtr = (int32 *)VAR_ADDRESS(66);
|
|
|
|
_curGobTopVarPtr = (int32 *)VAR_ADDRESS(67);
|
|
|
|
_curGobRightVarPtr = (int32 *)VAR_ADDRESS(68);
|
|
|
|
_curGobBottomVarPtr = (int32 *)VAR_ADDRESS(69);
|
|
|
|
_curGobDoAnimVarPtr = (int32 *)VAR_ADDRESS(70);
|
|
|
|
_curGobOrderVarPtr = (int32 *)VAR_ADDRESS(71);
|
|
|
|
_curGobNoTickVarPtr = (int32 *)VAR_ADDRESS(72);
|
|
|
|
_curGobTypeVarPtr = (int32 *)VAR_ADDRESS(73);
|
|
|
|
_curGobMaxTickVarPtr = (int32 *)VAR_ADDRESS(74);
|
|
|
|
_curGobTickVarPtr = (int32 *)VAR_ADDRESS(75);
|
|
|
|
_curGobActStartStateVarPtr = (int32 *)VAR_ADDRESS(76);
|
|
|
|
_curGobLookDirVarPtr = (int32 *)VAR_ADDRESS(77);
|
|
|
|
_curGobPickableVarPtr = (int32 *)VAR_ADDRESS(80);
|
|
|
|
_curGobRelaxVarPtr = (int32 *)VAR_ADDRESS(81);
|
|
|
|
_destItemStateVarPtr = (int32 *)VAR_ADDRESS(82);
|
|
|
|
_destItemFrameVarPtr = (int32 *)VAR_ADDRESS(83);
|
|
|
|
_destItemMultStateVarPtr = (int32 *)VAR_ADDRESS(84);
|
|
|
|
_destItemNextStateVarPtr = (int32 *)VAR_ADDRESS(85);
|
|
|
|
_destItemScrXVarPtr = (int32 *)VAR_ADDRESS(86);
|
|
|
|
_destItemScrYVarPtr = (int32 *)VAR_ADDRESS(87);
|
|
|
|
_destItemLeftVarPtr = (int32 *)VAR_ADDRESS(88);
|
|
|
|
_destItemTopVarPtr = (int32 *)VAR_ADDRESS(89);
|
|
|
|
_destItemRightVarPtr = (int32 *)VAR_ADDRESS(90);
|
|
|
|
_destItemBottomVarPtr = (int32 *)VAR_ADDRESS(91);
|
|
|
|
_destItemDoAnimVarPtr = (int32 *)VAR_ADDRESS(92);
|
|
|
|
_destItemOrderVarPtr = (int32 *)VAR_ADDRESS(93);
|
|
|
|
_destItemNoTickVarPtr = (int32 *)VAR_ADDRESS(94);
|
|
|
|
_destItemTypeVarPtr = (int32 *)VAR_ADDRESS(95);
|
|
|
|
_destItemMaxTickVarPtr = (int32 *)VAR_ADDRESS(96);
|
|
|
|
_destItemTickVarPtr = (int32 *)VAR_ADDRESS(97);
|
|
|
|
_destItemActStartStVarPtr = (int32 *)VAR_ADDRESS(98);
|
|
|
|
_destItemLookDirVarPtr = (int32 *)VAR_ADDRESS(99);
|
|
|
|
_destItemPickableVarPtr = (int32 *)VAR_ADDRESS(102);
|
|
|
|
_destItemRelaxVarPtr = (int32 *)VAR_ADDRESS(103);
|
|
|
|
_destItemMaxFrameVarPtr = (int32 *)VAR_ADDRESS(105);
|
|
|
|
_curGobVarPtr = (int32 *)VAR_ADDRESS(106);
|
|
|
|
_some0ValPtr = (int32 *)VAR_ADDRESS(107);
|
|
|
|
_curGobXPosVarPtr = (int32 *)VAR_ADDRESS(108);
|
|
|
|
_curGobYPosVarPtr = (int32 *)VAR_ADDRESS(109);
|
|
|
|
_curGobMaxFrameVarPtr = (int32 *)VAR_ADDRESS(110);
|
|
|
|
|
|
|
|
_itemInPocketVarPtr = (int32 *)VAR_ADDRESS(114);
|
|
|
|
|
|
|
|
*_itemInPocketVarPtr = -2;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::loadGobDataFromVars(void) {
|
2005-04-05 15:07:40 +00:00
|
|
|
Gob_Object *obj;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_itemIndInPocket = *_itemInPocketVarPtr;
|
|
|
|
|
|
|
|
obj = _goblins[_currentGoblin];
|
|
|
|
|
|
|
|
obj->state = *_curGobStateVarPtr;
|
|
|
|
obj->curFrame = *_curGobFrameVarPtr;
|
|
|
|
obj->multState = *_curGobMultStateVarPtr;
|
|
|
|
obj->nextState = *_curGobNextStateVarPtr;
|
|
|
|
obj->xPos = *_curGobScrXVarPtr;
|
|
|
|
obj->yPos = *_curGobScrYVarPtr;
|
|
|
|
obj->left = *_curGobLeftVarPtr;
|
|
|
|
obj->top = *_curGobTopVarPtr;
|
|
|
|
obj->right = *_curGobRightVarPtr;
|
|
|
|
obj->bottom = *_curGobBottomVarPtr;
|
|
|
|
obj->doAnim = *_curGobDoAnimVarPtr;
|
|
|
|
obj->order = *_curGobOrderVarPtr;
|
|
|
|
obj->noTick = *_curGobNoTickVarPtr;
|
|
|
|
obj->type = *_curGobTypeVarPtr;
|
|
|
|
obj->maxTick = *_curGobMaxTickVarPtr;
|
|
|
|
obj->tick = *_curGobTickVarPtr;
|
|
|
|
obj->actionStartState = *_curGobActStartStateVarPtr;
|
|
|
|
obj->curLookDir = *_curGobLookDirVarPtr;
|
|
|
|
obj->pickable = *_curGobPickableVarPtr;
|
|
|
|
obj->relaxTime = *_curGobRelaxVarPtr;
|
|
|
|
|
|
|
|
if (_actDestItemDesc == 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
obj = _actDestItemDesc;
|
|
|
|
|
|
|
|
obj->state = *_destItemStateVarPtr;
|
|
|
|
obj->curFrame = *_destItemFrameVarPtr;
|
|
|
|
obj->multState = *_destItemMultStateVarPtr;
|
|
|
|
obj->nextState = *_destItemNextStateVarPtr;
|
|
|
|
obj->xPos = *_destItemScrXVarPtr;
|
|
|
|
obj->yPos = *_destItemScrYVarPtr;
|
|
|
|
obj->left = *_destItemLeftVarPtr;
|
|
|
|
obj->top = *_destItemTopVarPtr;
|
|
|
|
obj->right = *_destItemRightVarPtr;
|
|
|
|
obj->bottom = *_destItemBottomVarPtr;
|
|
|
|
obj->doAnim = *_destItemDoAnimVarPtr;
|
|
|
|
obj->order = *_destItemOrderVarPtr;
|
|
|
|
obj->noTick = *_destItemNoTickVarPtr;
|
|
|
|
obj->type = *_destItemTypeVarPtr;
|
|
|
|
obj->maxTick = *_destItemMaxTickVarPtr;
|
|
|
|
obj->tick = *_destItemTickVarPtr;
|
|
|
|
obj->actionStartState = *_destItemActStartStVarPtr;
|
|
|
|
obj->curLookDir = *_destItemLookDirVarPtr;
|
|
|
|
obj->pickable = *_destItemPickableVarPtr;
|
|
|
|
obj->relaxTime = *_destItemRelaxVarPtr;
|
|
|
|
|
|
|
|
if (obj->type != _destItemType)
|
2005-04-05 15:07:40 +00:00
|
|
|
obj->toRedraw = 1;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (obj->state != _destItemState && obj->type == 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
obj->toRedraw = 1;
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::pickItem(int16 indexToPocket, int16 idToPocket) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 x;
|
|
|
|
int16 y;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_objects[indexToPocket]->pickable != 1)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_objects[indexToPocket]->type = 3;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_itemIndInPocket = indexToPocket;
|
|
|
|
_itemIdInPocket = idToPocket;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-05-29 18:24:52 +00:00
|
|
|
for (y = 0; y < _vm->_map->_mapHeight; y++) {
|
|
|
|
for (x = 0; x < _vm->_map->_mapWidth; x++) {
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_itemByteFlag == 1) {
|
2006-01-04 01:23:20 +00:00
|
|
|
if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) ==
|
2005-04-05 15:07:40 +00:00
|
|
|
idToPocket)
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemsMap[y][x] &= 0xff;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-01-04 01:23:20 +00:00
|
|
|
if ((_vm->_map->_itemsMap[y][x] & 0xff) == idToPocket)
|
|
|
|
_vm->_map->_itemsMap[y][x] &= 0xff00;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idToPocket >= 0 && idToPocket < 20) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_itemPoses[_itemIdInPocket].x = 0;
|
|
|
|
_vm->_map->_itemPoses[_itemIdInPocket].y = 0;
|
|
|
|
_vm->_map->_itemPoses[_itemIdInPocket].orient = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::placeItem(int16 indexInPocket, int16 idInPocket) {
|
2005-04-05 15:07:40 +00:00
|
|
|
Gob_Object *itemDesc;
|
|
|
|
int16 lookDir;
|
|
|
|
int16 xPos;
|
|
|
|
int16 yPos;
|
|
|
|
int16 layer;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
itemDesc = _objects[indexInPocket];
|
|
|
|
lookDir = _goblins[0]->curLookDir & 4;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
xPos = _gobPositions[0].x;
|
|
|
|
yPos = _gobPositions[0].y;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_itemIndInPocket = -1;
|
|
|
|
_itemIdInPocket = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
itemDesc->pickable = 1;
|
|
|
|
itemDesc->type = 0;
|
|
|
|
itemDesc->toRedraw = 1;
|
|
|
|
itemDesc->curFrame = 0;
|
2006-01-07 22:28:54 +00:00
|
|
|
itemDesc->order = _goblins[0]->order;
|
2005-04-05 15:07:40 +00:00
|
|
|
itemDesc->animation =
|
|
|
|
itemDesc->stateMach[itemDesc->state][0]->animation;
|
|
|
|
layer =
|
|
|
|
itemDesc->stateMach[itemDesc->state][itemDesc->stateColumn]->layer;
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_scenery->updateAnim(layer, 0, itemDesc->animation, 0,
|
2005-04-05 15:07:40 +00:00
|
|
|
itemDesc->xPos, itemDesc->yPos, 0);
|
|
|
|
|
|
|
|
itemDesc->yPos +=
|
2006-01-09 16:10:22 +00:00
|
|
|
(_gobPositions[0].y * 6) + 5 - _vm->_scenery->_toRedrawBottom;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (lookDir == 4) {
|
2006-01-07 22:28:54 +00:00
|
|
|
itemDesc->xPos += (_gobPositions[0].x * 12 + 14)
|
2006-01-09 16:10:22 +00:00
|
|
|
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-01-07 22:28:54 +00:00
|
|
|
itemDesc->xPos += (_gobPositions[0].x * 12)
|
2006-01-09 16:10:22 +00:00
|
|
|
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_map->placeItem(xPos, yPos, idInPocket);
|
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
|
|
|
if (yPos > 0) {
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_map->placeItem(xPos, yPos - 1, idInPocket);
|
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
|
|
|
}
|
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
|
|
|
if (lookDir == 4) {
|
2006-05-29 18:24:52 +00:00
|
|
|
if (xPos < _vm->_map->_mapWidth - 1) {
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_map->placeItem(xPos + 1, yPos, idInPocket);
|
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
|
|
|
if (yPos > 0) {
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_map->placeItem(xPos + 1, yPos - 1, idInPocket);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
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
|
|
|
if (xPos > 0) {
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_map->placeItem(xPos - 1, yPos, idInPocket);
|
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
|
|
|
if (yPos > 0) {
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_map->placeItem(xPos - 1, yPos - 1, idInPocket);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idInPocket >= 0 && idInPocket < 20) {
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_itemPoses[idInPocket].x = _gobPositions[0].x;
|
|
|
|
_vm->_map->_itemPoses[idInPocket].y = _gobPositions[0].y;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemPoses[idInPocket].orient = lookDir;
|
|
|
|
if (_vm->_map->_itemPoses[idInPocket].orient == 0) {
|
|
|
|
// _vm->_map->_itemPoses[idInPocket].x++;
|
2006-05-29 18:24:52 +00:00
|
|
|
if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x + 1, (int)_vm->_map->_itemPoses[idInPocket].y) == 1)
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemPoses[idInPocket].x++;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-05-29 18:24:52 +00:00
|
|
|
if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x - 1, (int)_vm->_map->_itemPoses[idInPocket].y) == 1)
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemPoses[idInPocket].x--;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::swapItems(int16 indexToPick, int16 idToPick) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 layer;
|
|
|
|
Gob_Object *pickObj;
|
|
|
|
Gob_Object *placeObj;
|
|
|
|
int16 idToPlace;
|
|
|
|
int16 x;
|
|
|
|
int16 y;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
pickObj = _objects[indexToPick];
|
|
|
|
placeObj = _objects[_itemIndInPocket];
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
idToPlace = _itemIdInPocket;
|
2005-04-05 15:07:40 +00:00
|
|
|
pickObj->type = 3;
|
2006-01-07 22:28:54 +00:00
|
|
|
_itemIndInPocket = indexToPick;
|
|
|
|
_itemIdInPocket = idToPick;
|
2006-01-03 23:14:39 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_itemByteFlag == 0) {
|
2006-05-29 18:24:52 +00:00
|
|
|
for (y = 0; y < _vm->_map->_mapHeight; y++) {
|
|
|
|
for (x = 0; x < _vm->_map->_mapWidth; x++) {
|
2006-01-04 01:23:20 +00:00
|
|
|
if ((_vm->_map->_itemsMap[y][x] & 0xff) == idToPick)
|
|
|
|
_vm->_map->_itemsMap[y][x] =
|
|
|
|
(_vm->_map->_itemsMap[y][x] & 0xff00) +
|
2005-04-05 15:07:40 +00:00
|
|
|
idToPlace;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
2006-05-29 18:24:52 +00:00
|
|
|
for (y = 0; y < _vm->_map->_mapHeight; y++) {
|
|
|
|
for (x = 0; x < _vm->_map->_mapWidth; x++) {
|
2006-01-04 01:23:20 +00:00
|
|
|
if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) ==
|
2005-04-05 15:07:40 +00:00
|
|
|
idToPick)
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemsMap[y][x] =
|
|
|
|
(_vm->_map->_itemsMap[y][x] & 0xff) +
|
2005-04-05 15:07:40 +00:00
|
|
|
(idToPlace << 8);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idToPick >= 0 && idToPick < 20) {
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemPoses[idToPlace].x =
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_itemPoses[_itemIdInPocket].x;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemPoses[idToPlace].y =
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_itemPoses[_itemIdInPocket].y;
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_map->_itemPoses[idToPlace].orient =
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_itemPoses[_itemIdInPocket].orient;
|
2006-01-04 01:23:20 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_vm->_map->_itemPoses[_itemIdInPocket].x = 0;
|
|
|
|
_vm->_map->_itemPoses[_itemIdInPocket].y = 0;
|
|
|
|
_vm->_map->_itemPoses[_itemIdInPocket].orient = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_itemIndInPocket = -1;
|
|
|
|
_itemIdInPocket = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
placeObj->type = 0;
|
|
|
|
placeObj->nextState = -1;
|
|
|
|
placeObj->multState = -1;
|
|
|
|
placeObj->unk14 = 0;
|
|
|
|
placeObj->toRedraw = 1;
|
|
|
|
placeObj->curFrame = 0;
|
2006-01-07 22:28:54 +00:00
|
|
|
placeObj->order = _goblins[0]->order;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
placeObj->animation =
|
|
|
|
placeObj->stateMach[placeObj->state][0]->animation;
|
|
|
|
|
|
|
|
layer =
|
|
|
|
placeObj->stateMach[placeObj->state][placeObj->stateColumn]->layer;
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_scenery->updateAnim(layer, 0, placeObj->animation, 0, placeObj->xPos,
|
2005-04-05 15:07:40 +00:00
|
|
|
placeObj->yPos, 0);
|
|
|
|
|
|
|
|
placeObj->yPos +=
|
2006-01-09 16:10:22 +00:00
|
|
|
(_gobPositions[0].y * 6) + 5 - _vm->_scenery->_toRedrawBottom;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-04 01:23:20 +00:00
|
|
|
if (_vm->_map->_itemPoses[idToPlace].orient == 4) {
|
2006-01-07 22:28:54 +00:00
|
|
|
placeObj->xPos += (_gobPositions[0].x * 12 + 14)
|
2006-01-09 16:10:22 +00:00
|
|
|
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-01-07 22:28:54 +00:00
|
|
|
placeObj->xPos += (_gobPositions[0].x * 12)
|
2006-01-09 16:10:22 +00:00
|
|
|
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Goblin::treatItemPick(int16 itemId) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 itemIndex;
|
|
|
|
Gob_Object *gobDesc;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
gobDesc = _goblins[_currentGoblin];
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (gobDesc->curFrame != 9)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gobDesc->stateMach != gobDesc->realStateMach)
|
|
|
|
return;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_readyToAct = 0;
|
|
|
|
_goesAtTarget = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
itemIndex = _itemToObject[itemId];
|
2005-04-05 15:07:40 +00:00
|
|
|
if (itemId != 0 && itemIndex != -1
|
2006-01-07 22:28:54 +00:00
|
|
|
&& _objects[itemIndex]->pickable != 1)
|
2005-04-05 15:07:40 +00:00
|
|
|
itemIndex = -1;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_itemIndInPocket != -1 && _itemIndInPocket == itemIndex)
|
2005-04-05 15:07:40 +00:00
|
|
|
itemIndex = -1;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_itemIndInPocket != -1 && itemIndex != -1
|
|
|
|
&& _objects[itemIndex]->pickable == 1) {
|
2006-01-03 23:14:39 +00:00
|
|
|
swapItems(itemIndex, itemId);
|
2006-01-07 22:28:54 +00:00
|
|
|
_itemIndInPocket = itemIndex;
|
|
|
|
_itemIdInPocket = itemId;
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_itemIndInPocket != -1 && itemIndex == -1) {
|
|
|
|
placeItem(_itemIndInPocket, _itemIdInPocket);
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_itemIndInPocket == -1 && itemIndex != -1) {
|
2006-01-03 23:14:39 +00:00
|
|
|
pickItem(itemIndex, itemId);
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
int16 Goblin::treatItem(int16 action) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 state;
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
state = _goblins[_currentGoblin]->state;
|
2005-04-05 15:07:40 +00:00
|
|
|
if ((state == 10 || state == 11) &&
|
2006-01-07 22:28:54 +00:00
|
|
|
_goblins[_currentGoblin]->curFrame == 0) {
|
|
|
|
_readyToAct = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (action == 3 && _currentGoblin == 0 &&
|
|
|
|
(state == 10 || state == 11) && _goblins[0]->curFrame == 0) {
|
|
|
|
saveGobDataToVars(_gobPositions[_currentGoblin].x,
|
|
|
|
_gobPositions[_currentGoblin].y, 0);
|
|
|
|
_goesAtTarget = 1;
|
2005-04-05 15:07:40 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_noPick == 0 && _currentGoblin == 0 &&
|
2005-04-05 15:07:40 +00:00
|
|
|
(state == 10 || state == 11)) {
|
2006-01-07 22:28:54 +00:00
|
|
|
treatItemPick(_destActionItem);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
saveGobDataToVars(_gobPositions[_currentGoblin].x,
|
|
|
|
_gobPositions[_currentGoblin].y, 0);
|
2005-04-05 15:07:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_goesAtTarget == 0) {
|
|
|
|
saveGobDataToVars(_gobPositions[_currentGoblin].x,
|
|
|
|
_gobPositions[_currentGoblin].y, 0);
|
2005-04-05 15:07:40 +00:00
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_itemToObject[_destActionItem] != 100 &&
|
|
|
|
_destActionItem != 0) {
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
if (_itemToObject[_destActionItem] == -1) {
|
|
|
|
_actDestItemDesc = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-01-07 22:28:54 +00:00
|
|
|
_actDestItemDesc =
|
|
|
|
_objects[_itemToObject
|
|
|
|
[_destActionItem]];
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-07 22:28:54 +00:00
|
|
|
_goesAtTarget = 0;
|
|
|
|
saveGobDataToVars(_gobPositions[_currentGoblin].x,
|
|
|
|
_gobPositions[_currentGoblin].y, 0);
|
|
|
|
return _destActionItem;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-07 18:49:20 +00:00
|
|
|
void Goblin::playSounds(Mult::Mult_Object *obj) {
|
|
|
|
int i;
|
|
|
|
Mult::Mult_AnimData *animData;
|
|
|
|
bool speaker;
|
|
|
|
int16 frequency;
|
|
|
|
int16 repCount;
|
|
|
|
int16 sndSlot;
|
|
|
|
int16 frame;
|
|
|
|
|
|
|
|
animData = obj->pAnimData;
|
|
|
|
|
|
|
|
for (i = 1; i <= obj->goblinStates[animData->state][0].dataCount; i++) {
|
2006-06-08 19:55:16 +00:00
|
|
|
speaker = obj->goblinStates[animData->state][i].speaker != 0;
|
2006-06-07 18:49:20 +00:00
|
|
|
if ((obj->goblinStates[animData->state][i].sndItem != -1) || (speaker == 1)) {
|
|
|
|
frame = obj->goblinStates[animData->state][i].sndFrame;
|
|
|
|
repCount = obj->goblinStates[animData->state][i].repCount;
|
|
|
|
frequency = obj->goblinStates[animData->state][i].freq;
|
|
|
|
if (animData->frame == frame) {
|
|
|
|
if (!speaker) {
|
|
|
|
sndSlot = obj->goblinStates[animData->state][i].sndItem;
|
|
|
|
_vm->_snd->stopSound(0);
|
|
|
|
if (sndSlot < _soundSlotsCount)
|
|
|
|
_vm->_snd->playSample(_vm->_game->_soundSamples[_soundSlots[sndSlot] & 0x7FFF],
|
|
|
|
repCount, frequency);
|
|
|
|
} else
|
|
|
|
_vm->_snd->speakerOn(frequency, repCount * 10);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Goblin::sub_195C7(int16 index, int16 state) {
|
|
|
|
Mult::Mult_Object *obj;
|
|
|
|
Mult::Mult_AnimData *animData;
|
|
|
|
int16 layer;
|
|
|
|
int16 animation;
|
|
|
|
|
|
|
|
obj = &_vm->_mult->_objects[index];
|
|
|
|
animData = obj->pAnimData;
|
|
|
|
|
|
|
|
if (obj->goblinStates[state] == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
layer = obj->goblinStates[state][0].layer;
|
|
|
|
animation = obj->goblinStates[state][0].animation;
|
|
|
|
animData->layer = layer;
|
|
|
|
animData->animation = animation;
|
|
|
|
animData->state = state;
|
|
|
|
animData->frame = 0;
|
|
|
|
animData->isPaused = 0;
|
|
|
|
animData->isStatic = 0;
|
2006-06-12 21:33:30 +00:00
|
|
|
animData->newCycle = _vm->_scenery->_animations[animation].layers[layer].framesCount;
|
2006-06-07 18:49:20 +00:00
|
|
|
_vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 1);
|
|
|
|
|
|
|
|
if (_vm->_map->_bigTiles) {
|
|
|
|
*obj->pPosY = ((obj->goblinY + 1) * _vm->_map->_tilesHeight) -
|
|
|
|
(_vm->_scenery->_animBottom - _vm->_scenery->_animTop) -
|
|
|
|
(obj->goblinY + 1) / 2;
|
|
|
|
} else {
|
|
|
|
*obj->pPosY = (obj->goblinY + 1) * _vm->_map->_tilesHeight -
|
|
|
|
(_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
|
|
|
|
}
|
|
|
|
*obj->pPosX = obj->goblinX * _vm->_map->_tilesWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Goblin::sub_11984(Mult::Mult_Object *obj) {
|
|
|
|
Mult::Mult_AnimData *animData;
|
|
|
|
int16 layer;
|
|
|
|
int16 animation;
|
|
|
|
int16 framesCount;
|
|
|
|
|
|
|
|
animData = obj->pAnimData;
|
|
|
|
|
|
|
|
if (animData->isStatic != 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
layer = obj->goblinStates[animData->state][0].layer;
|
|
|
|
animation = obj->goblinStates[animData->state][0].animation;
|
2006-06-12 21:33:30 +00:00
|
|
|
framesCount = _vm->_scenery->_animations[animation].layers[layer].framesCount;
|
2006-06-07 18:49:20 +00:00
|
|
|
animData->newCycle = framesCount;
|
|
|
|
playSounds(obj);
|
|
|
|
|
|
|
|
if (animData->isPaused == 0)
|
|
|
|
animData->frame++;
|
|
|
|
|
|
|
|
switch (animData->field_16) {
|
|
|
|
case 0:
|
|
|
|
case 1:
|
|
|
|
animData->isPaused = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
if (animData->frame == 0)
|
|
|
|
animData->isPaused = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
if (animData->frame >= framesCount)
|
|
|
|
animData->isPaused = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((animData->field_F == -1) && (animData->frame >= framesCount)) {
|
|
|
|
if (animData->field_15 <= 0) {
|
|
|
|
animData->field_15 = animData->unknown;
|
|
|
|
animData->frame = 0;
|
|
|
|
} else
|
|
|
|
animData->field_15--;
|
|
|
|
}
|
|
|
|
|
2006-12-14 19:07:43 +00:00
|
|
|
if (animData->frame < framesCount)
|
|
|
|
return;
|
|
|
|
|
2006-06-07 18:49:20 +00:00
|
|
|
if (animData->field_F != -1) {
|
|
|
|
animData->frame = 0;
|
|
|
|
animData->state = animData->field_F;
|
|
|
|
animData->field_F = -1;
|
|
|
|
animData->animation = obj->goblinStates[animData->state][0].animation;
|
|
|
|
animData->layer = obj->goblinStates[animData->state][0].layer;
|
2006-06-12 21:33:30 +00:00
|
|
|
*obj->pPosX += _vm->_scenery->_animations[animation].layers[layer].animDeltaX;
|
|
|
|
*obj->pPosY += _vm->_scenery->_animations[animation].layers[layer].animDeltaY;
|
|
|
|
animData->newCycle = _vm->_scenery->_animations[animation].layers[layer].framesCount;
|
2006-06-07 18:49:20 +00:00
|
|
|
animData->isPaused = 0;
|
|
|
|
} else
|
|
|
|
animData->frame--;
|
|
|
|
}
|
|
|
|
|
2006-08-12 09:16:08 +00:00
|
|
|
void Goblin::sub_197A6(int16 destX, int16 destY, int16 objIndex) {
|
|
|
|
Mult::Mult_Object *obj;
|
|
|
|
Mult::Mult_AnimData *animData;
|
|
|
|
int16 mouseX;
|
|
|
|
int16 mouseY;
|
|
|
|
int16 gobDestX;
|
|
|
|
int16 gobDestY;
|
|
|
|
int16 mapWidth;
|
|
|
|
int16 mapHeight;
|
|
|
|
int16 di;
|
|
|
|
int16 si;
|
|
|
|
int16 var_1E;
|
|
|
|
int16 var_20;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
obj = &_vm->_mult->_objects[objIndex];
|
|
|
|
animData = obj->pAnimData;
|
|
|
|
|
|
|
|
obj->gobDestX = destX;
|
|
|
|
obj->gobDestY = destY;
|
|
|
|
animData->field_13 = destX;
|
|
|
|
animData->field_14 = destY;
|
|
|
|
|
|
|
|
if ((animData->isBusy != 0) && (destX != -1) && (destY != -1)) {
|
|
|
|
if ((destX == -1) && (destY == -1)) {
|
|
|
|
mouseX = _vm->_global->_inter_mouseX;
|
|
|
|
mouseY = _vm->_global->_inter_mouseY;
|
|
|
|
if (_vm->_map->_bigTiles)
|
2007-02-14 16:36:17 +00:00
|
|
|
mouseY += ((_vm->_global->_inter_mouseY / _vm->_map->_tilesHeight) + 1) / 2;
|
2006-08-12 09:16:08 +00:00
|
|
|
obj->gobDestX = mouseX / _vm->_map->_tilesWidth;
|
|
|
|
obj->gobDestY = mouseY / _vm->_map->_tilesHeight;
|
|
|
|
gobDestX = obj->gobDestX;
|
|
|
|
gobDestY = obj->gobDestY;
|
|
|
|
if (_vm->_map->getPass(obj->gobDestX, obj->gobDestY) == 0) {
|
|
|
|
mapWidth = _vm->_map->_screenWidth / _vm->_map->_tilesWidth;
|
|
|
|
mapHeight = 200 / _vm->_map->_tilesHeight;
|
|
|
|
var_20 = 0;
|
|
|
|
di = -1;
|
|
|
|
si = -1;
|
|
|
|
|
|
|
|
for (i = 1; i <= gobDestX; i++)
|
|
|
|
if (_vm->_map->getPass(gobDestX - i, gobDestY) != 0)
|
|
|
|
break;
|
|
|
|
if (i <= gobDestX)
|
|
|
|
di = ((i - 1) * _vm->_map->_tilesWidth) + (mouseX % _vm->_map->_tilesWidth) + 1;
|
|
|
|
var_1E = i;
|
|
|
|
|
|
|
|
for (i = 1; (gobDestX + i) < mapWidth; i++)
|
|
|
|
if (_vm->_map->getPass(gobDestX + i, gobDestY) != 0)
|
|
|
|
break;
|
|
|
|
if ((gobDestX + i) < mapWidth)
|
|
|
|
si = (i * _vm->_map->_tilesWidth) - (mouseX % _vm->_map->_tilesWidth);
|
|
|
|
|
|
|
|
if ((si != -1) && ((di == -1) || (di > si))) {
|
|
|
|
di = si;
|
|
|
|
var_20 = 1;
|
|
|
|
var_1E = i;
|
|
|
|
}
|
|
|
|
si = -1;
|
|
|
|
|
|
|
|
for (i = 1; (gobDestY + i) < mapHeight; i++)
|
|
|
|
if (_vm->_map->getPass(gobDestX, gobDestY + i) != 0)
|
|
|
|
break;
|
|
|
|
if ((gobDestY + i) < mapHeight)
|
|
|
|
si = (i * _vm->_map->_tilesHeight) - (mouseY % _vm->_map->_tilesHeight);
|
|
|
|
|
|
|
|
if ((si != -1) && ((di == -1) || (di > si))) {
|
|
|
|
di = si;
|
|
|
|
var_20 = 2;
|
|
|
|
var_1E = i;
|
|
|
|
}
|
|
|
|
si = -1;
|
|
|
|
|
|
|
|
for (i = 1; i <= gobDestY; i++)
|
|
|
|
if (_vm->_map->getPass(gobDestX, gobDestY - i) != 0)
|
|
|
|
break;
|
|
|
|
if (i <= gobDestY)
|
|
|
|
si = ((i - 1) * _vm->_map->_tilesHeight) + (mouseY % _vm->_map->_tilesHeight) + 1;
|
|
|
|
|
|
|
|
if ((si != -1) && ((di == -1) || (di > si))) {
|
|
|
|
var_20 = 3;
|
|
|
|
var_1E = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (var_20 == 0)
|
|
|
|
gobDestX -= var_1E;
|
|
|
|
else if (var_20 == 1)
|
|
|
|
gobDestX += var_1E;
|
|
|
|
else if (var_20 == 2)
|
|
|
|
gobDestY += var_1E;
|
|
|
|
else if (var_20 == 3)
|
|
|
|
gobDestY -= var_1E;
|
|
|
|
}
|
|
|
|
obj->gobDestX = gobDestX;
|
|
|
|
obj->gobDestY = gobDestY;
|
|
|
|
animData->field_13 = gobDestX;
|
|
|
|
animData->field_14 = gobDestY;
|
|
|
|
if (animData->field_13 == -1) {
|
|
|
|
animData->field_13 = obj->goblinX;
|
|
|
|
obj->gobDestX = obj->goblinX;
|
|
|
|
}
|
|
|
|
if (animData->field_14 == -1) {
|
|
|
|
animData->field_14 = obj->goblinY;
|
|
|
|
obj->gobDestY = obj->goblinY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
initiateMove(obj);
|
|
|
|
}
|
|
|
|
|
2006-11-27 14:19:30 +00:00
|
|
|
void Goblin::sub_19AB7(Mult::Mult_AnimData *animData) {
|
|
|
|
switch(animData->state) {
|
|
|
|
case 2:
|
|
|
|
animData->layer = 8;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
animData->layer = 9;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 17:
|
|
|
|
animData->layer = 26;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 18:
|
|
|
|
animData->layer = 32;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 21:
|
|
|
|
animData->layer = 22;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 22:
|
|
|
|
animData->layer = 20;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 23:
|
|
|
|
animData->layer = 21;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Goblin::sub_19B45(Mult::Mult_AnimData *animData) {
|
|
|
|
switch(animData->state) {
|
|
|
|
case 2:
|
|
|
|
animData->layer = 10;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
animData->layer = 11;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 17:
|
|
|
|
animData->layer = 29;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 18:
|
|
|
|
animData->layer = 35;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 21:
|
|
|
|
animData->layer = 25;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 22:
|
|
|
|
animData->layer = 23;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 23:
|
|
|
|
animData->layer = 24;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-05 15:07:40 +00:00
|
|
|
} // End of namespace Gob
|