mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-22 09:49:11 +00:00
XEEN: Added saving of maze monster/object data
This commit is contained in:
parent
3b1edcdf36
commit
edccbe63f2
@ -34,6 +34,19 @@ namespace Xeen {
|
||||
|
||||
class XeenEngine;
|
||||
|
||||
#define SYNC_AS(SUFFIX,STREAM,TYPE,SIZE) \
|
||||
template<typename T> \
|
||||
void syncAs ## SUFFIX(T &val, Version minVersion = 0, Version maxVersion = kLastVersion) { \
|
||||
if (_version < minVersion || _version > maxVersion) \
|
||||
return; \
|
||||
if (_loadStream) \
|
||||
val = static_cast<TYPE>(_loadStream->read ## STREAM()); \
|
||||
else { \
|
||||
TYPE tmp = (TYPE)val; \
|
||||
_saveStream->write ## STREAM(tmp); \
|
||||
} \
|
||||
_bytesSynced += SIZE; \
|
||||
}
|
||||
/*
|
||||
* Main resource manager
|
||||
*/
|
||||
@ -69,6 +82,8 @@ public:
|
||||
XeenSerializer(Common::SeekableReadStream *in, Common::WriteStream *out) :
|
||||
Common::Serializer(in, out), _in(in) {}
|
||||
|
||||
SYNC_AS(Sint8, Byte, int8, 1)
|
||||
|
||||
bool finished() const { return _in != nullptr && _in->pos() >= _in->size(); }
|
||||
};
|
||||
|
||||
|
@ -883,7 +883,6 @@ void Interface::setIndoorsMonsters() {
|
||||
void Interface::setIndoorObjects() {
|
||||
Common::Point mazePos = _vm->_party._mazePosition;
|
||||
_objNumber = 0;
|
||||
int objIndx = 0;
|
||||
const int8 *posOffset = &SCREEN_POSITIONING[_vm->_party._mazeDirection * 48];
|
||||
Common::Point pt;
|
||||
|
||||
|
@ -611,11 +611,11 @@ MobStruct::MobStruct() {
|
||||
_direction = DIR_NORTH;
|
||||
}
|
||||
|
||||
bool MobStruct::synchronize(Common::SeekableReadStream &s) {
|
||||
_pos.x = (int8)s.readByte();
|
||||
_pos.y = (int8)s.readByte();
|
||||
_id = s.readByte();
|
||||
_direction = (Direction)s.readByte();
|
||||
bool MobStruct::synchronize(XeenSerializer &s) {
|
||||
s.syncAsSint8(_pos.x);
|
||||
s.syncAsSint8(_pos.y);
|
||||
s.syncAsByte(_id);
|
||||
s.syncAsByte(_direction);
|
||||
|
||||
return _id != 0xff || _pos.x != -1 || _pos.y != -1;
|
||||
}
|
||||
@ -658,85 +658,134 @@ MazeWallItem::MazeWallItem() {
|
||||
MonsterObjectData::MonsterObjectData(XeenEngine *vm): _vm(vm) {
|
||||
}
|
||||
|
||||
void MonsterObjectData::synchronize(Common::SeekableReadStream &s,
|
||||
bool isOutdoors, MonsterData monsterData) {
|
||||
_objectSprites.clear();
|
||||
_monsterSprites.clear();
|
||||
_monsterAttackSprites.clear();
|
||||
_wallItemSprites.clear();
|
||||
_objects.clear();
|
||||
_monsters.clear();
|
||||
_wallItems.clear();
|
||||
|
||||
void MonsterObjectData::synchronize(XeenSerializer &s, MonsterData monsterData) {
|
||||
Common::Array<MobStruct> mobStructs;
|
||||
MobStruct mobStruct;
|
||||
byte b;
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if ((b = s.readByte()) != 0xff)
|
||||
if (s.isLoading()) {
|
||||
_objectSprites.clear();
|
||||
_monsterSprites.clear();
|
||||
_monsterAttackSprites.clear();
|
||||
_wallItemSprites.clear();
|
||||
_objects.clear();
|
||||
_monsters.clear();
|
||||
_wallItems.clear();
|
||||
}
|
||||
|
||||
for (uint i = 0; i < 16; ++i) {
|
||||
b = (i >= _objectSprites.size()) ? 0xff : _objectSprites[i]._spriteId;
|
||||
s.syncAsByte(b);
|
||||
if (b != 0xff)
|
||||
_objectSprites.push_back(SpriteResourceEntry(b));
|
||||
}
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if ((b = s.readByte()) != 0xff)
|
||||
for (uint i = 0; i < 16; ++i) {
|
||||
b = (i >= _monsterSprites.size()) ? 0xff : _monsterSprites[i]._spriteId;
|
||||
s.syncAsByte(b);
|
||||
if (b != 0xff)
|
||||
_monsterSprites.push_back(SpriteResourceEntry(b));
|
||||
}
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if ((b = s.readByte()) != 0xff)
|
||||
for (uint i = 0; i < 16; ++i) {
|
||||
b = (i >= _wallItemSprites.size()) ? 0xff : _wallItemSprites[i]._spriteId;
|
||||
s.syncAsByte(b);
|
||||
if (b != 0xff)
|
||||
_wallItemSprites.push_back(SpriteResourceEntry(b));
|
||||
}
|
||||
|
||||
// Merge together object data
|
||||
MobStruct mobStruct;
|
||||
mobStruct.synchronize(s);
|
||||
do {
|
||||
MazeObject obj;
|
||||
obj._position = mobStruct._pos;
|
||||
obj._id = mobStruct._id;
|
||||
obj._direction = mobStruct._direction;
|
||||
obj._frame = 100;
|
||||
obj._spriteId = _objectSprites[obj._id]._spriteId;
|
||||
obj._sprites = &_objectSprites[obj._id]._sprites;
|
||||
|
||||
_objects.push_back(obj);
|
||||
mobStruct.synchronize(s);
|
||||
} while (mobStruct._id != 255 || mobStruct._pos.x != -1);
|
||||
|
||||
// Merge together monster data
|
||||
mobStruct.synchronize(s);
|
||||
do {
|
||||
MazeMonster mon;
|
||||
mon._position = mobStruct._pos;
|
||||
mon._id = mobStruct._id;
|
||||
mon._spriteId = _monsterSprites[mon._id]._spriteId;
|
||||
mon._sprites = &_monsterSprites[mon._id]._sprites;
|
||||
mon._attackSprites = &_monsterSprites[mon._id]._attackSprites;
|
||||
|
||||
MonsterStruct &md = monsterData[mon._spriteId];
|
||||
mon._hp = md._hp;
|
||||
mon._frame = _vm->getRandomNumber(7);
|
||||
mon._effect1 = mon._effect2 = md._animationEffect;
|
||||
if (md._animationEffect)
|
||||
mon._effect3 = _vm->getRandomNumber(7);
|
||||
|
||||
_monsters.push_back(mon);
|
||||
mobStruct.synchronize(s);
|
||||
} while (mobStruct._id != 255 || mobStruct._pos.x != -1);
|
||||
|
||||
// Merge together wall item data
|
||||
mobStruct.synchronize(s);
|
||||
do {
|
||||
if (mobStruct._id < (int)_wallItemSprites.size()) {
|
||||
MazeWallItem wi;
|
||||
wi._position = mobStruct._pos;
|
||||
wi._id = mobStruct._id;
|
||||
wi._direction = mobStruct._direction;
|
||||
wi._spriteId = _wallItemSprites[wi._id]._spriteId;
|
||||
wi._sprites = &_wallItemSprites[wi._id]._sprites;
|
||||
|
||||
_wallItems.push_back(wi);
|
||||
if (s.isSaving()) {
|
||||
// Save objects
|
||||
for (uint i = 0; i < _objects.size(); ++i) {
|
||||
mobStruct._pos = _objects[i]._position;
|
||||
mobStruct._id = _objects[i]._id;
|
||||
mobStruct._direction = _objects[i]._direction;
|
||||
mobStruct.synchronize(s);
|
||||
}
|
||||
|
||||
mobStruct._pos.x = mobStruct._pos.y = -1;
|
||||
mobStruct._id = 0xff;
|
||||
mobStruct.synchronize(s);
|
||||
} while (mobStruct._id != 255 || mobStruct._pos.x != -1);
|
||||
|
||||
// Save monsters
|
||||
for (uint i = 0; i < _monsters.size(); ++i) {
|
||||
mobStruct._pos = _monsters[i]._position;
|
||||
mobStruct._id = _monsters[i]._id;
|
||||
mobStruct._direction = DIR_NORTH;
|
||||
mobStruct.synchronize(s);
|
||||
}
|
||||
mobStruct._pos.x = mobStruct._pos.y = -1;
|
||||
mobStruct._id = 0xff;
|
||||
mobStruct.synchronize(s);
|
||||
|
||||
// Save wall items
|
||||
if (_wallItems.size() == 0) {
|
||||
MobStruct nullStruct;
|
||||
nullStruct.synchronize(s);
|
||||
} else {
|
||||
for (uint i = 0; i < _wallItems.size(); ++i) {
|
||||
mobStruct._pos = _wallItems[i]._position;
|
||||
mobStruct._id = _wallItems[i]._id;
|
||||
mobStruct._direction = _wallItems[i]._direction;
|
||||
mobStruct.synchronize(s);
|
||||
}
|
||||
}
|
||||
mobStruct._pos.x = mobStruct._pos.y = -1;
|
||||
mobStruct._id = 0xff;
|
||||
mobStruct.synchronize(s);
|
||||
|
||||
} else {
|
||||
// Load monster/obbject data and merge together with sprite Ids
|
||||
// Merge together object data
|
||||
mobStruct.synchronize(s);
|
||||
do {
|
||||
MazeObject obj;
|
||||
obj._position = mobStruct._pos;
|
||||
obj._id = mobStruct._id;
|
||||
obj._direction = mobStruct._direction;
|
||||
obj._frame = 100;
|
||||
obj._spriteId = _objectSprites[obj._id]._spriteId;
|
||||
obj._sprites = &_objectSprites[obj._id]._sprites;
|
||||
|
||||
_objects.push_back(obj);
|
||||
mobStruct.synchronize(s);
|
||||
} while (mobStruct._id != 255 || mobStruct._pos.x != -1);
|
||||
|
||||
// Merge together monster data
|
||||
mobStruct.synchronize(s);
|
||||
do {
|
||||
MazeMonster mon;
|
||||
mon._position = mobStruct._pos;
|
||||
mon._id = mobStruct._id;
|
||||
mon._spriteId = _monsterSprites[mon._id]._spriteId;
|
||||
mon._sprites = &_monsterSprites[mon._id]._sprites;
|
||||
mon._attackSprites = &_monsterSprites[mon._id]._attackSprites;
|
||||
|
||||
MonsterStruct &md = monsterData[mon._spriteId];
|
||||
mon._hp = md._hp;
|
||||
mon._frame = _vm->getRandomNumber(7);
|
||||
mon._effect1 = mon._effect2 = md._animationEffect;
|
||||
if (md._animationEffect)
|
||||
mon._effect3 = _vm->getRandomNumber(7);
|
||||
|
||||
_monsters.push_back(mon);
|
||||
mobStruct.synchronize(s);
|
||||
} while (mobStruct._id != 255 || mobStruct._pos.x != -1);
|
||||
|
||||
// Merge together wall item data
|
||||
mobStruct.synchronize(s);
|
||||
do {
|
||||
if (mobStruct._id < (int)_wallItemSprites.size()) {
|
||||
MazeWallItem wi;
|
||||
wi._position = mobStruct._pos;
|
||||
wi._id = mobStruct._id;
|
||||
wi._direction = mobStruct._direction;
|
||||
wi._spriteId = _wallItemSprites[wi._id]._spriteId;
|
||||
wi._sprites = &_wallItemSprites[wi._id]._sprites;
|
||||
|
||||
_wallItems.push_back(wi);
|
||||
}
|
||||
|
||||
mobStruct.synchronize(s);
|
||||
} while (mobStruct._id != 255 || mobStruct._pos.x != -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -888,7 +937,8 @@ void Map::load(int mapId) {
|
||||
Common::String mobName = Common::String::format("maze%c%03d.mob",
|
||||
(mapId >= 100) ? 'x' : '0', mapId);
|
||||
File mobFile(mobName);
|
||||
_mobData.synchronize(mobFile, _isOutdoors, _monsterData);
|
||||
XeenSerializer sMob(&mobFile, nullptr);
|
||||
_mobData.synchronize(sMob, _monsterData);
|
||||
mobFile.close();
|
||||
|
||||
Common::String headName = Common::String::format("aaze%c%03d.hed",
|
||||
@ -925,7 +975,8 @@ void Map::load(int mapId) {
|
||||
Common::String filename = Common::String::format("maze%c%03d.mob",
|
||||
(_vm->_party._mazeId >= 100) ? 'x' : '0', _vm->_party._mazeId);
|
||||
File mobFile(filename, *_vm->_saves);
|
||||
_mobData.synchronize(mobFile, _isOutdoors, _monsterData);
|
||||
XeenSerializer sMob(&mobFile, nullptr);
|
||||
_mobData.synchronize(sMob, _monsterData);
|
||||
mobFile.close();
|
||||
|
||||
// Load sprites for the objects
|
||||
@ -1068,6 +1119,14 @@ void Map::saveMaze() {
|
||||
XeenSerializer sEvents(nullptr, &fEvents);
|
||||
_events.synchronize(sEvents);
|
||||
fEvents.finalize();
|
||||
|
||||
// Save the maze MOB file
|
||||
filename = Common::String::format("maze%c%03d.mob",
|
||||
(mazeNum >= 100) ? 'x' : '0', mazeNum);
|
||||
OutFile fMob(_vm, filename);
|
||||
XeenSerializer sMob(nullptr, &fEvents);
|
||||
_mobData.synchronize(sMob, _monsterData);
|
||||
fEvents.finalize();
|
||||
}
|
||||
|
||||
void Map::cellFlagLookup(const Common::Point &pt) {
|
||||
|
@ -228,7 +228,7 @@ public:
|
||||
public:
|
||||
MobStruct();
|
||||
|
||||
bool synchronize(Common::SeekableReadStream &s);
|
||||
bool synchronize(XeenSerializer &s);
|
||||
};
|
||||
|
||||
struct MazeObject {
|
||||
@ -295,8 +295,7 @@ public:
|
||||
public:
|
||||
MonsterObjectData(XeenEngine *vm);
|
||||
|
||||
void synchronize(Common::SeekableReadStream &s, bool isOutdoors,
|
||||
MonsterData monsterData);
|
||||
void synchronize(XeenSerializer &s, MonsterData monsterData);
|
||||
};
|
||||
|
||||
class HeadData {
|
||||
|
Loading…
Reference in New Issue
Block a user