[Scummvm-cvs-logs] SF.net SVN: scummvm: [22979] scummvm/trunk/engines/gob

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Wed Jun 7 20:49:47 CEST 2006


Revision: 22979
Author:   drmccoy
Date:     2006-06-07 11:49:20 -0700 (Wed, 07 Jun 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=22979&view=rev

Log Message:
-----------
More goblin handling functions, now the deactivated goblin shows
his boredom. It's the wrong goblin that's deactivated, though.
Also, the entering animation is still missing (now nothing is drawn
instead).

Modified Paths:
--------------
    scummvm/trunk/engines/gob/goblin.cpp
    scummvm/trunk/engines/gob/goblin.h
    scummvm/trunk/engines/gob/goblin_v1.cpp
    scummvm/trunk/engines/gob/goblin_v2.cpp
    scummvm/trunk/engines/gob/inter_v2.cpp
    scummvm/trunk/engines/gob/map.cpp
    scummvm/trunk/engines/gob/map.h
    scummvm/trunk/engines/gob/map_v1.cpp
    scummvm/trunk/engines/gob/map_v2.cpp
    scummvm/trunk/engines/gob/mult.h
    scummvm/trunk/engines/gob/mult_v2.cpp
Modified: scummvm/trunk/engines/gob/goblin.cpp
===================================================================
--- scummvm/trunk/engines/gob/goblin.cpp	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/goblin.cpp	2006-06-07 18:49:20 UTC (rev 22979)
@@ -61,11 +61,6 @@
 	_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;
 
@@ -1220,552 +1215,6 @@
 
 }
 
-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(-1, _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(0, 0, 0);
-
-					_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(0, 0, 0);
-
-					_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(-1, _vm->_map->_curGoblinX,
-						_vm->_map->_curGoblinY, _gobDestX,
-						_gobDestY) == 3 && _vm->_map->getPass(_pressedMapX, _pressedMapY) != 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->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6 &&
-		    _currentGoblin != 1) {
-			_pathExistence = 0;
-			break;
-		}
-
-		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
-			gobDesc->nextState = 8;
-			break;
-		}
-
-		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
-		    _currentGoblin == 1) {
-			gobDesc->nextState = 28;
-			break;
-		}
-
-		gobDesc->nextState = rotateState(gobDesc->curLookDir, 2);
-		break;
-
-	case Map::kDirS:
-		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6 &&
-		    _currentGoblin != 1) {
-			_pathExistence = 0;
-			break;
-		}
-
-		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
-			gobDesc->nextState = 9;
-			break;
-		}
-
-		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
-		    _currentGoblin == 1) {
-			gobDesc->nextState = 29;
-			break;
-		}
-
-		gobDesc->nextState = rotateState(gobDesc->curLookDir, 6);
-		break;
-
-	case Map::kDirSE:
-		if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY + 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->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY + 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->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY - 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->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY - 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->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 ||
-		    (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 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;
@@ -1801,7 +1250,7 @@
 	moveInitStep(framesCount, action, cont, gobDesc, &gobIndex,
 	    &nextAct);
 	moveTreatRopeStairs(gobDesc);
-	moveAdvance(gobDesc, nextAct, framesCount);
+	moveAdvance(0, gobDesc, nextAct, framesCount);
 
 	return gobIndex;
 }
@@ -2312,6 +1761,38 @@
 	}
 }
 
