text: /* ScummVM - Graphic Adventure Engine
   *
   * ScummVM is the legal property of its developers, whose names
   * are too numerous to list here. Please refer to the COPYRIGHT
   * file distributed with this source distribution.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 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.
   *
   */
  
  #include "common/endian.h"
  
  #include "gob/gob.h"
  #include "gob/goblin.h"
  #include "gob/global.h"
  #include "gob/util.h"
  #include "gob/game.h"
  #include "gob/map.h"
  #include "gob/mult.h"
  #include "gob/scenery.h"
  #include "gob/inter.h"
  
  namespace Gob {
  
  Goblin_v2::Goblin_v2(GobEngine *vm) : Goblin_v1(vm) {
  	_gobsCount = -1;
  	_rotStates[0][0] =  0; _rotStates[0][1] = 18; _rotStates[0][2] = 19; _rotStates[0][3] = 20;
  	_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] = 23; _rotStates[3][1] = 21; _rotStates[3][2] = 22; _rotStates[3][3] =  6;
  }
  
  void Goblin_v2::freeObjects() {
  	_vm->_map->_mapUnknownBool = false;
  
  	if (_gobsCount < 0)
  		return;
  
  	for (int i = 0; i < _gobsCount; i++) {
  		delete[] _vm->_mult->_objects[i].goblinStates[0];
  		delete[] _vm->_mult->_objects[i].goblinStates;
  	}
  	for (int i = 0; i < _soundSlotsCount; i++)
  		if ((_soundSlots[i] & 0x8000) == 0)
  			_vm->_game->freeSoundSlot(_soundSlots[i]);
  	_gobsCount = -1;
  }
  
  void Goblin_v2::placeObject(Gob_Object *objDesc, char animated,
  		int16 index, int16 x, int16 y, int16 state) {
  	Mult::Mult_Object *obj;
  	Mult::Mult_AnimData *objAnim;
  	int16 layer;
  	int16 animation;
  
  	obj = &_vm->_mult->_objects[index];
  	objAnim = obj->pAnimData;
  
  	obj->goblinX = x;
  	obj->goblinY = y;
  	objAnim->order = y;
  
  	if (state == -1) {
  		objAnim->frame = 0;
  		objAnim->isPaused = 0;
  		objAnim->isStatic = 0;
  		objAnim->newCycle = 0;
  		_vm->_scenery->updateAnim(objAnim->layer, 0, objAnim->animation, 0,
  				*obj->pPosX, *obj->pPosY, 0);
  		if (!_vm->_map->hasBigTiles())
  			*obj->pPosY = (y + 1) * _vm->_map->getTilesHeight()
  				- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
  		else
  			*obj->pPosY = ((y + 1) * _vm->_map->getTilesHeight()) -
  				(_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (y + 1) / 2;
  		*obj->pPosX = x * _vm->_map->getTilesWidth();
  	} else {
  		if ((obj->goblinStates != 0) && (obj->goblinStates[state] != 0)) {
  			layer = obj->goblinStates[state][0].layer;
  			animation = obj->goblinStates[state][0].animation;
  			objAnim->state = state;
  			objAnim->layer = layer;
  			objAnim->animation = animation;
  			objAnim->frame = 0;
  			objAnim->isPaused = 0;
  			objAnim->isStatic = 0;
  			objAnim->newCycle = _vm->_scenery->getAnimLayer(animation, layer)->framesCount;
  			_vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
  			if (!_vm->_map->hasBigTiles())
  				*obj->pPosY = (y + 1) * _vm->_map->getTilesHeight()
  					- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
  			else
  				*obj->pPosY = ((y + 1) * _vm->_map->getTilesHeight()) -
  					(_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (y + 1) / 2;
  			*obj->pPosX = x * _vm->_map->getTilesWidth();
  			initiateMove(obj);
  		} else
  			initiateMove(obj);
  	}
  }
  
  void Goblin_v2::initiateMove(Mult::Mult_Object *obj) {
  	obj->destX = obj->gobDestX;
  	obj->destY = obj->gobDestY;
  	_vm->_map->findNearestToDest(obj);
  	_vm->_map->findNearestToGob(obj);
  	_vm->_map->optimizePoints(obj, obj->goblinX, obj->goblinY);
  	obj->pAnimData->pathExistence = _vm->_map->checkDirectPath(obj,
  			obj->goblinX, obj->goblinY, obj->gobDestX, obj->gobDestY);
  	if (obj->pAnimData->pathExistence == 3) {
  		const WayPoint &wayPoint = _vm->_map->getWayPoint(obj->nearestWayPoint);
  
  		obj->destX = wayPoint.x;
  		obj->destY = wayPoint.y;
  	}
  }
  
  void Goblin_v2::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct) {
  	Mult::Mult_AnimData *animData = obj->pAnimData;
  
  	animData->newCycle = _vm->_scenery->getAnimLayer(animData->animation, animData->layer)->framesCount;
  
  	int16 gobX     = obj->goblinX;
  	int16 gobY     = obj->goblinY;
  	int16 destX    = obj->destX;
  	int16 destY    = obj->destY;
  	int16 gobDestX = obj->gobDestX;
  	int16 gobDestY = obj->gobDestY;
  
  	animData->destX = gobDestX;
  	animData->destY = gobDestY;
  	animData->order = gobY;
  
  	Direction dir = kDirNone;
  
  	if (animData->pathExistence == 1) {
  
  		dir = _vm->_map->getDirection(gobX, gobY, destX, destY);
  		if (dir == kDirNone)
  			animData->pathExistence = 0;
  		if ((gobX == gobDestX) && (gobY == gobDestY))
  			animData->pathExistence = 4;
  
  	} else if (animData->pathExistence == 3) {
  
  		if ((gobX != gobDestX) || (gobY != gobDestY)) {
  
  			if (_vm->_map->checkDirectPath(obj, gobX, gobY, gobDestX, gobDestY) != 1) {
  
  				if ((gobX == destX) && (gobY == destY)) {
  
  					if (obj->nearestWayPoint > obj->nearestDest) {
  						_vm->_map->optimizePoints(obj, gobX, gobY);
  
  						const WayPoint &wayPoint = _vm->_map->getWayPoint(obj->nearestWayPoint);
  
  						destX = wayPoint.x;
  						destY = wayPoint.y;
  
  						if (_vm->_map->checkDirectPath(obj, gobX, gobY, destX, destY) == 3) {
  							WRITE_VAR(56, 1);
  							animData->pathExistence = 0;
  						}
  						if (obj->nearestWayPoint > obj->nearestDest)
  							obj->nearestWayPoint--;
  					} else if (obj->nearestWayPoint < obj->nearestDest) {
  						_vm->_map->optimizePoints(obj, gobX, gobY);
  
  						const WayPoint &wayPoint = _vm->_map->getWayPoint(obj->nearestWayPoint);
  
  						destX = wayPoint.x;
  						destY = wayPoint.y;
  
  						if (_vm->_map->checkDirectPath(obj, gobX, gobY, destX, destY) == 3) {
  							WRITE_VAR(56, 1);
  							animData->pathExistence = 0;
  						}
  						if (obj->nearestWayPoint < obj->nearestDest)
  							obj->nearestWayPoint++;
  					} else {
  						if ((_vm->_map->checkDirectPath(obj, gobX, gobY, gobDestX, gobDestY) == 3) &&
  								(_vm->_map->getPass(gobDestX, gobDestY) != 0)) {
  
  							const WayPoint &wayPoint = _vm->_map->getWayPoint(obj->nearestWayPoint);
  
  							destX = wayPoint.x;
  							destY = wayPoint.y;
  
  							WRITE_VAR(56, 1);
  						} else {
  							animData->pathExistence = 1;
  							destX = gobDestX;
  							destY = gobDestY;
  						}
  					}
  
  				}
  
  			} else {
  				destX = gobDestX;
  				destY = gobDestY;
  			}
  
  			dir = _vm->_map->getDirection(gobX, gobY, destX, destY);
  
  		} else {
  			animData->pathExistence = 4;
  			destX = gobDestX;
  			destY = gobDestY;
  		}
  
  	}
  
  	obj->goblinX   = gobX;
  	obj->goblinY   = gobY;
  	obj->destX     = destX;
  	obj->destY     = destY;
  	obj->gobDestX  = gobDestX;
  	obj->gobDestY  = gobDestY;
  
  	switch (dir) {
  	case kDirNW:
  		animData->nextState = 1;
  		if (_vm->_map->getScreenWidth() == 640) {
  			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
  				animData->nextState = 40;
  			if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) != 10)
  				animData->nextState = 1;
  		}
  		break;
  
  	case kDirN:
  		animData->nextState =
  			(animData->curLookDir == 2) ? 2 : rotateState(animData->curLookDir, 2);
  		if (_vm->_map->getScreenWidth() == 640) {
  			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) {
  				if      (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) == 10)
  					animData->nextState = 40;
  				else if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY - 2) == 10)
  					animData->nextState = 42;
  				else
  					animData->nextState = 2;
  			}
  
  			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20)
  				animData->nextState = 38;
  			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19)
  				animData->nextState = 26;
  		}
  		break;
  
  	case kDirNE:
  		animData->nextState = 3;
  		if (_vm->_map->getScreenWidth() == 640) {
  			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
  				animData->nextState = 42;
  			if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY - 2) != 10)
  				animData->nextState = 3;
  		}
  		break;
  
  	case kDirW:
  		animData->nextState = rotateState(animData->curLookDir, 0);
  		break;
  
  	case kDirE:
  		animData->nextState = rotateState(animData->curLookDir, 4);
  		break;
  
  	case kDirSW:
  		animData->nextState = 7;
  		if (_vm->_map->getScreenWidth() == 640) {
  			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
  				animData->nextState = 41;
  			if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY + 2) != 10)
  				animData->nextState = 7;
  		}
  		break;
  
  	case kDirS:
  		animData->nextState =
  			(animData->curLookDir == 6) ? 6 : rotateState(animData->curLookDir, 6);
  		if (_vm->_map->getScreenWidth() == 640) {
  			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20)
  				animData->nextState = 39;
  			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19)
  				animData->nextState = 27;
  		}
  		break;
  
  	case kDirSE:
  		animData->nextState = 5;
  		if (_vm->_map->getScreenWidth() == 640) {
  			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
  				animData->nextState = 43;
  			if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY + 2) != 10)
  				animData->nextState = 5;
  		}
  		break;
  
  	default:
  		if      (animData->curLookDir == 0)
  			animData->nextState = 8;
  		else if (animData->curLookDir == 2)
  			animData->nextState = 29;
  		else if (animData->curLookDir == 4)
  			animData->nextState = 9;
  		else if (animData->curLookDir == 6)
  			animData->nextState = 28;
  		break;
  	}
  }
  
  void Goblin_v2::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
  		int16 nextAct, int16 framesCount) {
  
  	if (!obj->goblinStates)
  		return;
  
  	movePathFind(obj, 0, 0);
  	playSounds(obj);
  
  	Mult::Mult_AnimData *animData = obj->pAnimData;
  
  	framesCount = _vm->_scenery->getAnimLayer(animData->animation, animData->layer)->framesCount;
  
  	if (animData->isPaused == 0)
  		animData->frame++;
  
  	switch (animData->stateType) {
  	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;
  
  	default:
  		break;
  	}
  
  	switch (animData->state) {
  	case 0:
  	case 1:
  	case 7:
  	case 13:
  	case 16:
  	case 23:
  	case 40:
  	case 41:
  		animData->curLookDir = 0;
  		break;
  
  	case 2:
  	case 15:
  	case 18:
  	case 21:
  	case 26:
  	case 38:
  		animData->curLookDir = 2;
  		break;
  
  	case 3:
  	case 4:
  	case 5:
  	case 12:
  	case 19:
  	case 22:
  	case 42:
  	case 43:
  		animData->curLookDir = 4;
  		break;
  
  	case 6:
  	case 14:
  	case 17:
  	case 20:
  	case 27:
  	case 39:
  		animData->curLookDir = 6;
  		break;
  
  	case 8:
  	case 9:
  	case 28:
  	case 29:
  		if (animData->pathExistence == 4)
  			animData->pathExistence = 5;
  		break;
  
  	default:
  		break;
  	}
  
  	if ((animData->newState != -1) && (animData->frame == framesCount) &&
  	    (animData->newState != animData->state)) {
  
  		animData->nextState = animData->newState;
  		animData->newState  = -1;
  		animData->state     = animData->nextState;
  
  		Scenery::AnimLayer *animLayer =
  			_vm->_scenery->getAnimLayer(animData->animation, animData->layer);
  
  		*obj->pPosX += animLayer->animDeltaX;
  		*obj->pPosY += animLayer->animDeltaY;
  
  		int16 animation = obj->goblinStates[animData->nextState][0].animation;
  		int16 layer     = obj->goblinStates[animData->nextState][0].layer;
  
  		animData->layer     = layer;
  		animData->animation = animation;
  		animData->frame     = 0;
  
  		return;
  	}
  
  	if (isMovement(animData->state)) {
  		int16 state = animData->nextState;
  
  		if (animData->frame == ((framesCount + 1) / 2)) {
  			int16 gobX = obj->goblinX;
  			int16 gobY = obj->goblinY + 1;
  
  			advMovement(obj, state);
  
  			if (animData->state != state) {
  				int16 animation = obj->goblinStates[state][0].animation;
  				int16 layer     = obj->goblinStates[state][0].layer;
  
  				animData->layer     = layer;
  				animData->animation = animation;
  				animData->frame     = 0;
  				animData->state     = state;
  
  				_vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
  				uint32 gobPosX =  gobX * _vm->_map->getTilesWidth();
  				uint32 gobPosY = (gobY * _vm->_map->getTilesHeight()) -
  				                 (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
  
  				if (_vm->_map->hasBigTiles())
  					gobPosY -= gobY / 2;
  
  				*obj->pPosX = gobPosX;
  				*obj->pPosY = gobPosY;
  			}
  		}
  	}
  
  	if (animData->frame < framesCount)
  		return;
  
  	int16 state     = animData->nextState;
  	int16 animation = obj->goblinStates[state][0].animation;
  	int16 layer     = obj->goblinStates[state][0].layer;
  
  	animData->layer     = layer;
  	animData->animation = animation;
  	animData->frame     = 0;
  	animData->state     = state;
  
  	int16 gobX = obj->goblinX;
  	int16 gobY = obj->goblinY + 1;
  
  	advMovement(obj, state);
  
  	_vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
  	uint32 gobPosX =  gobX * _vm->_map->getTilesWidth();
  	uint32 gobPosY = (gobY * _vm->_map->getTilesHeight()) -
  	                 (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
  
  	if (_vm->_map->hasBigTiles())
  		gobPosY -= gobY / 2;
  
  	*obj->pPosX = gobPosX;
  	*obj->pPosY = gobPosY;
  }
  
  void Goblin_v2::handleGoblins() {
  	Mult::Mult_Object *obj0, *obj1;
  	Mult::Mult_AnimData *anim0, *anim1;
  	int16 pass;
  	int16 gob1State, gob2State;
  	int16 gob1X, gob2X;
  	int16 gob1Y, gob2Y;
  	int16 gob1DestX, gob2DestX;
  	int16 gob1DestY, gob2DestY;
  
  	obj0 = &_vm->_mult->_objects[0];
  	obj1 = &_vm->_mult->_objects[1];
  	anim0 = obj0->pAnimData;
  	anim1 = obj1->pAnimData;
  
  	gob1State = anim0->state;
  	gob2State = anim1->state;
  
  	if (!anim0->isBusy) {
  		if (!_gob1Busy && (anim0->isStatic == 0)) {
  			if ((VAR(_gob1RelaxTimeVar) == 0) && (gob1State == 28)) {
  				// Goblin 1 showing boredom
  				gob1State = _vm->_util->getRandom(3) + 24;
  				setState(0, gob1State);
  				WRITE_VAR(_gob1RelaxTimeVar, 100);
  			} else
  				WRITE_VAR(_gob1RelaxTimeVar, VAR(_gob1RelaxTimeVar) - 1);
  		}
  		if ((gob1State == 8) || (gob1State == 9) || (gob1State == 29))
  			anim0->curLookDir = 6;
  	}
  	if (!anim1->isBusy) {
  		if (!_gob2Busy && (anim1->isStatic == 0)) {
  			if ((VAR(_gob2RelaxTimeVar) == 0) && (gob2State == 28)) {
  				// Goblin 2 showing boredom
  				gob2State = _vm->_util->getRandom(3) + 24;
  				setState(1, gob2State);
  				WRITE_VAR(_gob2RelaxTimeVar, 100);
  			} else
  				WRITE_VAR(_gob2RelaxTimeVar, VAR(_gob2RelaxTimeVar) - 1);
  		}
  		if ((gob2State == 8) || (gob2State == 9) || (gob2State == 29))
  			anim1->curLookDir = 6;
  	}
  
  	if ((anim0->isBusy == 1) && (anim0->isStatic == 0) &&
  			((anim0->state == 28) || (anim0->state == 29)))
  		anim0->curLookDir = 0;
  	if ((anim1->isBusy == 1) && (anim1->isStatic == 0) &&
  			((anim1->state == 28) || (anim1->state == 29)))
  		anim1->curLookDir = 0;
  
  	if (VAR(18) != ((uint32) -1)) {
  		if (anim0->layer == 44)
  			anim0->curLookDir = 4;
  		else if (anim0->layer == 45)
  			anim0->curLookDir = 0;
  		if (anim0->isBusy == 0)
  			anim0->curLookDir = 6;
  	}
  	if (VAR(19) != ((uint32) -1)) {
  		if (anim1->layer == 48)
  			anim1->curLookDir = 4;
  		else if (anim1->layer == 49)
  			anim1->curLookDir = 0;
  		if (anim1->isBusy == 0)
  			anim1->curLookDir = 6;
  	}
  
  	if ((anim0->layer == 45) && (anim0->curLookDir == 4) && (anim0->pathExistence == 5) &&
  			(VAR(18) == ((uint32) -1)) && !_gob1NoTurn) {
  		setState(0, 19); // Turning right->left
  	}
  	if ((anim0->layer == 44) && (anim0->curLookDir == 0) && (anim0->pathExistence == 5) &&
  			(VAR(18) == ((uint32) -1)) && !_gob1NoTurn) {
  		setState(0, 16); // Turning left->right
  	}
  	if ((anim1->layer == 49) && (anim1->curLookDir == 4) && (anim1->pathExistence == 5) &&
  			(VAR(19) == ((uint32) -1)) && !_gob2NoTurn) {
  		setState(1, 19); // Turning right->left
  	}
  	if ((anim1->layer == 48) && (anim1->curLookDir == 0) && (anim1->pathExistence == 5) &&
  			(VAR(19) == ((uint32) -1)) && !_gob2NoTurn) {
  		setState(1, 16); // Turning left->right
  	}
  
  	gob1X = obj0->goblinX;
  	gob2X = obj1->goblinX;
  	gob1Y = obj0->goblinY;
  	gob2Y = obj1->goblinY;
  	gob1DestX = anim0->destX;
  	gob2DestX = anim1->destX;
  	gob1DestY = anim0->destY;
  	gob2DestY = anim1->destY;
  
  	pass = _vm->_map->getPass(gob1X, gob1Y);
  	if ((pass > 17) && (pass < 21)) // Ladders, ropes, stairs
  		updateLayer1(anim0);
  	pass = _vm->_map->getPass(gob2X, gob2Y);
  	if ((pass > 17) && (pass < 21)) // Ladders, ropes, stairs
  		updateLayer2(anim1);
  
  	if ((gob1DestX < 0) || (gob1DestX > 39) || (gob1DestY < 0) || (gob1DestY > 39))
  		return;
  
  	if (gob1Y > gob1DestY) {
  		if (_vm->_map->getPass(gob1DestX, gob1DestY) > 17) {
  			do {
  				gob1DestY--;
  			} while (_vm->_map->getPass(gob1DestX, gob1DestY) > 17);
  			gob1DestY++;
  			if (_vm->_map->getPass(gob1DestX - 1, gob1DestY) == 0) {
  				if (_vm->_map->getPass(gob1DestX + 1, gob1DestY) != 0)
  					gob1DestX++;
  			} else
  				gob1DestX--;
  			move(gob1DestX, gob1DestY, 0);
  		}
  	} else {
  		if (_vm->_map->getPass(gob1DestX, gob1DestY) > 17) {
  			do {
  				gob1DestY++;
  			} while (_vm->_map->getPass(gob1DestX, gob1DestY) > 17);
  			gob1DestY--;
  			if (_vm->_map->getPass(gob1DestX - 1, gob1DestY) == 0) {
  				if (_vm->_map->getPass(gob1DestX + 1, gob1DestY) != 0)
  					gob1DestX++;
  			} else
  				gob1DestX--;
  			move(gob1DestX, gob1DestY, 0);
  		}
  	}
  	if (gob2Y > gob2DestY) {
  		if (_vm->_map->getPass(gob2DestX, gob2DestY) > 17) {
  			do {
  				gob2DestY--;
  			} while (_vm->_map->getPass(gob2DestX, gob2DestY) > 17);
  			gob2DestY++;
  			if (_vm->_map->getPass(gob2DestX - 1, gob2DestY) == 0) {
  				if (_vm->_map->getPass(gob2DestX + 1, gob2DestY) != 0)
  					gob2DestX++;
  			} else
  				gob2DestX--;
  			move(gob2DestX, gob2DestY, 1);
  		}
  	} else {
  		if (_vm->_map->getPass(gob2DestX, gob2DestY) > 17) {
  			do {
  				gob2DestY++;
  			} while (_vm->_map->getPass(gob2DestX, gob2DestY) > 17);
  			gob2DestY--;
  			if (_vm->_map->getPass(gob2DestX - 1, gob2DestY) == 0) {
  				if (_vm->_map->getPass(gob2DestX + 1, gob2DestY) != 0)
  					gob2DestX++;
  			} else
  				gob2DestX--;
  			move(gob2DestX, gob2DestY, 1);
  		}
  	}
  }
  
  bool Goblin_v2::isMovement(int8 state) {
  	if ((state >= 0) && (state < 8))
  		return true;
  	if ((state == 38) || (state == 39))
  		return true;
  
  	return false;
  }
  
  void Goblin_v2::advMovement(Mult::Mult_Object *obj, int8 state) {
  	switch (state) {
  	case 0:
  		obj->goblinX--;
  		break;
  
  	case 1:
  		obj->goblinX--;
  		obj->goblinY--;
  		break;
  
  	case 2:
  	case 38:
  		obj->goblinY--;
  		break;
  
  	case 3:
  		obj->goblinX++;
  		obj->goblinY--;
  		break;
  
  	case 4:
  		obj->goblinX++;
  		break;
  
  	case 5:
  		obj->goblinX++;
  		obj->goblinY++;
  		break;
  
  	case 6:
  	case 39:
  		obj->goblinY++;
  		break;
  
  	case 7:
  		obj->goblinX--;
  		obj->goblinY++;
  		break;
  
  	default:
  		break;
  	}
  }
  
  } // End of namespace Gob
  