mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
Reorganize all files in sub directories. The file placement isn't as intuitive as it might be for other engines, which is probably the reason why this hasn't been done before.
584 lines
17 KiB
C++
584 lines
17 KiB
C++
/* 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.
|
|
*
|
|
*/
|
|
|
|
#ifdef ENABLE_LOL
|
|
|
|
#include "kyra/engine/lol.h"
|
|
#include "kyra/graphics/screen_lol.h"
|
|
|
|
#include "common/savefile.h"
|
|
#include "common/substream.h"
|
|
#include "common/memstream.h"
|
|
|
|
#include "graphics/scaler.h"
|
|
|
|
namespace Kyra {
|
|
|
|
Common::Error LoLEngine::loadGameState(int slot) {
|
|
const uint16 *cdf[] = { _charDefsMan, _charDefsWoman, _charDefsKieran, _charDefsMan, _charDefsAkshel };
|
|
|
|
const char *fileName = getSavegameFilename(slot);
|
|
|
|
SaveHeader header;
|
|
Common::InSaveFile *saveFile = openSaveForReading(fileName, header);
|
|
if (!saveFile) {
|
|
_txt->printMessage(2, "%s", getLangString(0x425D));
|
|
return Common::kNoError;
|
|
}
|
|
|
|
if (header.originalSave)
|
|
warning("Trying to load savegame from original interpreter, while this is possible, it is not officially supported");
|
|
|
|
_screen->fadeClearSceneWindow(10);
|
|
completeDoorOperations();
|
|
_screen->fillRect(112, 0, 287, 119, 0, 0);
|
|
_screen->updateScreen();
|
|
|
|
Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
LoLCharacter *c = &_characters[i];
|
|
c->flags = in.readUint16();
|
|
in.read(c->name, 11);
|
|
c->raceClassSex = in.readByte();
|
|
c->id = in.readSint16();
|
|
c->curFaceFrame = in.readByte();
|
|
c->tempFaceFrame = in.readByte();
|
|
c->screamSfx = in.readByte();
|
|
if (header.originalSave)
|
|
in.skip(4);
|
|
for (int ii = 0; ii < 8; ii++)
|
|
c->itemsMight[ii] = in.readUint16();
|
|
for (int ii = 0; ii < 8; ii++)
|
|
c->protectionAgainstItems[ii] = in.readUint16();
|
|
c->itemProtection = in.readUint16();
|
|
c->hitPointsCur = in.readSint16();
|
|
c->hitPointsMax = in.readUint16();
|
|
c->magicPointsCur = in.readSint16();
|
|
c->magicPointsMax = in.readUint16();
|
|
c->field_41 = in.readByte();
|
|
c->damageSuffered = in.readUint16();
|
|
c->weaponHit = in.readUint16();
|
|
c->totalMightModifier = in.readUint16();
|
|
c->totalProtectionModifier = in.readUint16();
|
|
c->might = in.readUint16();
|
|
c->protection = in.readUint16();
|
|
c->nextAnimUpdateCountdown = in.readSint16();
|
|
for (int ii = 0; ii < 11; ii++)
|
|
c->items[ii] = in.readUint16();
|
|
for (int ii = 0; ii < 3; ii++)
|
|
c->skillLevels[ii] = in.readByte();
|
|
for (int ii = 0; ii < 3; ii++)
|
|
c->skillModifiers[ii] = in.readSByte();
|
|
for (int ii = 0; ii < 3; ii++)
|
|
c->experiencePts[ii] = in.readUint32();
|
|
for (int ii = 0; ii < 5; ii++)
|
|
c->characterUpdateEvents[ii] = in.readByte();
|
|
for (int ii = 0; ii < 5; ii++)
|
|
c->characterUpdateDelay[ii] = in.readByte();
|
|
|
|
if (c->flags & 1) {
|
|
loadCharFaceShapes(i, c->id);
|
|
c->defaultModifiers = cdf[c->raceClassSex];
|
|
}
|
|
}
|
|
|
|
if (header.version < 17)
|
|
in.skip(80);
|
|
|
|
_currentBlock = in.readUint16();
|
|
_partyPosX = in.readUint16();
|
|
_partyPosY = in.readUint16();
|
|
_updateFlags = in.readUint16();
|
|
_scriptDirection = in.readByte();
|
|
_selectedSpell = in.readByte();
|
|
|
|
if (header.originalSave)
|
|
in.skip(2);
|
|
|
|
_sceneDefaultUpdate = in.readByte();
|
|
_compassBroken = in.readByte();
|
|
_drainMagic = in.readByte();
|
|
_currentDirection = in.readUint16();
|
|
_compassDirection = in.readUint16();
|
|
_selectedCharacter = in.readSByte();
|
|
|
|
if (header.originalSave)
|
|
in.skip(1);
|
|
|
|
_currentLevel = in.readByte();
|
|
for (int i = 0; i < 48; i++)
|
|
_inventory[i] = in.readSint16();
|
|
_inventoryCurItem = in.readSint16();
|
|
_itemInHand = in.readSint16();
|
|
_lastMouseRegion = in.readSint16();
|
|
|
|
if (header.originalSave || header.version <= 15) {
|
|
uint16 flags[40];
|
|
memset(flags, 0, sizeof(flags));
|
|
|
|
if (header.version == 14) {
|
|
for (int i = 0; i < 16; i++)
|
|
flags[i] = in.readUint16();
|
|
flags[26] = in.readUint16();
|
|
flags[36] = in.readUint16();
|
|
} else if (header.originalSave || header.version == 15) {
|
|
for (int i = 0; i < 40; i++)
|
|
flags[i] = in.readUint16();
|
|
}
|
|
|
|
memset(_flagsTable, 0, sizeof(_flagsTable));
|
|
for (uint i = 0; i < ARRAYSIZE(flags); ++i) {
|
|
for (uint k = 0; k < 16; ++k) {
|
|
if (flags[i] & (1 << k))
|
|
setGameFlag(((i << 4) & 0xFFF0) | (k & 0x000F));
|
|
}
|
|
}
|
|
} else {
|
|
uint32 flagsSize = in.readUint32();
|
|
assert(flagsSize <= sizeof(_flagsTable));
|
|
in.read(_flagsTable, flagsSize);
|
|
}
|
|
|
|
if (header.originalSave)
|
|
in.skip(120);
|
|
|
|
for (int i = 0; i < 24; i++)
|
|
_globalScriptVars[i] = in.readUint16();
|
|
|
|
if (header.originalSave)
|
|
in.skip(152);
|
|
|
|
_brightness = in.readByte();
|
|
_lampOilStatus = in.readByte();
|
|
_lampEffect = in.readSByte();
|
|
|
|
if (header.originalSave)
|
|
in.skip(1);
|
|
|
|
_credits = in.readUint16();
|
|
for (int i = 0; i < 8; i++)
|
|
_globalScriptVars2[i] = in.readUint16();
|
|
in.read(_availableSpells, 7);
|
|
_hasTempDataFlags = in.readUint32();
|
|
|
|
uint8 *origCmp = 0;
|
|
if (header.originalSave) {
|
|
in.skip(6);
|
|
origCmp = new uint8[2496];
|
|
}
|
|
|
|
for (int i = 0; i < 400; i++) {
|
|
LoLItem *t = &_itemsInPlay[i];
|
|
t->nextAssignedObject = in.readUint16();
|
|
t->nextDrawObject = in.readUint16();
|
|
t->flyingHeight = in.readByte();
|
|
t->block = in.readUint16();
|
|
t->x = in.readUint16();
|
|
t->y = in.readUint16();
|
|
t->level = in.readSByte();
|
|
t->itemPropertyIndex = in.readUint16();
|
|
t->shpCurFrame_flg = in.readUint16();
|
|
if (header.version < 17)
|
|
in.skip(4);
|
|
}
|
|
|
|
for (int i = 0; i < 1024; i++) {
|
|
LevelBlockProperty *l = &_levelBlockProperties[i];
|
|
l->assignedObjects = l->drawObjects = 0;
|
|
l->direction = 5;
|
|
}
|
|
|
|
for (int i = 0; i < 29; i++) {
|
|
if (!(_hasTempDataFlags & (1 << i))) {
|
|
if (header.originalSave) {
|
|
if (in.size() - in.pos() >= 2500)
|
|
in.skip(2500);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (_lvlTempData[i]) {
|
|
delete[] _lvlTempData[i]->wallsXorData;
|
|
delete[] _lvlTempData[i]->flags;
|
|
releaseMonsterTempData(_lvlTempData[i]);
|
|
releaseFlyingObjectTempData(_lvlTempData[i]);
|
|
releaseWallOfForceTempData(_lvlTempData[i]);
|
|
delete _lvlTempData[i];
|
|
}
|
|
|
|
_lvlTempData[i] = new LevelTempData;
|
|
_lvlTempData[i]->wallsXorData = new uint8[4096];
|
|
_lvlTempData[i]->flags = new uint16[1024];
|
|
LoLMonster *lm = new LoLMonster[30];
|
|
_lvlTempData[i]->monsters = lm;
|
|
FlyingObject *lf = new FlyingObject[_numFlyingObjects];
|
|
_lvlTempData[i]->flyingObjects = lf;
|
|
LevelTempData *l = _lvlTempData[i];
|
|
|
|
uint32 next = in.pos() + 2500;
|
|
|
|
if (header.originalSave) {
|
|
in.skip(4);
|
|
in.read(origCmp, in.readUint16());
|
|
_screen->decodeFrame4(origCmp, _tempBuffer5120, 5120);
|
|
memcpy(l->wallsXorData, _tempBuffer5120, 4096);
|
|
for (int ii = 0; ii < 1024; ii++)
|
|
l->flags[ii] = _tempBuffer5120[4096 + ii];
|
|
} else {
|
|
in.read(l->wallsXorData, 4096);
|
|
for (int ii = 0; ii < 1024; ii++)
|
|
l->flags[ii] = in.readByte();
|
|
}
|
|
|
|
if (header.originalSave)
|
|
l->monsterDifficulty = in.readUint16();
|
|
|
|
for (int ii = 0; ii < 30; ii++) {
|
|
LoLMonster *m = &lm[ii];
|
|
m->nextAssignedObject = in.readUint16();
|
|
m->nextDrawObject = in.readUint16();
|
|
m->flyingHeight = in.readByte();
|
|
m->block = in.readUint16();
|
|
m->x = in.readUint16();
|
|
m->y = in.readUint16();
|
|
m->shiftStep = in.readSByte();
|
|
m->destX = in.readUint16();
|
|
m->destY = in.readUint16();
|
|
m->destDirection = in.readByte();
|
|
m->hitOffsX = in.readSByte();
|
|
m->hitOffsY = in.readSByte();
|
|
m->currentSubFrame = in.readByte();
|
|
m->mode = in.readByte();
|
|
m->fightCurTick = in.readSByte();
|
|
m->id = in.readByte();
|
|
m->direction = in.readByte();
|
|
m->facing = in.readByte();
|
|
m->flags = in.readUint16();
|
|
m->damageReceived = in.readUint16();
|
|
m->hitPoints = in.readSint16();
|
|
m->speedTick = in.readByte();
|
|
m->type = in.readByte();
|
|
|
|
if (header.originalSave)
|
|
in.skip(4);
|
|
|
|
m->numDistAttacks = in.readByte();
|
|
m->curDistWeapon = in.readByte();
|
|
m->distAttackTick = in.readSByte();
|
|
m->assignedItems = in.readUint16();
|
|
m->properties = &_monsterProperties[m->type];
|
|
in.read(m->equipmentShapes, 4);
|
|
}
|
|
|
|
for (int ii = 0; ii < _numFlyingObjects; ii++) {
|
|
FlyingObject *m = &lf[ii];
|
|
m->enable = in.readByte();
|
|
m->objectType = in.readByte();
|
|
m->attackerId = in.readUint16();
|
|
m->item = in.readSint16();
|
|
m->x = in.readUint16();
|
|
m->y = in.readUint16();
|
|
m->flyingHeight = in.readByte();
|
|
m->direction = in.readByte();
|
|
m->distance = in.readByte();
|
|
m->field_D = in.readSByte();
|
|
m->c = in.readByte();
|
|
m->flags = in.readByte();
|
|
m->wallFlags = in.readByte();
|
|
}
|
|
|
|
if (header.originalSave)
|
|
in.seek(next, SEEK_SET);
|
|
else
|
|
l->monsterDifficulty = in.readByte();
|
|
}
|
|
|
|
delete[] origCmp;
|
|
|
|
calcCharPortraitXpos();
|
|
memset(_moneyColumnHeight, 0, sizeof(_moneyColumnHeight));
|
|
int t = _credits;
|
|
_credits = 0;
|
|
giveCredits(t, 0);
|
|
setHandItem(_itemInHand);
|
|
loadLevel(_currentLevel);
|
|
gui_drawPlayField();
|
|
timerSpecialCharacterUpdate(0);
|
|
_flagsTable[73] |= 0x08;
|
|
|
|
while (!_screen->isMouseVisible())
|
|
_screen->showMouse();
|
|
|
|
return Common::kNoError;
|
|
}
|
|
|
|
Common::Error LoLEngine::saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) {
|
|
const char *fileName = getSavegameFilename(slot);
|
|
|
|
Common::OutSaveFile *out = openSaveForWriting(fileName, saveName, thumbnail);
|
|
if (!out)
|
|
return _saveFileMan->getError();
|
|
|
|
completeDoorOperations();
|
|
generateTempData();
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
LoLCharacter *c = &_characters[i];
|
|
out->writeUint16BE(c->flags);
|
|
out->write(c->name, 11);
|
|
out->writeByte(c->raceClassSex);
|
|
out->writeSint16BE(c->id);
|
|
out->writeByte(c->curFaceFrame);
|
|
out->writeByte(c->tempFaceFrame);
|
|
out->writeByte(c->screamSfx);
|
|
for (int ii = 0; ii < 8; ii++)
|
|
out->writeUint16BE(c->itemsMight[ii]);
|
|
for (int ii = 0; ii < 8; ii++)
|
|
out->writeUint16BE(c->protectionAgainstItems[ii]);
|
|
out->writeUint16BE(c->itemProtection);
|
|
out->writeSint16BE(c->hitPointsCur);
|
|
out->writeUint16BE(c->hitPointsMax);
|
|
out->writeSint16BE(c->magicPointsCur);
|
|
out->writeUint16BE(c->magicPointsMax);
|
|
out->writeByte(c->field_41);
|
|
out->writeUint16BE(c->damageSuffered);
|
|
out->writeUint16BE(c->weaponHit);
|
|
out->writeUint16BE(c->totalMightModifier);
|
|
out->writeUint16BE(c->totalProtectionModifier);
|
|
out->writeUint16BE(c->might);
|
|
out->writeUint16BE(c->protection);
|
|
out->writeSint16BE(c->nextAnimUpdateCountdown);
|
|
for (int ii = 0; ii < 11; ii++)
|
|
out->writeUint16BE(c->items[ii]);
|
|
for (int ii = 0; ii < 3; ii++)
|
|
out->writeByte(c->skillLevels[ii]);
|
|
for (int ii = 0; ii < 3; ii++)
|
|
out->writeSByte(c->skillModifiers[ii]);
|
|
for (int ii = 0; ii < 3; ii++)
|
|
out->writeUint32BE(c->experiencePts[ii]);
|
|
for (int ii = 0; ii < 5; ii++)
|
|
out->writeByte(c->characterUpdateEvents[ii]);
|
|
for (int ii = 0; ii < 5; ii++)
|
|
out->writeByte(c->characterUpdateDelay[ii]);
|
|
}
|
|
|
|
out->writeUint16BE(_currentBlock);
|
|
out->writeUint16BE(_partyPosX);
|
|
out->writeUint16BE(_partyPosY);
|
|
out->writeUint16BE(_updateFlags);
|
|
out->writeByte(_scriptDirection);
|
|
out->writeByte(_selectedSpell);
|
|
out->writeByte(_sceneDefaultUpdate);
|
|
out->writeByte(_compassBroken);
|
|
out->writeByte(_drainMagic);
|
|
out->writeUint16BE(_currentDirection);
|
|
out->writeUint16BE(_compassDirection);
|
|
out->writeSByte(_selectedCharacter);
|
|
out->writeByte(_currentLevel);
|
|
for (int i = 0; i < 48; i++)
|
|
out->writeSint16BE(_inventory[i]);
|
|
out->writeSint16BE(_inventoryCurItem);
|
|
out->writeSint16BE(_itemInHand);
|
|
out->writeSint16BE(_lastMouseRegion);
|
|
out->writeUint32BE(ARRAYSIZE(_flagsTable));
|
|
out->write(_flagsTable, ARRAYSIZE(_flagsTable));
|
|
for (int i = 0; i < 24; i++)
|
|
out->writeUint16BE(_globalScriptVars[i]);
|
|
out->writeByte(_brightness);
|
|
out->writeByte(_lampOilStatus);
|
|
out->writeSByte(_lampEffect);
|
|
out->writeUint16BE(_credits);
|
|
for (int i = 0; i < 8; i++)
|
|
out->writeUint16BE(_globalScriptVars2[i]);
|
|
out->write(_availableSpells, 7);
|
|
out->writeUint32BE(_hasTempDataFlags);
|
|
|
|
resetItems(0);
|
|
|
|
for (int i = 0; i < 400; i++) {
|
|
LoLItem *t = &_itemsInPlay[i];
|
|
out->writeUint16BE(t->nextAssignedObject);
|
|
out->writeUint16BE(t->nextDrawObject);
|
|
out->writeByte(t->flyingHeight);
|
|
out->writeUint16BE(t->block);
|
|
out->writeUint16BE(t->x);
|
|
out->writeUint16BE(t->y);
|
|
out->writeSByte(t->level);
|
|
out->writeUint16BE(t->itemPropertyIndex);
|
|
out->writeUint16BE(t->shpCurFrame_flg);
|
|
}
|
|
|
|
addLevelItems();
|
|
|
|
for (int i = 0; i < 29; i++) {
|
|
LevelTempData *l = _lvlTempData[i];
|
|
if (!l || !(_hasTempDataFlags & (1 << i)))
|
|
continue;
|
|
|
|
out->write(l->wallsXorData, 4096);
|
|
for (int ii = 0; ii < 1024; ii++)
|
|
out->writeByte(l->flags[ii] & 0xFF);
|
|
|
|
LoLMonster *lm = (LoLMonster *)_lvlTempData[i]->monsters;
|
|
FlyingObject *lf = (FlyingObject *)_lvlTempData[i]->flyingObjects;
|
|
|
|
for (int ii = 0; ii < 30; ii++) {
|
|
LoLMonster *m = &lm[ii];
|
|
out->writeUint16BE(m->nextAssignedObject);
|
|
out->writeUint16BE(m->nextDrawObject);
|
|
out->writeByte(m->flyingHeight);
|
|
out->writeUint16BE(m->block);
|
|
out->writeUint16BE(m->x);
|
|
out->writeUint16BE(m->y);
|
|
out->writeSByte(m->shiftStep);
|
|
out->writeUint16BE(m->destX);
|
|
out->writeUint16BE(m->destY);
|
|
out->writeByte(m->destDirection);
|
|
out->writeSByte(m->hitOffsX);
|
|
out->writeSByte(m->hitOffsY);
|
|
out->writeByte(m->currentSubFrame);
|
|
out->writeByte(m->mode);
|
|
out->writeSByte(m->fightCurTick);
|
|
out->writeByte(m->id);
|
|
out->writeByte(m->direction);
|
|
out->writeByte(m->facing);
|
|
out->writeUint16BE(m->flags);
|
|
out->writeUint16BE(m->damageReceived);
|
|
out->writeSint16BE(m->hitPoints);
|
|
out->writeByte(m->speedTick);
|
|
out->writeByte(m->type);
|
|
out->writeByte(m->numDistAttacks);
|
|
out->writeByte(m->curDistWeapon);
|
|
out->writeSByte(m->distAttackTick);
|
|
out->writeUint16BE(m->assignedItems);
|
|
out->write(m->equipmentShapes, 4);
|
|
}
|
|
|
|
for (int ii = 0; ii < _numFlyingObjects; ii++) {
|
|
FlyingObject *m = &lf[ii];
|
|
out->writeByte(m->enable);
|
|
out->writeByte(m->objectType);
|
|
out->writeUint16BE(m->attackerId);
|
|
out->writeSint16BE(m->item);
|
|
out->writeUint16BE(m->x);
|
|
out->writeUint16BE(m->y);
|
|
out->writeByte(m->flyingHeight);
|
|
out->writeByte(m->direction);
|
|
out->writeByte(m->distance);
|
|
out->writeSByte(m->field_D);
|
|
out->writeByte(m->c);
|
|
out->writeByte(m->flags);
|
|
out->writeByte(m->wallFlags);
|
|
}
|
|
out->writeByte(l->monsterDifficulty);
|
|
}
|
|
|
|
out->finalize();
|
|
|
|
// check for errors
|
|
if (out->err()) {
|
|
warning("Can't write file '%s'. (Disk full?)", fileName);
|
|
return Common::kUnknownError;
|
|
} else {
|
|
debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName);
|
|
}
|
|
|
|
delete out;
|
|
return Common::kNoError;
|
|
}
|
|
|
|
Graphics::Surface *LoLEngine::generateSaveThumbnail() const {
|
|
if (_flags.platform != Common::kPlatformPC98)
|
|
return 0;
|
|
|
|
uint8 *screenPal = new uint8[16 * 3];
|
|
assert(screenPal);
|
|
_screen->getRealPalette(0, screenPal);
|
|
|
|
uint8 *screenBuf = new uint8[Screen::SCREEN_W * Screen::SCREEN_H];
|
|
assert(screenBuf);
|
|
|
|
Graphics::Surface *dst = new Graphics::Surface();
|
|
assert(dst);
|
|
|
|
_screen->copyRegionToBuffer(0, 0, 0, 320, 200, screenBuf);
|
|
Screen_LoL::convertPC98Gfx(screenBuf, Screen::SCREEN_W, Screen::SCREEN_H, Screen::SCREEN_W);
|
|
::createThumbnail(dst, screenBuf, Screen::SCREEN_W, Screen::SCREEN_H, screenPal);
|
|
|
|
delete[] screenBuf;
|
|
delete[] screenPal;
|
|
return dst;
|
|
}
|
|
|
|
void LoLEngine::restoreBlockTempData(int levelIndex) {
|
|
memset(_tempBuffer5120, 0, 5120);
|
|
KyraRpgEngine::restoreBlockTempData(levelIndex);
|
|
restoreTempDataAdjustMonsterStrength(levelIndex - 1);
|
|
}
|
|
|
|
void *LoLEngine::generateMonsterTempData(LevelTempData *tmp) {
|
|
LoLMonster *m = new LoLMonster[30];
|
|
memcpy(m, _monsters, sizeof(LoLMonster) * 30);
|
|
tmp->monsterDifficulty = _monsterDifficulty;
|
|
return m;
|
|
}
|
|
|
|
void LoLEngine::restoreTempDataAdjustMonsterStrength(int index) {
|
|
if (_lvlTempData[index]->monsterDifficulty == _monsterDifficulty)
|
|
return;
|
|
|
|
uint16 d = (_monsterModifiers1[_lvlTempData[index]->monsterDifficulty] << 8) / _monsterModifiers1[_monsterDifficulty];
|
|
|
|
for (int i = 0; i < 30; i++) {
|
|
if (_monsters[i].mode >= 14 || _monsters[i].block == 0 || _monsters[i].hitPoints <= 0)
|
|
continue;
|
|
|
|
_monsters[i].hitPoints = (d * _monsters[i].hitPoints) >> 8;
|
|
if (_monsterDifficulty < _lvlTempData[index]->monsterDifficulty)
|
|
_monsters[i].hitPoints++;
|
|
if (_monsters[i].hitPoints == 0)
|
|
_monsters[i].hitPoints = 1;
|
|
}
|
|
}
|
|
|
|
void LoLEngine::restoreMonsterTempData(LevelTempData *tmp) {
|
|
memcpy(_monsters, tmp->monsters, sizeof(LoLMonster) * 30);
|
|
|
|
for (int i = 0; i < 30; i++) {
|
|
if (_monsters[i].block) {
|
|
_monsters[i].block = 0;
|
|
_monsters[i].properties = &_monsterProperties[_monsters[i].type];
|
|
placeMonster(&_monsters[i], _monsters[i].x, _monsters[i].y);
|
|
}
|
|
}
|
|
}
|
|
|
|
void LoLEngine::releaseMonsterTempData(LevelTempData *tmp) {
|
|
LoLMonster *p = (LoLMonster *)tmp->monsters;
|
|
delete[] p;
|
|
}
|
|
|
|
} // End of namespace Kyra
|
|
|
|
#endif // ENABLE_LOL
|