+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++) {
+		speaker = obj->goblinStates[animData->state][i].speaker;
+		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_19BD3(void) {
 	Mult::Mult_Object *obj0;
 	Mult::Mult_Object *obj1;
@@ -2327,8 +1808,8 @@
 	int16 di;
 	int16 si;
 
-	obj0 = &(_vm->_mult->_objects[0]);
-	obj1 = &(_vm->_mult->_objects[1]);
+	obj0 = &_vm->_mult->_objects[0];
+	obj1 = &_vm->_mult->_objects[1];
 	anim0 = obj0->pAnimData;
 	anim1 = obj1->pAnimData;
 
@@ -2339,66 +1820,66 @@
 		if ((_word_2F9BC == 0) && (anim0->isStatic == 0)) {
 			if ((VAR(_dword_2F9B6) == 0) && (si == 28)) {
 				si = _vm->_util->getRandom(3) + 24;
-				warning("GOB2 Stub! sub_195C7(0, si);");
+				sub_195C7(0, si);
 				WRITE_VAR(_dword_2F9B6, 100);
 			} else
 				WRITE_VAR(_dword_2F9B6, VAR(_dword_2F9B6) - 1);
 		}
 		if ((si == 8) || (si == 9) || (si == 29))
-			anim0->field_10 = 6;
+			anim0->curLookDir = 6;
 	}
 	if (anim1->someFlag == 0) {
 		if ((_word_2F9BA == 0) && (anim1->isStatic == 0)) {
 			if ((VAR(_dword_2F9B2) == 0) && (di == 28)) {
 				di = _vm->_util->getRandom(3) + 24;
-				warning("GOB2 Stub! sub_195C7(1, di);");
+				sub_195C7(1, di);
 				WRITE_VAR(_dword_2F9B2, 100);
 			} else
 				WRITE_VAR(_dword_2F9B2, VAR(_dword_2F9B2) - 1);
 		}
 		if ((di == 8) || (di == 9) || (di == 29))
-			anim1->field_10 = 6;
+			anim1->curLookDir = 6;
 	}
 
 	if ((anim0->someFlag == 1) && (anim0->isStatic == 0) &&
 			((anim0->state == 28) || (anim0->state == 29)))
-		anim0->field_10 = 0;
+		anim0->curLookDir = 0;
 	if ((anim1->someFlag == 1) && (anim1->isStatic == 0) &&
 			((anim1->state == 28) || (anim1->state == 29)))
-		anim1->field_10 = 0;
+		anim1->curLookDir = 0;
 
 	if (VAR(18) != ((uint32) -1)) {
 		if (anim0->layer == 44)
-			anim0->field_10 = 4;
+			anim0->curLookDir = 4;
 		else if (anim0->layer == 45)
-			anim0->field_10 = 0;
+			anim0->curLookDir = 0;
 		if (anim0->someFlag == 0)
-			anim0->field_10 = 6;
+			anim0->curLookDir = 6;
 	}
 	if (VAR(19) != ((uint32) -1)) {
 		if (anim1->layer == 48)
-			anim1->field_10 = 4;
+			anim1->curLookDir = 4;
 		else if (anim1->layer == 49)
-			anim1->field_10 = 0;
+			anim1->curLookDir = 0;
 		if (anim1->someFlag == 0)
-			anim1->field_10 = 6;
+			anim1->curLookDir = 6;
 	}
 
-	if ((anim0->layer == 45) && (anim0->field_10 == 4) && (anim0->field_12 == 5) &&
+	if ((anim0->layer == 45) && (anim0->curLookDir == 4) && (anim0->pathExistence == 5) &&
 			(VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
-		warning("GOB2 Stub! sub_195C7(0, 19);");
+		sub_195C7(0, 19);
 	}
-	if ((anim0->layer == 44) && (anim0->field_10 == 0) && (anim0->field_12 == 5) &&
+	if ((anim0->layer == 44) && (anim0->curLookDir == 0) && (anim0->pathExistence == 5) &&
 			(VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
-		warning("GOB2 Stub! sub_195C7(0, 16);");
+		sub_195C7(0, 16);
 	}
-	if ((anim1->layer == 49) && (anim1->field_10 == 4) && (anim1->field_12 == 5) &&
+	if ((anim1->layer == 49) && (anim1->curLookDir == 4) && (anim1->pathExistence == 5) &&
 			(VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
-		warning("GOB2 Stub! sub_195C7(1, 19);");
+		sub_195C7(1, 19);
 	}
-	if ((anim1->layer == 48) && (anim1->field_10 == 0) && (anim1->field_12 == 5) &&
+	if ((anim1->layer == 48) && (anim1->curLookDir == 0) && (anim1->pathExistence == 5) &&
 			(VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
-		warning("GOB2 Stub! sub_195C7(1, 16);");
+		sub_195C7(1, 16);
 	}
 
 	gob1X = obj0->goblinX;
@@ -2476,4 +1957,97 @@
 	}
 }
 
+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;
+	animData->newCycle = _vm->_scenery->_animations[animation].layers[layer]->framesCount;
+	_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;
+	framesCount = _vm->_scenery->_animations[animation].layers[layer]->framesCount;
+	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--;
+	}
+
+	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;
+		*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;
+		animData->isPaused = 0;
+	} else
+		animData->frame--;
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/goblin.h
===================================================================
--- scummvm/trunk/engines/gob/goblin.h	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/goblin.h	2006-06-07 18:49:20 UTC (rev 22979)
@@ -26,6 +26,7 @@
 #include "gob/gob.h"
 #include "gob/util.h"
 #include "gob/sound.h"
+#include "gob/mult.h"
 
 namespace Gob {
 
@@ -34,6 +35,7 @@
 #define TYPE_MOBILE		3
 
 class Goblin {
+
 public:
 #pragma START_PACK_STRUCTS
 	struct Gob_State {
@@ -47,12 +49,6 @@
 		int16 sndFrame;		// +Eh
 	} GCC_PACK;
 
-	struct Gob2_State {
-		int16 animation;
-		int16 layer;
-		int16 field_4;
-	};
-
 	typedef Gob_State *Gob_PState;
 
 	typedef Gob_PState Gob_StateLine[6];
@@ -219,11 +215,15 @@
 	int16 doMove(Gob_Object *gobDesc, int16 cont, int16 action);
 
 	void sub_19BD3(void);
+	void sub_195C7(int16 index, int16 state);
+	void sub_11984(Mult::Mult_Object *obj);
 
 	virtual void placeObject(Gob_Object * objDesc, char animated,
 			int16 index, int16 x, int16 y, int16 state) = 0;
 	virtual void freeObjects(void) = 0;
-	virtual void initiateMove(int16 index) = 0;
+	virtual void initiateMove(Mult::Mult_Object *obj) = 0;
+	virtual void moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
+			int16 nextAct, int16 framesCount) = 0;
 
 	Goblin(GobEngine *vm);
 	virtual ~Goblin();
@@ -244,8 +244,9 @@
 	void moveInitStep(int16 framesCount, int16 action, int16 cont,
 					  Gob_Object *gobDesc, int16 *pGobIndex, int16 *pNextAct);
 	void moveTreatRopeStairs(Gob_Object *gobDesc);
-	void movePathFind(Gob_Object *gobDesc, int16 nextAct);
-	void moveAdvance(Gob_Object *gobDesc, int16 nextAct, int16 framesCount);
+	void playSounds(Mult::Mult_Object *obj);
+
+	virtual void movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct) = 0;
 };
 
 class Goblin_v1 : public Goblin {
@@ -253,10 +254,15 @@
 	virtual void placeObject(Gob_Object * objDesc, char animated,
 			int16 index, int16 x, int16 y, int16 state);
 	virtual void freeObjects(void);
-	virtual void initiateMove(int16 index);
+	virtual void initiateMove(Mult::Mult_Object *obj);
+	virtual void moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
+			int16 nextAct, int16 framesCount);
 
 	Goblin_v1(GobEngine *vm);
 	virtual ~Goblin_v1() {};
+
+protected:
+	virtual void movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct);
 };
 
 class Goblin_v2 : public Goblin_v1 {
@@ -264,10 +270,15 @@
 	virtual void placeObject(Gob_Object * objDesc, char animated,
 			int16 index, int16 x, int16 y, int16 state);
 	virtual void freeObjects(void);
-	virtual void initiateMove(int16 index);
+	virtual void initiateMove(Mult::Mult_Object *obj);
+	virtual void moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
+			int16 nextAct, int16 framesCount);
 
 	Goblin_v2(GobEngine *vm);
 	virtual ~Goblin_v2() {};
+
+protected:
+	virtual void movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct);
 };
 
 }				// End of namespace Gob

