Initial commit
This commit is contained in:
85
engines/ultima/nuvie/save/obj_list.h
Normal file
85
engines/ultima/nuvie/save/obj_list.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_SAVE_OBJ_LIST_H
|
||||
#define NUVIE_SAVE_OBJ_LIST_H
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
#define OBJLIST_OFFSET_PARTY_NAMES 0xf00
|
||||
#define OBJLIST_OFFSET_PARTY_ROSTER 0xfe0
|
||||
#define OBJLIST_OFFSET_NUM_IN_PARTY 0xff0
|
||||
|
||||
//U6 specific offsets
|
||||
#define OBJLIST_OFFSET_U6_MOVEMENT_POINTS 0x14f1
|
||||
#define OBJLIST_OFFSET_U6_TALK_FLAGS 0x17f1
|
||||
#define OBJLIST_OFFSET_U6_MOVEMENT_FLAGS 0x19f1
|
||||
#define OBJLIST_OFFSET_U6_QUEST_FLAG 0x1bf1
|
||||
#define OBJLIST_OFFSET_U6_REST_COUNTER 0x1bf2
|
||||
#define OBJLIST_OFFSET_U6_GAMETIME 0x1bf3
|
||||
#define OBJLIST_OFFSET_U6_KARMA 0x1bf9
|
||||
|
||||
#define OBJLIST_OFFSET_U6_WIND_DIR 0x1bfa
|
||||
#define OBJLIST_OFFSET_U6_TIMERS 0x1c03
|
||||
#define OBJLIST_OFFSET_U6_ECLIPSE 0x1c12
|
||||
#define OBJLIST_OFFSET_U6_ALCOHOL 0x1c17
|
||||
#define OBJLIST_OFFSET_U6_MOONSTONES 0x1c1b
|
||||
#define OBJLIST_OFFSET_U6_GARGISH_LANG 0x1c5f
|
||||
|
||||
#define OBJLIST_OFFSET_U6_COMBAT_MODE 0x1c69
|
||||
#define OBJLIST_OFFSET_U6_SOLO_MODE 0x1c6a
|
||||
#define OBJLIST_OFFSET_U6_COMMAND_BAR 0x1c6c
|
||||
#define OBJLIST_OFFSET_U6_GENDER 0x1c71
|
||||
|
||||
//MD specific offsets
|
||||
|
||||
#define OBJLIST_OFFSET_MD_MOVEMENT_POINTS 0x15f1
|
||||
#define OBJLIST_OFFSET_MD_TALK_FLAGS 0x18f1
|
||||
#define OBJLIST_OFFSET_MD_MOVEMENT_FLAGS 0x1af1
|
||||
#define OBJLIST_OFFSET_MD_BLUE_BERRY_COUNTER 0x1d05
|
||||
#define OBJLIST_OFFSET_MD_COMMAND_BAR 0x1d26
|
||||
#define OBJLIST_OFFSET_MD_GENDER 0x1d27
|
||||
#define OBJLIST_OFFSET_MD_BERRY_TIMERS 0x1d2f
|
||||
|
||||
//WOU specific offsets (MD and SE)
|
||||
|
||||
#define OBJLIST_OFFSET_WOU_GAMETIME 0x1cf3
|
||||
|
||||
#define OBJLIST_PARTY_MODE 0xff
|
||||
|
||||
//u6 wind direction
|
||||
#define OBJLIST_U6_WIND_DIR_N 0
|
||||
#define OBJLIST_U6_WIND_DIR_NE 1
|
||||
#define OBJLIST_U6_WIND_DIR_E 2
|
||||
#define OBJLIST_U6_WIND_DIR_SE 3
|
||||
#define OBJLIST_U6_WIND_DIR_S 4
|
||||
#define OBJLIST_U6_WIND_DIR_SW 5
|
||||
#define OBJLIST_U6_WIND_DIR_W 6
|
||||
#define OBJLIST_U6_WIND_DIR_NW 7
|
||||
#define OBJLIST_U6_WIND_DIR_C 0xff
|
||||
|
||||
#define OBJLIST_OFFSET_SE_COMMAND_BAR 0x1d6c
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
587
engines/ultima/nuvie/save/save_game.cpp
Normal file
587
engines/ultima/nuvie/save/save_game.cpp
Normal file
@@ -0,0 +1,587 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/files/nuvie_io.h"
|
||||
#include "ultima/nuvie/files/nuvie_io_file.h"
|
||||
#include "ultima/nuvie/files/u6_lzw.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/widgets/console.h"
|
||||
#include "ultima/nuvie/save/save_game.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/core/game.h"
|
||||
#include "ultima/nuvie/core/obj_manager.h"
|
||||
#include "ultima/nuvie/save/obj_list.h"
|
||||
#include "ultima/nuvie/actors/actor_manager.h"
|
||||
#include "ultima/nuvie/core/egg_manager.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/portraits/portrait.h"
|
||||
#include "ultima/nuvie/core/game_clock.h"
|
||||
#include "ultima/nuvie/gui/widgets/command_bar.h"
|
||||
#include "ultima/nuvie/core/weather.h"
|
||||
#include "ultima/nuvie/script/script.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/nuvie.h"
|
||||
#include "common/system.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/translation.h"
|
||||
#include "gui/browser.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
#define OBJLIST_FILENAME "savegame/objlist"
|
||||
#define OBJBLK_FILENAME "savegame/objblkxx"
|
||||
#define GAME_ID(GT) ((GT == GAME_SAVAGE_EMPIRE) ? MKTAG16('S', 'E') : \
|
||||
((GT == GAME_MARTIAN_DREAMS) ? MKTAG16('M', 'D') : MKTAG16('U', '6')))
|
||||
|
||||
SaveGame::SaveGame(Configuration *cfg) : config(cfg) {
|
||||
// We don't need ObjManager here as there will be nothing to clean at this stage
|
||||
init(nullptr);
|
||||
}
|
||||
|
||||
SaveGame::~SaveGame() {
|
||||
objlist.close();
|
||||
}
|
||||
|
||||
void SaveGame::init(ObjManager *obj_manager) {
|
||||
if (objlist.get_size() > 0)
|
||||
objlist.close();
|
||||
|
||||
if (obj_manager)
|
||||
obj_manager->clean();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool SaveGame::load_new() {
|
||||
Common::Path filename;
|
||||
U6Lzw lzw;
|
||||
NuvieIOBuffer buf;
|
||||
uint32 decomp_size;
|
||||
uint8 i;
|
||||
uint32 pos;
|
||||
|
||||
ObjManager *obj_manager = Game::get_game()->get_obj_manager();
|
||||
|
||||
init(obj_manager);
|
||||
|
||||
// Load surface chunks
|
||||
config_get_path(config, "lzobjblk", filename);
|
||||
unsigned char *data = lzw.decompress_file(filename, decomp_size);
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
buf.open(data, decomp_size, NUVIE_BUF_NOCOPY);
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
obj_manager->load_super_chunk(&buf, 0, i);
|
||||
|
||||
buf.close();
|
||||
free(data);
|
||||
|
||||
// Load dungeon chunks
|
||||
config_get_path(config, "lzdngblk", filename);
|
||||
data = lzw.decompress_file(filename, decomp_size);
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
buf.open(data, decomp_size, NUVIE_BUF_NOCOPY);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
obj_manager->load_super_chunk(&buf, i, 0);
|
||||
|
||||
pos = buf.position();
|
||||
buf.close();
|
||||
|
||||
// load objlist
|
||||
objlist.open(&data[pos], decomp_size - pos, NUVIE_BUF_COPY);
|
||||
|
||||
update_objlist_for_new_game();
|
||||
|
||||
load_objlist();
|
||||
|
||||
Actor *player = Game::get_game()->get_player()->get_actor();
|
||||
Game::get_game()->get_egg_manager()->spawn_eggs(player->get_x(), player->get_y(), player->get_z(), true);
|
||||
|
||||
free(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGame::load_original() {
|
||||
Std::string objblk_filename;
|
||||
Common::Path path, objlist_filename;
|
||||
char x, y;
|
||||
uint16 len;
|
||||
NuvieIOFileRead objlist_file;
|
||||
|
||||
NuvieIOFileRead *objblk_file = new NuvieIOFileRead();
|
||||
ObjManager *obj_manager = Game::get_game()->get_obj_manager();
|
||||
|
||||
init(obj_manager);
|
||||
|
||||
objblk_filename = OBJBLK_FILENAME;
|
||||
len = objblk_filename.size();
|
||||
|
||||
uint8 i = 0;
|
||||
|
||||
for (y = 'a'; y < 'i'; y++) {
|
||||
for (x = 'a'; x < 'i'; x++) {
|
||||
objblk_filename[len - 1] = y;
|
||||
objblk_filename[len - 2] = x;
|
||||
ConsoleAddInfo("Loading file: %s", objblk_filename.c_str());
|
||||
config_get_path(config, objblk_filename, path);
|
||||
if (objblk_file->open(path) == false) {
|
||||
delete objblk_file;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj_manager->load_super_chunk(objblk_file, 0, i) == false) {
|
||||
delete objblk_file;
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
objblk_file->close();
|
||||
}
|
||||
}
|
||||
|
||||
objblk_filename[len - 1] = 'i';
|
||||
|
||||
for (i = 0, x = 'a'; x < 'f'; x++, i++) { // Load dungeons
|
||||
objblk_filename[len - 2] = x;
|
||||
config_get_path(config, objblk_filename, path);
|
||||
objblk_file->open(path);
|
||||
|
||||
if (obj_manager->load_super_chunk(objblk_file, i, 0) == false) {
|
||||
delete objblk_file;
|
||||
return false;
|
||||
}
|
||||
|
||||
objblk_file->close();
|
||||
}
|
||||
|
||||
delete objblk_file;
|
||||
|
||||
//print_egg_list();
|
||||
config_get_path(config, OBJLIST_FILENAME, objlist_filename);
|
||||
if (objlist_file.open(objlist_filename) == false)
|
||||
return false;
|
||||
|
||||
unsigned char *data = objlist_file.readAll();
|
||||
|
||||
objlist.open(data, objlist_file.get_size(), NUVIE_BUF_COPY);
|
||||
free(data);
|
||||
|
||||
load_objlist();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGame::transfer_character() {
|
||||
::GUI::BrowserDialog dialog(_("Transfer Character"), true);
|
||||
if (!dialog.runModal())
|
||||
return false;
|
||||
|
||||
Common::FSNode folder = dialog.getResult();
|
||||
|
||||
// TODO: Load in character data from given folder and start new game
|
||||
GUIErrorMessage(Common::String::format("Load party file from folder - %s", folder.getPath().toString(Common::Path::kNativeSeparator).c_str()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SaveGame::load_objlist() {
|
||||
Game *game;
|
||||
GameClock *clock;
|
||||
ActorManager *actor_manager;
|
||||
ObjManager *obj_manager;
|
||||
ViewManager *view_manager;
|
||||
MapWindow *map_window;
|
||||
MsgScroll *scroll;
|
||||
CommandBar *command_bar;
|
||||
Player *player;
|
||||
Party *party;
|
||||
Portrait *portrait;
|
||||
Weather *weather;
|
||||
uint16 px, py;
|
||||
uint8 pz;
|
||||
|
||||
game = Game::get_game();
|
||||
|
||||
clock = game->get_clock();
|
||||
actor_manager = game->get_actor_manager();
|
||||
obj_manager = game->get_obj_manager();
|
||||
scroll = game->get_scroll();
|
||||
map_window = game->get_map_window();
|
||||
command_bar = game->get_command_bar();
|
||||
|
||||
player = game->get_player();
|
||||
party = game->get_party();
|
||||
portrait = game->get_portrait();
|
||||
view_manager = game->get_view_manager();
|
||||
weather = game->get_weather();
|
||||
|
||||
portrait->load(&objlist); // load avatar portrait number.
|
||||
|
||||
clock->load(&objlist);
|
||||
game->set_ethereal(false); // needs to go before actor_manager->load(&objlist);
|
||||
actor_manager->load(&objlist);
|
||||
|
||||
party->load(&objlist);
|
||||
player->load(&objlist);
|
||||
|
||||
weather->load(&objlist);
|
||||
|
||||
command_bar->set_combat_mode(party->is_in_combat_mode()); // update CommandBar
|
||||
command_bar->load(&objlist);
|
||||
|
||||
view_manager->reload();
|
||||
|
||||
game->get_script()->call_load_game(&objlist);
|
||||
game->get_event()->set_control_cheat(false);
|
||||
|
||||
player->get_location(&px, &py, &pz);
|
||||
obj_manager->update(px, py, pz); // spawn eggs.
|
||||
|
||||
map_window->centerMapOnActor(player->get_actor());
|
||||
|
||||
scroll->display_string("\nGame Loaded\n\n");
|
||||
|
||||
scroll->init(player->get_name());
|
||||
|
||||
scroll->display_prompt();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGame::check_version(NuvieIOFileRead *loadfile, uint16 gameType) {
|
||||
uint16 version, gt;
|
||||
|
||||
loadfile->seekStart();
|
||||
version = loadfile->read2();
|
||||
gt = loadfile->read2();
|
||||
|
||||
if (version != SAVE_VERSION) {
|
||||
DEBUG(0, LEVEL_ERROR, "Incompatible savegame version. Savegame version '%d', current system version '%d'\n", version, SAVE_VERSION);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gt != gameType) {
|
||||
DEBUG(0, LEVEL_ERROR, "Incorrect game type\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGame::load(const Common::String &filename) {
|
||||
uint8 i;
|
||||
uint32 bytes_read;
|
||||
NuvieIOFileRead loadFile;
|
||||
GameId gameType = g_engine->getGameId();
|
||||
ObjManager *obj_manager = Game::get_game()->get_obj_manager();
|
||||
|
||||
Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(filename);
|
||||
if (!saveFile || !loadFile.open(saveFile))
|
||||
return false;
|
||||
|
||||
ConsoleAddInfo("Loading Game: %s", filename.c_str());
|
||||
DEBUG(0, LEVEL_NOTIFICATION, "Loading Game: %s\n", filename.c_str());
|
||||
|
||||
if (!check_version(&loadFile, GAME_ID(gameType))) {
|
||||
DEBUG(0, LEVEL_NOTIFICATION, "version incorrect\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
init(obj_manager); // needs to come after checking for failure
|
||||
|
||||
// Load actor inventories
|
||||
obj_manager->load_super_chunk(&loadFile, 0, 0);
|
||||
|
||||
// Load eggs
|
||||
obj_manager->load_super_chunk(&loadFile, 0, 0);
|
||||
|
||||
// Load surface objects
|
||||
for (i = 0; i < 64; i++) {
|
||||
ConsoleAddInfo("Loading super chunk %d of 64", i + 1);
|
||||
obj_manager->load_super_chunk(&loadFile, 0, i);
|
||||
}
|
||||
|
||||
// Load dungeon objects
|
||||
for (i = 0; i < 5; i++) {
|
||||
obj_manager->load_super_chunk(&loadFile, i + 1, 0);
|
||||
}
|
||||
|
||||
uint32 objlist_size = loadFile.read4();
|
||||
unsigned char *data = loadFile.readBuf(objlist_size, &bytes_read);
|
||||
|
||||
objlist.open(data, objlist_size, NUVIE_BUF_COPY);
|
||||
|
||||
free(data);
|
||||
loadFile.close();
|
||||
|
||||
load_objlist();
|
||||
|
||||
delete saveFile;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGame::save(const Common::String &filename, const Common::String &save_description, bool isAutosave) {
|
||||
NuvieIOFileWrite saveFile;
|
||||
GameId gameType = g_engine->getGameId();
|
||||
ObjManager *obj_manager = Game::get_game()->get_obj_manager();
|
||||
|
||||
bool newgame;
|
||||
config->value("config/newgame", newgame, false);
|
||||
if (newgame) {
|
||||
config->set("config/newgame", false);
|
||||
config->write();
|
||||
}
|
||||
|
||||
saveFile.open(filename, isAutosave);
|
||||
|
||||
saveFile.write2(SAVE_VERSION);
|
||||
saveFile.write2(GAME_ID(gameType));
|
||||
|
||||
obj_manager->save_inventories(&saveFile);
|
||||
|
||||
obj_manager->save_eggs(&saveFile);
|
||||
|
||||
// Save surface objects
|
||||
for (uint8 i = 0; i < 64; i++)
|
||||
obj_manager->save_super_chunk(&saveFile, 0, i);
|
||||
|
||||
// Save dungeon objects
|
||||
for (uint8 i = 0; i < 5; i++)
|
||||
obj_manager->save_super_chunk(&saveFile, i + 1, 0);
|
||||
|
||||
save_objlist();
|
||||
|
||||
saveFile.write4(objlist.get_size());
|
||||
saveFile.writeBuf(objlist.get_raw_data(), objlist.get_size());
|
||||
|
||||
saveFile.writeDesc(save_description);
|
||||
saveFile.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGame::save_objlist() {
|
||||
Game *game;
|
||||
GameClock *clock;
|
||||
ActorManager *actor_manager;
|
||||
Player *player;
|
||||
Party *party;
|
||||
Weather *weather;
|
||||
|
||||
game = Game::get_game();
|
||||
|
||||
clock = game->get_clock();
|
||||
actor_manager = game->get_actor_manager();
|
||||
|
||||
player = game->get_player();
|
||||
party = game->get_party();
|
||||
weather = game->get_weather();
|
||||
|
||||
clock->save(&objlist);
|
||||
actor_manager->save(&objlist);
|
||||
|
||||
player->save(&objlist);
|
||||
party->save(&objlist);
|
||||
|
||||
weather->save(&objlist);
|
||||
game->get_command_bar()->save(&objlist);
|
||||
|
||||
game->get_script()->call_save_game(&objlist);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SaveGame::update_objlist_for_new_game() {
|
||||
nuvie_game_t type = Game::get_game()->get_game_type();
|
||||
if (type == NUVIE_GAME_SE) {
|
||||
update_objlist_for_new_game_se();
|
||||
} else if (type == NUVIE_GAME_MD) {
|
||||
update_objlist_for_new_game_md();
|
||||
} else {
|
||||
update_objlist_for_new_game_u6();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SaveGame::update_objlist_for_new_game_u6() {
|
||||
Std::string name = "";
|
||||
|
||||
config->value("config/newgamedata/name", name, "Avatar");
|
||||
objlist.seek(0xf00);
|
||||
int len = name.size();
|
||||
if (len > 13)
|
||||
len = 13;
|
||||
|
||||
objlist.writeBuf((const unsigned char *)name.c_str(), len + 1);
|
||||
|
||||
objlist.seek(0x1c71); // gender
|
||||
|
||||
int gender;
|
||||
config->value("config/newgamedata/gender", gender, 0);
|
||||
|
||||
objlist.write1(gender == 1 ? 0 : 1);
|
||||
|
||||
int portrait;
|
||||
config->value("config/newgamedata/portrait", portrait, 0);
|
||||
|
||||
objlist.write1((uint8)(gender * 6 + portrait) + 1);
|
||||
|
||||
int stat;
|
||||
config->value("config/newgamedata/str", stat, 0xf);
|
||||
objlist.seek(0x901);
|
||||
objlist.write1(stat);
|
||||
|
||||
config->value("config/newgamedata/dex", stat, 0xf);
|
||||
objlist.seek(0xa01);
|
||||
objlist.write1(stat);
|
||||
|
||||
int intelligence;
|
||||
config->value("config/newgamedata/int", intelligence, 0xf);
|
||||
objlist.seek(0xb01);
|
||||
objlist.write1(intelligence);
|
||||
|
||||
config->value("config/newgamedata/exp", stat, 0x172);
|
||||
objlist.seek(0xc02);
|
||||
objlist.write2(stat); // experience
|
||||
|
||||
config->value("config/newgamedata/magic", stat, intelligence * 2);
|
||||
objlist.seek(0x13f2);
|
||||
objlist.write1(stat); // magic
|
||||
|
||||
config->value("config/newgamedata/level", stat, 3);
|
||||
objlist.seek(0xff2);
|
||||
objlist.write1(stat); //level
|
||||
}
|
||||
|
||||
void SaveGame::update_objlist_for_new_game_se() {
|
||||
Std::string name = "";
|
||||
|
||||
config->value("config/newgamedata/name", name, "Avatar");
|
||||
objlist.seek(0xf00);
|
||||
int len = name.size();
|
||||
if (len > 13)
|
||||
len = 13;
|
||||
|
||||
objlist.writeBuf((const unsigned char *)name.c_str(), len + 1);
|
||||
|
||||
int str, dex, intelligence;
|
||||
config->value("config/newgamedata/str", str, 0xf);
|
||||
objlist.seek(0x901);
|
||||
objlist.write1(str);
|
||||
|
||||
config->value("config/newgamedata/dex", dex, 0xf);
|
||||
objlist.seek(0xa01);
|
||||
objlist.write1(dex);
|
||||
|
||||
config->value("config/newgamedata/int", intelligence, 0xf);
|
||||
objlist.seek(0xb01);
|
||||
objlist.write1(intelligence);
|
||||
|
||||
objlist.seek(0xe01);
|
||||
objlist.write1(str * 2 + intelligence); //hp
|
||||
|
||||
objlist.seek(0x14f2);
|
||||
objlist.write1(dex); // movement points
|
||||
}
|
||||
|
||||
void SaveGame::update_objlist_for_new_game_md() {
|
||||
Std::string name = "";
|
||||
|
||||
int gender;
|
||||
config->value("config/newgamedata/gender", gender, 0);
|
||||
|
||||
config->value("config/newgamedata/name", name, "Avatar");
|
||||
objlist.seek(0xf00);
|
||||
int len = name.size();
|
||||
if (len > 13)
|
||||
len = 13;
|
||||
|
||||
objlist.writeBuf((const unsigned char *)name.c_str(), len + 1);
|
||||
|
||||
int str, dex, intelligence;
|
||||
config->value("config/newgamedata/str", str, 0xf);
|
||||
objlist.seek(0x901);
|
||||
objlist.write1(str);
|
||||
|
||||
config->value("config/newgamedata/dex", dex, 0xf);
|
||||
objlist.seek(0xa01);
|
||||
objlist.write1(dex);
|
||||
|
||||
config->value("config/newgamedata/int", intelligence, 0xf);
|
||||
objlist.seek(0xb01);
|
||||
objlist.write1(intelligence);
|
||||
|
||||
objlist.seek(0xc02);
|
||||
objlist.write2(600); // experience
|
||||
|
||||
objlist.seek(0xe01);
|
||||
objlist.write1(str * 2 + (4 * 24)); //hp = strength * 2 + level * 24
|
||||
|
||||
objlist.seek(0xff2);
|
||||
objlist.write1(4); // level
|
||||
|
||||
// FIXME: movement points where are they?
|
||||
objlist.seek(0x14f2);
|
||||
objlist.write1(dex); // movement points
|
||||
|
||||
objlist.seek(0x15f2);
|
||||
objlist.write1(20); // movement points
|
||||
|
||||
objlist.seek(OBJLIST_OFFSET_MD_GENDER);
|
||||
objlist.write1(gender);
|
||||
|
||||
// Read in avatar's obj_n + frame_n data
|
||||
objlist.seek(0x403);
|
||||
uint8 b2 = objlist.read1();
|
||||
uint16 obj_n = gender == 0 ? 343 : 344;
|
||||
uint8 frame_n = (b2 & 0xfc) >> 2;
|
||||
|
||||
// Write out adjusted avatar gender obj_n + frame_n
|
||||
objlist.seek(0x402);
|
||||
objlist.write1(obj_n & 0xff);
|
||||
b2 = obj_n >> 8;
|
||||
b2 += frame_n << 2;
|
||||
objlist.write1(b2);
|
||||
|
||||
// Also write to the old obj_n + frame_n data.
|
||||
objlist.seek(0x16f3);
|
||||
objlist.write1(obj_n & 0xff);
|
||||
b2 = obj_n >> 8;
|
||||
b2 += frame_n << 2;
|
||||
objlist.write1(b2);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
89
engines/ultima/nuvie/save/save_game.h
Normal file
89
engines/ultima/nuvie/save/save_game.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_SAVE_SAVE_GAME_H
|
||||
#define NUVIE_SAVE_SAVE_GAME_H
|
||||
|
||||
#define SAVE_VERSION_MAJOR 1
|
||||
#define SAVE_VERSION_MINOR 0
|
||||
#define SAVE_VERSION (SAVE_VERSION_MAJOR * 256 + SAVE_VERSION_MINOR)
|
||||
|
||||
#include "ultima/shared/std/string.h"
|
||||
#include "ultima/nuvie/files/nuvie_io_file.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class ActorManager;
|
||||
class ObjManager;
|
||||
class Actor;
|
||||
class Map;
|
||||
class NuvieIO;
|
||||
class NuvieIOFileWrite;
|
||||
|
||||
class SaveGame {
|
||||
private:
|
||||
Configuration *config;
|
||||
NuvieIOBuffer objlist;
|
||||
protected:
|
||||
bool load_objlist();
|
||||
bool save_objlist();
|
||||
|
||||
void update_objlist_for_new_game();
|
||||
void update_objlist_for_new_game_u6();
|
||||
void update_objlist_for_new_game_se();
|
||||
void update_objlist_for_new_game_md();
|
||||
public:
|
||||
SaveGame(Configuration *cfg);
|
||||
~SaveGame();
|
||||
|
||||
void init(ObjManager *obj_manager);
|
||||
|
||||
/**
|
||||
* Sets up a new game
|
||||
*/
|
||||
bool load_new();
|
||||
|
||||
/**
|
||||
* Loads in the savegame created by the original Ultima 6
|
||||
*/
|
||||
bool load_original();
|
||||
|
||||
/**
|
||||
* Transfers in a character from a previous Ultima game
|
||||
*/
|
||||
bool transfer_character();
|
||||
|
||||
/**
|
||||
* Loads the savegame with the given name
|
||||
*/
|
||||
bool load(const Common::String &filename);
|
||||
|
||||
bool check_version(NuvieIOFileRead *loadfile, uint16 gameType);
|
||||
|
||||
bool save(const Common::String &filename, const Common::String &save_description, bool isAutosave);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user