[Scummvm-cvs-logs] SF.net SVN: scummvm:[39582] scummvm/trunk/engines/kyra

athrxx at users.sourceforge.net athrxx at users.sourceforge.net
Sat Mar 21 15:30:26 CET 2009


Revision: 39582
          http://scummvm.svn.sourceforge.net/scummvm/?rev=39582&view=rev
Author:   athrxx
Date:     2009-03-21 14:30:25 +0000 (Sat, 21 Mar 2009)

Log Message:
-----------
LOL: The guards will now attack you when you throw certain items at them. They can't do any damage though, since this isn't implemented yet.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/gui_lol.cpp
    scummvm/trunk/engines/kyra/items_lol.cpp
    scummvm/trunk/engines/kyra/lol.cpp
    scummvm/trunk/engines/kyra/lol.h
    scummvm/trunk/engines/kyra/scene_lol.cpp
    scummvm/trunk/engines/kyra/script_lol.cpp
    scummvm/trunk/engines/kyra/sprites_lol.cpp
    scummvm/trunk/engines/kyra/staticres.cpp

Modified: scummvm/trunk/engines/kyra/gui_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/gui_lol.cpp	2009-03-21 02:58:01 UTC (rev 39581)
+++ scummvm/trunk/engines/kyra/gui_lol.cpp	2009-03-21 14:30:25 UTC (rev 39582)
@@ -943,7 +943,7 @@
 }
 
 int LoLEngine::clickedUpArrow(Button *button) {
-	if (button->data2Val2 && !(_unkGameFlag & 4))
+	if (button->data2Val2 && !_floatingCursorsEnabled)
 		return 0;
 
 	moveParty(_currentDirection, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 0, 80);
@@ -952,7 +952,7 @@
 }
 
 int LoLEngine::clickedDownArrow(Button *button) {
-	if (button->data2Val2 && !(_unkGameFlag & 4))
+	if (button->data2Val2 && !_floatingCursorsEnabled)
 		return 0;
 
 	moveParty(_currentDirection ^ 2, 0, 1, 83);
@@ -961,7 +961,7 @@
 }
 
 int LoLEngine::clickedLeftArrow(Button *button) {
-	if (button->data2Val2 && !(_unkGameFlag & 4))
+	if (button->data2Val2 && !_floatingCursorsEnabled)
 		return 0;
 
 	moveParty((_currentDirection - 1) & 3, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 2, 82);
@@ -970,7 +970,7 @@
 }
 
 int LoLEngine::clickedRightArrow(Button *button) {
-	if (button->data2Val2 && !(_unkGameFlag & 4))
+	if (button->data2Val2 && !_floatingCursorsEnabled)
 		return 0;
 
 	moveParty((_currentDirection + 1) & 3, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 3, 84);
@@ -979,7 +979,7 @@
 }
 
 int LoLEngine::clickedTurnLeftArrow(Button *button) {
-	if (button->data2Val2 && !(_unkGameFlag & 4))
+	if (button->data2Val2 && !_floatingCursorsEnabled)
 		return 0;
 
 	gui_toggleButtonDisplayMode(79, 1);
@@ -1001,7 +1001,7 @@
 }
 
 int LoLEngine::clickedTurnRightArrow(Button *button) {
-	if (button->data2Val2 && !(_unkGameFlag & 4))
+	if (button->data2Val2 && !_floatingCursorsEnabled)
 		return 0;
 
 	gui_toggleButtonDisplayMode(81, 1);

Modified: scummvm/trunk/engines/kyra/items_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/items_lol.cpp	2009-03-21 02:58:01 UTC (rev 39581)
+++ scummvm/trunk/engines/kyra/items_lol.cpp	2009-03-21 14:30:25 UTC (rev 39582)
@@ -413,7 +413,7 @@
 }
 
 void LoLEngine::objectFlightProcessHits(FlyingObject *t, int x, int y, int objectOnNextBlock) {
-	int r = 0;
+	uint16 r = 0;
 
 	if (objectOnNextBlock == 1) {
 		runLevelScriptCustom(calcNewBlockPosition(_itemsInPlay[t->item].blockPropertyIndex, t->direction >> 1), 0x8000, -1, t->item, 0, 0);
@@ -432,7 +432,7 @@
 			return;
 
 		} else {
-			r = flyingObjectHitMonsters(x, y);
+			r = getClosestMonster(x, y);
 		}
 
 	} else if (objectOnNextBlock == 4) {
@@ -445,25 +445,13 @@
 			return;
 
 		} else {
-			r = flyingObjectHitParty(x, y);
+			r = getClosestPartyMember(x, y);
 		}
 	}
 
 	runItemScript(t->charNum, t->item, 0x8000, r, 0);
 }
 
