Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2012-01-15 16:58:18 +0000
committerStijn Buys <ingar@osirion.org>2012-01-15 16:58:18 +0000
commit714dc789aa08230468031ee6143be4535fbfd287 (patch)
tree398b100740e7881b96b5d9e75475700dd1f902ec /src/client/savegamemenu.cc
parent877aed6c718760dbc889ef667d8fd8881f6eb133 (diff)
Added client-side savegame functionality.
Diffstat (limited to 'src/client/savegamemenu.cc')
-rw-r--r--src/client/savegamemenu.cc219
1 files changed, 199 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