Modified: scummvm/trunk/engines/gob/goblin_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/goblin_v1.cpp	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/goblin_v1.cpp	2006-06-07 18:49:20 UTC (rev 22979)
@@ -32,6 +32,10 @@
 namespace Gob {
 
 Goblin_v1::Goblin_v1(GobEngine *vm) : Goblin(vm) {
+	_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;
 }
 
 void Goblin_v1::freeObjects(void) {
@@ -138,12 +142,12 @@
 	}
 }
 
-void Goblin_v1::initiateMove(int16 index) {
+void Goblin_v1::initiateMove(Mult::Mult_Object *obj) {
 	_vm->_map->findNearestToDest(0);
 	_vm->_map->findNearestToGob(0);
 	_vm->_map->optimizePoints(0, 0, 0);
 
-	_pathExistence = _vm->_map->checkDirectPath(-1, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+	_pathExistence = _vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
 	    _pressedMapX, _pressedMapY);
 
 	if (_pathExistence == 3) {
@@ -158,4 +162,551 @@
 	}
 }
 
+void Goblin_v1::movePathFind(Mult::Mult_Object *obj, 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(0, _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(0, 0, 0);
+
+					_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(0, 0, 0);
+
+					_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(0, _vm->_map->_curGoblinX,
+						_vm->_map->_curGoblinY, _gobDestX,
+						_gobDestY) == 3 && _vm->_map->getPass(_pressedMapX, _pressedMapY) != 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->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6 &&
+		    _currentGoblin != 1) {
+			_pathExistence = 0;
+			break;
+		}
+
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
+			gobDesc->nextState = 8;
+			break;
+		}
+
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
+		    _currentGoblin == 1) {
+			gobDesc->nextState = 28;
+			break;
+		}
+
+		gobDesc->nextState = rotateState(gobDesc->curLookDir, 2);
+		break;
+
+	case Map::kDirS:
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6 &&
+		    _currentGoblin != 1) {
+			_pathExistence = 0;
+			break;
+		}
+
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
+			gobDesc->nextState = 9;
+			break;
+		}
+
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
+		    _currentGoblin == 1) {
+			gobDesc->nextState = 29;
+			break;
+		}
+
+		gobDesc->nextState = rotateState(gobDesc->curLookDir, 6);
+		break;
+
+	case Map::kDirSE:
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY + 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->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY + 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->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY - 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->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY - 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->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 ||
+		    (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 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_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
+		int16 nextAct, int16 framesCount) {
+	int16 i;
+	int16 newX;
+	int16 newY;
+	int16 flag;
+
+	movePathFind(0, 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;
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/goblin_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/goblin_v2.cpp	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/goblin_v2.cpp	2006-06-07 18:49:20 UTC (rev 22979)
@@ -35,6 +35,10 @@
 
 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(void) {
@@ -101,26 +105,421 @@
 				*obj->pPosY = ((y + 1) / 2) * _vm->_map->_tilesHeight
 					- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
 			*obj->pPosX = x * _vm->_map->_tilesWidth;
-			initiateMove(index);
+			initiateMove(obj);
 		} else
-			initiateMove(index);
+			initiateMove(obj);
 	}
 }
 
