diff options
-rw-r--r-- | src/client/savegamemenu.cc | 219 | ||||
-rw-r--r-- | src/client/savegamemenu.h | 8 |
2 files changed, 207 insertions, 20 deletions
diff --git a/src/client/savegamemenu.cc b/src/client/savegamemenu.cc index 18d474d..9f8ee99 100644 --- a/src/client/savegamemenu.cc +++ b/src/client/savegamemenu.cc @@ -4,6 +4,12 @@ the terms of the GNU General Public License version 2 */ +#include <iomanip> +#include <cstdio> + +#include "core/application.h" +#include "core/gameinterface.h" +#include "core/gameserver.h" #include "client/savegamemenu.h" #include "filesystem/filesystem.h" #include "ui/ui.h" @@ -42,9 +48,12 @@ SaveGameMenu::SaveGameMenu(ui::Widget *parent, const char *label, const Mode mod savegamemenu_filelistview = new ui::ListView(this); savegamemenu_filelistview->set_label("files"); + // savegame desription label savegamemenu_descrlabel = new ui::Label(this); savegamemenu_descrlabel->set_label("description"); + // save button + savegamemenu_savebutton = new ui::Button(this, "Save"); //savegamemenu_descrinput = new ui::InputBox(this); // delete button @@ -79,20 +88,25 @@ void SaveGameMenu::resize() savegamemenu_titlelabel->bottom() + padding ); - // resize description label - savegamemenu_descrlabel->set_size( - width() - savegamemenu_filelistview->right() - 2.0f * padding, - savegamemenu_filelistview->height() - ); - savegamemenu_descrlabel->set_location(savegamemenu_filelistview->right() + padding, savegamemenu_filelistview->top()); - - // resize eject button savegamemenu_deletebutton->set_size(icon_size, icon_size); savegamemenu_deletebutton->set_location( savegamemenu_filelistview->right() - icon_size, savegamemenu_filelistview->bottom() + padding ); + + // resize description label + savegamemenu_descrlabel->set_size( + width() - savegamemenu_filelistview->right() - 2.0f * padding, + savegamemenu_filelistview->height() - ui::UI::elementsize.height() - padding + ); + savegamemenu_descrlabel->set_location(savegamemenu_filelistview->right() + padding, savegamemenu_filelistview->top()); + + // resize save button + savegamemenu_savebutton->set_size(ui::UI::elementsize); + savegamemenu_savebutton->set_location( + savegamemenu_descrlabel->left() + (savegamemenu_descrlabel->width() - ui::UI::elementsize.width()) * 0.5f, + savegamemenu_descrlabel->bottom() + padding); } void SaveGameMenu::refresh() @@ -105,12 +119,23 @@ void SaveGameMenu::refresh() filesystem::Directory directory(savegamepath); savegamemenu_filelistview->clear(); + savegamemenu_deletebutton->disable(); + savegamemenu_savebutton->hide(); + savegamemenu_savebutton->enable(); if (savegamemenu_mode == Save) { listitem = new ui::ListItem(savegamemenu_filelistview, "NEW SAVEGAME"); listitem->set_label("new"); + listitem->set_sortkey("[new]"); listitem->set_font(ui::root()->font_tiny()); listitem->set_height(listitem->font()->height() * 2.0f); + + savegamemenu_savebutton->set_text("Save"); + if (!core::localcontrol()) { + savegamemenu_savebutton->disable(); + } + } else { + savegamemenu_savebutton->set_text("Load"); } for (filesystem::Directory::FileNames::const_iterator it = directory.filenames().begin(); @@ -123,22 +148,32 @@ void SaveGameMenu::refresh() std::string ext = filename.substr(filename.size() - 4); aux::lowercase(ext); - if (ext.compare(".sav")) { + if (ext.compare(".ini")) { continue; } - std::string label = filename.substr(0, filename.size() - 4); + std::string savename = filename.substr(0, filename.size() - 4); - listitem = new ui::ListItem(savegamemenu_filelistview, label.c_str()); - listitem->set_value(filename); - - listitem->set_font(ui::root()->font_tiny()); - listitem->set_height(listitem->font()->height() * 2.0f); - - // TODO savegame info, sortkey timestamp + std::string descr; + std::string timestamp; + get_savegame_info(savename, descr, timestamp); + + if (descr.size()) { + std::ostringstream descrstr; + descrstr << descr << '\n'<< timestamp; + listitem = new ui::ListItem(savegamemenu_filelistview, descrstr.str().c_str()); + listitem->set_value(savename); + listitem->set_sortkey(timestamp); + + listitem->set_font(ui::root()->font_tiny()); + listitem->set_height(listitem->font()->height() * 3.0f); + } } + savegamemenu_filelistview->sort_reverse(); savegamemenu_filelistview->event_resize(); + + show_file_info(); } void SaveGameMenu::show() @@ -151,12 +186,18 @@ void SaveGameMenu::show() void SaveGameMenu::show_file_info() { savegamemenu_descrlabel->clear(); + savegamemenu_deletebutton->disable(); - if (savegamemenu_filelistview->selected()) { - std::string filename(savegamemenu_filelistview->selected()->value().c_str()); - savegamemenu_descrlabel->set_text(filename); + if (savegamemenu_filelistview->selected()) { + std::string savename(savegamemenu_filelistview->selected()->value().c_str()); + savegamemenu_descrlabel->set_text(savegamemenu_filelistview->selected()->text() + '\n' + '\n' + savename); + if (savename.size()) { + savegamemenu_deletebutton->enable(); + } + savegamemenu_savebutton->show(); } } + bool SaveGameMenu::on_keypress(const int key, const unsigned int modifier) { if (key == SDLK_ESCAPE) { @@ -178,6 +219,29 @@ bool SaveGameMenu::on_emit(ui::Widget *sender, const ui::Widget::Event event, vo parent()->hide(); return true; } + } else if (sender == savegamemenu_savebutton) { + if (event == ui::Widget::EventButtonClicked) { + if (savegamemenu_mode == Save) { + if (savegamemenu_filelistview->selected()) { + savegame(savegamemenu_filelistview->selected()->value()); + parent()->hide(); + } + } else { + if (savegamemenu_filelistview->selected()) { + loadgame(savegamemenu_filelistview->selected()->value()); + parent()->hide(); + } + } + return true; + } + } else if (sender == savegamemenu_deletebutton) { + if (event == ui::Widget::EventButtonClicked) { + if (savegamemenu_filelistview->selected()) { + deletegame(savegamemenu_filelistview->selected()->value()); + refresh(); + } + return true; + } } else if (sender == savegamemenu_filelistview) { if (event == ui::Widget::EventListViewChanged) { show_file_info(); @@ -188,6 +252,121 @@ bool SaveGameMenu::on_emit(ui::Widget *sender, const ui::Widget::Event event, vo return Window::on_emit(sender, event, data); } +void SaveGameMenu::get_savegame_info(const std::string & savename, std::string &game_descr, std::string &game_timestamp) +{ + filesystem::IniFile inifile("savegames/" + savename); + + game_descr.clear(); + game_timestamp.clear(); + + if (!inifile.is_open()) { + return; + } + + while(inifile.getline()) { + if (inifile.got_key()) { + + if (inifile.in_section("savegame")) { + + if (inifile.got_key_string("description", game_descr)) { + continue; + + } else if (inifile.got_key_string("timestamp", game_timestamp)) { + continue; + } + } + } + } + inifile.close(); +} + +void SaveGameMenu::deletegame(std::string savename) +{ + std::string filename(filesystem::writedir() + "savegames/" + savename + ".ini"); + + con_debug << "Deleteing " << filename << std::endl; + ::remove(filename.c_str()); +} + +void SaveGameMenu::savegame(std::string savename) +{ + if (!core::server() || !core::server()->module()) + return; + + if (!core::localcontrol()) { + return; + } + + if (!savename.size()) { + std::string filename; + unsigned long n = 0; + do { + n++; + std::ostringstream numberstr; + numberstr << std::setfill('0') << std::setw(4) << n; + + savename.assign("save"); + savename.append(numberstr.str()); + + filename.assign(filesystem::writedir() + "savegames/" + savename + ".ini"); + } while (sys::file_exists(filename)); + } + + filesystem::OFileStream ofs("savegames/" + savename + ".ini"); + + con_debug << "Saving " << ofs.filename() << std::endl; + + ofs << "; Project::OSiRiON" << std::endl; + ofs << "; savegame data" << std::endl; + ofs << std::endl; + + ofs << "[savegame]" << std::endl; + ofs << "description="; + if (core::localcontrol()->state() == core::Entity::Docked) { + // FIXME implement entity->dock() + ofs << core::localplayer()->view()->name(); + } else { + ofs << core::localplayer()->zone()->name(); + } + ofs << std::endl; + + int year = 0; int month = 0; int day = 0; int hours = 0; int minutes = 0; int seconds = 0; int msec = 0; + sys::get_localtime(year, month, day, hours, minutes, seconds, msec); + + std::ostringstream timestampstr; + timestampstr << std::setfill('0') << std::setw(4) << year << "-" << std::setw(2) << month << "-" << std::setw(2) << day << " "; + timestampstr << std::setw(2) << hours << ":" << std::setw(2) << minutes << ":" << std::setw(2) << seconds; + + ofs << "timestamp=" << timestampstr.str() << std::endl; + + ofs << std::endl; + + core::server()->module()->game_save(core::localplayer(), ofs); + + ofs.close(); +} + +void SaveGameMenu::loadgame(std::string savename) { + + filesystem::IniFile inifile("savegames/" + savename); + if (!inifile.is_open()) { + con_warn << "Could not open file " << inifile.filename() << "!" << std::endl; + return; + } + + con_debug << "Loading " << inifile.filename() << std::endl; + + if (core::application()->connected()) + core::application()->disconnect(); + + core::application()->connect(""); + + if (core::application()->connected() && core::server() && core::server()->module()) { + core::server()->module()->game_load(core::localplayer(), inifile); + } + + inifile.close(); +} } // namespace client diff --git a/src/client/savegamemenu.h b/src/client/savegamemenu.h index d5b69e3..2d895d8 100644 --- a/src/client/savegamemenu.h +++ b/src/client/savegamemenu.h @@ -25,6 +25,12 @@ public: SaveGameMenu(ui::Widget *parent = 0, const char *label = 0, const Mode mode = Save); virtual ~SaveGameMenu(); + static void loadgame(std::string savename); + + static void savegame(std::string savename); + + static void deletegame(std::string savename); + protected: /// called when the widget receives a key press @@ -42,6 +48,8 @@ protected: void refresh(); private: + void get_savegame_info(const std::string & savename, std::string &game_descr, std::string &game_timestamp); + Mode savegamemenu_mode; ui::Label *savegamemenu_titlelabel; |