scummvm/engines/gob/goblin.cpp
2006-02-26 01:25:27 +00:00

2382 lines
60 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004 Ivan Dubrov
* Copyright (C) 2004-2006 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "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"
#include "gob/cdrom.h"
#include "gob/music.h"
namespace Gob {
Goblin::Goblin(GobEngine *vm) : _vm(vm) {
_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;
_rotStates[0][0] = 0; _rotStates[0][1] = 22; _rotStates[0][2] = 23; _rotStates[0][3] = 24;
_rotStates[1][0] = 13; _rotStates[1][1] = 2; _rotStates[1][2] = 12; _rotStates[1][3] = 14;
_rotStates[2][0] = 16; _rotStates[2][1] = 15; _rotStates[2][2] = 4; _rotStates[2][3] = 17;
_rotStates[3][0] = 27; _rotStates[3][1] = 25; _rotStates[3][2] = 26; _rotStates[3][3] = 6;
_boreCounter = 0;
_positionedGob = 5;
_noPick = 0;
_objList = 0;
int i;
for (i = 0; i < 4; i++)
_goblins[i] = 0;
_currentGoblin = 0;
for (i = 0; i < 16; i++)
_soundData[i] = 0;
for (i = 0; i < 3; i++) {
_gobPositions[i].x = 0;
_gobPositions[i].y = 0;
}
_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;
for (i = 0; i < 20; i++) {
_itemToObject[i] = 0;
_objects[i] = 0;
}
_objCount = 0;
_gobsCount = 0;
}
char Goblin::rotateState(int16 from, int16 to) {
return _rotStates[from / 2][to / 2];
}
int16 Goblin::peekGoblin(Gob_Object *_curGob) {
Util::ListNode *ptr;
Gob_Object *desc;
int16 index;
int16 i;
ptr = _objList->pHead;
index = 0;
while (ptr != 0) {
desc = (Gob_Object *) ptr->pData;
if (desc != _curGob) {
for (i = 0; i < 3; i++) {
if (desc != _goblins[i])
continue;
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) {
index = i + 1;
}
}
}
ptr = ptr->pNext;
}
return index;
}
void Goblin::initList(void) {
_objList = new Util::List;
_objList->pHead = 0;
_objList->pTail = 0;
}
void Goblin::sortByOrder(Util::List *list) {
Util::ListNode *ptr;
Util::ListNode *ptr2;
ptr = list->pHead;
while (ptr->pNext != 0) {
for (ptr2 = ptr->pNext; ptr2 != 0; ptr2 = ptr2->pNext) {
Gob_Object *objDesc = (Gob_Object *)ptr->pData;
Gob_Object *objDesc2 = (Gob_Object *)ptr2->pData;
if (objDesc->order <= objDesc2->order) {
if (objDesc->order != objDesc2->order)
continue;
if (objDesc->bottom <= objDesc2->bottom) {
if (objDesc->bottom != objDesc2->bottom)
continue;
if (objDesc != _goblins[_currentGoblin])
continue;
}
}
SWAP(ptr->pData, ptr2->pData);
}
ptr = ptr->pNext;
}
}
void Goblin::playSound(Snd::SoundDesc *snd, int16 repCount, int16 freq) {
if (snd != 0) {
_vm->_snd->stopSound(0);
_vm->_snd->playSample(snd, repCount, freq);
}
}
void Goblin::drawObjects(void) {
Util::ListNode *ptr;
Util::ListNode *ptr2;
Gob_Object *objDesc;
Gob_Object *gobDesc2;
int16 layer;
ptr = _objList->pHead;
for (ptr = _objList->pHead; ptr != 0; ptr = ptr->pNext) {
objDesc = (Gob_Object *) ptr->pData;
if (objDesc->type == 3)
objDesc->toRedraw = 1;
else if (objDesc->type == 1)
objDesc->toRedraw = 0;
}
for (ptr = _objList->pHead; ptr != 0; ptr = ptr->pNext) {
objDesc = (Gob_Object *) ptr->pData;
if (objDesc->toRedraw == 0)
continue;
_vm->_video->drawSprite(_vm->_anim->_animSurf, _vm->_draw->_backSurface,
objDesc->left, objDesc->top, objDesc->right,
objDesc->bottom, objDesc->left, objDesc->top, 0);
_vm->_draw->invalidateRect(objDesc->left, objDesc->top,
objDesc->right, objDesc->bottom);
if (objDesc->type != 0)
continue;
layer =
objDesc->stateMach[objDesc->state][objDesc->stateColumn]->
layer;
_vm->_scenery->updateAnim(layer, objDesc->curFrame, objDesc->animation,
0, objDesc->xPos, objDesc->yPos, 0);
if (_vm->_scenery->_toRedrawLeft == -12345) {
objDesc->dirtyLeft = objDesc->left;
objDesc->dirtyRight = objDesc->right;
objDesc->dirtyTop = objDesc->top;
objDesc->dirtyBottom = objDesc->bottom;
} else {
objDesc->dirtyLeft =
MIN(objDesc->left, _vm->_scenery->_toRedrawLeft);
objDesc->dirtyRight =
MAX(objDesc->right, _vm->_scenery->_toRedrawRight);
objDesc->dirtyTop =
MIN(objDesc->top, _vm->_scenery->_toRedrawTop);
objDesc->dirtyBottom =
MAX(objDesc->bottom, _vm->_scenery->_toRedrawBottom);
}
objDesc->dirtyLeft = 0;
objDesc->dirtyRight = 319;
objDesc->dirtyTop = 0;
objDesc->dirtyBottom = 199;
}
sortByOrder(_objList);
for (ptr = _objList->pHead; ptr != 0; ptr = ptr->pNext) {
objDesc = (Gob_Object *) ptr->pData;
if (objDesc->toRedraw) {
layer =
objDesc->stateMach[objDesc->state][objDesc->
stateColumn]->layer;
if (objDesc->type == 0) {
if (objDesc->visible == 0) {
_vm->_scenery->updateAnim(layer,
objDesc->curFrame,
objDesc->animation, 0,
objDesc->xPos, objDesc->yPos, 0);
} else {
_vm->_scenery->updateAnim(layer,
objDesc->curFrame,
objDesc->animation, 2,
objDesc->xPos, objDesc->yPos, 1);
}
if (_vm->_scenery->_toRedrawLeft == -12345) {
objDesc->left = 0;
objDesc->top = 0;
objDesc->right = 0;
objDesc->bottom = 0;
} else {
_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;
_vm->_scenery->updateStatic(objDesc->order);
}
} else {
objDesc->left = 0;
objDesc->top = 0;
objDesc->right = 0;
objDesc->bottom = 0;
objDesc->type = 1;
}
continue;
}
if (objDesc->type == 0 && objDesc->visible != 0) {
for (ptr2 = _objList->pHead; ptr2 != 0;
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;
_vm->_scenery->_toRedrawLeft = gobDesc2->dirtyLeft;
_vm->_scenery->_toRedrawRight = gobDesc2->dirtyRight;
_vm->_scenery->_toRedrawTop = gobDesc2->dirtyTop;
_vm->_scenery->_toRedrawBottom = gobDesc2->dirtyBottom;
layer =
objDesc->stateMach[objDesc->
state][objDesc->stateColumn]->layer;
_vm->_scenery->updateAnim(layer, objDesc->curFrame,
objDesc->animation, 4, objDesc->xPos,
objDesc->yPos, 1);
_vm->_scenery->updateStatic(objDesc->order);
}
}
}
for (ptr = _objList->pHead; ptr != 0; ptr = ptr->pNext) {
objDesc = (Gob_Object *) ptr->pData;
if (objDesc->toRedraw == 0 || objDesc->type == 1)
continue;
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) {
playSound(_soundData[sndItem],
repCount, freq);
}
}
sndFrame = state->sndFrame & 0xff;
sndItem = state->sndItem & 0xff;
freq = 100 * (state->freq & 0xff);
repCount = state->repCount & 0xff;
if (objDesc->curFrame == sndFrame) {
if (sndItem != 0xff) {
playSound(_soundData[sndItem],
repCount, freq);
}
}
} else {
// 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) {
if (sndItem != -1) {
playSound(_soundData[sndItem],
repCount, freq);
}
}
}
}
// _vm->_scenery->updateAnim(27, 0, 9, 2, 10, 10, 1);
}
void Goblin::animateObjects(void) {
Util::ListNode *node;
Gob_Object *objDesc;
Scenery::AnimLayer *pLayer;
int16 layer;
for (node = _objList->pHead; node != 0; node = node->pNext) {
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 =
_vm->_scenery->_animations[objDesc->animation].layers[layer];
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) {
objDesc->stateMach = _goblins[(int)(objDesc->multObjIndex)]->stateMach;
objDesc->state = objDesc->multState - 40;
} else {
objDesc->stateMach = objDesc->realStateMach;
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;
}
}
}
void Goblin::placeObject(Gob_Object *objDesc, char animated) {
int16 layer;
if (objDesc->stateMach[objDesc->state][0] != 0) {
objDesc->animation =
objDesc->stateMach[objDesc->state][0]->animation;
objDesc->noTick = 0;
objDesc->toRedraw = 1;
objDesc->doAnim = animated;
objDesc->maxTick = 1;
objDesc->tick = 1;
objDesc->curFrame = 0;
objDesc->type = 0;
objDesc->actionStartState = 0;
objDesc->nextState = -1;
objDesc->multState = -1;
objDesc->stateColumn = 0;
objDesc->curLookDir = 0;
objDesc->visible = 1;
objDesc->pickable = 0;
objDesc->unk14 = 0;
objDesc->relaxTime = _vm->_util->getRandom(30);
layer = objDesc->stateMach[objDesc->state][0]->layer;
_vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0,
objDesc->xPos, objDesc->yPos, 0);
objDesc->order = _vm->_scenery->_toRedrawBottom / 24 + 3;
objDesc->left = objDesc->xPos;
objDesc->right = objDesc->xPos;
objDesc->dirtyLeft = objDesc->xPos;
objDesc->dirtyRight = objDesc->xPos;
objDesc->top = objDesc->yPos;
objDesc->bottom = objDesc->yPos;
objDesc->dirtyTop = objDesc->yPos;
objDesc->dirtyBottom = objDesc->yPos;
_vm->_util->listInsertBack(_objList, objDesc);
}
}
int16 Goblin::getObjMaxFrame(Gob_Object * objDesc) {
int16 layer;
layer = objDesc->stateMach[objDesc->state][0]->layer;
return _vm->_scenery->_animations[objDesc->animation].layers[layer]->framesCount -
1;
}
int16 Goblin::objIntersected(Gob_Object *obj1, Gob_Object *obj2) {
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;
}
void Goblin::setMultStates(Gob_Object * gobDesc) {
gobDesc->stateMach = _goblins[(int)gobDesc->multObjIndex]->stateMach;
}
int16 Goblin::nextLayer(Gob_Object *gobDesc) {
if (gobDesc->nextState == 10)
gobDesc->curLookDir = 0;
if (gobDesc->nextState == 11)
gobDesc->curLookDir = 4;
if (gobDesc->nextState > 39) {
setMultStates(gobDesc);
} 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;
}
void Goblin::showBoredom(int16 gobIndex) {
Gob_Object *gobDesc;
int16 frame;
int16 frameCount;
int16 layer;
int16 state;
int16 boreFlag;
gobDesc = _goblins[gobIndex];
layer = gobDesc->stateMach[gobDesc->state][0]->layer;
frameCount =
_vm->_scenery->_animations[gobDesc->animation].layers[layer]->framesCount;
state = gobDesc->state;
frame = gobDesc->curFrame;
gobDesc->noTick = 0;
gobDesc->toRedraw = 1;
boreFlag = 1 << _vm->_util->getRandom(7);
if (gobIndex != _currentGoblin && _vm->_util->getRandom(3) != 0) {
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;
} else if (state >= 18 && state <= 21 && VAR(59) == 0) {
if (state == 30 || state == 31) // ???
return;
if (frame != frameCount)
return;
gobDesc->multState = 104 + gobIndex;
}
}
// index - goblin to select+1
// index==0 - switch to next
void Goblin::switchGoblin(int16 index) {
int16 next;
int16 tmp;
debugC(4, DEBUG_GAMEFLOW, "switchGoblin");
if (VAR(59) != 0)
return;
if (_goblins[_currentGoblin]->state <= 39 &&
_goblins[_currentGoblin]->curFrame != 0)
return;
if (index != 0 && _goblins[index - 1]->type != 0)
return;
if (index == 0)
next = (_currentGoblin + 1) % 3;
else
next = index - 1;
if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3 ||
_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6)
return;
if (_goblins[(_currentGoblin + 1) % 3]->type != 0 &&
_goblins[(_currentGoblin + 2) % 3]->type != 0)
return;
_gobPositions[_currentGoblin].x = _vm->_map->_curGoblinX;
_gobPositions[_currentGoblin].y = _vm->_map->_curGoblinY;
_goblins[_currentGoblin]->doAnim = 1;
_goblins[_currentGoblin]->nextState = 21;
nextLayer(_goblins[_currentGoblin]);
_currentGoblin = next;
if (_goblins[_currentGoblin]->type != 0)
_currentGoblin = (_currentGoblin + 1) % 3;
_goblins[_currentGoblin]->doAnim = 0;
if (_goblins[_currentGoblin]->curLookDir == 4)
_goblins[_currentGoblin]->nextState = 18;
else
_goblins[_currentGoblin]->nextState = 19;
_goblins[_currentGoblin]->toRedraw = 1;
nextLayer(_goblins[_currentGoblin]);
tmp = _gobPositions[_currentGoblin].x;
_pressedMapX = tmp;
_vm->_map->_destX = tmp;
_gobDestX = tmp;
_vm->_map->_curGoblinX = tmp;
tmp = _gobPositions[_currentGoblin].y;
_pressedMapY = tmp;
_vm->_map->_destY = tmp;
_gobDestY = tmp;
_vm->_map->_curGoblinY = tmp;
*_curGobVarPtr = _currentGoblin;
_pathExistence = 0;
_readyToAct = 0;
}
void Goblin::adjustDest(int16 posX, int16 posY) {
int16 resDelta;
int16 resDeltaDir;
int16 resDeltaPix;
int16 deltaPix;
int16 i;
if (_vm->_map->_passMap[_pressedMapY][_pressedMapX] == 0 &&
(_gobAction == 0
|| _vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0)) {
resDelta = -1;
resDeltaDir = 0;
resDeltaPix = 0;
for (i = 1;
i <= _pressedMapX
&& _vm->_map->_passMap[_pressedMapY][_pressedMapX - i] == 0;
i++);
if (i <= _pressedMapX) {
resDeltaPix = (i - 1) * 12 + (posX % 12) + 1;
resDelta = i;
}
for (i = 1;
(i + _pressedMapX) < Map::kMapWidth
&& _vm->_map->_passMap[_pressedMapY][_pressedMapX + i] == 0;
i++);
if (_pressedMapX + i < Map::kMapWidth) {
deltaPix = (i * 12) - (posX % 12);
if (resDelta == -1 || deltaPix < resDeltaPix) {
resDeltaPix = deltaPix;
resDelta = i;
resDeltaDir = 1;
}
}
for (i = 1;
(i + _pressedMapY) < Map::kMapHeight
&& _vm->_map->_passMap[_pressedMapY + i][_pressedMapX] == 0;
i++);
if (_pressedMapY + i < Map::kMapHeight) {
deltaPix = (i * 6) - (posY % 6);
if (resDelta == -1 || deltaPix < resDeltaPix) {
resDeltaPix = deltaPix;
resDelta = i;
resDeltaDir = 2;
}
}
for (i = 1;
i <= _pressedMapY
&& _vm->_map->_passMap[_pressedMapY - i][_pressedMapX] == 0;
i++);
if (i <= _pressedMapY) {
deltaPix = (i * 6) + (posY % 6);
if (resDelta == -1 || deltaPix < resDeltaPix) {
resDeltaPix = deltaPix;
resDelta = i;
resDeltaDir = 3;
}
}
switch (resDeltaDir) {
case 0:
_pressedMapX -= resDelta;
break;
case 1:
_pressedMapX += resDelta;
break;
case 2:
_pressedMapY += resDelta;
break;
case 3:
_pressedMapY -= resDelta;
break;
}
}
}
void Goblin::adjustTarget(void) {
if (_gobAction == 4
&& _vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0) {
if (_pressedMapY > 0
&& _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX] !=
0) {
_pressedMapY--;
} else if (_pressedMapX < Map::kMapWidth - 1
&& _vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] !=
0) {
_pressedMapX++;
} else if (_pressedMapX < Map::kMapWidth - 1 && _pressedMapY > 0
&& _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX +
1] != 0) {
_pressedMapY--;
_pressedMapX++;
}
}
}
void Goblin::targetDummyItem(Gob_Object *gobDesc) {
if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0 &&
_vm->_map->_passMap[_pressedMapY][_pressedMapX] == 1) {
if (gobDesc->curLookDir == 0) {
_vm->_map->_itemPoses[0].x = _pressedMapX;
_vm->_map->_itemPoses[0].y = _pressedMapY;
_vm->_map->_itemPoses[0].orient = -4;
} else {
_vm->_map->_itemPoses[0].x = _pressedMapX;
_vm->_map->_itemPoses[0].y = _pressedMapY;
_vm->_map->_itemPoses[0].orient = -1;
}
}
}
void Goblin::targetItem(void) {
int16 tmpX;
int16 tmpY;
int16 items;
int16 layer;
int16 tmpPosX;
int16 tmpPosY;
Gob_Object *itemDesc;
if (_gobAction == 3 || _gobAction == 4) {
items = _vm->_map->_itemsMap[_pressedMapY][_pressedMapX];
if (_gobAction == 4 && (items & 0xff00) != 0 &&
_objects[_itemToObject[(items & 0xff00) >> 8]]->
pickable == 1) {
_destItemId = (items & 0xff00) >> 8;
_destActionItem = (items & 0xff00) >> 8;
_itemByteFlag = 1;
} else if ((items & 0xff) == 0) {
_destItemId = (items & 0xff00) >> 8;
_destActionItem = (items & 0xff00) >> 8;
_itemByteFlag = 1;
} else if (_gobAction == 3 && _currentGoblin == 2 &&
(items & 0xff00) != 0) {
_destItemId = (items & 0xff00) >> 8;
_destActionItem = (items & 0xff00) >> 8;
_itemByteFlag = 1;
} else {
_destItemId = items & 0xff;
_destActionItem = items & 0xff;
_itemByteFlag = 0;
}
_pressedMapY = _vm->_map->_itemPoses[_destItemId].y;
_vm->_map->_destY = _vm->_map->_itemPoses[_destItemId].y;
_gobDestY = _vm->_map->_itemPoses[_destItemId].y;
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;
} else if ((items & 0xff00) != 0) {
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;
}
} 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;
}
}
if ((_vm->_map->_itemsMap[_pressedMapY +
1][_pressedMapX] & 0xff00) ==
(_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] &
0xff00)) {
_pressedMapY++;
_vm->_map->_destY = _pressedMapY;
_gobDestY = _pressedMapY;
}
} else {
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;
}
} 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;
}
}
if ((_vm->_map->_itemsMap[_pressedMapY +
1][_pressedMapX]) ==
(_vm->_map->_itemsMap[_pressedMapY][_pressedMapX])) {
_pressedMapY++;
_vm->_map->_destY = _pressedMapY;
_gobDestY = _pressedMapY;
}
}
if (_gobAction == 4 && _destActionItem != 0 &&
_itemToObject[_destActionItem] != -1 &&
_objects[_itemToObject[_destActionItem]]->
pickable == 1) {
itemDesc =
_objects[_itemToObject[_destActionItem]];
itemDesc->animation =
itemDesc->stateMach[itemDesc->state][0]->animation;
layer =
itemDesc->stateMach[itemDesc->state][itemDesc->
stateColumn]->layer;
_vm->_scenery->updateAnim(layer, 0, itemDesc->animation, 0,
itemDesc->xPos, itemDesc->yPos, 0);
tmpX = (_vm->_scenery->_toRedrawRight + _vm->_scenery->_toRedrawLeft) / 2;
tmpY = _vm->_scenery->_toRedrawBottom;
tmpPosY = tmpY / 6;
if ((tmpY % 3) < 3 && tmpPosY > 0)
tmpPosY--;
tmpPosX = tmpX / 12;
if ((tmpX % 12) < 6 && tmpPosX > 0)
tmpPosX--;
if (_vm->_map->_itemPoses[_destActionItem].orient == 0 ||
_vm->_map->_itemPoses[_destActionItem].orient == -1) {
tmpPosX++;
}
if (_vm->_map->_passMap[tmpPosY][tmpPosX] == 1) {
_pressedMapX = tmpPosX;
_vm->_map->_destX = tmpPosX;
_gobDestX = tmpPosX;
_pressedMapY = tmpPosY;
_vm->_map->_destY = tmpPosY;
_gobDestY = tmpPosY;
}
}
}
}
void Goblin::initiateMove(void) {
_vm->_map->findNearestToDest();
_vm->_map->findNearestToGob();
_vm->_map->optimizePoints();
_pathExistence = _vm->_map->checkDirectPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
_pressedMapX, _pressedMapY);
if (_pathExistence == 3) {
if (_vm->_map->checkLongPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
_pressedMapX, _pressedMapY,
_vm->_map->_nearestWayPoint, _vm->_map->_nearestDest) == 0) {
_pathExistence = 0;
} else {
_vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
_vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
}
}
}
void Goblin::moveFindItem(int16 posX, int16 posY) {
int16 i;
if (_gobAction == 3 || _gobAction == 4) {
for (i = 0; i < 20; i++) {
if (_objects[i] == 0)
continue;
if (_objects[i]->type != 0)
continue;
if (_objects[i]->left > posX)
continue;
if (_objects[i]->right < posX)
continue;
if (_objects[i]->top > posY)
continue;
if (_objects[i]->bottom < posY)
continue;
if (_objects[i]->right - _objects[i]->left < 40)
posX =
(_objects[i]->left +
_objects[i]->right) / 2;
if (_objects[i]->bottom - _objects[i]->top < 40)
posY =
(_objects[i]->top +
_objects[i]->bottom) / 2;
break;
}
_pressedMapX = posX / 12;
_pressedMapY = posY / 6;
if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0
&& i < 20) {
if (_vm->_map->_itemsMap[_pressedMapY +
1][_pressedMapX] != 0) {
_pressedMapY++;
} else if (_vm->_map->_itemsMap[_pressedMapY +
1][_pressedMapX + 1] != 0) {
_pressedMapX++;
_pressedMapY++;
} else
if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX +
1] != 0) {
_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--;
} else
if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX -
1] != 0) {
_pressedMapX--;
} else if (_vm->_map->_itemsMap[_pressedMapY +
1][_pressedMapX - 1] != 0) {
_pressedMapX--;
_pressedMapY++;
}
}
} else {
_pressedMapX = posX / 12;
_pressedMapY = posY / 6;
}
}
void Goblin::moveCheckSelect(int16 framesCount, Gob_Object * gobDesc, int16 *pGobIndex,
int16 *nextAct) {
if (gobDesc->right > _vm->_global->_inter_mouseX &&
gobDesc->left < _vm->_global->_inter_mouseX &&
gobDesc->bottom > _vm->_global->_inter_mouseY &&
gobDesc->bottom - 10 < _vm->_global->_inter_mouseY && _gobAction == 0) {
if (gobDesc->curLookDir & 4)
*nextAct = 16;
else
*nextAct = 23;
gobDesc->curFrame = framesCount - 1;
_pathExistence = 0;
} else {
*pGobIndex = peekGoblin(gobDesc);
if (*pGobIndex != 0) {
_pathExistence = 0;
} else if (_vm->_map->_curGoblinX == _pressedMapX &&
_vm->_map->_curGoblinY == _pressedMapY) {
if (_gobAction != 0)
_readyToAct = 1;
_pathExistence = 0;
}
}
}
void Goblin::moveInitStep(int16 framesCount, int16 action, int16 cont,
Gob_Object *gobDesc, int16 *pGobIndex, int16 *pNextAct) {
int16 posX;
int16 posY;
if (cont != 0 && _goesAtTarget == 0 &&
_readyToAct == 0 && VAR(59) == 0 &&
gobDesc->type != 1 &&
gobDesc->state != 10 && gobDesc->state != 11) {
if (gobDesc->state >= 40) {
gobDesc->curFrame = framesCount - 1;
}
_gobAction = action;
_forceNextState[0] = -1;
_forceNextState[1] = -1;
_forceNextState[2] = -1;
if (action == 3) {
posX = _vm->_global->_inter_mouseX + 6;
posY = _vm->_global->_inter_mouseY + 7;
} else if (action == 4) {
posX = _vm->_global->_inter_mouseX + 7;
posY = _vm->_global->_inter_mouseY + 12;
} else {
posX = _vm->_global->_inter_mouseX;
posY = _vm->_global->_inter_mouseY;
}
moveFindItem(posX, posY);
adjustDest(posX, posY);
adjustTarget();
_vm->_map->_destX = _pressedMapX;
_gobDestX = _pressedMapX;
_vm->_map->_destY = _pressedMapY;
_gobDestY = _pressedMapY;
targetDummyItem(gobDesc);
targetItem();
initiateMove();
moveCheckSelect(framesCount, gobDesc, pGobIndex, pNextAct);
} else {
if (_readyToAct != 0 &&
(_vm->_map->_curGoblinX != _pressedMapX ||
_vm->_map->_curGoblinY != _pressedMapY))
_readyToAct = 0;
if (gobDesc->type == 1) {
*pGobIndex = peekGoblin(gobDesc);
}
}
}
void Goblin::moveTreatRopeStairs(Gob_Object *gobDesc) {
if (_currentGoblin != 1)
return;
if (gobDesc->nextState == 28
&& _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 6) {
_forceNextState[0] = 28;
_forceNextState[1] = -1;
}
if (gobDesc->nextState == 29
&& _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 6) {
_forceNextState[0] = 29;
_forceNextState[1] = -1;
}
if ((gobDesc->nextState == 28 || gobDesc->nextState == 29
|| gobDesc->nextState == 20)
&& _vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6) {
if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4
|| gobDesc->curLookDir == 2)
&& _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 6) {
_forceNextState[0] = 28;
_forceNextState[1] = -1;
} else if ((gobDesc->curLookDir == 0
|| gobDesc->curLookDir == 4
|| gobDesc->curLookDir == 6)
&& _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 6) {
_forceNextState[0] = 29;
_forceNextState[1] = -1;
}
}
if (gobDesc->nextState == 8
&& _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 3) {
_forceNextState[0] = 8;
_forceNextState[1] = -1;
}
if (gobDesc->nextState == 9
&& _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 3) {
_forceNextState[0] = 9;
_forceNextState[1] = -1;
}
if (gobDesc->nextState == 20
&& _vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3) {
if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4
|| gobDesc->curLookDir == 2)
&& _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 3) {
_forceNextState[0] = 8;
_forceNextState[1] = -1;
} else if ((gobDesc->curLookDir == 0
|| gobDesc->curLookDir == 4
|| gobDesc->curLookDir == 6)
&& _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 3) {
_forceNextState[0] = 9;
_forceNextState[1] = -1;
}
}
}
void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
if (_pathExistence == 1) {
_vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
_vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
if (_vm->_map->_curGoblinX == _pressedMapX &&
_vm->_map->_curGoblinY == _pressedMapY && _gobAction != 0) {
_readyToAct = 1;
_pathExistence = 0;
}
nextAct = _vm->_map->getDirection(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
_vm->_map->_destX, _vm->_map->_destY);
if (nextAct == 0)
_pathExistence = 0;
} else if (_pathExistence == 3) {
_vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
_vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
if (_vm->_map->_curGoblinX == _gobDestX && _vm->_map->_curGoblinY == _gobDestY) {
_pathExistence = 1;
_vm->_map->_destX = _pressedMapX;
_vm->_map->_destY = _pressedMapY;
} else {
if (_vm->_map->checkDirectPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
_gobDestX, _gobDestY) == 1) {
_vm->_map->_destX = _gobDestX;
_vm->_map->_destY = _gobDestY;
} else if (_vm->_map->_curGoblinX == _vm->_map->_destX && _vm->_map->_curGoblinY == _vm->_map->_destY) {
if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest) {
_vm->_map->optimizePoints();
_vm->_map->_destX =
_vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
x;
_vm->_map->_destY =
_vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
y;
if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest)
_vm->_map->_nearestWayPoint--;
} else if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest) {
_vm->_map->optimizePoints();
_vm->_map->_destX =
_vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
x;
_vm->_map->_destY =
_vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
y;
if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest)
_vm->_map->_nearestWayPoint++;
} else {
if (_vm->_map->checkDirectPath(_vm->_map->_curGoblinX,
_vm->_map->_curGoblinY, _gobDestX,
_gobDestY) == 3 && _vm->_map->_passMap[_pressedMapY][_pressedMapX] != 0) {
_vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
_vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
} else {
_pathExistence = 1;
_vm->_map->_destX = _pressedMapX;
_vm->_map->_destY = _pressedMapY;
}
}
}
nextAct =
_vm->_map->getDirection(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
_vm->_map->_destX, _vm->_map->_destY);
}
}
if (_readyToAct != 0 && (_gobAction == 3 || _gobAction == 4))
nextAct = 0x4dc8;
switch (nextAct) {
case Map::kDirW:
gobDesc->nextState = rotateState(gobDesc->curLookDir, 0);
break;
case Map::kDirE:
gobDesc->nextState = rotateState(gobDesc->curLookDir, 4);
break;
case 16:
gobDesc->nextState = 16;
break;
case 23:
gobDesc->nextState = 23;
break;
case Map::kDirN:
if (_vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
}
if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3) {
gobDesc->nextState = 8;
break;
}
if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6 &&
_currentGoblin == 1) {
gobDesc->nextState = 28;
break;
}
gobDesc->nextState = rotateState(gobDesc->curLookDir, 2);
break;
case Map::kDirS:
if (_vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
}
if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3) {
gobDesc->nextState = 9;
break;
}
if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6 &&
_currentGoblin == 1) {
gobDesc->nextState = 29;
break;
}
gobDesc->nextState = rotateState(gobDesc->curLookDir, 6);
break;
case Map::kDirSE:
if (_vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX + 1] == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
}
gobDesc->nextState = 5;
if (gobDesc->curLookDir == 4)
break;
gobDesc->nextState = rotateState(gobDesc->curLookDir, 4);
break;
case Map::kDirSW:
if (_vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX - 1] == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
}
gobDesc->nextState = 7;
if (gobDesc->curLookDir == 0)
break;
gobDesc->nextState = rotateState(gobDesc->curLookDir, 0);
break;
case Map::kDirNW:
if (_vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX - 1] == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
}
gobDesc->nextState = 1;
if (gobDesc->curLookDir == 0)
break;
gobDesc->nextState = rotateState(gobDesc->curLookDir, 0);
break;
case Map::kDirNE:
if (_vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX + 1] == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
}
gobDesc->nextState = 3;
if (gobDesc->curLookDir == 4)
break;
gobDesc->nextState = rotateState(gobDesc->curLookDir, 4);
break;
case 0x4dc8:
if (_currentGoblin == 0 && _gobAction == 3
&& _itemIndInPocket == -1) {
_destItemId = -1;
_readyToAct = 0;
break;
}
if (_currentGoblin == 0 && _gobAction == 4 &&
_itemIndInPocket == -1 && _destActionItem == 0) {
gobDesc->multState = 104;
_destItemId = -1;
_readyToAct = 0;
break;
}
if (_currentGoblin == 0 && _gobAction == 4 &&
_itemIndInPocket == -1 && _destActionItem != 0 &&
_itemToObject[_destActionItem] != -1 &&
_objects[_itemToObject[_destActionItem]]->
pickable == 0) {
gobDesc->multState = 104;
_destItemId = -1;
_readyToAct = 0;
break;
}
switch (_vm->_map->_itemPoses[_destActionItem].orient) {
case 0:
case -4:
gobDesc->nextState = 10;
gobDesc->curLookDir = 0;
_destItemId = -1;
break;
case -1:
case 4:
gobDesc->nextState = 11;
gobDesc->curLookDir = 4;
_destItemId = -1;
break;
}
break;
default:
if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3 ||
(_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6
&& _currentGoblin == 1)) {
gobDesc->nextState = 20;
break;
}
switch (gobDesc->curLookDir) {
case 2:
case 4:
gobDesc->nextState = 18;
break;
case 6:
case 0:
gobDesc->nextState = 19;
break;
}
break;
}
return;
}
void Goblin::moveAdvance(Gob_Object *gobDesc, int16 nextAct, int16 framesCount) {
int16 i;
int16 newX;
int16 newY;
int16 flag;
movePathFind(gobDesc, nextAct);
gobDesc->curFrame++;
if (gobDesc->curFrame == 1)
gobDesc->actionStartState = gobDesc->state;
if (_goesAtTarget == 0
&& gobDesc->stateMach == gobDesc->realStateMach) {
switch (gobDesc->state) {
case 0:
case 1:
case 7:
case 13:
case 16:
case 27:
gobDesc->curLookDir = 0;
break;
case 3:
case 4:
case 5:
case 12:
case 23:
case 26:
gobDesc->curLookDir = 4;
break;
case 28:
if (_currentGoblin != 1)
break;
gobDesc->curLookDir = 2;
break;
case 2:
case 8:
case 15:
case 22:
case 25:
gobDesc->curLookDir = 2;
break;
case 29:
if (_currentGoblin != 1)
break;
gobDesc->curLookDir = 6;
break;
case 6:
case 9:
case 14:
case 17:
case 24:
gobDesc->curLookDir = 6;
break;
}
}
if (gobDesc->state >= 0 && gobDesc->state < 10 &&
gobDesc->stateMach == gobDesc->realStateMach &&
(gobDesc->curFrame == 3 || gobDesc->curFrame == 6)) {
_vm->_snd->speakerOn(10 * _vm->_util->getRandom(3) + 50, 5);
}
if (_currentGoblin == 0
&& gobDesc->stateMach == gobDesc->realStateMach
&& (gobDesc->state == 10 || gobDesc->state == 11)
&& gobDesc->curFrame == 9) {
_vm->_snd->stopSound(0);
if (_itemIndInPocket != -1) {
_vm->_snd->playSample(_soundData[14], 1, 9000);
}
if (_itemIndInPocket == -1) {
_vm->_snd->playSample(_soundData[14], 1, 5000);
}
}
if (_boreCounter++ == 120) {
_boreCounter = 0;
for (i = 0; i < 3; i++)
showBoredom(i);
}
if (gobDesc->multState != -1 && gobDesc->curFrame == framesCount &&
gobDesc->state != gobDesc->multState) {
gobDesc->nextState = gobDesc->multState;
gobDesc->multState = -1;
newX =
_vm->_scenery->_animations[gobDesc->animation].
layers[_gobStateLayer]->animDeltaX + gobDesc->xPos;
newY =
_vm->_scenery->_animations[gobDesc->animation].
layers[_gobStateLayer]->animDeltaY + gobDesc->yPos;
_gobStateLayer = nextLayer(gobDesc);
gobDesc->xPos = newX;
gobDesc->yPos = newY;
} else {
if (gobDesc->curFrame == 3 &&
gobDesc->stateMach == gobDesc->realStateMach &&
(gobDesc->state < 10 ||
(_currentGoblin == 1 && (gobDesc->state == 28
|| gobDesc->state == 29))
)) {
flag = 0;
if (_forceNextState[0] != -1) {
gobDesc->nextState = _forceNextState[0];
for (i = 0; i < 9; i++)
_forceNextState[i] =
_forceNextState[i + 1];
}
_vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
_vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
if (gobDesc->nextState != gobDesc->state) {
_gobStateLayer = nextLayer(gobDesc);
flag = 1;
}
switch (gobDesc->state) {
case 0:
_gobPositions[_currentGoblin].x--;
break;
case 2:
case 8:
_gobPositions[_currentGoblin].y--;
break;
case 4:
_gobPositions[_currentGoblin].x++;
break;
case 6:
case 9:
_gobPositions[_currentGoblin].y++;
break;
case 1:
_gobPositions[_currentGoblin].x--;
_gobPositions[_currentGoblin].y--;
break;
case 3:
_gobPositions[_currentGoblin].x++;
_gobPositions[_currentGoblin].y--;
break;
case 5:
_gobPositions[_currentGoblin].x++;
_gobPositions[_currentGoblin].y++;
break;
case 7:
_gobPositions[_currentGoblin].x--;
_gobPositions[_currentGoblin].y++;
break;
case 38:
_gobPositions[_currentGoblin].y++;
break;
}
if (_currentGoblin == 1) {
if (gobDesc->state == 28)
_gobPositions[1].y--;
if (gobDesc->state == 29)
_gobPositions[1].y++;
}
if (flag != 0) {
_vm->_scenery->updateAnim(_gobStateLayer, 0,
gobDesc->animation, 0, gobDesc->xPos,
gobDesc->yPos, 0);
gobDesc->yPos =
(_vm->_map->_curGoblinY + 1) * 6 -
(_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop);
gobDesc->xPos =
_vm->_map->_curGoblinX * 12 - (_vm->_scenery->_toRedrawLeft -
_vm->_scenery->_animLeft);
}
if ((gobDesc->state == 10 || gobDesc->state == 11)
&& _currentGoblin != 0)
_goesAtTarget = 1;
}
if (gobDesc->curFrame != framesCount)
return;
if (_forceNextState[0] != -1) {
gobDesc->nextState = _forceNextState[0];
for (i = 0; i < 10; i++)
_forceNextState[i] =
_forceNextState[i + 1];
}
_vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
_vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
_gobStateLayer = nextLayer(gobDesc);
if (gobDesc->stateMach == gobDesc->realStateMach) {
switch (gobDesc->nextState) {
case 0:
_gobPositions[_currentGoblin].x--;
break;
case 2:
case 8:
_gobPositions[_currentGoblin].y--;
break;
case 4:
_gobPositions[_currentGoblin].x++;
break;
case 6:
case 9:
_gobPositions[_currentGoblin].y++;
break;
case 1:
_gobPositions[_currentGoblin].x--;
_gobPositions[_currentGoblin].y--;
break;
case 3:
_gobPositions[_currentGoblin].x++;
_gobPositions[_currentGoblin].y--;
break;
case 5:
_gobPositions[_currentGoblin].x++;
_gobPositions[_currentGoblin].y++;
break;
case 7:
_gobPositions[_currentGoblin].x--;
_gobPositions[_currentGoblin].y++;
break;
case 38:
_gobPositions[_currentGoblin].y++;
break;
}
if (_currentGoblin == 1) {
if (gobDesc->nextState == 28)
_gobPositions[1].y--;
if (gobDesc->nextState == 29)
_gobPositions[1].y++;
}
}
_vm->_scenery->updateAnim(_gobStateLayer, 0, gobDesc->animation, 0,
gobDesc->xPos, gobDesc->yPos, 0);
gobDesc->yPos =
(_vm->_map->_curGoblinY + 1) * 6 - (_vm->_scenery->_toRedrawBottom -
_vm->_scenery->_animTop);
gobDesc->xPos =
_vm->_map->_curGoblinX * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft);
if ((gobDesc->state == 10 || gobDesc->state == 11)
&& _currentGoblin != 0)
_goesAtTarget = 1;
}
return;
}
int16 Goblin::doMove(Gob_Object *gobDesc, int16 cont, int16 action) {
int16 framesCount;
int16 nextAct;
int16 gobIndex;
int16 layer;
nextAct = 0;
gobIndex = 0;
layer = gobDesc->stateMach[gobDesc->state][0]->layer;
framesCount =
_vm->_scenery->_animations[gobDesc->animation].layers[layer]->framesCount;
if (VAR(59) == 0 &&
gobDesc->state != 30 && gobDesc->state != 31) {
gobDesc->order = (gobDesc->bottom) / 24 + 3;
}
if (_positionedGob != _currentGoblin) {
_vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
_vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
}
_positionedGob = _currentGoblin;
gobDesc->animation =
gobDesc->stateMach[gobDesc->state][gobDesc->stateColumn]->
animation;
_gobStateLayer =
gobDesc->stateMach[gobDesc->state][gobDesc->stateColumn]->layer;
moveInitStep(framesCount, action, cont, gobDesc, &gobIndex,
&nextAct);
moveTreatRopeStairs(gobDesc);
moveAdvance(gobDesc, nextAct, framesCount);
return gobIndex;
}
void Goblin::freeObjects(void) {
int16 i;
int16 state;
int16 col;
for (i = 0; i < 16; i++) {
if (_soundData[i] == 0)
continue;
_vm->_snd->freeSoundDesc(_soundData[i]);
_soundData[i] = 0;
}
for (i = 0; i < 4; i++) {
if (_goblins[i] == 0)
continue;
_goblins[i]->stateMach = _goblins[i]->realStateMach;
for (state = 0; state < 40; state++) {
for (col = 0; col < 6; col++) {
delete _goblins[i]->stateMach[state][col];
_goblins[i]->stateMach[state][col] = 0;
}
}
if (i == 3) {
for (state = 40; state < 70; state++) {
delete _goblins[3]->stateMach[state][0];
_goblins[3]->stateMach[state][0] = 0;
}
}
delete[] _goblins[i]->stateMach;
delete _goblins[i];
_goblins[i] = 0;
}
for (i = 0; i < 20; i++) {
if (_objects[i] == 0)
continue;
_objects[i]->stateMach = _objects[i]->realStateMach;
for (state = 0; state < 40; state++) {
for (col = 0; col < 6; col++) {
delete _objects[i]->stateMach[state][col];
_objects[i]->stateMach[state][col] = 0;
}
}
delete[] _objects[i]->stateMach;
delete _objects[i];
_objects[i] = 0;
}
}
void Goblin::zeroObjects(void) {
int16 i;
for (i = 0; i < 4; i++)
_goblins[i] = 0;
for (i = 0; i < 20; i++)
_objects[i] = 0;
for (i = 0; i < 16; i++)
_soundData[i] = 0;
}
void Goblin::freeAllObjects(void) {
_vm->_util->deleteList(_objList);
freeObjects();
}
void Goblin::loadObjects(char *source) {
int16 i;
zeroObjects();
for (i = 0; i < 20; i++)
_itemToObject[i] = 100;
freeObjects();
initList();
strcpy(_vm->_map->_sourceFile, source);
_vm->_map->_sourceFile[strlen(_vm->_map->_sourceFile) - 4] = 0;
_vm->_map->loadMapObjects(source);
for (i = 0; i < _gobsCount; i++)
placeObject(_goblins[i], 0);
for (i = 0; i < _objCount; i++) {
placeObject(_objects[i], 1);
}
initVarPointers();
_actDestItemDesc = 0;
}
void Goblin::saveGobDataToVars(int16 xPos, int16 yPos, int16 someVal) {
Gob_Object *obj;
*_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)
return;
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;
}
void Goblin::initVarPointers(void) {
_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;
}
void Goblin::loadGobDataFromVars(void) {
Gob_Object *obj;
_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)
return;
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)
obj->toRedraw = 1;
if (obj->state != _destItemState && obj->type == 0)
obj->toRedraw = 1;
}
void Goblin::pickItem(int16 indexToPocket, int16 idToPocket) {
int16 x;
int16 y;
if (_objects[indexToPocket]->pickable != 1)
return;
_objects[indexToPocket]->type = 3;
_itemIndInPocket = indexToPocket;
_itemIdInPocket = idToPocket;
for (y = 0; y < Map::kMapHeight; y++) {
for (x = 0; x < Map::kMapWidth; x++) {
if (_itemByteFlag == 1) {
if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) ==
idToPocket)
_vm->_map->_itemsMap[y][x] &= 0xff;
} else {
if ((_vm->_map->_itemsMap[y][x] & 0xff) == idToPocket)
_vm->_map->_itemsMap[y][x] &= 0xff00;
}
}
}
if (idToPocket >= 0 && idToPocket < 20) {
_vm->_map->_itemPoses[_itemIdInPocket].x = 0;
_vm->_map->_itemPoses[_itemIdInPocket].y = 0;
_vm->_map->_itemPoses[_itemIdInPocket].orient = 0;
}
}
void Goblin::placeItem(int16 indexInPocket, int16 idInPocket) {
Gob_Object *itemDesc;
int16 lookDir;
int16 xPos;
int16 yPos;
int16 layer;
itemDesc = _objects[indexInPocket];
lookDir = _goblins[0]->curLookDir & 4;
xPos = _gobPositions[0].x;
yPos = _gobPositions[0].y;
_itemIndInPocket = -1;
_itemIdInPocket = 0;
itemDesc->pickable = 1;
itemDesc->type = 0;
itemDesc->toRedraw = 1;
itemDesc->curFrame = 0;
itemDesc->order = _goblins[0]->order;
itemDesc->animation =
itemDesc->stateMach[itemDesc->state][0]->animation;
layer =
itemDesc->stateMach[itemDesc->state][itemDesc->stateColumn]->layer;
_vm->_scenery->updateAnim(layer, 0, itemDesc->animation, 0,
itemDesc->xPos, itemDesc->yPos, 0);
itemDesc->yPos +=
(_gobPositions[0].y * 6) + 5 - _vm->_scenery->_toRedrawBottom;
if (lookDir == 4) {
itemDesc->xPos += (_gobPositions[0].x * 12 + 14)
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
} else {
itemDesc->xPos += (_gobPositions[0].x * 12)
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
}
_vm->_map->placeItem(xPos, yPos, idInPocket);
if (yPos > 0) {
_vm->_map->placeItem(xPos, yPos - 1, idInPocket);
}
if (lookDir == 4) {
if (xPos < Map::kMapWidth - 1) {
_vm->_map->placeItem(xPos + 1, yPos, idInPocket);
if (yPos > 0) {
_vm->_map->placeItem(xPos + 1, yPos - 1, idInPocket);
}
}
} else {
if (xPos > 0) {
_vm->_map->placeItem(xPos - 1, yPos, idInPocket);
if (yPos > 0) {
_vm->_map->placeItem(xPos - 1, yPos - 1, idInPocket);
}
}
}
if (idInPocket >= 0 && idInPocket < 20) {
_vm->_map->_itemPoses[idInPocket].x = _gobPositions[0].x;
_vm->_map->_itemPoses[idInPocket].y = _gobPositions[0].y;
_vm->_map->_itemPoses[idInPocket].orient = lookDir;
if (_vm->_map->_itemPoses[idInPocket].orient == 0) {
// _vm->_map->_itemPoses[idInPocket].x++;
if (_vm->_map->_passMap[(int)_vm->_map->_itemPoses[idInPocket].y][_vm->_map->_itemPoses[idInPocket].x + 1] == 1)
_vm->_map->_itemPoses[idInPocket].x++;
} else {
if (_vm->_map->_passMap[(int)_vm->_map->_itemPoses[idInPocket].y][_vm->_map->_itemPoses[idInPocket].x - 1] == 1)
_vm->_map->_itemPoses[idInPocket].x--;
}
}
}
void Goblin::swapItems(int16 indexToPick, int16 idToPick) {
int16 layer;
Gob_Object *pickObj;
Gob_Object *placeObj;
int16 idToPlace;
int16 x;
int16 y;
pickObj = _objects[indexToPick];
placeObj = _objects[_itemIndInPocket];
idToPlace = _itemIdInPocket;
pickObj->type = 3;
_itemIndInPocket = indexToPick;
_itemIdInPocket = idToPick;
if (_itemByteFlag == 0) {
for (y = 0; y < Map::kMapHeight; y++) {
for (x = 0; x < Map::kMapWidth; x++) {
if ((_vm->_map->_itemsMap[y][x] & 0xff) == idToPick)
_vm->_map->_itemsMap[y][x] =
(_vm->_map->_itemsMap[y][x] & 0xff00) +
idToPlace;
}
}
} else {
for (y = 0; y < Map::kMapHeight; y++) {
for (x = 0; x < Map::kMapWidth; x++) {
if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) ==
idToPick)
_vm->_map->_itemsMap[y][x] =
(_vm->_map->_itemsMap[y][x] & 0xff) +
(idToPlace << 8);
}
}
}
if (idToPick >= 0 && idToPick < 20) {
_vm->_map->_itemPoses[idToPlace].x =
_vm->_map->_itemPoses[_itemIdInPocket].x;
_vm->_map->_itemPoses[idToPlace].y =
_vm->_map->_itemPoses[_itemIdInPocket].y;
_vm->_map->_itemPoses[idToPlace].orient =
_vm->_map->_itemPoses[_itemIdInPocket].orient;
_vm->_map->_itemPoses[_itemIdInPocket].x = 0;
_vm->_map->_itemPoses[_itemIdInPocket].y = 0;
_vm->_map->_itemPoses[_itemIdInPocket].orient = 0;
}
_itemIndInPocket = -1;
_itemIdInPocket = 0;
placeObj->type = 0;
placeObj->nextState = -1;
placeObj->multState = -1;
placeObj->unk14 = 0;
placeObj->toRedraw = 1;
placeObj->curFrame = 0;
placeObj->order = _goblins[0]->order;
placeObj->animation =
placeObj->stateMach[placeObj->state][0]->animation;
layer =
placeObj->stateMach[placeObj->state][placeObj->stateColumn]->layer;
_vm->_scenery->updateAnim(layer, 0, placeObj->animation, 0, placeObj->xPos,
placeObj->yPos, 0);
placeObj->yPos +=
(_gobPositions[0].y * 6) + 5 - _vm->_scenery->_toRedrawBottom;
if (_vm->_map->_itemPoses[idToPlace].orient == 4) {
placeObj->xPos += (_gobPositions[0].x * 12 + 14)
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
} else {
placeObj->xPos += (_gobPositions[0].x * 12)
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
}
}
void Goblin::treatItemPick(int16 itemId) {
int16 itemIndex;
Gob_Object *gobDesc;
gobDesc = _goblins[_currentGoblin];
if (gobDesc->curFrame != 9)
return;
if (gobDesc->stateMach != gobDesc->realStateMach)
return;
_readyToAct = 0;
_goesAtTarget = 0;
itemIndex = _itemToObject[itemId];
if (itemId != 0 && itemIndex != -1
&& _objects[itemIndex]->pickable != 1)
itemIndex = -1;
if (_itemIndInPocket != -1 && _itemIndInPocket == itemIndex)
itemIndex = -1;
if (_itemIndInPocket != -1 && itemIndex != -1
&& _objects[itemIndex]->pickable == 1) {
swapItems(itemIndex, itemId);
_itemIndInPocket = itemIndex;
_itemIdInPocket = itemId;
return;
}
if (_itemIndInPocket != -1 && itemIndex == -1) {
placeItem(_itemIndInPocket, _itemIdInPocket);
return;
}
if (_itemIndInPocket == -1 && itemIndex != -1) {
pickItem(itemIndex, itemId);
return;
}
}
int16 Goblin::treatItem(int16 action) {
int16 state;
state = _goblins[_currentGoblin]->state;
if ((state == 10 || state == 11) &&
_goblins[_currentGoblin]->curFrame == 0) {
_readyToAct = 0;
}
if (action == 3 && _currentGoblin == 0 &&
(state == 10 || state == 11) && _goblins[0]->curFrame == 0) {
saveGobDataToVars(_gobPositions[_currentGoblin].x,
_gobPositions[_currentGoblin].y, 0);
_goesAtTarget = 1;
return -1;
}
if (_noPick == 0 && _currentGoblin == 0 &&
(state == 10 || state == 11)) {
treatItemPick(_destActionItem);
saveGobDataToVars(_gobPositions[_currentGoblin].x,
_gobPositions[_currentGoblin].y, 0);
return 0;
}
if (_goesAtTarget == 0) {
saveGobDataToVars(_gobPositions[_currentGoblin].x,
_gobPositions[_currentGoblin].y, 0);
return 0;
} else {
if (_itemToObject[_destActionItem] != 100 &&
_destActionItem != 0) {
if (_itemToObject[_destActionItem] == -1) {
_actDestItemDesc = 0;
} else {
_actDestItemDesc =
_objects[_itemToObject
[_destActionItem]];
}
}
_goesAtTarget = 0;
saveGobDataToVars(_gobPositions[_currentGoblin].x,
_gobPositions[_currentGoblin].y, 0);
return _destActionItem;
}
}
} // End of namespace Gob