-void Goblin_v2::initiateMove(int16 index) {
-	Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
-
+void Goblin_v2::initiateMove(Mult::Mult_Object *obj) {
 	obj->destX = obj->gobDestX;
 	obj->destY = obj->gobDestY;
-	_vm->_map->findNearestToDest(index);
-	_vm->_map->findNearestToGob(index);
-	_vm->_map->optimizePoints(index, obj->goblinX, obj->goblinY);
-	obj->pAnimData->field_12 = _vm->_map->checkDirectPath(index,
+	_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->field_12 == 3) {
+	if (obj->pAnimData->pathExistence == 3) {
 		obj->destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
 		obj->destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
 	}
 }
 
+void Goblin_v2::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct) {
+	Mult::Mult_AnimData *animData;
+	int16 framesCount;
+	int16 gobX;
+	int16 gobY;
+	int16 gobDestX;
+	int16 gobDestY;
+	int16 destX;
+	int16 destY;
+	int16 dir;
+
+	dir = 0;
+	animData = obj->pAnimData;
+	framesCount =
+		_vm->_scenery->_animations[(int)animData->animation].layers[animData->layer]->framesCount;
+	gobX = obj->goblinX;
+	gobY = obj->goblinY;
+	animData->order = gobY;
+	gobDestX = obj->gobDestX;
+	gobDestY = obj->gobDestY;
+	animData->field_13 = gobDestX;
+	animData->field_14 = gobDestY;
+	destX = obj->destX;
+	destY = obj->destY;
+
+	if (animData->pathExistence == 1) {
+		dir = _vm->_map->getDirection(gobX, gobY, destX, destY);
+		if (dir == 0)
+			animData->pathExistence = 0;
+		if ((gobX == destX) && (gobY == destY))
+			animData->pathExistence = 4;
+	} else if (animData->pathExistence == 3) {
+		if ((gobX == gobDestX) && (gobY == gobDestY)) {
+			animData->pathExistence = 4;
+			destX = gobDestX;
+			destY = gobDestY;
+		} else {
+			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);
+						destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
+						destY = _vm->_map->_wayPoints[obj->nearestWayPoint].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) { // loc_10E96
+						_vm->_map->optimizePoints(obj, gobX, gobY);
+						destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
+						destY = _vm->_map->_wayPoints[obj->nearestWayPoint].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)) {
+							destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
+							destY = _vm->_map->_wayPoints[obj->nearestWayPoint].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);
+		}
+	}
+
+	obj->goblinX = gobX;
+	obj->goblinY = gobY;
+	obj->gobDestX = gobDestX;
+	obj->gobDestY = gobDestY;
+	obj->destX = destX;
+	obj->destY = destY;
+
+	switch (dir) {
+	case Map::kDirNW:
+		animData->nextState = 1;
+		if (_vm->_map->_screenWidth == 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 Map::kDirN:
+		animData->nextState = animData->curLookDir == 2 ? 2 : rotateState(2, animData->curLookDir);
+		if (_vm->_map->_screenWidth == 640) {
+			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) {
+				if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) != 10) {
+					if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY - 2) == 10)
+						animData->nextState = 42;
+					else
+						animData->nextState = 2;
+				} else
+					animData->nextState = 40;
+			} else if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20)
+				animData->nextState = 38;
+			else if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19)
+				animData->nextState = 26;
+		}
+		break;
+
+	case Map::kDirNE:
+		animData->nextState =	3;
+		if (_vm->_map->_screenWidth == 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 Map::kDirW:
+		animData->nextState = rotateState(0, animData->curLookDir);
+		break;
+
+	case Map::kDirE:
+		animData->nextState = rotateState(4, animData->curLookDir);
+		break;
+
+	case Map::kDirSW:
+		animData->nextState = 7;
+		if (_vm->_map->_screenWidth == 640) {
+			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
+				animData->nextState = 41;
+			if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY) != 10)
+				animData->nextState = 7;
+		}
+		break;
+
+	case Map::kDirS:
+		animData->nextState = animData->curLookDir == 6 ? 6 : rotateState(6, animData->curLookDir);
+		if (_vm->_map->_screenWidth == 640) {
+			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20)
+				animData->nextState = 39;
+			else if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19)
+				animData->nextState = 27;
+		}
+		break;
+
+	case Map::kDirSE:
+		animData->nextState = 5;
+		if (_vm->_map->_screenWidth == 640) {
+			if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
+				animData->nextState = 43;
+			if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY) != 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) {
+	Mult::Mult_AnimData *animData;
+	int16 gobX;
+	int16 gobY;
+	int16 animation;
+	int16 state;
+	int16 layer;
+
+	movePathFind(obj, 0, 0);
+	playSounds(obj);
+
+	animData = obj->pAnimData;
+
+	framesCount =
+		_vm->_scenery->_animations[(int)animData->animation].layers[animData->layer]->framesCount;
+
+	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;
+	}
+
+	switch(animData->state) {
+	case 0:
+	case 1:
+	case 7:
+	case 13:
+	case 16:
+	case 23:
+		// loc_11452
+		animData->curLookDir = 0;
+		break;
+
+	case 2:
+	case 15:
+	case 18:
+	case 21:
+		animData->curLookDir = 2;
+		break;
+
+	case 3:
+	case 4:
+	case 5:
+	case 12:
+	case 19:
+	case 22:
+		animData->curLookDir = 4;
+		break;
+
+	case 6:
+	case 14:
+	case 17:
+	case 20:
+		animData->curLookDir = 6;
+		break;
+
+	case 8:
+	case 9:
+	case 28:
+	case 29:
+		if (animData->pathExistence == 4)
+			animData->pathExistence = 5;
+		break;
+	}
+
+	if ((animData->field_F != -1) && (animData->frame == framesCount) &&
+			(animData->field_F != animData->state)) { // loc_114B6
+		animData->nextState = animData->field_F;
+		animData->field_F = -1;
+		animData->state = animData->nextState;
+		*obj->pPosX +=
+			_vm->_scenery->_animations[animData->animation].layers[animData->layer]->animDeltaX;
+		*obj->pPosY +=
+			_vm->_scenery->_animations[animData->animation].layers[animData->layer]->animDeltaY;
+		animation = obj->goblinStates[animData->nextState][0].animation;
+		layer = obj->goblinStates[animData->nextState][0].layer;
+		animData->layer = layer;
+		animData->animation = animation;
+		animData->frame = 0;
+	} else {
+		if (((animData->state >= 0) && (animData->state < 8)) ||
+				(animData->state == 38) || (animData->state == 39)) { // loc_115C4
+			state = animData->nextState;
+			if (animData->frame == ((framesCount + 1) / 2)) {
+				gobX = obj->goblinX;
+				gobY = obj->goblinY;
+				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;
+				}
+				if (animData->state != state) {
+					animation = obj->goblinStates[state][0].animation;
+					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);
+					if (_vm->_map->_bigTiles)
+						*obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
+							(_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (gobY + 1) / 2;
+					else
+						*obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
+							(_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
+					*obj->pPosX = gobX * _vm->_map->_tilesWidth;
+				}
+			}
+		}
+
+		if (animData->frame >= framesCount) {
+			state = animData->nextState;
+			animation = obj->goblinStates[state][0].animation;
+			layer = obj->goblinStates[state][0].layer;
+			animData->layer = layer;
+			animData->animation = animation;
+			animData->frame = 0;
+			animData->state = state;
+			gobX = obj->goblinX;
+			gobY = obj->goblinY;
+			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;
+			}
+			_vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
+			if (_vm->_map->_bigTiles)
+				*obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
+					(_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (gobY + 1) / 2;
+			else
+				*obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
+					(_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
+			*obj->pPosX = gobX * _vm->_map->_tilesWidth;
+		}
+	}
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/inter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v2.cpp	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/inter_v2.cpp	2006-06-07 18:49:20 UTC (rev 22979)
@@ -715,7 +715,7 @@
 void Inter_v2::o2_stub0x54(void) {
 	int16 index = _vm->_parse->parseValExpr();
 
-	_vm->_mult->_objects[index].pAnimData->field_12 = 4;
+	_vm->_mult->_objects[index].pAnimData->pathExistence = 4;
 }
 
 void Inter_v2::o2_stub0x80(void) {
@@ -958,10 +958,25 @@
 void Inter_v2::o2_moveGoblin(void) {
 	Mult::Mult_Object *obj;
 	Mult::Mult_AnimData *objAnim;
-	int16 destX = _vm->_parse->parseValExpr();
-	int16 destY = _vm->_parse->parseValExpr();
-	int16 index = _vm->_parse->parseValExpr();
+	int16 destX;
+	int16 destY;
+	int16 index;
+	int16 mouseX;
+	int16 mouseY;
+	int16 gobDestX;
+	int16 gobDestY;
+	int16 mapWidth;
+	int16 mapHeight;
+	int16 di;
+	int16 si;
+	int16 var_1E;
+	int16 var_20;
+	int i;
 
+	destX = _vm->_parse->parseValExpr();
+	destY = _vm->_parse->parseValExpr();
+	index = _vm->_parse->parseValExpr();
+
 	obj = &_vm->_mult->_objects[index];
 	objAnim = obj->pAnimData;
 
@@ -971,10 +986,89 @@
 	objAnim->field_14 = destY;
 	if (objAnim->someFlag != 0) {
 		if ((destX == -1) && (destY == -1)) {
-			warning("STUB: Gob2 drawOperation moveGoblin (%d %d %d), someFlag: %d", destX, destY, index, objAnim->someFlag);
+			mouseX = _vm->_global->_inter_mouseX;
+			mouseY = _vm->_global->_inter_mouseY;
+			if (_vm->_map->_bigTiles)
+				mouseY += ((_vm->_global->_inter_mouseX / _vm->_map->_tilesHeight) + 1) / 2;
+			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;
+			objAnim->field_13 = gobDestX;
+			objAnim->field_14 = gobDestY;
+			if (objAnim->field_13 == -1) {
+				objAnim->field_13 = obj->goblinX;
+				obj->gobDestX = obj->goblinX;
+			}
+			if (objAnim->field_14 == -1) {
+				objAnim->field_14 = obj->goblinY;
+				obj->gobDestY = obj->goblinY;
+			}
 		}
 	}
-	_vm->_goblin->initiateMove(index);
+	_vm->_goblin->initiateMove(obj);
 }
 
 void Inter_v2::o2_writeGoblinPos(void) {
@@ -1042,9 +1136,9 @@
 			obj->goblinY = val;
 			*obj->pPosX *= _vm->_map->_tilesWidth;
 			objAnim->field_15 = objAnim->unknown;
-			objAnim->field_E = -1;
+			objAnim->nextState = -1;
 			objAnim->field_F = -1;
-			objAnim->field_12 = 0;
+			objAnim->pathExistence = 0;
 			objAnim->state = objAnim->layer;
 			objAnim->layer = obj->goblinStates[objAnim->state][0].layer;
 			objAnim->animation = obj->goblinStates[objAnim->state][0].animation;
@@ -1065,7 +1159,7 @@
 			obj = &_vm->_mult->_objects[objIndex];
 			objAnim = obj->pAnimData;
 
-			objAnim->field_E = -1;
+			objAnim->nextState = -1;
 			objAnim->field_F = -1;
 			objAnim->state = objAnim->layer;
 			objAnim->layer = obj->goblinStates[objAnim->state][0].layer;

Modified: scummvm/trunk/engines/gob/map.cpp
===================================================================
--- scummvm/trunk/engines/gob/map.cpp	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/map.cpp	2006-06-07 18:49:20 UTC (rev 22979)
@@ -248,13 +248,9 @@
 	return lnearestWayPoint;
 }
 
-int16 Map::checkDirectPath(int16 index, int16 x0, int16 y0, int16 x1, int16 y1) {
-	Mult::Mult_Object *obj = 0;
+int16 Map::checkDirectPath(Mult::Mult_Object *obj, int16 x0, int16 y0, int16 x1, int16 y1) {
 	uint16 dir;
 
-	if ((index >= 0) && (index < _vm->_mult->_objCount))
-		obj = &_vm->_mult->_objects[index];
-
 	while (1) {
 		dir = getDirection(x0, y0, x1, y1);
 
@@ -329,7 +325,7 @@
 			nextLink = 1;
 
 		if (nextLink != 0) {
-			if (checkDirectPath(-1, x0, y0, x1, y1) == 1)
+			if (checkDirectPath(0, x0, y0, x1, y1) == 1)
 				return 1;
 
 			nextLink = 0;
@@ -348,7 +344,7 @@
 		}
 		if (i0 == i1 && _wayPoints[i0].x == x0
 		    && _wayPoints[i0].y == y0) {
-			if (checkDirectPath(-1, x0, y0, x1, y1) == 1)
+			if (checkDirectPath(0, x0, y0, x1, y1) == 1)
 				return 1;
 			return 0;
 		}

Modified: scummvm/trunk/engines/gob/map.h
===================================================================
--- scummvm/trunk/engines/gob/map.h	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/map.h	2006-06-07 18:49:20 UTC (rev 22979)
@@ -24,6 +24,7 @@
 #define GOB_MAP_H
 
 #include "gob/util.h"
+#include "gob/mult.h"
 
 namespace Gob {
 
@@ -87,7 +88,7 @@
 	void placeItem(int16 x, int16 y, int16 id);
 
 	int16 getDirection(int16 x0, int16 y0, int16 x1, int16 y1);
-	int16 checkDirectPath(int16 index, int16 x0, int16 y0, int16 x1, int16 y1);
+	int16 checkDirectPath(Mult::Mult_Object *obj, int16 x0, int16 y0, int16 x1, int16 y1);
 	int16 checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1);
 	void loadItemToObject(void);
 	void loadDataFromAvo(char *dest, int16 size);
@@ -97,9 +98,9 @@
 	virtual void setPass(int x, int y, int8 pass, int heightOff = -1) = 0;
 
 	virtual void loadMapObjects(char *avjFile) = 0;
-	virtual void findNearestToGob(int16 index) = 0;
-	virtual void findNearestToDest(int16 index) = 0;
-	virtual void optimizePoints(int16 index, int16 x, int16 y) = 0;
+	virtual void findNearestToGob(Mult::Mult_Object *obj) = 0;
+	virtual void findNearestToDest(Mult::Mult_Object *obj) = 0;
+	virtual void optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) = 0;
 
 	Map(GobEngine *vm);
 	virtual ~Map() {};
@@ -115,9 +116,9 @@
 class Map_v1 : public Map {
 public:
 	virtual void loadMapObjects(char *avjFile);
-	virtual void optimizePoints(int16 index, int16 x, int16 y);
-	virtual void findNearestToGob(int16 index);
-	virtual void findNearestToDest(int16 index);
+	virtual void findNearestToGob(Mult::Mult_Object *obj);
+	virtual void findNearestToDest(Mult::Mult_Object *obj);
+	virtual void optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y);
 
 	virtual inline int8 getPass(int x, int y, int heightOff = -1) {
 		return _passMap[y * _mapWidth + x];
@@ -134,9 +135,9 @@
 class Map_v2 : public Map_v1 {
 public:
 	virtual void loadMapObjects(char *avjFile);
-	virtual void optimizePoints(int16 index, int16 x, int16 y);
-	virtual void findNearestToGob(int16 index);
-	virtual void findNearestToDest(int16 index);
+	virtual void findNearestToGob(Mult::Mult_Object *obj);
+	virtual void findNearestToDest(Mult::Mult_Object *obj);
+	virtual void optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y);
 
 	virtual inline int8 getPass(int x, int y, int heightOff = -1) {
 		if (heightOff == -1)

Modified: scummvm/trunk/engines/gob/map_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/map_v1.cpp	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/map_v1.cpp	2006-06-07 18:49:20 UTC (rev 22979)
@@ -389,32 +389,32 @@
 	}
 }
 
-void Map_v1::optimizePoints(int16 index, int16 x, int16 y) {
+void Map_v1::optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) {
 	int16 i;
 
 	if (_nearestWayPoint < _nearestDest) {
 		for (i = _nearestWayPoint; i <= _nearestDest; i++) {
-			if (checkDirectPath(-1, _curGoblinX, _curGoblinY,
+			if (checkDirectPath(0, _curGoblinX, _curGoblinY,
 				_wayPoints[i].x, _wayPoints[i].y) == 1)
 				_nearestWayPoint = i;
 		}
 	} else if (_nearestWayPoint > _nearestDest) {
 		for (i = _nearestWayPoint; i >= _nearestDest; i--) {
-			if (checkDirectPath(-1, _curGoblinX, _curGoblinY,
+			if (checkDirectPath(0, _curGoblinX, _curGoblinY,
 				_wayPoints[i].x, _wayPoints[i].y) == 1)
 				_nearestWayPoint = i;
 		}
 	}
 }
 
-void Map_v1::findNearestToGob(int16 index) {
+void Map_v1::findNearestToGob(Mult::Mult_Object *obj) {
 	int16 wayPoint = findNearestWayPoint(_curGoblinX, _curGoblinY);
 
 	if (wayPoint != -1)
 		_nearestWayPoint = wayPoint;
 }
 
-void Map_v1::findNearestToDest(int16 index) {
+void Map_v1::findNearestToDest(Mult::Mult_Object *obj) {
 	int16 wayPoint = findNearestWayPoint(_destX, _destY);
 
 	if (wayPoint != -1)

Modified: scummvm/trunk/engines/gob/map_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/map_v2.cpp	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/map_v2.cpp	2006-06-07 18:49:20 UTC (rev 22979)
@@ -60,7 +60,7 @@
 	char *dataPtrBak;
 	char *dataPtrBak2;
 	int8 statesMask[102];
-	Goblin::Gob2_State *statesPtr;
+	Mult::Mult_GobState *statesPtr;
 
 	var = _vm->_parse->parseVarIndex();
 	variables = _vm->_global->_inter_variables + var;
@@ -138,8 +138,8 @@
 	_vm->_goblin->_gobsCount = tmp;
 	for (i = 0; i < _vm->_goblin->_gobsCount; i++) {
 		memset(statesMask, -1, 101);
-		_vm->_mult->_objects[i].goblinStates = new Goblin::Gob2_State*[101];
-		memset(_vm->_mult->_objects[i].goblinStates, 0, 101 * sizeof(Goblin::Gob2_State *));
+		_vm->_mult->_objects[i].goblinStates = new Mult::Mult_GobState*[101];
+		memset(_vm->_mult->_objects[i].goblinStates, 0, 101 * sizeof(Mult::Mult_GobState *));
 		memcpy(statesMask, dataPtr, 100);
 		dataPtr += 100;
 		dataPtrBak2 = dataPtr;
@@ -153,7 +153,7 @@
 				dataPtr += numData * 9;
 			}
 		}
-		statesPtr = new Goblin::Gob2_State[statesCount];
+		statesPtr = new Mult::Mult_GobState[statesCount];
 		_vm->_mult->_objects[i].goblinStates[0] = statesPtr;
 		dataPtr = dataPtrBak2;
 		for (j = 0; j < 100; j++) {
@@ -165,18 +165,17 @@
 				_vm->_mult->_objects[i].goblinStates[state][0].layer = READ_LE_UINT16(dataPtr);
 				dataPtr += 2;
 				numData = *dataPtr++;
-				_vm->_mult->_objects[i].goblinStates[state][0].field_4 = numData;
-				for (k = 0; k < numData; k++) {
+				_vm->_mult->_objects[i].goblinStates[state][0].dataCount = numData;
+				for (k = 1; k <= numData; k++) {
 					dataPtr++;
-					_vm->_mult->_objects[i].goblinStates[state][k].animation = *((byte *) dataPtr) << 8;
+					_vm->_mult->_objects[i].goblinStates[state][k].sndItem = *dataPtr;
 					dataPtr += 2;
-					_vm->_mult->_objects[i].goblinStates[state][k].animation += *((byte *) dataPtr);
+					_vm->_mult->_objects[i].goblinStates[state][k].sndFrame = *dataPtr;
 					dataPtr += 2;
-					_vm->_mult->_objects[i].goblinStates[state][k].layer = *((byte *) dataPtr) << 8;
+					_vm->_mult->_objects[i].goblinStates[state][k].freq = READ_LE_UINT16(dataPtr);
 					dataPtr += 2;
-					_vm->_mult->_objects[i].goblinStates[state][k].layer += *((byte *) dataPtr);
-					_vm->_mult->_objects[i].goblinStates[state][k].field_4 = READ_LE_UINT16(dataPtr);
-					dataPtr += 2;
+					_vm->_mult->_objects[i].goblinStates[state][k].repCount = *dataPtr++;
+					_vm->_mult->_objects[i].goblinStates[state][k].speaker = *dataPtr++;
 					statesPtr++;
 				}
 			}
@@ -188,39 +187,33 @@
 		_vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
 }
 
-void Map_v2::findNearestToGob(int16 index) {
-	Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+void Map_v2::findNearestToGob(Mult::Mult_Object *obj) {
 	int16 wayPoint = findNearestWayPoint(obj->goblinX, obj->goblinY);
 
 	if (wayPoint != -1)
 		obj->nearestWayPoint = wayPoint;
 }
 
-void Map_v2::findNearestToDest(int16 index) {
-	Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+void Map_v2::findNearestToDest(Mult::Mult_Object *obj) {
 	int16 wayPoint = findNearestWayPoint(obj->destX, obj->destY);
 
 	if (wayPoint != -1)
 		obj->nearestDest = wayPoint;
 }
 
-void Map_v2::optimizePoints(int16 index, int16 x, int16 y) {
-	Mult::Mult_Object *obj;
+void Map_v2::optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) {
 	int i;
-	
 	int16 var_2;
 
-	obj = &_vm->_mult->_objects[index];
-
 	if (obj->nearestWayPoint < obj->nearestDest) {
 		var_2 = obj->nearestWayPoint;
 		for (i = obj->nearestWayPoint; i <= obj->nearestDest; i++) {
-			if (checkDirectPath(index, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
+			if (checkDirectPath(obj, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
 				obj->nearestWayPoint = i;
 		}
 	} else {
 		for (i = obj->nearestWayPoint; i >= obj->nearestDest && _wayPoints[i].field_2 != 1; i--) {
-			if (checkDirectPath(index, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
+			if (checkDirectPath(obj, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
 				obj->nearestWayPoint = i;
 		}
 	}

Modified: scummvm/trunk/engines/gob/mult.h
===================================================================
--- scummvm/trunk/engines/gob/mult.h	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/mult.h	2006-06-07 18:49:20 UTC (rev 22979)
@@ -26,7 +26,6 @@
 #include "gob/gob.h"
 #include "gob/sound.h"
 #include "gob/video.h"
-#include "gob/goblin.h"
 
 namespace Gob {
 
@@ -52,16 +51,28 @@
 		int8 somethingFrame;     // New in GOB2
 		int8 someFlag;           // New in GOB2
 		int8 state;              // New in GOB2
-		int8 field_E;            // New in GOB2
+		int8 nextState;          // New in GOB2
 		int8 field_F;            // New in GOB2
-		int8 field_10;           // New in GOB2
-		int8 field_12;           // New in GOB2
+		int8 curLookDir;         // New in GOB2
+		int8 pathExistence;      // New in GOB2
 		int8 field_13;           // New in GOB2
 		int8 field_14;           // New in GOB2
 		int8 field_15;           // New in GOB2
+		int8 field_16;           // New in GOB2
 		int8 field_17;           // New in GOB2
 	} GCC_PACK;
 
+	struct Mult_GobState {
+		int16 animation; // .
+		int16 layer;     // |- [0]
+		int16 dataCount; // '
+		int8 sndItem;    // .
+		uint8 sndFrame;  // |
+		int16 freq;      // |- [1+]
+		int8 repCount;   // |
+		uint8 speaker;   // '
+	};
+
 	struct Mult_Object {
 		int32 *pPosX;
 		int32 *pPosY;
@@ -71,20 +82,20 @@
 		int16 lastRight;
 		int16 lastTop;
 		int16 lastBottom;
-		int8 someFlag;                     // New in GOB2
-		int16 somethingLeft;               // New in GOB2
-		int16 somethingTop;                // New in GOB2
-		int16 somethingRight;              // New in GOB2
-		int16 somethingBottom;             // New in GOB2
-		int8 goblinX;                      // New in GOB2
-		int8 goblinY;                      // New in GOB2
-		int8 destX;                        // New in GOB2
-		int8 destY;                        // New in GOB2
-		int8 gobDestX;                     // New in GOB2
-		int8 gobDestY;                     // New in GOB2
-		int8 nearestWayPoint;              // New in GOB2
-		int8 nearestDest;                  // New in GOB2
-		Goblin::Gob2_State **goblinStates; // New in GOB2
+		int8 someFlag;                      // New in GOB2
+		int16 somethingLeft;                // New in GOB2
+		int16 somethingTop;                 // New in GOB2
+		int16 somethingRight;               // New in GOB2
+		int16 somethingBottom;              // New in GOB2
+		int8 goblinX;                       // New in GOB2
+		int8 goblinY;                       // New in GOB2
+		int8 destX;                         // New in GOB2
+		int8 destY;                         // New in GOB2
+		int8 gobDestX;                      // New in GOB2
+		int8 gobDestY;                      // New in GOB2
+		int8 nearestWayPoint;               // New in GOB2
+		int8 nearestDest;                   // New in GOB2
+		Mult::Mult_GobState **goblinStates; // New in GOB2
 	};
 
 	struct Mult_StaticKey {
@@ -346,6 +357,7 @@
 
 	void sub_62DD(int16 index);
 	void sub_6A35(void);
+	void sub_10C87(Mult_Object *obj);
 };
 
 }				// End of namespace Gob

Modified: scummvm/trunk/engines/gob/mult_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/mult_v2.cpp	2006-06-07 09:52:44 UTC (rev 22978)
+++ scummvm/trunk/engines/gob/mult_v2.cpp	2006-06-07 18:49:20 UTC (rev 22979)
@@ -35,6 +35,7 @@
 #include "gob/palanim.h"
 #include "gob/parse.h"
 #include "gob/music.h"
+#include "gob/map.h"
 
 namespace Gob {
 
@@ -309,7 +310,9 @@
 void Mult_v2::multSub(uint16 multindex) {
 	uint16 flags;
 	int16 expr;
+	int16 textFrame;
 	int i;
+	int j;
 	int16 di;
 
 	flags = multindex;
@@ -353,7 +356,56 @@
 	expr = _vm->_parse->parseValExpr();
 	_multData2->animKeysIndices1[di] = expr;
 	_multData2->animKeysIndices2[di] = expr;
-	// loc_5D0E
+	
+	WRITE_VAR(18 + di, expr);
+	if (expr == -1) { // loc_5D0E
+		if (_objects)
+			for (i = 0; i < 4; i++)
+				if ((_multData2->field_124[di][i] != -1) && (_multData2->field_124[di][i] != 1024))
+					_objects[_multData2->field_124[di][i]].pAnimData->animType =
+						_objects[_multData2->field_124[di][i]].pAnimData->field_17;
+	} else { // loc_5DDC
+		if (_multData2->field_156 == 1) {
+			_multData2->field_157[di] = 32000;
+			for (i = 0; i < _multData2->textKeysCount; i++) {
+				textFrame = _multData2->textKeys[i].frame;
+				if ((textFrame > _multData2->animKeysIndices2[di]) &&
+						(textFrame < _multData2->field_157[di])) {
+					_multData2->field_157[di] = textFrame;
+				}
+			}
+		} else {
+			_multData2->field_157[di] = 0;
+			for (i = 0; i < _multData2->textKeysCount; i++) {
+				textFrame = _multData2->textKeys[i].frame;
+				if ((textFrame < _multData2->animKeysIndices2[di]) &&
+						(textFrame > _multData2->field_157[di])) {
+					_multData2->field_157[di] = textFrame;
+				}
+			}
+		}
+		if (_objects) {
+			for (i = 0; i < 4; i++) {
+				if ((_multData2->field_124[di][i] != -1) && (_multData2->field_124[di][i] != 1024))
+					_objects[_multData2->field_124[di][i]].pAnimData->field_17 =
+						_objects[_multData2->field_124[di][i]].pAnimData->animType;
+			}
+		}
+		// loc_5FCF
+		for (i = 0; i < 4; i++ /* var_C += 2, var_E += 4*/) {
+			_multData2->field_15F[di][i] = 0;
+			for (j = 0; j < _multData2->animKeysCount[i]; j++) {
+				if (_multData2->animKeys[i][j].frame >= _multData2->animKeysIndices2[di])
+					_multData2->field_15F[di][i] = j;
+			}
+		}
+		if (_multData2->field_156 == -1) { // loc_60CF
+			warning("Mult_v2::multSub(), somepointer05 and somepointer05indices");
+		}
+		// loc_6187
+		warning("Mult_v2::multSub(), somepointer05");
+	}
+
 	warning("GOB2 Stub! Mult_v2::multSub()");
 }
 
@@ -412,14 +464,6 @@
 			_animArrayY = new int32[_objCount];
 
 			_animArrayData = new Mult_AnimData[_objCount];
-			// TODO: Delete that after the code that initializes these fields exists!
-			int i;
-			for (i = 0; i < _objCount; i++) {
-				_animArrayData[i].field_13 = 0;
-				_animArrayData[i].field_14 = 0;
-				_animArrayData[i].field_17 = 0;
-			}
-			// ---'
 
 			for (_counter = 0; _counter < _objCount; _counter++) {
 				multObj = &_objects[_counter];
@@ -1277,9 +1321,9 @@
 				}
 			}
 			else if (animData1->animType == 100)
-				warning("GOB2 Stub! sub_10C87(animObj1);");
+				_vm->_goblin->moveAdvance(animObj1, 0, 0, 0);
 			else if (animData1->animType == 101)
-				warning("GOB2 Stub! sub_11984(animObj1);");
+				_vm->_goblin->sub_11984(animObj1);
 		} else
 			animObj1->tick++;
 	}


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.





More information about the Scummvm-git-logs mailing list