diff options
| author | Florian Kagerer | 2009-03-01 14:45:30 +0000 | 
|---|---|---|
| committer | Florian Kagerer | 2009-03-01 14:45:30 +0000 | 
| commit | 7ea5cefef4fb1ef9db52cbf5df7f884770113684 (patch) | |
| tree | 7ad307cd465c99268b7adc8a8054467df4e6e581 | |
| parent | 40c4733124a43fb2e921efd07a782ed1688cbc90 (diff) | |
| download | scummvm-rg350-7ea5cefef4fb1ef9db52cbf5df7f884770113684.tar.gz scummvm-rg350-7ea5cefef4fb1ef9db52cbf5df7f884770113684.tar.bz2 scummvm-rg350-7ea5cefef4fb1ef9db52cbf5df7f884770113684.zip  | |
LOL: implemented some monster related code (monsters now get placed in the maze, but they still don't do anything)
svn-id: r39039
| -rw-r--r-- | dists/engine-data/kyra.dat | bin | 255891 -> 256287 bytes | |||
| -rw-r--r-- | engines/kyra/gui_lol.cpp | 10 | ||||
| -rw-r--r-- | engines/kyra/items_lol.cpp | 34 | ||||
| -rw-r--r-- | engines/kyra/lol.cpp | 40 | ||||
| -rw-r--r-- | engines/kyra/lol.h | 149 | ||||
| -rw-r--r-- | engines/kyra/module.mk | 1 | ||||
| -rw-r--r-- | engines/kyra/resource.h | 6 | ||||
| -rw-r--r-- | engines/kyra/scene_lol.cpp | 433 | ||||
| -rw-r--r-- | engines/kyra/screen.cpp | 21 | ||||
| -rw-r--r-- | engines/kyra/screen.h | 2 | ||||
| -rw-r--r-- | engines/kyra/script_lol.cpp | 141 | ||||
| -rw-r--r-- | engines/kyra/sprites_lol.cpp | 942 | ||||
| -rw-r--r-- | engines/kyra/staticres.cpp | 18 | ||||
| -rw-r--r-- | engines/kyra/timer_lol.cpp | 10 | ||||
| -rw-r--r-- | tools/create_kyradat/create_kyradat.cpp | 8 | ||||
| -rw-r--r-- | tools/create_kyradat/create_kyradat.h | 6 | ||||
| -rw-r--r-- | tools/create_kyradat/lol_cd.h | 6 | ||||
| -rw-r--r-- | tools/create_kyradat/misc.h | 6 | 
18 files changed, 1333 insertions, 500 deletions
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat Binary files differindex 0ad8f84071..d4967caa17 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index 81f65c0a9d..34ae13b000 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -1304,7 +1304,7 @@ int LoLEngine::clickedInventoryScroll(Button *button) {  	return 1;  } -int LoLEngine::clickedScenePressSwitch(Button *button) { +int LoLEngine::clickedWall(Button *button) {  	int block = calcNewBlockPosition(_currentBlock, _currentDirection);  	int dir = _currentDirection ^ 2;  	uint8 type = _wllBuffer3[_levelBlockProperties[block].walls[dir]]; @@ -1312,23 +1312,27 @@ int LoLEngine::clickedScenePressSwitch(Button *button) {  	int res = 0;  	switch (type) {  		case 1: -			res = clickedDecoration(block, dir); +			res = clickedWallShape(block, dir);  			break;  		case 2: +			res = clicked2(block, dir);  			break;  		case 3: +			res = clicked3(block, dir);  			break;  		case 4: +			res = clickedWallOnlyScript(block);  			break;  		case 5: -			res = switchOpenDoor(block, dir); +			res = clickedDoorSwitch(block, dir);  			break;  		case 6: +			res = clicked6(block, dir);  			break;  		default: diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp index 741cb20d6d..7c584f7738 100644 --- a/engines/kyra/items_lol.cpp +++ b/engines/kyra/items_lol.cpp @@ -96,7 +96,7 @@ int LoLEngine::makeItem(int itemIndex, int curFrame, int flags) {  			if (t)  				break;  			else -				ii = _itemsInPlay[ii - 1].itemIndexUnk; +				ii = _itemsInPlay[ii - 1].next;  		}  		if (t) { @@ -109,22 +109,22 @@ int LoLEngine::makeItem(int itemIndex, int curFrame, int flags) {  	if (cnt) {  		slot = r;  		if (testUnkItemFlags(r)) { -			if (_itemsInPlay[r].itemIndexUnk) -				_itemsInPlay[_itemsInPlay[r].itemIndexUnk].level = _itemsInPlay[r].level; +			if (_itemsInPlay[r].next) +				_itemsInPlay[_itemsInPlay[r].next].level = _itemsInPlay[r].level;  			deleteItem(r);  			slot = r;  		} else { -			int ii = _itemsInPlay[slot].itemIndexUnk; +			int ii = _itemsInPlay[slot].next;  			while (ii) {  				if (testUnkItemFlags(ii)) { -					_itemsInPlay[slot].itemIndexUnk = _itemsInPlay[ii].itemIndexUnk; +					_itemsInPlay[slot].next = _itemsInPlay[ii].next;  					deleteItem(ii);  					slot = ii;  					break;  				} else {  					slot = ii;  				} -				ii = _itemsInPlay[slot].itemIndexUnk; +				ii = _itemsInPlay[slot].next;  			}  		}  	} @@ -154,11 +154,11 @@ void LoLEngine::deleteItem(int itemIndex) {  	_itemsInPlay[itemIndex].shpCurFrame_flg |= 0x8000;  } -MonsterInPlay *LoLEngine::findItem(uint16 index) { +ItemInPlay *LoLEngine::findItem(uint16 index) {  	if (index & 0x8000) -		return &_monsters[index & 0x7fff]; +		return (ItemInPlay *)&_monsters[index & 0x7fff];  	else -		return (MonsterInPlay *)&_itemsInPlay[index]; +		return &_itemsInPlay[index];  }  void LoLEngine::runItemScript(int charNum, int item, int reg0, int reg3, int reg4) { @@ -225,7 +225,7 @@ void LoLEngine::clickSceneSub1() {  				ItemInPlay *item = &_itemsInPlay[s];  				if (item->shpCurFrame_flg & 0x4000) { -					if (clickSceneSub1Sub1(item->x, item->y, _partyPosX, _partyPosY) > 319) +					if (checkMonsterSpace(item->x, item->y, _partyPosX, _partyPosY) > 319)  						break;  					int w =	sceneItemWidth[s & 7] << 1; @@ -236,7 +236,7 @@ void LoLEngine::clickSceneSub1() {  					uint8 shpIx = _itemProperties[item->itemPropertyIndex].shpIndex;  					uint8 *shp = (_itemProperties[item->itemPropertyIndex].flags & 0x40) ? _gameShapes[shpIx] : _itemShapes[_gameShapeMap[shpIx]];					 -					drawSceneItem(shp, 0, item->x, item->y, w, h, 0, t, 0); +					drawItemOrMonster(shp, 0, item->x, item->y, w, h, 0, t, 0);  				}  				s = item->unk2; @@ -246,8 +246,16 @@ void LoLEngine::clickSceneSub1() {  	}  } -int LoLEngine::clickSceneSub1Sub1(int itemX, int itemY, int partyX, int partyY) { -	return 1; +int LoLEngine::checkMonsterSpace(int itemX, int itemY, int partyX, int partyY) { +	int a = itemX - partyX; +	if (a < 0) +		a = -a; + +	int b = itemY - partyY; +	if (b < 0) +		b = -b; + +	return a + b;  }  int LoLEngine::checkSceneForItems(LevelBlockProperty *block, int pos) { diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 7ee1a32c85..96fddd8660 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -89,7 +89,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy  	_itemIconShapes = _itemShapes = _gameShapes = _thrownShapes = _iceShapes = _fireballShapes = 0;  	_levelShpList = _levelDatList = 0;  	_monsterShapes = _monsterPalettes = 0; -	_buf4 = 0; +	_monsterShapesEx = 0;  	_gameShapeMap = 0;  	memset(_monsterUnk, 0, 3); @@ -111,7 +111,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy  	_buttonPressTimer = 0;  	_selectedCharacter = 0;  	_unkFlag = 0; -	_scriptBoolSkipExec = _sceneUpdateRequired = false; +	_suspendScript = _sceneUpdateRequired = false;  	_scriptDirection = 0;  	_currentDirection = 0;  	_currentBlock = 0; @@ -259,10 +259,10 @@ LoLEngine::~LoLEngine() {  			delete[]  _monsterPalettes[i];  		delete[] _monsterPalettes;  	} -	if (_buf4) { -		for (int i = 0; i < 384; i++) -			delete[]  _buf4[i]; -		delete[] _buf4; +	if (_monsterShapesEx) { +		for (int i = 0; i < 576; i++) +			delete[]  _monsterShapesEx[i]; +		delete[] _monsterShapesEx;  	}  	for (Common::Array<const TIMOpcode*>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i) @@ -417,8 +417,8 @@ Common::Error LoLEngine::init() {  	_monsterPalettes = new uint8*[48];  	memset(_monsterPalettes, 0, 48 * sizeof(uint8*)); -	_buf4 = new uint8*[384]; -	memset(_buf4, 0, 384 * sizeof(uint8*)); +	_monsterShapesEx = new uint8*[576]; +	memset(_monsterShapesEx, 0, 576 * sizeof(uint8*));  	memset(&_scriptData, 0, sizeof(EMCData));  	_levelFlagUnk = 0; @@ -1501,6 +1501,25 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int unk1, char *str  	return 1;  } +void LoLEngine::cmzS7(int a, int block) { +	if (!(_unkGameFlag & 1)) +		return; + +	// TODO +} + +void LoLEngine::giveItemToMonster(MonsterInPlay *monster, uint16 item) { +	uint16 *c = &monster->assignedItems;	 +	while (*c) +		c = &_itemsInPlay[*c].next; +	*c = item; +	_itemsInPlay[item].next = 0; +} + +const uint16 *LoLEngine::getCharacterOrMonsterStats(int id) { +	return (id & 0x8000) ? (const uint16*)_monsters[id & 0x7fff].properties->pos : _characters[id].defaultModifiers; +} +  void LoLEngine::delay(uint32 millis, bool cUpdate, bool isMainLoop) {  	uint32 endTime = _system->getMillis() + millis;  	while (endTime > _system->getMillis()) { @@ -1514,11 +1533,6 @@ void LoLEngine::runLoopSub4(int a) {  	cmzS7(a, _currentBlock);  } -void LoLEngine::calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs) { -	x = (block & 0x1f) << 8 | xOffs; -	y = ((block & 0xffe0) << 3) | yOffs; -} -  bool LoLEngine::notEnoughMagic(int charNum, int spellNum, int spellLevel) {  	if (_spellProperties[spellNum].mpRequired[spellLevel] > _characters[charNum].magicPointsCur) {  		if (characterSays(0x4043, _characters[charNum].id, true)) diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 63b8a47d20..23ae1831df 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -93,14 +93,14 @@ struct SpellProperty {  struct LevelBlockProperty {  	uint8 walls[4]; -	uint16 itemIndex; +	uint16 itemMonsterIndex;  	uint16 field_6; -	uint8 field_8; +	uint8 direction;  	uint8 flags;  };  struct MonsterProperty { -	uint8 id; +	uint8 shapeIndex;  	uint8 maxWidth;  	uint16 field2[2];  	uint16 protection; @@ -111,14 +111,15 @@ struct MonsterProperty {  	uint16 itemProtection;  	uint16 might;  	uint8 b; -	uint16 unk5[2]; +	uint16 flags; +	uint16 unk5;  	uint16 unk6[5];  	uint8 unk7[4];  	uint8 unk8[3];  };  struct MonsterInPlay { -	uint16 itemIndexUnk; +	uint16 next;  	uint16 unk2;  	uint8 unk4;  	uint16 blockPropertyIndex; @@ -128,34 +129,31 @@ struct MonsterInPlay {  	uint16 itemPosX;  	uint16 itemPosY;  	uint8 field10; -	uint16 anon8; +	uint8 anon8; +	uint8 anonh;  	uint8 anon9; -	uint8 field_14; +	uint8 mode;  	uint8 field_15; -	uint8 field_16; +	uint8 id;  	uint8 field_17; -	uint8 field_18; -	uint16 field_19; +	uint8 facing; +	uint16 flags;  	uint8 field_1B;  	uint8 field_1C; -	int16 monsterMight; +	int16 might;  	uint8 field_1F;  	uint8 type;  	MonsterProperty *properties;  	uint8 field_25;  	uint8 field_26;  	uint8 field_27; -	uint16 itix; -	uint8 field_2A; -	uint8 field_2B; -	uint16 field_2C; -	uint8 field_2D; -	uint8 field_2E; +	uint16 assignedItems; +	uint8 field_2A[4];  };  struct ItemInPlay { -	uint16 itemIndexUnk; +	uint16 next;  	uint16 unk2;  	uint8 unk4;  	uint16 blockPropertyIndex; @@ -165,7 +163,8 @@ struct ItemInPlay {  	uint16 itemPropertyIndex;  	uint16 shpCurFrame_flg;  	uint8 field10; -	uint16 anon8; +	uint8 anon8; +	uint8 anonh;  	uint8 anon9;  }; @@ -310,7 +309,7 @@ private:  	void enableTimer(int id);  	void timerProcessOpenDoor(int timerNum); -	void timerSub2(int timerNum); +	void timerProcessMonsters(int timerNum);  	void timerSub3(int timerNum);  	void timerSub4(int timerNum);  	void timerSub5(int timerNum); @@ -434,7 +433,7 @@ private:  	int clickedScenePickupItem(Button *button);  	int clickedInventorySlot(Button *button);  	int clickedInventoryScroll(Button *button); -	int clickedScenePressSwitch(Button *button); +	int clickedWall(Button *button);  	int clickedScene(Button *button);  	int clickedScroll(Button *button);  	int clickedUnk23(Button *button); @@ -474,14 +473,14 @@ private:  	TextDisplayer_LoL *_txt;  	// emc scripts -	void runInitScript(const char *filename, int func); +	void runInitScript(const char *filename, int optionalFunc);  	void runInfScript(const char *filename);  	void runLevelScript(int block, int sub);  	void runLevelScriptCustom(int block, int sub, int charNum, int item, int reg3, int reg4); -	bool checkScriptUnk(int func); +	bool checkSceneUpdateNeed(int func);  	EMCData _scriptData; -	bool _scriptBoolSkipExec; +	bool _suspendScript;  	uint16 _scriptDirection;  	uint16 _currentDirection;  	uint16 _currentBlock; @@ -515,6 +514,7 @@ private:  	int olol_setGlobalVar(EMCState *script);  	int olol_mapShapeToBlock(EMCState *script);  	int olol_resetBlockShapeAssignment(EMCState *script); +	int olol_initMonster(EMCState *script);  	int olol_loadMonsterProperties(EMCState *script);  	int olol_68(EMCState *script);  	int olol_setScriptTimer(EMCState *script); @@ -523,14 +523,16 @@ private:  	int olol_releaseTimScript(EMCState *script);  	int olol_initDialogueSequence(EMCState *script);  	int olol_restoreSceneAfterDialogueSequence(EMCState *script); -	int olol_85(EMCState *script); +	int olol_giveItemToMonster(EMCState *script);  	int olol_loadLangFile(EMCState *script); +	int olol_playSoundEffect(EMCState *script);  	int olol_stopTimScript(EMCState *script);  	int olol_playCharacterScriptChat(EMCState *script);	  	int olol_loadSoundFile(EMCState *script);  	int olol_setPaletteBrightness(EMCState *script); +	int olol_printMessage(EMCState *script);  	int olol_playDialogueTalkText(EMCState *script); -	int olol_checkDialogueState(EMCState *script);	 +	int olol_checkForMonsterMode1(EMCState *script);	  	int olol_setNextFunc(EMCState *script);  	int olol_setDoorState(EMCState *script);  	int olol_assignCustomSfx(EMCState *script); @@ -627,14 +629,8 @@ private:  	int _loadLevelFlag;  	int _levelFlagUnk;  	int _unkCharNum; -  	int _charStatsTemp[5]; -	uint8 **_monsterShapes; -	uint8 **_monsterPalettes; -	uint8 **_buf4; -	uint8 _monsterUnk[3]; -  	const LoLCharacter *_charDefaults;  	int _charDefaultsSize; @@ -663,16 +659,6 @@ private:  	// level  	void loadLevel(int index);  	void addLevelItems(); -	int initCmzWithScript(int block); -	void initCMZ1(MonsterInPlay *l, int a); -	void initCMZ2(MonsterInPlay *l, uint16 a, uint16 b); -	int cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2); -	void cmzS2(MonsterInPlay *l, int a); -	void cmzS3(MonsterInPlay *l); -	void cmzS4(uint16 &itemIndex, int a); -	int cmzS5(uint16 a, uint16 b); -	void cmzS6(uint16 &itemIndex, int a); -	void cmzS7(int a, int block);  	void loadLevelWLL(int index, bool mapShapes);  	void moveItemToBlock(uint16 *cmzItemIndex, uint16 item);  	int assignLevelShapes(int index); @@ -680,8 +666,6 @@ private:  	void loadLevelCmzFile(int index);  	void loadCMZ_Sub(int index1, int index2);  	void loadCmzFile(const char *file); -	void loadMonsterShapes(const char *file, int monsterIndex, int b); -	void releaseMonsterShapes(int monsterIndex);  	void loadLevelShpDat(const char *shpFile, const char *datFile, bool flag);  	void loadLevelGraphics(const char *file, int specialColor, int weight, int vcnLen, int vmpLen, const char *palFile); @@ -706,10 +690,6 @@ private:  	void drawLevelModifyScreenDim(int dim, int16 x1, int16 y1, int16 x2, int16 y2);  	void drawDecorations(int index);  	void drawIceShapes(int index, int iceShapeIndex); -	void drawMonstersAndItems(int block); -	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); -	void drawSceneItem(uint8 *shape, uint8 *ovl, int x, int y, int w, int h, int flags, int unk1, int unk2);  	void drawScriptShapes(int pageNum);  	void updateSceneWindow(); @@ -719,12 +699,19 @@ private:  	void updateCompass();  	void moveParty(uint16 direction, int unk1, int unk2, int buttonShape); -	uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction);  	bool checkBlockPassability(uint16 block, uint16 direction);  	void notifyBlockNotPassable(int scrollFlag); -	int clickedDecoration(uint16 block, uint16 direction); -	int switchOpenDoor(uint16 block, uint16 direction); +	uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction); +	uint16 calcBlockIndex(uint16 x, uint16 y); +	void calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs); + +	int clickedWallShape(uint16 block, uint16 direction); +	int clicked2(uint16 block, uint16 direction); +	int clicked3(uint16 block, uint16 direction); +	int clickedWallOnlyScript(uint16 block); +	int clickedDoorSwitch(uint16 block, uint16 direction); +	int clicked6(uint16 block, uint16 direction);  	bool clickedShape(int shapeIndex);  	void openDoorSub1(uint16 block, int unk); @@ -800,8 +787,6 @@ private:  	LevelBlockProperty *_levelBlockProperties;  	LevelBlockProperty *_curBlockCaps[18]; -	MonsterInPlay *_monsters; -	MonsterProperty *_monsterProperties;  	uint16 _partyPosX;  	uint16 _partyPosY; @@ -880,11 +865,11 @@ private:  	int makeItem(int itemIndex, int curFrame, int flags);  	bool testUnkItemFlags(int itemIndex);  	void deleteItem(int itemIndex); -	MonsterInPlay *findItem(uint16 index); +	ItemInPlay *findItem(uint16 index);  	void runItemScript(int charNum, int item, int reg0, int reg3, int reg4);  	void setHandItem(uint16 itemIndex);  	void clickSceneSub1(); -	int clickSceneSub1Sub1(int itemX, int itemY, int partyX, int partyY); +	int checkMonsterSpace(int itemX, int itemY, int partyX, int partyY);  	int checkSceneForItems(LevelBlockProperty *block, int pos);  	void foundItemSub(int item, int block); @@ -910,10 +895,62 @@ private:  	const uint16 *_inventorySlotDesc;  	int _inventorySlotDescSize; +	// monsters +	void loadMonsterShapes(const char *file, int monsterIndex, int b); +	void releaseMonsterShapes(int monsterIndex); +	int placeMonstersUnk(int block); +	void setMonsterMode(MonsterInPlay *monster, int a); +	void placeMonster(MonsterInPlay *monster, uint16 x, uint16 y); +	int cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2); +	void cmzS2(MonsterInPlay *monster, int a); +	void cmzS3(MonsterInPlay *monster); +	void removeItemOrMonsterFromBlock(uint16 *blockItemIndex, int id); +	void assignItemOrMonsterToBlock(uint16 *blockItemIndex, int id); +	void cmzS7(int a, int block); +	void giveItemToMonster(MonsterInPlay *monster, uint16 a); +	int checkBlockBeforeMonsterPlacement(int x, int y, int monsterWidth, int p1, int p2); +	int calcMonsterSkillLevel(int id, int a); +	int checkBlockForWallsAndSufficientSpace(int block, int x, int y, int monsterWidth, int p1, int p2); +	bool checkBlockOccupiedByParty(int x, int y, int p1); +	const uint16 *getCharacterOrMonsterStats(int id); +	void drawMonstersAndItems(int block);	 +	void drawMonster(uint16 id); +	int getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags); +	void recalcItemMonsterPositions(uint16 direction, uint16 itemIndex, LevelBlockProperty *l, bool flag); +	int calcItemMonsterPosition(ItemInPlay *i, uint16 direction); +	void recalcSpritePosition(uint16 partyX, uint16 partyY, int &itemX, int &itemY, 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 w, int h, int flags, int tblValue, bool flip); +	int calcDrawingLayerParameters(int srcX, int srcY, int16 &x2, int16 &y2, int16 &w, int16 &h, uint8 *shape, int flip); +	 +	void updateMonster(MonsterInPlay *monster); +	void moveMonster(MonsterInPlay *monster); +	void shiftMonster(MonsterInPlay *monster); + +	MonsterInPlay *_monsters; +	MonsterProperty *_monsterProperties; +	uint8 **_monsterShapes; +	uint8 **_monsterPalettes; +	uint8 **_monsterShapesEx; +	uint8 _monsterUnk[3]; + +	const uint16 *_monsterModifiers; +	int _monsterModifiersSize; +	const int8 *_monsterLevelOffs; +	int _monsterLevelOffsSize; +	const uint8 *_monsterDirFlags; +	int _monsterDirFlagsSize; +	const int8 *_monsterScaleX; +	int _monsterScaleXSize; +	const int8 *_monsterScaleY; +	int _monsterScaleYSize; +	const uint16 *_monsterScaleWH; +	int _monsterScaleWHSize; +  	// misc  	void delay(uint32 millis, bool cUpdate = false, bool isMainLoop = false);  	void runLoopSub4(int a); -	void calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs);  	uint8 *_pageBuffer1;  	uint8 *_pageBuffer2; diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index f83b936092..b5c62ab394 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -63,6 +63,7 @@ MODULE_OBJS := \  	sound.o \  	sound_lok.o \  	sprites.o \ +	sprites_lol.o \  	staticres.o \  	text.o \  	text_lok.o \ diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index d28001d893..d48b590792 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -228,6 +228,12 @@ enum kKyraResources {  	//lolCharDefsUnk,  	lolCharDefsAkshel,  	lolExpRequirements, +	lolMonsterModifiers, +	lolMonsterLevelOffsets, +	lolMonsterDirFlags, +	lolMonsterScaleY, +	lolMonsterScaleX, +	lolMonsterScaleWH,  	lolInventoryDesc,  	lolLevelShpList, diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp index 7c34bdc945..7922345973 100644 --- a/engines/kyra/scene_lol.cpp +++ b/engines/kyra/scene_lol.cpp @@ -71,7 +71,7 @@ void LoLEngine::loadLevel(int index) {  	char filename[13];  	snprintf(filename, sizeof(filename), "LEVEL%d.INI", index); -	int f = _levelFlagUnk & (1 << ((index + 0xff) & 0xff)); +	int f = _levelFlagUnk & (1 << (index - 1));  	runInitScript(filename, f ? 0 : 1); @@ -82,7 +82,7 @@ void LoLEngine::loadLevel(int index) {  	runInfScript(filename);  	addLevelItems(); -	initCmzWithScript(_currentBlock); +	placeMonstersUnk(_currentBlock);  	_screen->generateGrayOverlay(_screen->_currentPalette, _screen->_grayOverlay,32, 16, 0, 0, 128, true); @@ -103,186 +103,19 @@ void LoLEngine::addLevelItems() {  		if (_itemsInPlay[i].level != _currentLevel)  			continue; -		moveItemToBlock(&_levelBlockProperties[_itemsInPlay[i].blockPropertyIndex].itemIndex, i); +		moveItemToBlock(&_levelBlockProperties[_itemsInPlay[i].blockPropertyIndex].itemMonsterIndex, i); -		_levelBlockProperties[_itemsInPlay[i].blockPropertyIndex].field_8 = 5; +		_levelBlockProperties[_itemsInPlay[i].blockPropertyIndex].direction = 5;  		_itemsInPlay[i].unk2 = 0;  	}  } -int LoLEngine::initCmzWithScript(int block) { -	int i = _levelBlockProperties[block].itemIndex; -	int cnt = 0; -	MonsterInPlay *t = 0; - -	while (i) { -		t = findItem(i); -		i = t->itemIndexUnk; -		if (!(i & 0x8000)) -			continue; - -		i &= 0x7fff; -		t = &_monsters[i]; - -		cnt++; -		initCMZ1(t, 14); - -		checkScriptUnk(t->blockPropertyIndex); - -		initCMZ2(t, 0, 0); -	} -	return cnt; -} - -void LoLEngine::initCMZ1(MonsterInPlay *l, int a) { -	if (l->field_14 == 13 && a != 14) -		return; -	if (a == 7) { -		l->itemPosX = _partyPosX; -		l->itemPosY = _partyPosX; -	} - -	if (l->field_14 == 1 && a == 7) { -		for (int i = 0; i < 30; i++) { -			if (l->field_14 != 1) -				continue; -			l->field_14 = a; -			l->field_15 = 0; -			l->itemPosX = _partyPosX; -			l->itemPosY = _partyPosY; -			cmzS2(l, cmzS1(l->x, l->y, l->itemPosX, l->itemPosY)); -		} -	} else { -		l->field_14 = a; -		l->field_15 = 0; -		if (a == 14) -			l->monsterMight = 0; -		if (a == 13 && (l->field_19 & 0x20)) { -			l->field_14 = 0; -			cmzS3(l); -			if (_currentLevel != 29) -				initCMZ1(l, 14); -			runLevelScriptCustom(0x404, -1, l->field_16, l->field_16, 0, 0); -			checkScriptUnk(l->blockPropertyIndex); -			if (l->field_14 == 14) -				initCMZ2(l, 0, 0); -		} -	} - -} - -void LoLEngine::initCMZ2(MonsterInPlay *l, uint16 a, uint16 b) { -	bool cont = true; -	int t = l->blockPropertyIndex; -	if (l->blockPropertyIndex) { -		cmzS4(_levelBlockProperties[l->blockPropertyIndex].itemIndex, ((uint16)l->field_16) | 0x8000); -		_levelBlockProperties[l->blockPropertyIndex].field_8 = 5; -		checkScriptUnk(l->blockPropertyIndex); -	} else { -		cont = false; -	} - -	l->blockPropertyIndex = cmzS5(a, b); - -	if (l->x != a || l->y != b) { -		l->x = a; -		l->y = b; -		l->anon9 = (++l->anon9) & 3; -	} - -	if (l->blockPropertyIndex == 0) -		return; - -	cmzS6(_levelBlockProperties[l->blockPropertyIndex].itemIndex, ((uint16)l->field_16) | 0x8000); -	_levelBlockProperties[l->blockPropertyIndex].field_8 = 5; -	checkScriptUnk(l->blockPropertyIndex); - -	if (l->properties->unk8[0] == 0 || cont == false) -		return; - -	if ((!(l->properties->unk5[0] & 0x100) || ((l->anon9 & 1) == 0)) && l->blockPropertyIndex == t) -		return; - -	if (l->blockPropertyIndex != t) -		runLevelScriptCustom(l->blockPropertyIndex, 0x800, -1, l->field_16, 0, 0); - -	if (_updateFlags & 1) -		return; - -	cmzS7(l->properties->unk3[5], l->blockPropertyIndex); -} - -int LoLEngine::cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2) { -	int16 r = 0; -	int16 t1 = y1 - y2; -	if (t1 < 0) { -		r++; -		t1 = -t1; -	} - -	r <<= 1; - -	int16 t2 = x2 - x1; - -	if (t2 < 0) { -		r++; -		t2 = -t2; -	} - -	uint8 f = 0; - -	if (t2 >= t1) { -		if (t2 > t1) -			f = 1; -		SWAP(t1, t2); -	} - -	r = (r << 1) | f; - -	t1 = (t1 + 1) >> 1; - -	f = 0; -	f = (t2 > t1) ? 1 : 0; -	r = (r << 1) | f; - -	static const uint8 Retv[] = { 1, 2, 1, 0, 7, 6, 7, 0, 3, 2, 3, 4, 5, 6, 5, 4}; -	return Retv[r]; -} - -void LoLEngine::cmzS2(MonsterInPlay *l, int a) { -	// TODO -} - -void LoLEngine::cmzS3(MonsterInPlay *l) { -	// TODO -} - -void LoLEngine::cmzS4(uint16 &itemIndex, int a) { -	// TODO -} - -int LoLEngine::cmzS5(uint16 a, uint16 b) { -	// TODO -	return 0; -} - -void LoLEngine::cmzS6(uint16 &itemIndex, int a) { -	// TODO -} - -void LoLEngine::cmzS7(int a, int block) { -	if (!(_unkGameFlag & 1)) -		return; - -	// TODO -} -  void LoLEngine::moveItemToBlock(uint16 *cmzItemIndex, uint16 item) { -	MonsterInPlay *tmp = 0; +	ItemInPlay *tmp = 0;  	while (*cmzItemIndex & 0x8000) {  		tmp = findItem(*cmzItemIndex); -		cmzItemIndex = &tmp->itemIndexUnk; +		cmzItemIndex = &tmp->next;  	}  	tmp = findItem(item); @@ -294,11 +127,11 @@ void LoLEngine::moveItemToBlock(uint16 *cmzItemIndex, uint16 item) {  		return;  	*cmzItemIndex = item; -	cmzItemIndex = &tmp->itemIndexUnk; +	cmzItemIndex = &tmp->next;  	while (*cmzItemIndex) {  		tmp = findItem(*cmzItemIndex); -		cmzItemIndex = &tmp->itemIndexUnk; +		cmzItemIndex = &tmp->next;  	}  	*cmzItemIndex = ix; @@ -434,7 +267,7 @@ void LoLEngine::loadLevelCmzFile(int index) {  		if (_monsters[i].blockPropertyIndex) {  			_monsters[i].blockPropertyIndex = 0;  			_monsters[i].properties = &_monsterProperties[_monsters[i].type]; -			initCMZ2(&_monsters[i], _monsters[i].x, _monsters[i].y); +			placeMonster(&_monsters[i], _monsters[i].x, _monsters[i].y);  		}  	} @@ -450,15 +283,15 @@ void LoLEngine::loadCMZ_Sub(int index1, int index2) {  	//int r = 0;  	for (int i = 0; i < 30; i++) { -		if (_monsters[i].field_14 >= 14 || _monsters[i].blockPropertyIndex == 0 || _monsters[i].monsterMight <= 0) +		if (_monsters[i].mode >= 14 || _monsters[i].blockPropertyIndex == 0 || _monsters[i].might <= 0)  			continue; -		int t = (val * _monsters[i].monsterMight) >> 8; -		_monsters[i].monsterMight = t; +		int t = (val * _monsters[i].might) >> 8; +		_monsters[i].might = t;  		if (index2 < index1) -			_monsters[i].monsterMight++; -		if (_monsters[i].monsterMight == 0) -			_monsters[i].monsterMight = 1; +			_monsters[i].might++; +		if (_monsters[i].might == 0) +			_monsters[i].might = 1;  	}  } @@ -473,7 +306,7 @@ void LoLEngine::loadCmzFile(const char *file) {  		for (int ii = 0; ii < 4; ii++)  			_levelBlockProperties[i].walls[ii] = p[i * len + ii]; -		_levelBlockProperties[i].field_8 = 5; +		_levelBlockProperties[i].direction = 5;  		if (_wllBuffer4[_levelBlockProperties[i].walls[0]] == 17) {  			_levelBlockProperties[i].flags &= 0xef; @@ -482,111 +315,6 @@ void LoLEngine::loadCmzFile(const char *file) {  	}  } -void LoLEngine::loadMonsterShapes(const char *file, int monsterIndex, int b) { -	releaseMonsterShapes(monsterIndex); -	_screen->loadBitmap(file, 3, 3, 0); - -	const uint8 *p = _screen->getCPagePtr(2); -	const uint8 *ts[16]; - -	for (int i = 0; i < 16; i++) { -		ts[i] = _screen->getPtrToShape(p, i); - -		bool replaced = false; -		int pos = monsterIndex << 4; - -		for (int ii = 0; ii < i; ii++) { -			if (ts[i] != ts[ii]) -				continue; - -			_monsterShapes[pos + i] = _monsterShapes[pos + ii]; -			replaced = true; -			break; -		} - -		if (!replaced) -			_monsterShapes[pos + i] = _screen->makeShapeCopy(p, i); - -		int size = _screen->getShapePaletteSize(_monsterShapes[pos + i]) << 3; -		_monsterPalettes[pos + i] = new uint8[size]; -		memset(_monsterPalettes[pos + i], 0, size); -	} - -	for (int i = 0; i < 4; i++) { -		for (int ii = 0; ii < 16; ii++) { -			uint8 **of = &_buf4[(monsterIndex << 7) + (i << 5) + (ii << 1)]; -			int s = (i << 4) + ii + 17; -			*of = _screen->makeShapeCopy(p, s); - -			////TODO -		} -	} -	_monsterUnk[monsterIndex] = b & 0xff; - -	uint8 *tsh = _screen->makeShapeCopy(p, 16); - -	_screen->clearPage(3); -	_screen->drawShape(2, tsh, 0, 0, 0, 0); - -	uint8 *tmpPal1 = new uint8[64]; -	uint8 *tmpPal2 = new uint8[256]; -	uint16 *tmpPal3 = new uint16[256]; -	memset (tmpPal1, 0, 64); -	memset (tmpPal2, 0, 256); -	memset (tmpPal3, 0xff, 512); - -	for (int i = 0; i < 64; i++) { -		tmpPal1[i] = *p; -		p += 320; -	} - -	p = _screen->getCPagePtr(2); - -	for (int i = 0; i < 16; i++) { -		int pos = (monsterIndex << 4) + i; -		memcpy(tmpPal2, _monsterShapes[pos] + 10, 256); -		uint8 numCol = *tmpPal2; - -		for (int ii = 0; ii < numCol; ii++) { -			uint8 *cl = (uint8*)memchr(tmpPal1, tmpPal2[1 + ii], 64); -			if (!cl) -				continue; -			tmpPal3[ii] = (uint16) (cl - tmpPal1); -		} - -		for (int ii = 0; ii < 8; ii++) { -			memcpy(tmpPal2, _monsterShapes[pos] + 10, 256); -			for (int iii = 0; iii < numCol; iii++) { -				if (tmpPal3[iii] == 0xffff) -					continue; -				if (p[tmpPal3[iii] * 320 + ii + 1]) -					tmpPal2[1 + iii] = p[tmpPal3[iii] * 320 + ii + 1]; -			} -			memcpy(_monsterPalettes[pos] + ii * numCol, &tmpPal2[1], numCol); -		} -	} - -	delete[] tmpPal1; -	delete[] tmpPal2; -	delete[] tmpPal3; -	delete[]  tsh; -} - -void LoLEngine::releaseMonsterShapes(int monsterIndex) { -	for (int i = 0; i < 16; i++) { -		int pos = (monsterIndex << 4) + i; -		if (_monsterShapes[pos]) { -			delete[] _monsterShapes[pos]; -			_monsterShapes[pos] = 0; -		} - -		if (_monsterPalettes[pos]) { -			delete[] _monsterPalettes[pos]; -			_monsterPalettes[pos] = 0; -		} -	} -} -  void LoLEngine::loadLevelShpDat(const char *shpFile, const char *datFile, bool flag) {  	memset(_tempBuffer5120, 0, 5120); @@ -724,14 +452,14 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight  void LoLEngine::resetItems(int flag) {  	for (int i = 0; i < 1024; i++) { -		_levelBlockProperties[i].field_8 = 5; -		uint16 id = _levelBlockProperties[i].itemIndex; +		_levelBlockProperties[i].direction = 5; +		uint16 id = _levelBlockProperties[i].itemMonsterIndex;  		MonsterInPlay *r = 0;  		while (id & 0x8000) {  			r = (MonsterInPlay*)findItem(id);  			assert(r); -			id = r->itemIndexUnk; +			id = r->next;  		}  		if (!id) @@ -740,7 +468,7 @@ void LoLEngine::resetItems(int flag) {  		ItemInPlay *it = &_itemsInPlay[id];  		it->level = _currentLevel;  		it->blockPropertyIndex = i; -		r->itemIndexUnk = 0; +		r->next = 0;  	}  	if (flag) @@ -750,7 +478,7 @@ void LoLEngine::resetItems(int flag) {  void LoLEngine::resetLvlBuffer() {  	memset(_monsters, 0, 30 * sizeof(MonsterInPlay));  	for (int i = 0; i < 30; i++) -		_monsters[i].field_14 = 0x10; +		_monsters[i].mode = 0x10;  }  void LoLEngine::resetBlockProperties() { @@ -921,16 +649,25 @@ uint16 LoLEngine::calcNewBlockPosition(uint16 curBlock, uint16 direction) {  	return (curBlock + blockPosTable[direction]) & 0x3ff;  } +uint16 LoLEngine::calcBlockIndex(uint16 x, uint16 y) { + 	return ((y & 0xff00) >> 3) | (x >> 8); +} + +void LoLEngine::calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs) { +	x = (block & 0x1f) << 8 | xOffs; +	y = ((block & 0xffe0) << 3) | yOffs; +} +  bool LoLEngine::checkBlockPassability(uint16 block, uint16 direction) {  	if (testWallFlag(block, direction, 1))  		return false; -	uint16 d = _levelBlockProperties[block].itemIndex; +	uint16 d = _levelBlockProperties[block].itemMonsterIndex;  	while (d) {  		if (d & 0x8000)  			return false; -		d = findItem(d)->itemIndexUnk; +		d = findItem(d)->next;  	}  	return true; @@ -945,7 +682,7 @@ void LoLEngine::notifyBlockNotPassable(int scrollFlag) {  	snd_playSoundEffect(19, -1);  } -int LoLEngine::clickedDecoration(uint16 block, uint16 direction) { +int LoLEngine::clickedWallShape(uint16 block, uint16 direction) {  	uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];  	if (!clickedShape(v))  		return 0; @@ -956,7 +693,20 @@ int LoLEngine::clickedDecoration(uint16 block, uint16 direction) {  	return 1;  } -int LoLEngine::switchOpenDoor(uint16 block, uint16 direction) { +int LoLEngine::clicked2(uint16 block, uint16 direction) { +	return 1; +} + +int LoLEngine::clicked3(uint16 block, uint16 direction) { +	return 1; +} + +int LoLEngine::clickedWallOnlyScript(uint16 block) { +	runLevelScript(block, 0x40);	 +	return 1; +} + +int LoLEngine::clickedDoorSwitch(uint16 block, uint16 direction) {  	uint8 v = _wllShapeMap[_levelBlockProperties[block].walls[direction]];  	if (!clickedShape(v))  		return 0; @@ -973,6 +723,10 @@ int LoLEngine::switchOpenDoor(uint16 block, uint16 direction) {  	return 1;  } +int LoLEngine::clicked6(uint16 block, uint16 direction) { +	return 1; +} +  bool LoLEngine::clickedShape(int shapeIndex) {  	while (shapeIndex) {  		uint16 s = _levelShapeProperties[shapeIndex].shapeIndex[1]; @@ -1654,7 +1408,7 @@ void LoLEngine::drawSceneShapes() {  		drawIceShapes(t, 0); -		if (_curBlockCaps[t]->itemIndex && (w & 0x80)) +		if (_curBlockCaps[t]->itemMonsterIndex && (w & 0x80))  			drawMonstersAndItems(t);  		drawIceShapes(t, 1); @@ -1847,89 +1601,6 @@ void LoLEngine::drawIceShapes(int index, int iceShapeIndex) {  		return;  } -void LoLEngine::drawMonstersAndItems(int block) { -	 - -} - -void LoLEngine::drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags) { -	uint8 c = _dscDoor1[(_currentDirection << 5) + unk2]; -	int r = (c / 5) + 5 * _dscDimMap[index]; -	uint16 d = _dscShapeOvlIndex[r]; -	uint16 t = (index << 5) + c; - -	_shpDmY = _dscDoorMonsterY[t] + 120; - -	if (flags & 1) { -		// TODO -	} - -	int u = 0; - -	if (flags & 2) { -		uint8 dimW = _dscDimMap[index]; -		_dmScaleW = _dscDoorMonsterScaleTable[dimW << 1]; -		_dmScaleH = _dscDoorMonsterScaleTable[(dimW << 1) + 1]; -		u = _dscDoor4[dimW]; -	} - -	d += 2; - -	if (!_dmScaleW || !_dmScaleH) -		return; - -	int s = _screen->getShapeScaledHeight(shape, _dmScaleH) >> 1; - -	if (w) -		w = (w * _dmScaleW) >> 8; - -	if (h) -		h = (h * _dmScaleH) >> 8; - -	_shpDmX = _dscDoorMonsterX[t] + w + 200; -	_shpDmY = _shpDmY + 4 - s + h - u; - -	if (d > 7) -		d = 7; - -	uint8 *ovl = _screen->getLevelOverlay(d); -	int doorScaledWitdh = _screen->getShapeScaledWidth(shape, _dmScaleW); - -	_shpDmX -= (doorScaledWitdh >> 1); -	_shpDmY -= s; - -	drawDoorOrMonsterShape(shape, table, _shpDmX, _shpDmY, flags, ovl); -} - -void LoLEngine::drawDoorOrMonsterShape(uint8 *shape, uint8 *table, int x, int y, int flags, const uint8 *ovl) { -	int flg = 0; - -	if (flags & 0x10) -		flg |= 1; - -	if (flags & 0x20) -		flg |= 0x1000; - -	if (flags & 0x40) -		flg |= 2; - -	if (flg & 0x1000) { -		if (table) -			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x9104, table, ovl, 1, _trueLightTable1, _trueLightTable2, _dmScaleW, _dmScaleH); -		else -			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x1104, ovl, 1, _trueLightTable1, _trueLightTable2, _dmScaleW, _dmScaleH); -	} else { -		if (table) -			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x8104, table, ovl, 1, _dmScaleW, _dmScaleH); -		else -			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x104, ovl, 1, _dmScaleW, _dmScaleH); -	} -} - -void LoLEngine::drawSceneItem(uint8 *shape, uint8 *ovl, int x, int y, int w, int h, int flags, int unk1, int unk2) { - -} -  void LoLEngine::drawScriptShapes(int pageNum) {  	if (!_scriptAssignedLevelShape)  		return; diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 71d49a7aae..04227322ed 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -1151,6 +1151,7 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int  	_dsTable = 0;  	_dsTableLoopCount = 0;  	_dsTable2 = 0; +	_dsTable5 = 0;  	_dsDrawLayer = 0;  	uint8 *table3 = 0; @@ -1195,7 +1196,7 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int  	}  	if ((flags & 0x2000) && _vm->gameFlags().gameID != GI_KYRA1) -		va_arg(args, int); +		_dsTable5 = va_arg(args,  uint8*);  	static const DsMarginSkipFunc dsMarginFunc[] = {  		&Screen::drawShapeMarginNoScaleUpwind, @@ -1248,6 +1249,10 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int  		&Screen::drawShapePlotType14,		// used by Kyra 1 (invisibility)  		&Screen::drawShapePlotType11_15,	// used by Kyra 1 (invisibility)  		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, +		&Screen::drawShapePlotType37,		// used by LoL (monsters) +		0, 0, 0, 0, 0, 0, 0, 0, 0,  		0, 0, 0, 0, 0, 0, 0, 0, 0, 0  	}; @@ -1808,6 +1813,20 @@ void Screen::drawShapePlotType14(uint8 *dst, uint8 cmd) {  	*dst = cmd;  } +void Screen::drawShapePlotType37(uint8 *dst, uint8 cmd) { +	cmd = _dsTable2[cmd]; +	 +	if (cmd == 255) { +		cmd = _dsTable5[*dst]; +	} else { +		for (int i = 0; i < _dsTableLoopCount; ++i) +			cmd = _dsTable[cmd]; +	} + +	if (cmd) +		*dst = cmd; +} +  void Screen::decodeFrame3(const uint8 *src, uint8 *dst, uint32 size) {  	debugC(9, kDebugLevelScreen, "Screen::decodeFrame3(%p, %p, %u)", (const void *)src, (const void *)dst, size);  	const uint8 *dstEnd = dst + size; diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index 8299262d0e..737cd03082 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -332,6 +332,7 @@ protected:  	void drawShapePlotType12(uint8 *dst, uint8 cmd);  	void drawShapePlotType13(uint8 *dst, uint8 cmd);  	void drawShapePlotType14(uint8 *dst, uint8 cmd); +	void drawShapePlotType37(uint8 *dst, uint8 cmd);  	typedef int (Screen::*DsMarginSkipFunc)(uint8 *&dst, const uint8 *&src, int &cnt);  	typedef void (Screen::*DsLineFunc)(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); @@ -345,6 +346,7 @@ protected:  	const uint8 *_dsTable;  	int _dsTableLoopCount;  	const uint8 *_dsTable2; +	const uint8 *_dsTable5;  	int _dsDrawLayer;  	uint8 *_dsDstPage;  	int _dsTmpWidth; diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index 8e65cd3d9b..77bfba3025 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -32,7 +32,8 @@  namespace Kyra { -void LoLEngine::runInitScript(const char *filename, int func) { +void LoLEngine::runInitScript(const char *filename, int optionalFunc) { +	_suspendScript = true;	  	EMCData scriptData;  	EMCState scriptState;  	memset(&scriptData, 0, sizeof(EMCData)); @@ -43,14 +44,15 @@ void LoLEngine::runInitScript(const char *filename, int func) {  	while (_emc->isValid(&scriptState))  		_emc->run(&scriptState); -	if (func) { +	if (optionalFunc) {  		_emc->init(&scriptState, &scriptData); -		_emc->start(&scriptState, func); +		_emc->start(&scriptState, optionalFunc);  		while (_emc->isValid(&scriptState))  			_emc->run(&scriptState);  	}  	_emc->unload(&scriptData); +	_suspendScript = false;  }  void LoLEngine::runInfScript(const char *filename) { @@ -66,7 +68,7 @@ void LoLEngine::runLevelScriptCustom(int block, int sub, int charNum, int item,  	EMCState scriptState;  	memset(&scriptState, 0, sizeof(EMCState)); -	if (!_scriptBoolSkipExec) { +	if (!_suspendScript) {  		_emc->init(&scriptState, &_scriptData);  		_emc->start(&scriptState, block); @@ -78,14 +80,18 @@ void LoLEngine::runLevelScriptCustom(int block, int sub, int charNum, int item,  		scriptState.regs[5] = block;  		scriptState.regs[6] = _scriptDirection; -		while (_emc->isValid(&scriptState)) -			_emc->run(&scriptState); +		if (_emc->isValid(&scriptState)) { +			if (*(scriptState.ip - 1) & sub) { +				while (_emc->isValid(&scriptState)) +					_emc->run(&scriptState); +			} +		}  	} -	checkScriptUnk(block); +	checkSceneUpdateNeed(block);  } -bool LoLEngine::checkScriptUnk(int func) { +bool LoLEngine::checkSceneUpdateNeed(int func) {  	if (_sceneUpdateRequired)  		return true; @@ -116,7 +122,7 @@ int LoLEngine::olol_setGameFlag(EMCState *script) {  int LoLEngine::olol_testGameFlag(EMCState *script) {  	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_testGameFlag(%p) (%d)", (const void *)script, stackPos(0)); -	if (!stackPos(0)) +	if (stackPos(0) < 0)  		return 0;  	if (_gameFlags[stackPos(0) >> 4] & (1 << (stackPos(0) & 0x0f))) @@ -454,6 +460,7 @@ int LoLEngine::olol_setGlobalVar(EMCState *script) {  		break;  	case 3: +		setHandItem(b);  		break;  	case 4: @@ -488,7 +495,7 @@ int LoLEngine::olol_setGlobalVar(EMCState *script) {  	case 10:  		_sceneDefaultUpdate = b & 0xff; -		//TODO +		gui_toggleButtonDisplayMode(0, 0);  		break;  	case 11: @@ -519,6 +526,56 @@ int LoLEngine::olol_resetBlockShapeAssignment(EMCState *script) {  	return 1;  } +int LoLEngine::olol_initMonster(EMCState *script) { +	uint16 x = 0; +	uint16 y = 0; +	calcCoordinates(x, y, stackPos(0), stackPos(1), stackPos(2)); +	uint16 w = _monsterProperties[stackPos(4)].maxWidth; +	 +	if (checkBlockBeforeMonsterPlacement(x, y, w, 7, 7)) +		return -1; +	 +	for (uint8 i = 0; i < 30; i++) { +		MonsterInPlay *l = &_monsters[i]; +		if (l->might || l->mode == 13) +			continue; + +		memset(l, 0, sizeof(MonsterInPlay)); +		l->id = i; +		l->x = x; +		l->y = y; +		l->facing = stackPos(3); +		l->type = stackPos(4); +		l->properties = &_monsterProperties[l->type]; +		l->field_17 = l->facing << 1; +		l->might = (l->properties->might * _monsterModifiers[((_unkGameFlag & 0x30) >> 4)]) >> 8; + +		if (_currentLevel == 12 && l->type == 2) +			l->might = (l->might * (_rnd.getRandomNumberRng(1, 128) + 192)) >> 8; + +		l->field_25 = l->properties->unk6[0]; +		l->field_27 = _rnd.getRandomNumberRng(1, calcMonsterSkillLevel(l->id | 0x8000, 8)) - 1; +		l->unk4 = 2; +		l->flags = stackPos(5); +		l->assignedItems = 0; + +		setMonsterMode(l, stackPos(6)); +		placeMonster(l, l->x, l->y); + +		l->itemPosX = l->x; +		l->itemPosY = l->y; +		l->field10 = l->field_17; + +		for (int ii = 0; ii < 4; ii++) +			l->field_2A[ii] = stackPos(7 + ii); + +		checkSceneUpdateNeed(l->blockPropertyIndex);		 +		return i; +	} + +	return -1; +} +  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), @@ -529,12 +586,12 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) {  		stackPos(35), stackPos(36), stackPos(37), stackPos(38), stackPos(39), stackPos(40), stackPos(41));  	MonsterProperty *l = &_monsterProperties[stackPos(0)]; -	l->id = stackPos(1) & 0xff; +	l->shapeIndex = stackPos(1) & 0xff;  	int shpWidthMax = 0;  	for (int i = 0; i < 16; i++) { -		uint8 m = _monsterShapes[(l->id << 4) + i][3]; +		uint8 m = _monsterShapes[(l->shapeIndex << 4) + i][3];  		if (m > shpWidthMax)  			shpWidthMax = m;  	} @@ -556,18 +613,18 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) {  		l->unk3[i] = (stackPos(17 + i) << 8) / 100;  	} -	l->pos = &l->unk[0]; +	l->pos = &l->field2[0];  	l->itemProtection = stackPos(25);  	l->might = stackPos(26);  	l->b = 1; -	l->unk5[0] = stackPos(27); -	l->unk5[1] = stackPos(28); +	l->flags = stackPos(27); +	l->unk5 = stackPos(28);  	// FIXME??? -	l->unk5[1] = stackPos(29); +	l->unk5 = stackPos(29);  	//  	for (int i = 0; i < 5; i++) -		l->unk6[2 + i] = stackPos(30 + i); +		l->unk6[i] = stackPos(30 + i);  	for (int i = 0; i < 2; i++) {  		l->unk7[i] = stackPos(35 + i); @@ -575,12 +632,23 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) {  	}  	for (int i = 0; i < 3; i++) -		l->unk8[2 + i] = stackPos(39 + i); +		l->unk8[i] = stackPos(39 + i);  	return 1;  }  int LoLEngine::olol_68(EMCState *script) { + +	MonsterInPlay *m = &_monsters[stackPos(0)]; +	 +	if (m->mode == 1 || m->mode == 2) { +		calcCoordinates(m->itemPosX, m->itemPosY, stackPos(1), stackPos(2), stackPos(3)); +		m->field10 = stackPos(4); + +		if (m->x != m->itemPosX || m->y != m->itemPosY) +			cmzS2(m, cmzS1(m->x, m->y, m->itemPosX, m->itemPosY)); +	} +  	return 1;  } @@ -632,7 +700,11 @@ int LoLEngine::olol_restoreSceneAfterDialogueSequence(EMCState *script) {  	return 1;  } -int LoLEngine::olol_85(EMCState *script) { +int LoLEngine::olol_giveItemToMonster(EMCState *script) { +	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_giveItemToMonster(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); +	if (stackPos(0) == -1) +		return 0; +	giveItemToMonster(&_monsters[stackPos(0)], stackPos(1));  	return 1;  } @@ -646,6 +718,12 @@ int LoLEngine::olol_loadLangFile(EMCState *script) {  	return 1;  } +int LoLEngine::olol_playSoundEffect(EMCState *script) { +	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0)); +	snd_playSoundEffect(stackPos(0), 255); +	return 1; +} +  int LoLEngine::olol_stopTimScript(EMCState *script) {  	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_stopTimScript(%p) (%d)", (const void *)script, stackPos(0));  	_tim->stopAllFuncs(_activeTim[stackPos(0)]); @@ -674,6 +752,17 @@ int LoLEngine::olol_setPaletteBrightness(EMCState *script) {  	return old;  } +int LoLEngine::olol_printMessage(EMCState *script) { +	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_printMessage(%p) (%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), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); +	int snd = stackPos(2); +	_txt->printMessage(stackPos(0), getLangString(stackPos(1)), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); + +	if (snd) +		snd_playSoundEffect(snd, 255); + +	return 1; +} +  int LoLEngine::olol_playDialogueTalkText(EMCState *script) {  	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playDialogueTalkText(%p) (%d)", (const void *)script, stackPos(0));  	int track = stackPos(0); @@ -686,11 +775,11 @@ int LoLEngine::olol_playDialogueTalkText(EMCState *script) {  	return 1;  } -int LoLEngine::olol_checkDialogueState(EMCState *script) { +int LoLEngine::olol_checkForMonsterMode1(EMCState *script) {  	for (int i = 0; i < 30; i++) {  		if (stackPos(0) != _monsters[i].type && stackPos(0) != -1)  			continue; -		return (_monsters[i].field_14 == 1) ? 0 : 1; +		return (_monsters[i].mode == 1) ? 0 : 1;  	}  	return 1;  } @@ -895,7 +984,7 @@ void LoLEngine::setupOpcodeTable() {  	OpcodeUnImpl();  	// 0x38 -	OpcodeUnImpl(); +	Opcode(olol_initMonster);  	OpcodeUnImpl();  	OpcodeUnImpl();  	OpcodeUnImpl(); @@ -938,9 +1027,9 @@ void LoLEngine::setupOpcodeTable() {  	// 0x54  	OpcodeUnImpl(); -	Opcode(olol_85); +	Opcode(olol_giveItemToMonster);  	Opcode(olol_loadLangFile); -	OpcodeUnImpl(); +	Opcode(olol_playSoundEffect);  	// 0x58  	OpcodeUnImpl(); @@ -976,7 +1065,7 @@ void LoLEngine::setupOpcodeTable() {  	OpcodeUnImpl();  	OpcodeUnImpl();  	OpcodeUnImpl(); -	OpcodeUnImpl(); +	Opcode(olol_printMessage);  	// 0x70  	OpcodeUnImpl(); @@ -994,7 +1083,7 @@ void LoLEngine::setupOpcodeTable() {  	OpcodeUnImpl();  	OpcodeUnImpl();  	Opcode(olol_playDialogueTalkText); -	Opcode(olol_checkDialogueState); +	Opcode(olol_checkForMonsterMode1);  	// 0x7C  	Opcode(olol_setNextFunc); diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp new file mode 100644 index 0000000000..603a45cb93 --- /dev/null +++ b/engines/kyra/sprites_lol.cpp @@ -0,0 +1,942 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/lol.h" +#include "kyra/screen_lol.h" + +namespace Kyra { + +void LoLEngine::loadMonsterShapes(const char *file, int monsterIndex, int b) { +	releaseMonsterShapes(monsterIndex); +	_screen->loadBitmap(file, 3, 3, 0); + +	const uint8 *p = _screen->getCPagePtr(2); +	const uint8 *ts[16]; + +	for (int i = 0; i < 16; i++) { +		ts[i] = _screen->getPtrToShape(p, i); + +		bool replaced = false; +		int pos = monsterIndex << 4; + +		for (int ii = 0; ii < i; ii++) { +			if (ts[i] != ts[ii]) +				continue; + +			_monsterShapes[pos + i] = _monsterShapes[pos + ii]; +			replaced = true; +			break; +		} + +		if (!replaced) +			_monsterShapes[pos + i] = _screen->makeShapeCopy(p, i); + +		int size = _screen->getShapePaletteSize(_monsterShapes[pos + i]) << 3; +		_monsterPalettes[pos + i] = new uint8[size]; +		memset(_monsterPalettes[pos + i], 0, size); +	} + +	for (int i = 0; i < 4; i++) { +		for (int ii = 0; ii < 16; ii++) { +			uint8 **of = &_monsterShapesEx[monsterIndex * 192 + i * 48 + ii * 3]; +			int s = (i << 4) + ii + 17; +			of[0] = _screen->makeShapeCopy(p, s); +			of[1] = _screen->makeShapeCopy(p, s + 1); +			of[2] = _screen->makeShapeCopy(p, s + 2); +		} +	} +	_monsterUnk[monsterIndex] = b & 0xff; + +	uint8 *tsh = _screen->makeShapeCopy(p, 16); + +	_screen->clearPage(3); +	_screen->drawShape(2, tsh, 0, 0, 0, 0); + +	uint8 *tmpPal1 = new uint8[64]; +	uint8 *tmpPal2 = new uint8[256]; +	uint16 *tmpPal3 = new uint16[256]; +	memset (tmpPal1, 0, 64); +	memset (tmpPal2, 0, 256); +	memset (tmpPal3, 0xff, 512); + +	for (int i = 0; i < 64; i++) { +		tmpPal1[i] = *p; +		p += 320; +	} + +	p = _screen->getCPagePtr(2); + +	for (int i = 0; i < 16; i++) { +		int pos = (monsterIndex << 4) + i; +		memcpy(tmpPal2, _monsterShapes[pos] + 10, 256); +		uint8 numCol = *tmpPal2; + +		for (int ii = 0; ii < numCol; ii++) { +			uint8 *cl = (uint8*)memchr(tmpPal1, tmpPal2[1 + ii], 64); +			if (!cl) +				continue; +			tmpPal3[ii] = (uint16) (cl - tmpPal1); +		} + +		for (int ii = 0; ii < 8; ii++) { +			memcpy(tmpPal2, _monsterShapes[pos] + 10, 256); +			for (int iii = 0; iii < numCol; iii++) { +				if (tmpPal3[iii] == 0xffff) +					continue; +				if (p[tmpPal3[iii] * 320 + ii + 1]) +					tmpPal2[1 + iii] = p[tmpPal3[iii] * 320 + ii + 1]; +			} +			memcpy(_monsterPalettes[pos] + ii * numCol, &tmpPal2[1], numCol); +		} +	} + +	delete[] tmpPal1; +	delete[] tmpPal2; +	delete[] tmpPal3; +	delete[]  tsh; +} + +void LoLEngine::releaseMonsterShapes(int monsterIndex) { +	for (int i = 0; i < 16; i++) { +		int pos = (monsterIndex << 4) + i; +		if (_monsterShapes[pos]) { +			delete[] _monsterShapes[pos]; +			_monsterShapes[pos] = 0; +		} + +		if (_monsterPalettes[pos]) { +			delete[] _monsterPalettes[pos]; +			_monsterPalettes[pos] = 0; +		} +	} +} + +int LoLEngine::placeMonstersUnk(int block) { +	int i = _levelBlockProperties[block].itemMonsterIndex; +	int cnt = 0; +	MonsterInPlay *t = 0; + +	while (i) { +		t = (MonsterInPlay *)findItem(i); +		i = t->next; +		if (!(i & 0x8000)) +			continue; + +		i &= 0x7fff; +		t = &_monsters[i]; + +		cnt++; +		setMonsterMode(t, 14); + +		checkSceneUpdateNeed(t->blockPropertyIndex); + +		placeMonster(t, 0, 0); +	} +	return cnt; +} + +void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) { +	if (monster->mode == 13 && mode != 14) +		return; +	if (mode == 7) { +		monster->itemPosX = _partyPosX; +		monster->itemPosY = _partyPosX; +	} + +	if (monster->mode == 1 && mode == 7) { +		for (int i = 0; i < 30; i++) { +			if (monster->mode != 1) +				continue; +			monster->mode = mode; +			monster->field_15 = 0; +			monster->itemPosX = _partyPosX; +			monster->itemPosY = _partyPosY; +			cmzS2(monster, cmzS1(monster->x, monster->y, monster->itemPosX, monster->itemPosY)); +		} +	} else { +		monster->mode = mode; +		monster->field_15 = 0; +		if (mode == 14) +			monster->might = 0; +		if (mode == 13 && (monster->flags & 0x20)) { +			monster->mode = 0; +			cmzS3(monster); +			if (_currentLevel != 29) +				setMonsterMode(monster, 14); +			runLevelScriptCustom(0x404, -1, monster->id, monster->id, 0, 0); +			checkSceneUpdateNeed(monster->blockPropertyIndex); +			if (monster->mode == 14) +				placeMonster(monster, 0, 0); +		} +	} +} + +void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) { +	bool cont = true; +	int t = monster->blockPropertyIndex; +	if (monster->blockPropertyIndex) { +		removeItemOrMonsterFromBlock(&_levelBlockProperties[monster->blockPropertyIndex].itemMonsterIndex, ((uint16)monster->id) | 0x8000); +		_levelBlockProperties[monster->blockPropertyIndex].direction = 5; +		checkSceneUpdateNeed(monster->blockPropertyIndex); +	} else { +		cont = false; +	} + +	monster->blockPropertyIndex = calcBlockIndex(x, y); + +	if (monster->x != x || monster->y != y) { +		monster->x = x; +		monster->y = y; +		monster->anon9 = (++monster->anon9) & 3; +	} + +	if (monster->blockPropertyIndex == 0) +		return; + +	assignItemOrMonsterToBlock(&_levelBlockProperties[monster->blockPropertyIndex].itemMonsterIndex, ((uint16)monster->id) | 0x8000); +	_levelBlockProperties[monster->blockPropertyIndex].direction = 5; +	checkSceneUpdateNeed(monster->blockPropertyIndex); + +	if (monster->properties->unk8[0] == 0 || cont == false) +		return; + +	if ((!(monster->properties->flags & 0x100) || ((monster->anon9 & 1) == 0)) && monster->blockPropertyIndex == t) +		return; + +	if (monster->blockPropertyIndex != t) +		runLevelScriptCustom(monster->blockPropertyIndex, 0x800, -1, monster->id, 0, 0); + +	if (_updateFlags & 1) +		return; + +	cmzS7(monster->properties->unk3[5], monster->blockPropertyIndex); +} + +int LoLEngine::cmzS1(uint16 x1, uint16 y1, uint16 x2, uint16 y2) { +	int16 r = 0; +	int16 t1 = y1 - y2; +	if (t1 < 0) { +		r++; +		t1 = -t1; +	} + +	r <<= 1; + +	int16 t2 = x2 - x1; + +	if (t2 < 0) { +		r++; +		t2 = -t2; +	} + +	uint8 f = 0; + +	if (t2 >= t1) { +		if (t2 > t1) +			f = 1; +		SWAP(t1, t2); +	} + +	r = (r << 1) | f; + +	t1 = (t1 + 1) >> 1; + +	f = 0; +	f = (t2 > t1) ? 1 : 0; +	r = (r << 1) | f; + +	static const uint8 retVal[] = { 1, 2, 1, 0, 7, 6, 7, 0, 3, 2, 3, 4, 5, 6, 5, 4}; +	return retVal[r]; +} + +void LoLEngine::cmzS2(MonsterInPlay *monster, int a) { +	monster->field_17 = a; + +	if (!(a & 1) || ((monster->field_17 - (monster->facing << 1)) < 2)) +		monster->facing = monster->field_17 >> 1; + +	checkSceneUpdateNeed(monster->blockPropertyIndex); +} + +void LoLEngine::cmzS3(MonsterInPlay *l) { +	// TODO +} + +void LoLEngine::removeItemOrMonsterFromBlock(uint16 *blockItemIndex, int id) { +	while (*blockItemIndex) { +		if (*blockItemIndex == id) { +			ItemInPlay *t = findItem(id); +			blockItemIndex = &t->next; +			t->next = 0; +			return; +		} else { +			ItemInPlay *t = findItem(*blockItemIndex); +			blockItemIndex = &t->next; +		} +	} +} + +void LoLEngine::assignItemOrMonsterToBlock(uint16 *blockItemIndex, int id) { +	ItemInPlay *t = findItem(id); +	t->next = *blockItemIndex; +	*blockItemIndex = id; +} + +int LoLEngine::checkBlockBeforeMonsterPlacement(int x, int y, int monsterWidth, int p1, int p2) { +	int monsterUnk_ = 0; +	int x2 = 0; +	int y2 = 0; +	int xOffs = 0; +	int yOffs = 0; +	int flag = 0; +	 +	int r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y), x, y, monsterWidth, p1, p2); +	if (r) +		return r; + +	r = checkBlockOccupiedByParty(x, y, p1); +	if (r) +		return 4; + +	if (x & 0x80) { +		if (((x & 0xff) + monsterWidth) & 0xff00) { +			xOffs = 1; +			monsterUnk_ = 2; +			x2 = x + monsterWidth; + +			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x2, y), x, y, monsterWidth, p1, p2); +			if (r) +				return r; + +			r = checkBlockOccupiedByParty(x + xOffs, y, p1); +			if (r) +				return 4; + +			flag = 1; +		} +	} else { +		if (((x & 0xff) - monsterWidth) & 0xff00) { +			xOffs = -1; +			monsterUnk_ = 6; +			x2 = x - monsterWidth; + +			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x2, y), x, y, monsterWidth, p1, p2); +			if (r) +				return r; + +			r = checkBlockOccupiedByParty(x + xOffs, y, p1); +			if (r) +				return 4; + +			flag = 1; +		} +	} + +	if (y & 0x80) { +		if (((y & 0xff) + monsterWidth) & 0xff00) { +			yOffs = 1; +			monsterUnk_ = 4; +			y2 = y + monsterWidth; + +			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y2), x, y, monsterWidth, p1, p2); +			if (r) +				return r; + +			r = checkBlockOccupiedByParty(x, y + yOffs, p1); +			if (r) +				return 4; +		} else { +			flag = 0; +		} +	} else { +		if (((y & 0xff) - monsterWidth) & 0xff00) { +			yOffs = -1; +			monsterUnk_ = 0; +			y2 = y - monsterWidth; + +			r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y2), x, y, monsterWidth, p1, p2); +			if (r) +				return r; + +			r = checkBlockOccupiedByParty(x, y + yOffs, p1); +			if (r) +				return 4; +		} else { +			flag = 0; +		} +	} + +	if (!flag) +		return 0; + +	r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x2, y2), x, y, monsterWidth, p1, p2); +	if (r) +		return r; + +	r = checkBlockOccupiedByParty(x + xOffs, y + yOffs, p1); +	if (r) +		return 4; + +	return 0; +} + +int LoLEngine::calcMonsterSkillLevel(int id, int a) { +	const uint16 *c = getCharacterOrMonsterStats(id); +	int r = (a << 8) / c[4]; + +	if (!(id & 0x8000)) +		r = (r * _monsterModifiers[3 + ((_unkGameFlag & 0x30) << 4)]) >> 8; + +	id &= 0x7fff; + +	if (_characters[id].skillLevels[1] <= 3) +		return r; +	else if (_characters[id].skillLevels[1] <= 7) +		return (r- (r >> 2)); +	 +	return (r- (r >> 1)); +} + +int LoLEngine::checkBlockForWallsAndSufficientSpace(int block, int x, int y, int monsterWidth, int p1, int p2) { +	if (block == _currentBlock) +		p1 &= 0xfffe; + +	int _monsterBlock = 0; + +	if (p1 & 1) { +		_monsterBlock = block; +		if (testWallFlag(block, -1, p2)) +			return 1; +	} + +	_monsterBlock = 0; + +	if (!(p1 & 2)) +		return 0; + +	uint16 b = _levelBlockProperties[block].itemMonsterIndex; +	while (b & 0x8000) { +		MonsterInPlay *monster = &_monsters[b & 0x7fff]; +		 +		if (monster->mode < 13) { +			int r = checkMonsterSpace(x, y, monster->x, monster->y); +			if ((monsterWidth + monster->properties->maxWidth) > r) +				return 2; +		} + +		b = findItem(b)->next; +	} + +	return 0; +} + +bool LoLEngine::checkBlockOccupiedByParty(int x, int y, int p1) { +	if ((p1 & 4) && (_currentBlock == calcBlockIndex(x, y))) +		return true; + +	return false; +} + +void LoLEngine::drawMonstersAndItems(int block) { +	LevelBlockProperty *l = _curBlockCaps[block]; +	uint16 s = l->itemMonsterIndex;		 +	ItemInPlay *i = findItem(s); + +	if (l->direction != _currentDirection) { +		l->field_6 = 0; +		l->direction = _currentDirection; + +		while (s) { +			i = findItem(s); +			recalcItemMonsterPositions(_currentDirection, s, l, true); +			i = findItem(s); +			s = i->next; +		} +	} + +	s = l->field_6; +	while (s) { +		if (s & 0x8000) { +			s &= 0x7fff; +			if (block < 15) +				drawMonster(s); +			s = _monsters[s].unk2; +		} else { +			////////// +			// TODO + +		} +	} +} + +void LoLEngine::drawMonster(uint16 id) { +	MonsterInPlay *m = &_monsters[id];	 +	int16 flg = _monsterDirFlags[(_currentDirection << 2) + m->facing]; +	int curFrm = getMonsterCurFrame(m, flg & 0xffef); + +	if (curFrm == -1) { +		//////////// +		// TODO + +	} else { +		int d = m->flags & 7; +		bool flip = m->properties->flags & 0x200 ? true : false; +		flg &= 0x10; +		uint8 *shp = _monsterShapes[(m->properties->shapeIndex << 4) + curFrm]; +		 +		if (m->properties->flags & 0x800) +			flg |= 0x20; + +		uint8 *ovl1 = d ? _monsterPalettes[(m->properties->shapeIndex << 4) + (curFrm & 0x0f)] + (shp[10] * (d - 1)) : 0; +		uint8 *ovl2 = drawItemOrMonster(shp, ovl1, m->x + _monsterLevelOffs[m->level << 1], m->y + _monsterLevelOffs[(m->level << 1) + 1], 0, 0, flg | 1, -1, flip); + +		for (int i = 0; i <	4; i++) { +			int v = m->field_2A[i] - 1; +			if (v == -1) +				break; + +			uint8 *shp2 = _monsterShapesEx[m->properties->shapeIndex * 192 + v * 48 + curFrm * 3]; +			if (!shp2) +				continue; + +			//int dW = (READ_LE_UINT16(shp2 + 4) * _dmScaleW) >> 8; +			//int dH = (READ_LE_UINT16(shp2 + 6) * _dmScaleH) >> 8; +			//if (flg) +			//	_screen->getShapeScaledWidth(shp2, _dmScaleW); + +			drawDoorOrMonsterShape(shp2, 0, _shpDmX, _shpDmY, flg | 1, ovl2); +		} + +		if (!m->field_1B) +			return; + +		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)); +		 +		shp = _gameShapes[6]; +		 +		int cF = m->properties->flags & 0xc000; +		if (cF == 0x4000) +			cF = 63; +		else if (cF == 0x8000) +			cF = 15; +		else if (cF == 0xc000) +			cF = 74; +		else +			cF = 0; + +		uint8 *tbl = new uint8[256]; +		if (cF) {			 +			for (int i = 0; i < 256; i++) { +				tbl[i] = i; +				if (i < 2 || i > 7) +					continue; +				tbl[i] += cF; +			} +		} + +		dW += m->anon8; +		dH += m->anonh; + +		a = CLIP(a, 1, 4); + +		int sW = _dmScaleW / a; +		int sH = _dmScaleH / a; + +		_screen->drawShape(_sceneDrawPage1, shp, _shpDmX + dW, _shpDmY + dH, 13, 0x124, tbl, cF ? 1 : 0, sW, sH); + +		delete[] tbl; +	} +} + +int LoLEngine::getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags) { +	switch (_monsterUnk[m->properties->shapeIndex]) { +		case 0: +			if (dirFlags) { +				return (*m->properties->pos & 0xff) == 13 ? -1 : (dirFlags + m->anon9); +			} else { +				if (m->field_1B) +					return 12; + +				switch (m->mode - 5) { +					case 0: +						return m->field_1B ? 12 : ((m->properties->flags & 4) ? 13 : 0); +					case 3: +						return (m->field_15 + 13); +					case 6: +						return 14; +					case 8: +						return -1; +					default: +						return m->field_1B ? 12 : m->anon9; +				} +			} +			break; +		case 1: +			/////// +			// TODO +			break; +		case 2: +			/////// +			// TODO +			break; +		case 3: +			/////// +			// TODO +			break; +		default: +			break; +	} + +	return 0; +} + +void LoLEngine::recalcItemMonsterPositions(uint16 direction, uint16 itemIndex, LevelBlockProperty *l, bool flag) { +	if (l->direction != direction) { +		l->direction = 5; +		return; +	} + +	ItemInPlay *i1 = findItem(itemIndex); +	int r = calcItemMonsterPosition(i1, direction); +	uint16 *b = &l->field_6; +	ItemInPlay *i2 = 0; + +	while (b) { +		i2 = findItem(itemIndex); + +		if (flag) { +			if (calcItemMonsterPosition(i2, direction) >= r) +				break; +		} else { +			if (calcItemMonsterPosition(i2, direction) > r) +				break; +		} + +		b = &i2->unk2; +	} + +	i1->unk2 = *b; +	*b = itemIndex; +} + +int LoLEngine::calcItemMonsterPosition(ItemInPlay *i, uint16 direction) { +	int x = i->x; +	int y = i->y; + +	recalcSpritePosition(_partyPosX, _partyPosY, x, y, direction); + +	if (y < 0) +		y = 0; + +	int res = (i->unk4 << 12); +	res |= (4095 - y); + +	return res; +} + +void LoLEngine::recalcSpritePosition(uint16 partyX, uint16 partyY, int &itemX, int &itemY, uint16 direction) { +	int a = itemX - partyX; +	int b = partyY - itemY; + +	if (direction) { +		if (direction != 2) +			SWAP(a, b); +		if (direction != 3) { +			a = -a; +			if (direction != 1) +				b = -b; +		} else { +			b = -b; +		} +	} + +	itemX = a; +	itemY = b; +} + +void LoLEngine::drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags) { +	uint8 c = _dscDoor1[(_currentDirection << 5) + unk2]; +	int r = (c / 5) + 5 * _dscDimMap[index]; +	uint16 d = _dscShapeOvlIndex[r]; +	uint16 t = (index << 5) + c; + +	_shpDmY = _dscDoorMonsterY[t] + 120; + +	if (flags & 1) { +		// TODO +	} + +	int u = 0; + +	if (flags & 2) { +		uint8 dimW = _dscDimMap[index]; +		_dmScaleW = _dscDoorMonsterScaleTable[dimW << 1]; +		_dmScaleH = _dscDoorMonsterScaleTable[(dimW << 1) + 1]; +		u = _dscDoor4[dimW]; +	} + +	d += 2; + +	if (!_dmScaleW || !_dmScaleH) +		return; + +	int s = _screen->getShapeScaledHeight(shape, _dmScaleH) >> 1; + +	if (w) +		w = (w * _dmScaleW) >> 8; + +	if (h) +		h = (h * _dmScaleH) >> 8; + +	_shpDmX = _dscDoorMonsterX[t] + w + 200; +	_shpDmY = _shpDmY + 4 - s + h - u; + +	if (d > 7) +		d = 7; + +	uint8 *ovl = _screen->getLevelOverlay(d); +	int doorScaledWitdh = _screen->getShapeScaledWidth(shape, _dmScaleW); + +	_shpDmX -= (doorScaledWitdh >> 1); +	_shpDmY -= s; + +	drawDoorOrMonsterShape(shape, table, _shpDmX, _shpDmY, flags, ovl); +} + +void LoLEngine::drawDoorOrMonsterShape(uint8 *shape, uint8 *table, int x, int y, int flags, const uint8 *ovl) { +	int flg = 0; + +	if (flags & 0x10) +		flg |= 1; + +	if (flags & 0x20) +		flg |= 0x1000; + +	if (flags & 0x40) +		flg |= 2; + +	if (flg & 0x1000) { +		if (table) +			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x9104, table, ovl, 1, _trueLightTable1, _trueLightTable2, _dmScaleW, _dmScaleH); +		else +			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x1104, ovl, 1, _trueLightTable1, _trueLightTable2, _dmScaleW, _dmScaleH); +	} else { +		if (table) +			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x8104, table, ovl, 1, _dmScaleW, _dmScaleH); +		else +			_screen->drawShape(_sceneDrawPage1, shape, x, y, 13, flg | 0x104, ovl, 1, _dmScaleW, _dmScaleH); +	} +} + +uint8 *LoLEngine::drawItemOrMonster(uint8 *shape, uint8 *table, int x, int y, int w, int h, int flags, int tblValue, bool flip) { +	uint8 *ovl2 = 0; +	uint8 *ovl = 0; +	uint8 tmpOvl[16]; + +	if (flags & 0x80) { +		flags &= 0xff7f; +		ovl2 = table; +		table = 0; +	} else { +		ovl2 = _screen->getLevelOverlay(4); +	} + +	int r = calcDrawingLayerParameters(x, y, _shpDmX, _shpDmY, _dmScaleW, _dmScaleH, shape, flip); + +	if (tblValue == -1) { +		r = 7 - ((r / 3) - 1); +		r = CLIP(r, 0, 7); +		ovl = _screen->getLevelOverlay(r); +	} else {		 +		memset (tmpOvl + 1, tblValue, 15); +		table = tmpOvl; +		ovl = _screen->getLevelOverlay(7); +	} + +	int flg = flags & 0x10 ? 1 : 0; +	if (flags & 0x20) +		flg |= 0x1000; +	if (flags & 0x40) +		flg |= 2; + +	if (_currentLevel == 22) { +		if (ovl) +			ovl[255] = 0; +	} else { +		flg |= 0x2000; +	} + +	_shpDmX += ((_dmScaleW * w) >> 8); +	_shpDmY += ((_dmScaleH * h) >> 8); + +	int dH = _screen->getShapeScaledHeight(shape, _dmScaleH) >> 1; + +	if (flg & 0x1000) { +		if (table) +			_screen->drawShape(_sceneDrawPage1, shape, _shpDmX, _shpDmY, 13, flg | 0x8124, table, ovl, 0, _trueLightTable1, _trueLightTable2, _dmScaleW, _dmScaleH, ovl2); +		else +			_screen->drawShape(_sceneDrawPage1, shape, _shpDmX, _shpDmY, 13, flg | 0x124, ovl, 0, _trueLightTable1, _trueLightTable2, _dmScaleW, _dmScaleH, ovl2); +	} else { +		if (table) +			_screen->drawShape(_sceneDrawPage1, shape, _shpDmX, _shpDmY, 13, flg | 0x8124, table, ovl, 1, _dmScaleW, _dmScaleH, ovl2); +		else +			_screen->drawShape(_sceneDrawPage1, shape, _shpDmX, _shpDmY, 13, flg | 0x124, ovl, 1, _dmScaleW, _dmScaleH, ovl2); +	} + +	_shpDmX -= (_screen->getShapeScaledWidth(shape, _dmScaleW) >> 1); +	_shpDmY -= dH; + +	return ovl; +} + +int LoLEngine::calcDrawingLayerParameters(int x1, int y1, int16 &x2, int16 &y2, int16 &w, int16 &h, uint8 *shape, int flip) { +	recalcSpritePosition(_partyPosX, _partyPosY, x1, y1, _currentDirection); + +	if (y1 < 0) { +		w = h = x2 = y2 = 0; +		return 0; +	} + +	int l = y1 >> 5; +	y2 = _monsterScaleY[l]; +	x2 = ((_monsterScaleX[l] * x1) >> 8) + 200; +	w = h = _monsterScaleWH[_shpDmY - 56]; + +	if (flip) +		y2 = ((120 - y2) >> 1) + _screen->getShapeScaledHeight(shape, _dmScaleH); +	else  +		y2 -= (_screen->getShapeScaledHeight(shape, _dmScaleH) >> 1); + +	return l; +} + +void LoLEngine::updateMonster(MonsterInPlay *monster) { +	static const uint8 monsterState[] = { 1, 0, 1, 3, 3, 0, 0, 3, 4, 1, 0, 0, 4, 0, 0 }; +	if (monster->mode > 14) +		return; + +	int s = monsterState[monster->mode]; +	int a = monster->field_1F++; + +	if ((a < monster->properties->b) && (s & 4)) +		return; + +	monster->field_1F = 0; + +	if (monster->properties->flags & 0x40) { +		monster->might += _rnd.getRandomNumberRng(1, 8); +		if (monster->might > monster->properties->might) +			monster->might = monster->properties->might; +	} + +	if (monster->flags & 8) { +		monster->itemPosX = _partyPosX; +		monster->itemPosY = _partyPosY; +	} + +	if (s & 2) { + +		///// +		// TODO +	} + +	if ((s & 1) && (monster->flags & 0x10)) +		setMonsterMode(monster, 7); + +	//// +	// TODO + +	switch (monster->mode) { +		case 0: +		case 1: +			if (monster->flags & 0x10) { +				for (int i = 0; i < 30; i++) { +					if (_monsters[i].mode == 1) +						setMonsterMode(&_monsters[i], 7); +				} +			} else if (monster->mode == 1) { +				moveMonster(monster); +			} +			break; +		case 2: +			break; +		case 3: +			break; +		case 4: +			break; +		case 5: +			break; +		case 6: +			break; +		case 7: +			break; +		case 8: +			break; +		case 9: +			break; +		case 12: +			break; +		case 13: +			break; +		case 14: +			break; +		default: +			break; +	} + +	if (monster->field_1B) { +		if (monster->field_1B & 0x8000) +			monster->field_1B &= 0x7fff; +		else +			monster->field_1B = 0; +		checkSceneUpdateNeed(monster->blockPropertyIndex); +	} + +	monster->flags &= 0xffef; +} + +void LoLEngine::moveMonster(MonsterInPlay *monster) { +	static const int8 pos[] = { 0, 1, 3, 3, 0, 1, 2, 2, 1, 1, 2, 3, 0, 0, 2, 3, 0 }; +	if (monster->x != monster->itemPosX || monster->y != monster->itemPosY) { +		shiftMonster(monster);		 +	} else if (monster->field_17 != monster->field10) { +		int i = (monster->facing << 2) + (monster->field10 >> 1); +		cmzS2(monster, pos[i]); +	} +} + +void LoLEngine::shiftMonster(MonsterInPlay *monster) { +	if (monster->properties->flags & 0x400) +		return; + + + +} + +} // end of namespace Kyra + diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 17f473568b..df14925037 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -44,7 +44,7 @@  namespace Kyra { -#define RESFILE_VERSION 39 +#define RESFILE_VERSION 40  namespace {  bool checkKyraDat(Common::SeekableReadStream *file) { @@ -387,6 +387,12 @@ bool StaticResource::init() {  		//{ lolCharDefsUnk, lolRawDataBe16, "CHUNK.DEF" },  		{ lolCharDefsAkshel, lolRawDataBe16, "CHAKSHEL.DEF" },  		{ lolExpRequirements, lolRawDataBe32, "EXPERIENCE.DEF" }, +		{ lolMonsterModifiers, lolRawDataBe16, "MONSTMOD.DEF" }, +		{ lolMonsterLevelOffsets, kRawData, "MONSTLVL.DEF" }, +		{ lolMonsterDirFlags, kRawData, "MONSTDIR.DEF" }, +		{ lolMonsterScaleY, kRawData, "MONSTZY.DEF" }, +		{ lolMonsterScaleX, kRawData, "MONSTZX.DEF" }, +		{ lolMonsterScaleWH, lolRawDataBe16, "MONSTSCL.DEF" },  		{ lolInventoryDesc, lolRawDataBe16, "INVDESC.DEF" },  		{ lolLevelShpList, kStringList, "SHPFILES.TXT" }, @@ -1731,6 +1737,12 @@ void LoLEngine::initStaticResource() {  	_charDefsKieran = _staticres->loadRawDataBe16(lolCharDefsKieran, _charDefsKieranSize);  	_charDefsAkshel = _staticres->loadRawDataBe16(lolCharDefsAkshel, _charDefsAkshelSize);  	_expRequirements = (const int32*)_staticres->loadRawDataBe32(lolExpRequirements, _expRequirementsSize); +	_monsterModifiers = _staticres->loadRawDataBe16(lolMonsterModifiers, _monsterModifiersSize); +	_monsterLevelOffs = (const int8*)_staticres->loadRawData(lolMonsterLevelOffsets, _monsterLevelOffsSize); +	_monsterDirFlags = _staticres->loadRawData(lolMonsterDirFlags, _monsterDirFlagsSize); +	_monsterScaleX = (const int8*)_staticres->loadRawData(lolMonsterScaleX, _monsterScaleXSize); +	_monsterScaleY = (const int8*)_staticres->loadRawData(lolMonsterScaleY, _monsterScaleYSize); +	_monsterScaleWH = _staticres->loadRawDataBe16(lolMonsterScaleWH, _monsterScaleWHSize);  	_inventorySlotDesc = _staticres->loadRawDataBe16(lolInventoryDesc, _inventorySlotDescSize);  	_levelShpList = _staticres->loadStrings(lolLevelShpList, _levelShpListSize);  	_levelDatList = _staticres->loadStrings(lolLevelDatList, _levelDatListSize); @@ -1847,8 +1859,8 @@ void LoLEngine::assignButtonCallback(Button *button, int index) {  		cb(clickedInventorySlot),  		cb(clickedInventoryScroll),  		cb(clickedInventoryScroll), -		cb(clickedScenePressSwitch), -		cb(clickedScenePressSwitch), +		cb(clickedWall), +		cb(clickedWall),  		cb(clickedScene),  		cb(clickedUpArrow),  		cb(clickedDownArrow), diff --git a/engines/kyra/timer_lol.cpp b/engines/kyra/timer_lol.cpp index ab94d97101..994c691aa8 100644 --- a/engines/kyra/timer_lol.cpp +++ b/engines/kyra/timer_lol.cpp @@ -35,8 +35,8 @@ void LoLEngine::setupTimers() {  	debugC(9, kDebugLevelMain | kDebugLevelTimer, "LoLEngine::setupTimers()");  	_timer->addTimer(0, TimerV2(timerProcessOpenDoor), 15, true);	 -	_timer->addTimer(0x10, TimerV2(timerSub2), 6, true); -	_timer->addTimer(0x11, TimerV2(timerSub2), 6, true); +	_timer->addTimer(0x10, TimerV2(timerProcessMonsters), 6, true); +	_timer->addTimer(0x11, TimerV2(timerProcessMonsters), 6, true);  	_timer->setNextRun(0x11, 3);  	_timer->addTimer(3, TimerV2(timerSub3), 15, true);  	_timer->addTimer(4, TimerV2(timerSub4), 1, true); @@ -58,8 +58,12 @@ void LoLEngine::timerProcessOpenDoor(int timerNum) {  } -void LoLEngine::timerSub2(int timerNum) { +void LoLEngine::timerProcessMonsters(int timerNum) { +	//if (!_updateMonsters) +	//	return; +	for (int i = timerNum & 0x0f; i < 30; i += 2) +		updateMonster(&_monsters[i]);  }  void LoLEngine::timerSub3(int timerNum) { diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp index 4ec75d653c..6ed270638e 100644 --- a/tools/create_kyradat/create_kyradat.cpp +++ b/tools/create_kyradat/create_kyradat.cpp @@ -31,7 +31,7 @@  #include "md5.h"  enum { -	kKyraDatVersion = 39, +	kKyraDatVersion = 40,  	kIndexSize = 12  }; @@ -284,6 +284,12 @@ const ExtractFilename extractFilenames[] = {  	//{ lolCharDefsUnk, lolTypeRaw16, "CHUNK.DEF" },  	{ lolCharDefsAkshel, lolTypeRaw16, "CHAKSHEL.DEF" },  	{ lolExpRequirements, lolTypeRaw32, "EXPERIENCE.DEF" }, +	{ lolMonsterModifiers, lolTypeRaw16, "MONSTMOD.DEF" }, +	{ lolMonsterLevelOffsets, kTypeRawData, "MONSTLVL.DEF" }, +	{ lolMonsterDirFlags, kTypeRawData, "MONSTDIR.DEF" }, +	{ lolMonsterScaleY, kTypeRawData, "MONSTZY.DEF" }, +	{ lolMonsterScaleX, kTypeRawData, "MONSTZX.DEF" }, +	{ lolMonsterScaleWH, lolTypeRaw16, "MONSTSCL.DEF" },  	{ lolInventoryDesc, lolTypeRaw16, "INVDESC.DEF" },  	{ lolLevelShpList, kTypeStringList, "SHPFILES.TXT" },  	{ lolLevelDatList, kTypeStringList, "DATFILES.TXT" }, diff --git a/tools/create_kyradat/create_kyradat.h b/tools/create_kyradat/create_kyradat.h index ecd7bdd81e..10ce7494fb 100644 --- a/tools/create_kyradat/create_kyradat.h +++ b/tools/create_kyradat/create_kyradat.h @@ -193,6 +193,12 @@ enum kExtractID {  	//lolCharDefsUnk,  	lolCharDefsAkshel,  	lolExpRequirements, +	lolMonsterModifiers, +	lolMonsterLevelOffsets, +	lolMonsterDirFlags, +	lolMonsterScaleY, +	lolMonsterScaleX, +	lolMonsterScaleWH,  	lolInventoryDesc,  	lolLevelShpList, diff --git a/tools/create_kyradat/lol_cd.h b/tools/create_kyradat/lol_cd.h index 66f49d887d..dfc43c1839 100644 --- a/tools/create_kyradat/lol_cd.h +++ b/tools/create_kyradat/lol_cd.h @@ -16,6 +16,12 @@ const ExtractEntry lolCDFile2[] = {  	//{ lolCharDefsUnk, 0x0002B508, 0x0002B51A },  	{ lolCharDefsAkshel, 0x0002B51A, 0x0002B52C },  	{ lolExpRequirements, 0x0002B830, 0x0002B85C }, +	{ lolMonsterModifiers, 0x0002B85C, 0x0002B874 }, +	{ lolMonsterLevelOffsets, 0x00031FDF, 0x00031FFF }, +	{ lolMonsterDirFlags, 0x00031FFF, 0x0003200F }, +	{ lolMonsterScaleY, 0x00031BC0, 0x00031BDE }, +	{ lolMonsterScaleX, 0x00031BDE, 0x00031BFE }, +	{ lolMonsterScaleWH, 0x000285C0, 0x00028638 },  	{ lolInventoryDesc, 0x00032706, 0x0003271C },  	{ lolLevelShpList, 0x00032826, 0x000328A5 }, diff --git a/tools/create_kyradat/misc.h b/tools/create_kyradat/misc.h index 2b865b34a4..fbdaff9e91 100644 --- a/tools/create_kyradat/misc.h +++ b/tools/create_kyradat/misc.h @@ -499,6 +499,12 @@ const int lolCDFile2Need[] = {  	//lolCharDefsUnk,  	lolCharDefsAkshel,  	lolExpRequirements, +	lolMonsterModifiers, +	lolMonsterLevelOffsets, +	lolMonsterDirFlags, +	lolMonsterScaleY, +	lolMonsterScaleX, +	lolMonsterScaleWH,  	lolInventoryDesc,  	lolLevelShpList,  | 
