/* client/reputationwindow.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include "ui/paint.h" #include "ui/ui.h" #include "client/client.h" #include "client/reputationwindow.h" #include "core/reputation.h" #include "core/range.h" namespace client { class ReputationBar : public ui::Widget { public: ReputationBar(ui::Widget *parent = 0) : ui::Widget(parent) { bar_reputation = 0; set_border(false); } ~ReputationBar() { } inline const float reputation() const { return bar_reputation; } void set_reputation(const float reputation) { bar_reputation = reputation; } protected: virtual void resize() { if (parent()) { // small hack to keep the bars aligned within the listviewitem if the listview scrollbar appears/dissapears const float padding = ui::root()->font_large()->height(); set_width(parent()->width() - padding); } } virtual void draw() { const float box_padding = 4.0f; float box_width = floorf((width() - 19.0f * box_padding) / 20.0f); if (box_width < 1.0f) { box_width = floorf(width() / 20.0f); } math::Vector2f s(box_width, height()); const math::Vector2f g (global_location()); math::Vector2f pos (g); // draw squares math::Color c1; math::Color c2; for (int i = 0; i < 20; i++) { pos[0] = g[0] + floorf (width() / 20.0f * (float) i); if (i < 10) { if (bar_reputation <= (i - 10) * 10.0f ) { c1.assign(1.0f, 0.1f * (float) ( i), 0.1f * (float) ( i) ); c2.assign(1.0f, 0.1f * (float) (i +1), 0.1f * (float) (i + 1)); ui::Paint::draw_rectangle_gradient(pos, s, c1, c2); } } else { if (bar_reputation > (i - 10) * 10.0f) { c1.assign(0.1f * (float) (20 - i), 1.0f, 0.1f * (float) (20 - i)); c2.assign(0.1f * (float) (20 - i + 1), 1.0f, 0.1f * (float) (20 - i + 1)); ui::Paint::draw_rectangle_gradient(pos, s, c1, c2); } } } ui::Paint::set_color(palette()->border()); for (int i = 0; i < 20; i++) { pos[0] = g[0] + floorf (width() / 20.0f * (float) i); ui::Paint::draw_border(pos, s); } } private: float bar_reputation; }; ReputationWindow::ReputationWindow(ui::Widget *parent) : ui::Window(parent) { reputationwindow_info = 0; reputationwindow_info_timestamp = 0; reputationwindow_reputation_timestamp = 0; // window title reputationwindow_titlelabel = new ui::Label(this); reputationwindow_titlelabel->set_label("title"); reputationwindow_titlelabel->set_background(false); reputationwindow_titlelabel->set_border(false); reputationwindow_titlelabel->set_font(ui::root()->font_large()); reputationwindow_titlelabel->set_alignment(ui::AlignCenter); reputationwindow_titlelabel->set_text("REPUTATION"); // close button reputationwindow_closebutton = new ui::IconButton(reputationwindow_titlelabel, "bitmaps/icons/window_close"); // reputation listview reputationwindow_listview = new ui::ListView(this); reputationwindow_listview->set_label("listview"); // ---- right pane reputationwindow_pane_right = new ui::Widget(this); reputationwindow_pane_right->set_background(true); reputationwindow_pane_right->set_border(true); // ---- right pane: target label reputationwindow_targetlabel = new ui::Label(reputationwindow_pane_right); reputationwindow_targetlabel->set_label("info"); reputationwindow_targetlabel->set_background(false); reputationwindow_targetlabel->set_border(false); reputationwindow_targetlabel->set_alignment(ui::AlignCenter); // ---- right pane: target info reputationwindow_scrollpane = new ui::ScrollPane(reputationwindow_pane_right, reputationwindow_infotext); reputationwindow_scrollpane->set_background(false); reputationwindow_scrollpane->set_border(false); reputationwindow_scrollpane->set_alignment(ui::AlignTop); hide(); } ReputationWindow::~ReputationWindow() { } void ReputationWindow::show() { if (hidden()) { reputationwindow_info = 0; refresh(); } ui::Window::show(); } void ReputationWindow::refresh() { reputationwindow_listview->clear(); const float padding = ui::root()->font_large()->height(); ui::ListItem *selected_listitem = 0; for (core::Reputation::FactionReps::const_iterator it = core::localplayer()->reputation().factionreps().begin(); it != core::localplayer()->reputation().factionreps().end(); ++it) { if ((*it)->faction()) { std::string strdescription; if (roundf((*it)->reputation()) <= core::range::reputation_hostile) { strdescription.append("^1"); } else if (roundf((*it)->reputation()) >= core::range::reputation_friendly) { strdescription.append("^2"); } else { strdescription.append("^B"); } strdescription.append((*it)->faction()->name()); ui::ListItem *listitem = new ui::ListItem(reputationwindow_listview, strdescription.c_str()); listitem->set_alignment(ui::AlignTop | ui::AlignHCenter); listitem->set_font(ui::root()->font_tiny()); listitem->set_height(listitem->font()->height() * 3.5f); listitem->set_info((*it)->faction()); std::ostringstream strsortkey; strsortkey << std::setfill('0') << std::setw(3) << roundf((*it)->reputation() + 100); listitem->set_sortkey(strsortkey.str().c_str()); ReputationBar *bar = new ReputationBar(listitem); bar->set_reputation((*it)->reputation()); bar->set_size(reputationwindow_listview->width() - padding, bar->font()->height()); bar->set_location( padding * 0.5f, listitem->height() - bar->height() - padding * 0.5f); if ((*it)->faction() == reputationwindow_info) { selected_listitem = listitem; } } } reputationwindow_listview->sort(); reputationwindow_listview->event_resize(); reputationwindow_reputation_timestamp = core::localplayer()->reputation().timestamp(); if (selected_listitem) { reputationwindow_listview->select(selected_listitem); reputationwindow_info = selected_listitem->info(); } else { reputationwindow_info = 0; } set_info(reputationwindow_info); } void ReputationWindow::set_info(const core::Info *info) { reputationwindow_infotext.clear(); reputationwindow_targetlabel->clear(); reputationwindow_info = info; if (!info) { // player name reputationwindow_targetlabel->set_text(core::localplayer()->name()); std::ostringstream strinfotext; // player level strinfotext.str(""); strinfotext.clear(); strinfotext << "^NLevel: "; strinfotext << core::localplayer()->level(); reputationwindow_infotext.push_back(strinfotext.str()); // player credits strinfotext.str(""); strinfotext.clear(); strinfotext << "^NCredits: "; strinfotext << core::localplayer()->credits(); reputationwindow_infotext.push_back(strinfotext.str()); // ------------------ strinfotext.str(""); strinfotext.clear(); reputationwindow_infotext.push_back(strinfotext.str()); // player NPC kills strinfotext.str(""); strinfotext.clear(); strinfotext << "^NNPC kills: "; strinfotext << core::localplayer()->npckills(); reputationwindow_infotext.push_back(strinfotext.str()); // player PVP kills strinfotext.str(""); strinfotext.clear(); strinfotext << "^NPVP kills: "; strinfotext << core::localplayer()->pvpkills(); reputationwindow_infotext.push_back(strinfotext.str()); // player time wasted strinfotext.str(""); strinfotext.clear(); strinfotext << "^NTime wasted: "; long time_wasted = (core::localplayer()->time_wasted() + core::game()->timestamp() - core::localplayer()->time_joined()) / 1000; const long time_wasted_seconds = time_wasted % 60; time_wasted = (time_wasted - time_wasted_seconds) / 60; const long time_wasted_minutes = time_wasted % 60; time_wasted = (time_wasted - time_wasted_minutes) / 60; const long time_wasted_hours = time_wasted % 24; const long time_wasted_days = (time_wasted - time_wasted_hours) / 24; if (time_wasted_days > 0) { strinfotext << time_wasted_days << aux::plural("day", time_wasted_days) << " "; } strinfotext << std::setfill('0') << std::setw(2) << time_wasted_hours << ":" ; strinfotext << std::setfill('0') << std::setw(2) << time_wasted_minutes << ":"; strinfotext << std::setfill('0') << std::setw(2) << time_wasted_seconds; reputationwindow_infotext.push_back(strinfotext.str()); reputationwindow_info_timestamp = 0; } else { core::game()->request_info(info->id()); reputationwindow_targetlabel->set_text(info->name()); for (core::Info::Text::const_iterator it = info->text().begin(); it != info->text().end(); it++) { reputationwindow_infotext.push_back((*it)); } reputationwindow_info_timestamp = info->timestamp(); } } void ReputationWindow::draw() { if (reputationwindow_reputation_timestamp != core::localplayer()->reputation().timestamp()) { // refresh window content refresh(); } else if (!reputationwindow_info) { // update player info set_info(0); } else if (reputationwindow_info_timestamp != reputationwindow_info->timestamp()) { // update faction info set_info(reputationwindow_info); } ui::Window::draw(); } void ReputationWindow::resize() { const float padding = ui::root()->font_large()->height(); // resize label reputationwindow_titlelabel->set_size(width() - padding * 2.0f, reputationwindow_titlelabel->font()->height()); reputationwindow_titlelabel->set_location(padding, padding); // resize close button reputationwindow_closebutton->set_size(reputationwindow_titlelabel->font()->height(), reputationwindow_titlelabel->font()->height()); reputationwindow_closebutton->set_location(reputationwindow_titlelabel->width() - reputationwindow_closebutton->width(), 0); // resize reputation listview reputationwindow_listview->set_size(ui::UI::elementsize.width(), height() - reputationwindow_titlelabel->bottom() - padding * 2.0f); reputationwindow_listview->set_location(reputationwindow_titlelabel->left(), reputationwindow_titlelabel->bottom() + padding); // resize right pane reputationwindow_pane_right->set_size(width() - reputationwindow_listview->right() - padding * 2.0f, reputationwindow_listview->height()); reputationwindow_pane_right->set_location(reputationwindow_listview->right() + padding,reputationwindow_titlelabel->bottom() + padding); { const ui::Widget *pane = reputationwindow_pane_right; const float margin_horizontal = pane->font()->width(); const float margin_vertical = pane->font()->height() * 0.5f; // resize reputation info label reputationwindow_targetlabel->set_size(pane->width() - 2.0f * margin_horizontal, reputationwindow_targetlabel->font()->height()); reputationwindow_targetlabel->set_location(margin_horizontal, margin_vertical); // resize infotext scrollpane reputationwindow_scrollpane->set_size(pane->width()- 2.0f * margin_horizontal, pane->height() - reputationwindow_targetlabel->bottom() - 2.0f * margin_vertical); reputationwindow_scrollpane->set_location(margin_horizontal, reputationwindow_targetlabel->bottom() + margin_vertical); } } bool ReputationWindow::on_emit(ui::Widget *sender, const Event event, void *data) { if (event == ui::Widget::EventButtonClicked) { if (sender == reputationwindow_closebutton) { hide(); } return true; } else if (event == ui::Widget::EventListViewChanged) { if (sender == reputationwindow_listview) { set_info( reputationwindow_listview->selected() ? reputationwindow_listview->selected()->info() : 0); } return true; } return Window::on_emit(sender, event, data); } bool ReputationWindow::on_keypress(const int key, const unsigned int modifier) { switch (key) { case SDLK_ESCAPE: this->hide(); return true; break; default: break; } return Window::on_keypress(key, modifier); } } //namespace client