-uint16 LoLEngine::flyingObjectHitMonsters(int x, int y) {
-	////////////
-	// TODO
-	return 0;
-}
-
-uint16 LoLEngine::flyingObjectHitParty(int x, int y) {
-	////////////
-	// TODO
-	return 0;
-}
-
 void LoLEngine::updateFlyingObjects(FlyingObject *t) {
 	int x = 0;
 	int y = 0;

Modified: scummvm/trunk/engines/kyra/lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/lol.cpp	2009-03-21 02:58:01 UTC (rev 39581)
+++ scummvm/trunk/engines/kyra/lol.cpp	2009-03-21 14:30:25 UTC (rev 39582)
@@ -149,7 +149,6 @@
 	_tempBuffer5120 = 0;
 	_flyingItems = 0;
 	_monsters = 0;
-	_unkGameFlag = 0;
 	_lastMouseRegion = 0;
 	_monsterLastWalkDirection = _monsterCountUnk = _monsterShiftAlt = 0;
 	_monsterCurBlock = 0;
@@ -206,6 +205,10 @@
 	_activeButtons = 0;
 	_preserveEvents = false;
 	_buttonList1 = _buttonList2 = _buttonList3 = _buttonList4 = _buttonList5 = _buttonList6 = _buttonList7 = _buttonList8 = 0;
+
+	_monsterDifficulty = 1;
+	_smoothScrollingEnabled = true;
+	_floatingCursorsEnabled = false;
 }
 
 LoLEngine::~LoLEngine() {
@@ -730,7 +733,7 @@
 	_compassDirection = _compassDirectionIndex = -1;
 
 	_lastMouseRegion = -1;
-	_unkGameFlag |= 0x1B;
+	
 	/*
 	_unk5 = 1;
 	_unk6 = 1;
@@ -1080,7 +1083,7 @@
 	if (index & 0x8000) {
 		// Monster
 		index &= 0x7fff;
-		c = (_monsters[index].properties->itemProtection * _monsters[index].properties->protection) >> 8;
+		c = (_monsters[index].properties->itemProtection * _monsters[index].properties->fightingStats[2]) >> 8;
 	} else {
 		// Character
 		c = _characters[index].itemsProtection + _characters[index].protection;
@@ -1521,7 +1524,7 @@
 }
 
 void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
-	if (!(_unkGameFlag & 1))
+	if (!_sound->sfxEnabled())
 		return;
 
 	if (_environmentSfx)
@@ -1560,7 +1563,7 @@
 }
 
 void LoLEngine::snd_loadSoundFile(int track) {
-	if (_unkGameFlag & 2) {
+	if (_sound->musicEnabled()) {
 		char filename[13];
 		int t = (track - 250) * 3;
 
@@ -1585,7 +1588,7 @@
 	int res = _lastMusicTrack;
 	_lastMusicTrack = track;
 
-	if (_unkGameFlag & 2) {
+	if (_sound->musicEnabled()) {
 		snd_loadSoundFile(track);
 		int t = (track - 250) * 3;
 		_sound->playTrack(_musicTrackMap[t + 2]);
@@ -1595,7 +1598,7 @@
 }
 
 int LoLEngine::snd_stopMusic() {
-	if (_unkGameFlag & 2) {
+	if (_sound->musicEnabled()) {
 		if (_sound->isPlaying()) {
 			_sound->beginFadeOut();
 			_system->delayMillis(3 * _tickLength);
@@ -1716,7 +1719,7 @@
 }
 
 const uint16 *LoLEngine::getCharacterOrMonsterStats(int id) {
-	return (id & 0x8000) ? (const uint16*)_monsters[id & 0x7fff].properties->pos : _characters[id].defaultModifiers;
+	return (id & 0x8000) ? (const uint16*)_monsters[id & 0x7fff].properties->fightingStats : _characters[id].defaultModifiers;
 }
 
 void LoLEngine::delay(uint32 millis, bool cUpdate, bool isMainLoop) {
@@ -1771,6 +1774,113 @@
 	return false;
 }
 
+int LoLEngine::battleHitSkillTest(int16 attacker, int16 target, int skill) {
+	if (target == -1)
+		return 0;
+	if (attacker == -1)
+		return 1;
+
+	if (target & 0x8000) {
+		if (_monsters[target & 0x7fff].mode >= 13)
+			return 0;
+	}
+	
+	uint16 hitChanceModifier = 0;
+	uint16 evadeChanceModifier = 0;
+	int sk = 0;
+
+	if (attacker & 0x8000) {
+		hitChanceModifier = _monsters[target & 0x7fff].properties->fightingStats[0];
+		sk = 100 - _monsters[target & 0x7fff].properties->skillLevel;
+	} else {
+		hitChanceModifier = _characters[attacker].defaultModifiers[0];		
+		uint8 m = _characters[attacker].skillModifiers[skill];
+		if (skill == 1)
+			m *= 3;
+		sk = 100 - (_characters[attacker].skillLevels[skill] + m);
+	}
+
+	if (target & 0x8000) {
+		evadeChanceModifier = _monsters[target & 0x7fff].properties->fightingStats[3];
+		_monsters[target & 0x7fff].flags |= 0x10;
+	} else {
+		evadeChanceModifier = _characters[target].defaultModifiers[3];
+	}
+
+	int r = _rnd.getRandomNumberRng(1, 100);
+	if (r >= sk)
+		return 2;
+
+	uint16 v = ((_monsterModifiers[9 + _monsterDifficulty] * evadeChanceModifier) & 0xffffff00) / hitChanceModifier;
+
+	if (r < v)
+		return 0;
+
+	return 1;
+}
+
+int LoLEngine::calcInflictableDamage(int16 attacker, int16 target, int hitType) {
+	const uint16 *s = getCharacterOrMonsterStats(attacker);
+	
+	int res = 0;
+	for (int i = 0; i < 8; i++)
+		res += calcInflictableDamagePerStat(attacker, target, s[2 + i], i, hitType);
+
+	return res;
+}
+
+void LoLEngine::battleHit_sub2(int16 target, int damageInflicted, int16 attacker, uint32 b) {
+
+}
+
+void LoLEngine::battleHit_sub3(MonsterInPlay *monster, int16 target, int16 damageInflicted) {
+
+}
+
+int LoLEngine::calcInflictableDamagePerStat(int16 attacker, int16 target, uint16 stat2m, int index, int hitType) {
+	return 1;
+}
+
+uint16 LoLEngine::getClosestMonster(int x, int y) {
+	uint16 id = 0xffff;
+	int minDist = 0x7fff;
+
+	for (int i = 0; i < 30; i++) {
+		if (_monsters[i].mode > 13)
+			continue;
+
+		int d = ABS(x - _monsters[i].x) + ABS(y - _monsters[i].y);		
+		if (d < minDist) {
+			minDist = d;
+			id = 0x8000 | i;
+		}
+	}
+
+	return id;
+}
+
+uint16 LoLEngine::getClosestPartyMember(int x, int y) {
+	uint16 id = 0xffff;
+	int minDist = 0x7fff;
+
+	for (int i = 0; i < 4; i++) {
+		if (!(_characters[i].flags & 1) || _characters[i].hitPointsCur <= 0)
+			continue;
+
+		int16 charX = 0;
+		int16 charY = 0;
+		calcCoordinatesForSingleCharacter(i, charX, charY);
+
+		int d = ABS(x - charX) + ABS(y - charY);
+		if (d < minDist) {
+			minDist = d;
+			id = i;
+		}
+	}
+
+	return id;
+}
+
 } // end of namespace Kyra
 
 #endif // ENABLE_LOL

Modified: scummvm/trunk/engines/kyra/lol.h
===================================================================
--- scummvm/trunk/engines/kyra/lol.h	2009-03-21 02:58:01 UTC (rev 39581)
+++ scummvm/trunk/engines/kyra/lol.h	2009-03-21 14:30:25 UTC (rev 39582)
@@ -62,9 +62,9 @@
 	uint16 field_34;
 	uint8 field_36;
 	uint16 itemsProtection;
-	uint16 hitPointsCur;
+	int16 hitPointsCur;
 	uint16 hitPointsMax;
-	uint16 magicPointsCur;
+	int16 magicPointsCur;
 	uint16 magicPointsMax;
 	uint8 field_41;
 	uint16 damageSuffered;
@@ -100,15 +100,13 @@
 struct MonsterProperty {
 	uint8 shapeIndex;
 	uint8 maxWidth;
-	uint16 field2[2];
-	uint16 protection;
-	uint16 unk[6];
-	uint16 *pos;
+	uint16 fightingStats[10];
 	uint16 unk2[8];
 	uint16 unk3[8];
 	uint16 itemProtection;
 	uint16 might;
-	uint8 waitTicks;
+	uint8 speedTotalWaitTicks;
+	uint8 skillLevel;
 	uint16 flags;
 	uint16 unk5;
 	uint16 unk6[5];
@@ -129,10 +127,10 @@
 	uint8 destDirection;
 	uint8 anon8;
 	uint8 anonh;
-	uint8 anon9;
+	uint8 currentSubFrame;
 
 	uint8 mode;
-	uint8 field_15;
+	int8 fightCurTick;
 	uint8 id;
 	uint8 direction;
 	uint8 facing;
@@ -140,7 +138,7 @@
 	uint8 field_1B;
 	uint8 field_1C;
 	int16 might;
-	uint8 tick;
+	uint8 speedTick;
 	uint8 type;
 	MonsterProperty *properties;
 	uint8 field_25;
@@ -163,7 +161,7 @@
 	uint8 destDirection;
 	uint8 anon8;
 	uint8 anonh;
-	uint8 anon9;
+	uint8 currentSubFrame;
 };
 
 struct ItemProperty {
@@ -266,6 +264,11 @@
 	void startup();
 	void startupNew();
 
+	// options
+	int _monsterDifficulty;
+	bool _smoothScrollingEnabled;
+	bool _floatingCursorsEnabled;
+
 	// main loop
 	void runLoop();
 	void update();
@@ -569,7 +572,9 @@
 	int olol_initMonster(EMCState *script);
 	int olol_fadeClearSceneWindow(EMCState *script);
 	int olol_fadeSequencePalette(EMCState *script);
+	int olol_dummy0(EMCState *script);
 	int olol_loadMonsterProperties(EMCState *script);
+	int olol_battleHitSkillTest(EMCState *script);
 	int olol_moveMonster(EMCState *script);
 	int olol_dialogueBox(EMCState *script);
 	int olol_giveTakeMoney(EMCState *script);
@@ -597,7 +602,7 @@
 	int olol_setPaletteBrightness(EMCState *script);
 	int olol_printMessage(EMCState *script);
 	int olol_playDialogueTalkText(EMCState *script);
-	int olol_checkForMonsterMode1(EMCState *script);
+	int olol_checkMonsterTypeHostility(EMCState *script);
 	int olol_setNextFunc(EMCState *script);
 	int olol_setDoorState(EMCState *script);
 	int olol_processButtonClick(EMCState *script);
@@ -804,7 +809,9 @@
 
 	uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction);
 	uint16 calcBlockIndex(uint16 x, uint16 y);
-	void calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs);
+	void calcCoordinates(uint16 &x, uint16 &y, int block, uint16 xOffs, uint16 yOffs);
+	void calcCoordinatesForSingleCharacter(int charNum, int16 &x, int16 &y);
+	void calcCoordinatesAddDirectionOffset(int16 &x, int16 &y, int direction);
 
 	int clickedWallShape(uint16 block, uint16 direction);
 	int clicked2(uint16 block, uint16 direction);
@@ -906,8 +913,7 @@
 
 	int _lastMouseRegion;
 	int _seqWindowX1, _seqWindowY1,	_seqWindowX2, _seqWindowY2, _seqTrigger;
-	uint8 _unkGameFlag;
-
+	
 	uint8 *_tempBuffer5120;
 	
 	const char *const * _levelDatList;
@@ -979,8 +985,6 @@
 	void processObjectFlight(FlyingObject *t, int x, int y);
 	void updateObjectFlightPosition(FlyingObject *t);
 	void objectFlightProcessHits(FlyingObject *t, int x, int y, int objectOnNextBlock);
-	uint16 flyingObjectHitMonsters(int x, int y);
-	uint16 flyingObjectHitParty(int x, int y);
 	void updateFlyingObjects(FlyingObject *t);	
 
 	void assignItemToBlock(uint16 *assignedBlockObjects, int id);
@@ -1022,11 +1026,12 @@
 	void loadMonsterShapes(const char *file, int monsterIndex, int b);
 	void releaseMonsterShapes(int monsterIndex);
 	int disableMonstersForBlock(int block);
-	void setMonsterMode(MonsterInPlay *monster, int a);
+	void setMonsterMode(MonsterInPlay *monster, int mode);
+	bool updateMonsterAdjustBlocks(MonsterInPlay *monster);
 	void placeMonster(MonsterInPlay *monster, uint16 x, uint16 y);
 	int calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2);
 	void setMonsterDirection(MonsterInPlay *monster, int dir);
-	void cmzS3(MonsterInPlay *monster);
+	void monsterDropItems(MonsterInPlay *monster);
 	void removeAssignedObjectFromBlock(LevelBlockProperty *l, int id);
 	void removeDrawObjectFromBlock(LevelBlockProperty *l, int id);
 	void assignMonsterToBlock(uint16 *assignedBlockObjects, int id);
@@ -1042,7 +1047,7 @@
 	void reassignDrawObjects(uint16 direction, uint16 itemIndex, LevelBlockProperty *l, bool flag);
 	void redrawSceneItem();
 	int calcItemMonsterPosition(ItemInPlay *i, uint16 direction);
-	void recalcSpritePosition(uint16 partyX, uint16 partyY, int &itemX, int &itemY, uint16 direction);
+	void calcSpriteRelPosition(uint16 x1, uint16 y1, int &x2, int &y2, uint16 direction);
 	void drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags);
 	void drawDoorOrMonsterShape(uint8 *shape, uint8 *table, int x, int y, int flags, const uint8 *ovl);
 	uint8 *drawItemOrMonster(uint8 *shape, uint8 *ovl, int x, int y, int fineX, int fineY, int flags, int tblValue, bool flip);
@@ -1051,11 +1056,16 @@
 	void updateMonster(MonsterInPlay *monster);
 	void moveMonster(MonsterInPlay *monster);
 	void walkMonster(MonsterInPlay *monster);
+	bool chasePartyWithDistanceAttacks(MonsterInPlay *monster);
+	void chasePartyWithCloseAttacks(MonsterInPlay *monster);
 	int walkMonsterCalcNextStep(MonsterInPlay *monster);
 	int getMonsterDistance(uint16 block1, uint16 block2);
 	int walkMonster_s3(uint16 monsterBlock, int direction, int distance, uint16 curBlock);
 	int walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk);
 	void getNextStepCoords(int16 monsterX, int16 monsterY, int &newX, int &newY, uint16 direction);
+	void rearrangeAttackingMonster(MonsterInPlay *monster);
+	void moveStrayingMonster(MonsterInPlay *monster);
+	void mode13sub(MonsterInPlay *monster);
 
 	MonsterInPlay *_monsters;
 	MonsterProperty *_monsterProperties;
@@ -1093,6 +1103,16 @@
 	uint8 *_pageBuffer2;
 	uint32 _rndSpecial;
 
+	// fight
+	int battleHitSkillTest(int16 attacker, int16 target, int skill);
+	int calcInflictableDamage(int16 attacker, int16 target, int hitType);
+	void battleHit_sub2(int16 target, int damageInflicted, int16 attacker, uint32 b);
+	void battleHit_sub3(MonsterInPlay *monster, int16 target, int16 damageInflicted);
+	int calcInflictableDamagePerStat(int16 attacker, int16 target, uint16 stat2m, int index, int hitType);
+	
+	uint16 getClosestMonster(int x, int y);
+	uint16 getClosestPartyMember(int x, int y);
+
 	// spells
 	bool notEnoughMagic(int charNum, int spellNum, int spellLevel);
 

Modified: scummvm/trunk/engines/kyra/scene_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/scene_lol.cpp	2009-03-21 02:58:01 UTC (rev 39581)
+++ scummvm/trunk/engines/kyra/scene_lol.cpp	2009-03-21 14:30:25 UTC (rev 39582)
@@ -273,7 +273,7 @@
 		}
 	}
 
-	loadCMZ_Sub(tmpLvlVal, (_unkGameFlag & 0x30) >> 4);
+	loadCMZ_Sub(tmpLvlVal, _monsterDifficulty);
 
 	delete[] cmzdata;
 }
@@ -654,11 +654,43 @@
 	return ((y & 0xff00) >> 3) | (x >> 8);
 }
 
-void LoLEngine::calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs) {
+void LoLEngine::calcCoordinates(uint16 &x, uint16 &y, int block, uint16 xOffs, uint16 yOffs) {
 	x = (block & 0x1f) << 8 | xOffs;
 	y = ((block & 0xffe0) << 3) | yOffs;
 }
 
+void LoLEngine::calcCoordinatesForSingleCharacter(int charNum, int16 &x, int16 &y) {
+	static const uint8 xOffsets[] = {  0x80, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x40, 0x80, 0xC0 };
+	int c = countActiveCharacters();
+	if (!c)
+		return;
+
+	c = (c - 1) * 3 + charNum;
+
+	x = xOffsets[c];
+	y = 0x80;
+
+	calcCoordinatesAddDirectionOffset(x, y, _currentDirection);
+
+	x |= (_partyPosX & 0xff00);
+	y |= (_partyPosY & 0xff00);
+}
+
+void LoLEngine::calcCoordinatesAddDirectionOffset(int16 &x, int16 &y, int direction) {
+	if (!direction)
+		return;
+
+	if (direction & 1)
+		SWAP(x, y);
+
+	if (direction == 1)
+		y = (y - 256) * -1;
+
+	if (direction == 3) {
+		x = (x - 256) * -1;
+	}
+}
+
 bool LoLEngine::checkBlockPassability(uint16 block, uint16 direction) {
 	if (testWallFlag(block, direction, 1))
 		return false;
@@ -825,7 +857,7 @@
 }
 
 void LoLEngine::movePartySmoothScrollBlocked(int speed) {
-	if (!(_unkGameFlag & 8) || ((_unkGameFlag & 8) && _hideInventory))
+	if (!_smoothScrollingEnabled || (_smoothScrollingEnabled && _hideInventory))
 		return;
 
 	_screen->backupSceneWindow(_sceneDrawPage2 == 2 ? 2 : 6, 6);
@@ -863,7 +895,7 @@
 }
 
 void LoLEngine::movePartySmoothScrollUp(int speed) {
-	if (!(_unkGameFlag & 8) || ((_unkGameFlag & 8) && _hideInventory))
+	if (!_smoothScrollingEnabled || (_smoothScrollingEnabled && _hideInventory))
 		return;
 
 	int d = 0;
@@ -908,7 +940,7 @@
 }
 
 void LoLEngine::movePartySmoothScrollDown(int speed) {
-	if (!(_unkGameFlag & 8))
+	if (!_smoothScrollingEnabled)
 		return;
 
 	//int d = smoothScrollDrawSpecialShape(2);
@@ -943,7 +975,7 @@
 }
 
 void LoLEngine::movePartySmoothScrollLeft(int speed) {
-	if (!(_unkGameFlag & 8))
+	if (!_smoothScrollingEnabled)
 		return;
 
 	speed <<= 1;
@@ -969,7 +1001,7 @@
 }
 
 void LoLEngine::movePartySmoothScrollRight(int speed) {
-	if (!(_unkGameFlag & 8))
+	if (!_smoothScrollingEnabled)
 		return;
 
 	speed <<= 1;
@@ -1008,7 +1040,7 @@
 }
 
 void LoLEngine::movePartySmoothScrollTurnLeft(int speed) {
-	if (!(_unkGameFlag & 8))
+	if (!_smoothScrollingEnabled)
 		return;
 
 	speed <<= 1;
@@ -1052,7 +1084,7 @@
 }
 
 void LoLEngine::movePartySmoothScrollTurnRight(int speed) {
-	if (!(_unkGameFlag & 8))
+	if (!_smoothScrollingEnabled)
 		return;
 
 	speed <<= 1;

Modified: scummvm/trunk/engines/kyra/script_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_lol.cpp	2009-03-21 02:58:01 UTC (rev 39581)
+++ scummvm/trunk/engines/kyra/script_lol.cpp	2009-03-21 14:30:25 UTC (rev 39582)
@@ -684,7 +684,7 @@
 		if (l->might || l->mode == 13)
 			continue;
 
-		memset(l, 0, sizeof(MonsterInPlay));
+		memset(l, 0, sizeof(MonsterInPlay));		
 		l->id = i;
 		l->x = x;
 		l->y = y;
@@ -692,7 +692,7 @@
 		l->type = stackPos(4);
 		l->properties = &_monsterProperties[l->type];
 		l->direction = l->facing << 1;
-		l->might = (l->properties->might * _monsterModifiers[((_unkGameFlag & 0x30) >> 4)]) >> 8;
+		l->might = (l->properties->might * _monsterModifiers[_monsterDifficulty]) >> 8;
 
 		if (_currentLevel == 12 && l->type == 2)
 			l->might = (l->might * (_rnd.getRandomNumberRng(1, 128) + 192)) >> 8;
@@ -735,6 +735,10 @@
 	return 1;
 }
 
+int LoLEngine::olol_dummy0(EMCState *script) {
+	return 0;
+}
+
 int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadMonsterProperties(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
 		(const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5),
@@ -757,25 +761,25 @@
 
 	l->maxWidth = shpWidthMax;
 
-	l->field2[0] = (stackPos(2) << 8) / 100;
-	l->field2[1] = 256;
-	l->protection = (stackPos(3) << 8) / 100;
-	l->unk[0] = stackPos(4);
-	l->unk[1] = (stackPos(5) << 8) / 100;
-	l->unk[2] = (stackPos(6) << 8) / 100;
-	l->unk[3] = (stackPos(7) << 8) / 100;
-	l->unk[4] = (stackPos(8) << 8) / 100;
-	l->unk[5] = 0;
+	l->fightingStats[0] = (stackPos(2) << 8) / 100;		// hit chance
+	l->fightingStats[1] = 256;							//
+	l->fightingStats[2] = (stackPos(3) << 8) / 100;		// protection
+	l->fightingStats[3] = stackPos(4);					// evade chance
+	l->fightingStats[4] = (stackPos(5) << 8) / 100;		// speed
+	l->fightingStats[5] = (stackPos(6) << 8) / 100;		//
+	l->fightingStats[6] = (stackPos(7) << 8) / 100;		//
+	l->fightingStats[7] = (stackPos(8) << 8) / 100;		//
+	l->fightingStats[8] = 0;
+	l->fightingStats[9] = 0;
 
 	for (int i = 0; i < 8; i++) {
 		l->unk2[i] = stackPos(9 + i);
 		l->unk3[i] = (stackPos(17 + i) << 8) / 100;
 	}
 
-	l->pos = &l->field2[0];
 	l->itemProtection = stackPos(25);
 	l->might = stackPos(26);
-	l->waitTicks = 1;
+	l->speedTotalWaitTicks = 1;
 	l->flags = stackPos(27);
 	l->unk5 = stackPos(28);
 	// FIXME???
@@ -796,6 +800,11 @@
 	return 1;
 }
 
+int LoLEngine::olol_battleHitSkillTest(EMCState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_battleHitSkillTest(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
+	return battleHitSkillTest(stackPos(0), stackPos(1), stackPos(2));
+}
+
 int LoLEngine::olol_moveMonster(EMCState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveMonster(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
 	MonsterInPlay *m = &_monsters[stackPos(0)];
@@ -1022,7 +1031,8 @@
 	return 1;
 }
 
-int LoLEngine::olol_checkForMonsterMode1(EMCState *script) {
+int LoLEngine::olol_checkMonsterTypeHostility(EMCState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkMonsterTypeHostility(%p) (%d)", (const void *)script, stackPos(0));
 	for (int i = 0; i < 30; i++) {
 		if (stackPos(0) != _monsters[i].type && stackPos(0) != -1)
 			continue;
@@ -1445,14 +1455,14 @@
 	// 0x3C
 	OpcodeUnImpl();
 	OpcodeUnImpl();
-	OpcodeUnImpl();
+	Opcode(olol_dummy0);
 	Opcode(olol_loadMonsterProperties);
 
 	// 0x40
+	Opcode(olol_battleHitSkillTest);
 	OpcodeUnImpl();
 	OpcodeUnImpl();
 	OpcodeUnImpl();
-	OpcodeUnImpl();
 
 	// 0x44
 	Opcode(olol_moveMonster);
@@ -1536,7 +1546,7 @@
 	OpcodeUnImpl();
 	OpcodeUnImpl();
 	Opcode(olol_playDialogueTalkText);
-	Opcode(olol_checkForMonsterMode1);
+	Opcode(olol_checkMonsterTypeHostility);
 
 	// 0x7C
 	Opcode(olol_setNextFunc);

Modified: scummvm/trunk/engines/kyra/sprites_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sprites_lol.cpp	2009-03-21 02:58:01 UTC (rev 39581)
+++ scummvm/trunk/engines/kyra/sprites_lol.cpp	2009-03-21 14:30:25 UTC (rev 39582)
@@ -162,9 +162,10 @@
 void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) {
 	if (monster->mode == 13 && mode != 14)
 		return;
+
 	if (mode == 7) {
 		monster->destX = _partyPosX;
-		monster->destY = _partyPosX;
+		monster->destY = _partyPosY;
 	}
 
 	if (monster->mode == 1 && mode == 7) {
@@ -172,19 +173,19 @@
 			if (monster->mode != 1)
 				continue;
 			monster->mode = mode;
-			monster->field_15 = 0;
+			monster->fightCurTick = 0;
 			monster->destX = _partyPosX;
 			monster->destY = _partyPosY;
 			setMonsterDirection(monster, calcMonsterDirection(monster->x, monster->y, monster->destX, monster->destY));
 		}
 	} else {
 		monster->mode = mode;
-		monster->field_15 = 0;
+		monster->fightCurTick = 0;
 		if (mode == 14)
 			monster->might = 0;
 		if (mode == 13 && (monster->flags & 0x20)) {
 			monster->mode = 0;
-			cmzS3(monster);
+			monsterDropItems(monster);
 			if (_currentLevel != 29)
 				setMonsterMode(monster, 14);
 			runLevelScriptCustom(0x404, -1, monster->id, monster->id, 0, 0);
@@ -195,6 +196,47 @@
 	}
 }
 
+bool LoLEngine::updateMonsterAdjustBlocks(MonsterInPlay *monster) {
+	static const uint8 dims[] = { 0, 13, 9, 3 };
+	if (monster->properties->flags & 8)
+		return true;
+
+	uint16 x1 = (monster->x & 0xff00) | 0x80;
+	uint16 y1 = (monster->y & 0xff00) | 0x80;
+	int x2 = _partyPosX;
+	int y2 = _partyPosY;
+
+	uint16 dir = 0;
+	if (monster->properties->flags & 1) {
+		dir = monster->direction >> 1;
+	} else {
+		dir = calcMonsterDirection(x1, y1, x2, y2);
+		if ((monster->properties->flags & 2) && (dir == (monster->direction ^ 4)))
+			return false;
+		dir >>= 1;
+	}
+
+	calcSpriteRelPosition(x1, y1, x2, y2, dir);
+	x2 >>= 8;
+	y2 >>= 8;
+
+	if (y2 < 0 || y2 > 3)
+		return false;
+
+	int t = (x2 < 0) ? -x2 : x2;
+	if (t > y2)
+		return false;
+
+	for (int i = 0; i < 18; i++)
+		_curBlockCaps[i] = &_levelBlockProperties[(monster->blockPropertyIndex + _dscBlockIndex[dir + i]) & 0x3ff];
+
+	int16 fx1 = 0;
+	int16 fx2 = 0;
+	setLevelShapesDim(x2 + dims[y2], fx1, fx2, 13);
+
+	return (fx1 >= fx2) ? false : true;
+}
+
 void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
 	bool cont = true;
 	int t = monster->blockPropertyIndex;
@@ -211,7 +253,7 @@
 	if (monster->x != x || monster->y != y) {
 		monster->x = x;
 		monster->y = y;
-		monster->anon9 = (++monster->anon9) & 3;
+		monster->currentSubFrame = (++monster->currentSubFrame) & 3;
 	}
 
 	if (monster->blockPropertyIndex == 0)
@@ -224,7 +266,7 @@
 	if (monster->properties->sounds[0] == 0 || cont == false)
 		return;
 
-	if ((!(monster->properties->flags & 0x100) || ((monster->anon9 & 1) == 0)) && monster->blockPropertyIndex == t)
+	if ((!(monster->properties->flags & 0x100) || ((monster->currentSubFrame & 1) == 0)) && monster->blockPropertyIndex == t)
 		return;
 
 	if (monster->blockPropertyIndex != t)
@@ -238,6 +280,7 @@
 
 int LoLEngine::calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
 	int16 r = 0;
+
 	int16 t1 = y1 - y2;
 	if (t1 < 0) {
 		r++;
@@ -247,19 +290,15 @@
 	r <<= 1;
 
 	int16 t2 = x2 - x1;
-
 	if (t2 < 0) {
 		r++;
 		t2 = -t2;
 	}
 
-	uint8 f = 1;
+	uint8 f = (t1 > t2) ? 1 : 0;
 
-	if (t2 >= t1) {
-		if (t2 > t1)
-			f = 0;
+	if (t2 >= t1)
 		SWAP(t1, t2);
-	}
 
 	r = (r << 1) | f;
 
@@ -281,8 +320,13 @@
 	checkSceneUpdateNeed(monster->blockPropertyIndex);
 }
 
-void LoLEngine::cmzS3(MonsterInPlay *l) {
-	// TODO
+void LoLEngine::monsterDropItems(MonsterInPlay *monster) {
+	uint16 a = monster->assignedItems;
+	while (a) {
+		uint16 b = a;
+		a = _itemsInPlay[a].nextAssignedObject;
+		setItemPosition(b, monster->x, monster->y, 0, 1);
+	}
 }
 
 void LoLEngine::removeAssignedObjectFromBlock(LevelBlockProperty *l, int id) {
@@ -459,7 +503,7 @@
 	int r = (a << 8) / c[4];
 
 	if (!(id & 0x8000))
-		r = (r * _monsterModifiers[3 + ((_unkGameFlag & 0x30) << 4)]) >> 8;
+		r = (r * _monsterModifiers[3 + _monsterDifficulty]) >> 8;
 
 	id &= 0x7fff;
 
@@ -519,7 +563,6 @@
 
 			if ((_itemProperties[i->itemPropertyIndex].flags & 0x1000) && !(i->shpCurFrame_flg & 0xC000)) {
 				int shpIndex = _itemProperties[i->itemPropertyIndex].flags & 0x800 ? 7 : _itemProperties[i->itemPropertyIndex].shpIndex;
-				shpIndex=12;
 				int ii = 0;
 				for (; ii < 8; ii++) {
 					if (!_flyingItems[ii].enable)
@@ -612,7 +655,7 @@
 		int dW = _screen->getShapeScaledWidth(shp, _dmScaleW) >> 1;
 		int dH = _screen->getShapeScaledHeight(shp, _dmScaleH) >> 1;
 
-		int a = (m->mode == 13) ? (m->field_15 << 1) : (m->properties->might / (m->field_1B & 0x7fff));
+		int a = (m->mode == 13) ? (m->fightCurTick << 1) : (m->properties->might / (m->field_1B & 0x7fff));
 
 		shp = _gameShapes[6];
 
@@ -654,7 +697,7 @@
 	switch (_monsterUnk[m->properties->shapeIndex]) {
 		case 0:
 			if (dirFlags) {
-				return (*m->properties->pos & 0xff) == 13 ? -1 : (dirFlags + m->anon9);
+				return (m->properties->fightingStats[0] & 0xff) == 13 ? -1 : (dirFlags + m->currentSubFrame);
 			} else {
 				if (m->field_1B)
 					return 12;
@@ -663,13 +706,13 @@
 					case 0:
 						return m->field_1B ? 12 : ((m->properties->flags & 4) ? 13 : 0);
 					case 3:
-						return (m->field_15 + 13);
+						return (m->fightCurTick + 13);
 					case 6:
 						return 14;
 					case 8:
 						return -1;
 					default:
-						return m->field_1B ? 12 : m->anon9;
+						return m->field_1B ? 12 : m->currentSubFrame;
 				}
 			}
 			break;
@@ -738,8 +781,7 @@
 		int t = (i << 7) + 1;		
 		while (s) {
 			if (s & 0x8000) {
-				s &= 0x7fff;
-				s = _monsters[i].nextDrawObject;
+				s = _monsters[s & 0x7fff].nextDrawObject;
 			} else {
 				ItemInPlay *item = &_itemsInPlay[s];
 
@@ -769,7 +811,7 @@
 	int x = i->x;
 	int y = i->y;
 
-	recalcSpritePosition(_partyPosX, _partyPosY, x, y, direction);
+	calcSpriteRelPosition(_partyPosX, _partyPosY, x, y, direction);
 
 	if (y < 0)
 		y = 0;
@@ -780,9 +822,9 @@
 	return res;
 }
 
-void LoLEngine::recalcSpritePosition(uint16 partyX, uint16 partyY, int &itemX, int &itemY, uint16 direction) {
-	int a = itemX - partyX;
-	int b = partyY - itemY;
+void LoLEngine::calcSpriteRelPosition(uint16 x1, uint16 y1, int &x2, int &y2, uint16 direction) {
+	int a = x2 - x1;
+	int b = y1 - y2;
 
 	if (direction) {
 		if (direction != 2)
@@ -796,8 +838,8 @@
 		}
 	}
 
-	itemX = a;
-	itemY = b;
+	x2 = a;
+	y2 = b;
 }
 
 void LoLEngine::drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags) {
@@ -938,7 +980,7 @@
 }
 
 int LoLEngine::calcDrawingLayerParameters(int x1, int y1, int &x2, int &y2, uint16 &w, uint16 &h, uint8 *shape, int flip) {
-	recalcSpritePosition(_partyPosX, _partyPosY, x1, y1, _currentDirection);
+	calcSpriteRelPosition(_partyPosX, _partyPosY, x1, y1, _currentDirection);
 
 	if (y1 < 0) {
 		w = h = x2 = y2 = 0;
@@ -965,10 +1007,10 @@
 		return;
 
 	int f = flags[monster->mode];
-	if ((monster->tick++ < monster->properties->waitTicks) && (!(f & 4)))
+	if ((monster->speedTick++ < monster->properties->speedTotalWaitTicks) && (!(f & 4)))
 		return;
 
-	monster->tick = 0;
+	monster->speedTick = 0;
 
 	if (monster->properties->flags & 0x40) {
 		monster->might += _rnd.getRandomNumberRng(1, 8);
@@ -982,11 +1024,12 @@
 	}
 
 	if (f & 2) {
-
-		/////
-		// TODO
+		if (updateMonsterAdjustBlocks(monster)) {
+			setMonsterMode(monster, 7);
+			f &= 6;
+		}
 	}
-
+	
 	if ((f & 1) && (monster->flags & 0x10))
 		setMonsterMode(monster, 7);
 
@@ -1000,6 +1043,7 @@
 	switch (monster->mode) {
 		case 0:
 		case 1:
+			// friendly mode
 			if (monster->flags & 0x10) {
 				for (int i = 0; i < 30; i++) {
 					if (_monsters[i].mode == 1)
@@ -1009,28 +1053,87 @@
 				moveMonster(monster);
 			}
 			break;
+
 		case 2:
+			moveMonster(monster);
 			break;
-		case 3:
+
+		case 3:			
+			if (updateMonsterAdjustBlocks(monster))
+				setMonsterMode(monster, 7);
+			for (int i = 0; i < 4; i++) {
+				if (calcNewBlockPosition(monster->blockPropertyIndex, i) == _currentBlock)
+					setMonsterMode(monster, 7);
+			}
 			break;
+
 		case 4:
+			// straying around not tracing the party
+			moveStrayingMonster(monster);
 			break;
+
 		case 5:
+			// second recovery phase after delivering an attack
+			// monsters will rearrange positions in this phase so as to allow a maximum
+			// number of monsters possible attacking at the same time
+			_unkDrawLevelBool = true;
+			monster->fightCurTick--;
+			if ((monster->fightCurTick <= 0) || (checkDrawObjectSpace(_partyPosX, _partyPosY, monster->x, monster->y) > 256) || (monster->flags & 8))
+				setMonsterMode(monster, 7);
+			else
+				rearrangeAttackingMonster(monster);
 			break;
+
 		case 6:
+			// same as mode 5, but without rearranging
+			if (--monster->fightCurTick <= 0)
+				setMonsterMode(monster, 7);
 			break;
+
 		case 7:
+			// monster destination is set to current party position
+			// depending on the flag setting this gets updated each round
+			// monster can't change mode before arriving at destination and/or attacking the party
+			if (!chasePartyWithDistanceAttacks(monster))
+				chasePartyWithCloseAttacks(monster);
+			checkSceneUpdateNeed(monster->blockPropertyIndex);
 			break;
+
 		case 8:
+			// first recovery phase after delivering an attack
+			if (++monster->fightCurTick > 2) {
+				setMonsterMode(monster, 5);
+				monster->fightCurTick = (int8) ((((8 << 8) / monster->properties->fightingStats[4]) * _monsterModifiers[6 + _monsterDifficulty]) >> 8);
+			}
+			checkSceneUpdateNeed(monster->blockPropertyIndex);
 			break;
+
 		case 9:
+			if (--monster->fightCurTick) {
+				chasePartyWithCloseAttacks(monster);
+			} else {
+				setMonsterMode(monster, 7);
+				monster->flags &= 0xfff7;
+			}
+
 			break;
+
 		case 12:
+			checkSceneUpdateNeed(monster->blockPropertyIndex);
+			if (++monster->fightCurTick > 13)
+				runLevelScriptCustom(0x404, -1, monster->id, monster->id, 0, 0);
 			break;
+
 		case 13:
+			if (++monster->fightCurTick > 2)
+				mode13sub(monster);
+			checkSceneUpdateNeed(monster->blockPropertyIndex);
 			break;
+
 		case 14:
+			monster->field_1B = 0;
 			break;
+
 		default:
 			break;
 	}
@@ -1087,6 +1190,54 @@
 	placeMonster(monster, fx, fy);
 }
 
+bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
+	if (!monster->field_25)
+		return false;
+
+	return true;
+}
+
+void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
+	if (!(monster->flags & 8)) {
+		int dir = calcMonsterDirection(monster->x & 0xff00, monster->y & 0xff00, _partyPosX & 0xff00, _partyPosY & 0xff00);
+		int x1 = _partyPosX;
+		int y1 = _partyPosY;
+		
+		calcSpriteRelPosition(monster->x, monster->y, x1, y1, dir >> 1);
+
+		int t = (x1 < 0) ? -x1 : x1;
+		if (y1 <= 160 && t <= 80) {
+			if ((monster->direction == dir) && (monster->facing == (dir >> 1))) {
+				int dst = getClosestPartyMember(monster->x, monster->y);
+				snd_playSoundEffect(monster->properties->sounds[1], -1);
+				int m = monster->id | 0x8000;
+				int hit = battleHitSkillTest(m, dst, 0);
+
+				if (hit) {
+					int dmg = _rnd.getRandomNumberRng(2, calcInflictableDamage(m, dst, hit));
+					battleHit_sub2(dst, dmg, m, 0);
+					battleHit_sub3(monster, dst, dmg);
+				}
+					
+				setMonsterMode(monster, 8);
+				checkSceneUpdateNeed(monster->blockPropertyIndex);
+
+			} else {
+				setMonsterDirection(monster, dir);
+				checkSceneUpdateNeed(monster->blockPropertyIndex);
+			}
+			return;			
+		}
+	}
+
+	if (monster->x != monster->destX || monster->y != monster->destY) {
+		walkMonster(monster);
+	} else {
+		setMonsterDirection(monster, monster->destDirection);
+		setMonsterMode(monster, (_rnd.getRandomNumberRng(1, 100) <= 50) ? 4 : 3);
+	}
+}
+
 int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
 	static const int8 walkMonsterTable1[] = { 7, -6, 5, -4, 3, -2, 1, 0 };
 	static const int8 walkMonsterTable2[] = { -7, 6, -5, 4, -3, 2, -1, 0 };
@@ -1206,6 +1357,124 @@
 	newY = (srcY + shiftTableY[direction]) & 0x1fff;
 }
 
+void LoLEngine::rearrangeAttackingMonster(MonsterInPlay *monster) {
+	int t = (monster->direction >> 1);
+	uint16 mx = monster->x;
+	uint16 my = monster->y;
+	uint16 *c = (t & 1) ? &my : &mx;
+	bool centered = (*c & 0x7f) ? false : true;
+				
+	bool posFlag = true;
+	if (monster->properties->maxWidth <= 63) {
+		if (centered) {
+			bool r = false;
+			
+			if (_levelBlockProperties[monster->blockPropertyIndex].assignedObjects & 0x8000) {
+				r = true;
+			} else {
+				uint16 id = _levelBlockProperties[monster->blockPropertyIndex].assignedObjects;
+				id = (id & 0x8000) ? (id & 0x7fff) : 0xffff;
+
+				if (id != monster->id) {
+					r = true;
+				} else {					
+					for (int i = 0; i < 3; i++) {
+						t = (t + 1) & 3;
+						calcNewBlockPosition(monster->blockPropertyIndex, t);
+						id = _levelBlockProperties[monster->blockPropertyIndex].assignedObjects;
+						id = (id & 0x8000) ? (id & 0x7fff) : 0xffff;
+						if (id != 0xffff)
+							r = true;
+					}
+				}
+			}
+
+			if (r)
+				posFlag = false;
+		} else {
+			posFlag = false;
+		}
+	}
+
+	if (centered && posFlag)
+		return;
+	
+	if (posFlag) {
+		if (*c & 0x80)
+			*c -= 32;
+		else
+			*c += 32;
+	} else {
+		if (*c & 0x80)
+			*c += 32;
+		else
+			*c -= 32;
+	}
+	
+	if (walkMonsterCheckDest(mx, my, monster, 4))
+		return;
+		
+	int fx = _partyPosX;
+	int fy = _partyPosY;
+	calcSpriteRelPosition(mx, my, fx, fy, monster->direction >> 1);
+
+	t = (fx < 0) ? -fx : fx;
+	if (fy > 160 || t > 80)
+		return;
+
+	placeMonster(monster, mx, my);
+}
+
+void LoLEngine::moveStrayingMonster(MonsterInPlay *monster) {
+	int x = 0;
+	int y = 0;
+	
+	if (monster->fightCurTick) {
+		uint8 d = (monster->direction - monster->fightCurTick) & 6;
+		uint8 id = monster->id;
+	
+		for (int i = 0; i < 7; i++) {
+			getNextStepCoords(monster->x, monster->y, x, y, d);
+
+			if (!walkMonsterCheckDest(x, y, monster, 4)) {
+				placeMonster(monster, x, y);
+				setMonsterDirection(monster, d);
+				if (!i) {
+					if (++id > 3)
+						monster->fightCurTick = 0;
+				}
+				return;
+			}
+
+			d = (d + monster->fightCurTick) & 6;
+		}
+		setMonsterMode(monster, 3);
+
+	} else {
+		monster->direction &= 6;
+		getNextStepCoords(monster->x, monster->y, x, y, monster->direction);
+		if (!walkMonsterCheckDest(x, y, monster, 4)) {
+			placeMonster(monster, x, y);
+		} else {
+			monster->fightCurTick = _rnd.getRandomBit() ? 2 : -2;
+			monster->direction = (monster->direction + monster->fightCurTick) & 6;
+		}
+	}
+}
+
+void LoLEngine::mode13sub(MonsterInPlay *monster) {
+	setMonsterMode(monster, 14);
+	monsterDropItems(monster);
+	checkSceneUpdateNeed(monster->blockPropertyIndex);
+
+	uint8 w = _levelBlockProperties[monster->blockPropertyIndex].walls[0];
+	uint8 f = _levelBlockProperties[monster->blockPropertyIndex].flags;
+	if (_wllVmpMap[w] == 0 && _wllShapeMap[w] == 0 && !(f & 0x40) && !(monster->properties->flags & 0x1000))
+		_levelBlockProperties[monster->blockPropertyIndex].flags |= 0x80;
+
+	placeMonster(monster, 0, 0);
+}
+
 } // end of namespace Kyra
 
 #endif // ENABLE_LOL

Modified: scummvm/trunk/engines/kyra/staticres.cpp
===================================================================
--- scummvm/trunk/engines/kyra/staticres.cpp	2009-03-21 02:58:01 UTC (rev 39581)
+++ scummvm/trunk/engines/kyra/staticres.cpp	2009-03-21 14:30:25 UTC (rev 39582)
@@ -1001,9 +1001,9 @@
 		t->field_34 = file->readUint16LE();
 		t->field_36 = file->readByte();
 		t->itemsProtection = file->readUint16LE();
-		t->hitPointsCur = file->readUint16LE();;
+		t->hitPointsCur = file->readSint16LE();;
 		t->hitPointsMax = file->readUint16LE();;
-		t->magicPointsCur = file->readUint16LE();;
+		t->magicPointsCur = file->readSint16LE();;
 		t->magicPointsMax = file->readUint16LE();;
 		t->field_41 = file->readByte();
 		t->damageSuffered = file->readUint16LE();


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