1 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include <sigc++/functors/mem_fun.h>
23 #include "history-report-dialog.h"
25 #include "glade-helpers.h"
26 #include "image-helpers.h"
27 #include "input-helpers.h"
28 #include "line-chart.h"
29 #include "report-dialog.h"
30 #include "ucompose.hpp"
38 #include "playerlist.h"
40 #include "network-history.h"
41 #include "GraphicsCache.h"
42 #include "boxcompose.h"
44 HistoryReportDialog::HistoryReportDialog(Player *p, HistoryReportType type)
47 Glib::RefPtr<Gtk::Builder> xml
48 = Gtk::Builder::create_from_file(get_glade_path()
49 + "/history-report-dialog.ui");
51 xml->get_widget("dialog", dialog);
54 generatePastCitylists();
55 generatePastRuinlists();
56 generatePastEventlists();
58 xml->get_widget("map_image", map_image);
59 historymap = new HistoryMap(Citylist::getInstance(), Ruinlist::getInstance());
60 historymap->map_changed.connect
61 (sigc::mem_fun(this, &HistoryReportDialog::on_map_changed));
63 xml->get_widget("turn_scale", turn_scale);
64 set_title(_("History"));
65 turn_scale->set_range(1, past_citylists.size());
66 turn_scale->set_value(past_citylists.size());
68 turn_scale->signal_value_changed().connect
69 (sigc::bind(sigc::mem_fun(this, &HistoryReportDialog::on_turn_changed),
72 xml->get_widget("history_notebook", history_notebook);
73 history_notebook->set_current_page(type);
74 history_notebook->signal_switch_page().connect(
75 sigc::mem_fun(*this, &HistoryReportDialog::on_switch_page));
77 xml->get_widget("city_label", city_label);
78 xml->get_widget("ruin_label", ruin_label);
79 xml->get_widget("gold_label", gold_label);
80 xml->get_widget("winner_label", winner_label);
82 //events_list = Gtk::ListStore::create(events_columns);
83 //xml->get_widget("treeview", events_treeview);
84 //events_treeview->set_model(events_list);
85 //events_treeview->append_column("", events_columns.box);
86 //events_treeview->append_column("", events_columns.desc);
88 xml->get_widget("events_list_box", events_list_box);
89 Gtk::Button *close_button;
90 xml->get_widget("close_button", close_button);
91 close_button->signal_clicked().connect
92 (sigc::mem_fun(*this, &HistoryReportDialog::on_close_button));
95 xml->get_widget("city_alignment", city_alignment);
96 xml->get_widget("ruin_alignment", ruin_alignment);
97 xml->get_widget("gold_alignment", gold_alignment);
98 xml->get_widget("winner_alignment", winner_alignment);
100 Playerlist::iterator pit = Playerlist::getInstance()->begin();
102 for (; pit != Playerlist::getInstance()->end(); ++pit)
104 if (*pit == Playerlist::getInstance()->getNeutral())
106 colour = (*pit)->getColor();
107 if (*pit == d_player)
108 d_colours.push_front(colour);
110 d_colours.push_back(colour);
113 generatePastCityCounts();
114 city_chart = new LineChart(past_citycounts, d_colours,
115 Citylist::getInstance()->size(),
116 _("Cities"), _("Turns"));
117 city_alignment->add(*manage(city_chart));
119 generatePastRuinCounts();
120 ruin_chart = new LineChart(past_ruincounts, d_colours,
121 Ruinlist::getInstance()->size(),
122 _("Explored Ruins"), _("Turns"));
123 ruin_alignment->add(*manage(ruin_chart));
125 generatePastGoldCounts();
126 gold_chart = new LineChart(past_goldcounts, d_colours, 0,
127 _("Gold Pieces"), _("Turns"));
128 gold_alignment->add(*manage(gold_chart));
130 generatePastWinningCounts();
131 rank_chart = new LineChart(past_rankcounts, d_colours, 100,
132 _("Score"), _("Turns"));
133 winner_alignment->add(*manage(rank_chart));
135 fill_in_turn_info((guint32)turn_scale->get_value());
138 HistoryReportDialog::~HistoryReportDialog()
140 std::vector<std::list<NetworkHistory *> >::iterator it;
141 it = past_eventlists.begin();
142 for (; it != past_eventlists.end(); it++)
144 std::list<NetworkHistory*> hist = (*it);
145 std::list<NetworkHistory*>::iterator hit = hist.begin();
146 for (; hit != hist.end(); hit++)
153 void HistoryReportDialog::generatePastEventlists()
155 bool last_turn = false;
156 std::list<NetworkHistory*> *elist = new std::list<NetworkHistory*>();
158 //keep a set of pointers to remember how far we are into each player's history
159 std::list<History*> *hist[MAX_PLAYERS];
160 Playerlist::iterator pit = Playerlist::getInstance()->begin();
161 for (; pit != Playerlist::getInstance()->end(); ++pit)
163 if (*pit == Playerlist::getInstance()->getNeutral())
165 hist[(*pit)->getId()] = (*pit)->getHistorylist();
167 std::list<History*>::iterator hit[MAX_PLAYERS];
168 pit = Playerlist::getInstance()->begin();
169 for (; pit != Playerlist::getInstance()->end(); ++pit)
171 if (*pit == Playerlist::getInstance()->getNeutral())
173 hit[(*pit)->getId()] = hist[(*pit)->getId()]->begin();
176 unsigned int count = 0;
179 //now we see what cities we took this turn
180 pit = Playerlist::getInstance()->begin();
181 for (; pit != Playerlist::getInstance()->end(); ++pit)
183 if (*pit == Playerlist::getInstance()->getNeutral())
185 //dump everything up to the next turn
186 guint32 id = (*pit)->getId();
187 if (hit[id] == hist[id]->end())
189 for (; hit[id] != hist[id]->end(); ++hit[id])
191 if ((*hit[id])->getType() == History::START_TURN)
196 switch ((*hit[id])->getType())
198 case History::FOUND_SAGE:
199 case History::HERO_EMERGES:
200 case History::HERO_QUEST_STARTED:
201 case History::HERO_QUEST_COMPLETED:
202 case History::HERO_KILLED_IN_CITY:
203 case History::HERO_KILLED_IN_BATTLE:
204 case History::HERO_KILLED_SEARCHING:
205 case History::HERO_CITY_WON:
206 case History::HERO_FINDS_ALLIES:
207 case History::PLAYER_VANQUISHED:
208 case History::DIPLOMATIC_TREACHERY:
209 case History::DIPLOMATIC_WAR:
210 case History::DIPLOMATIC_PEACE:
211 case History::HERO_RUIN_EXPLORED:
212 elist->push_back(new NetworkHistory(*hit[id], (*pit)->getId()));
214 case History::START_TURN:
215 case History::GOLD_TOTAL:
216 case History::CITY_WON:
217 case History::CITY_RAZED:
219 case History::HERO_REWARD_RUIN:
220 case History::END_TURN:
224 if (hit[id] == hist[id]->end())
227 if (count == Playerlist::getInstance()->size() - 2)
231 //and add it to the list
232 past_eventlists.push_back(*elist);
233 std::list<NetworkHistory*> *new_elist = new std::list<NetworkHistory*>();
235 if (last_turn == true)
241 void HistoryReportDialog::generatePastCitylists()
243 bool last_turn = false;
245 //keep a set of pointers to remember how far we are into each player's history
246 std::list<History*> *hist[MAX_PLAYERS];
247 Playerlist::iterator pit = Playerlist::getInstance()->begin();
248 for (; pit != Playerlist::getInstance()->end(); ++pit)
250 if (*pit == Playerlist::getInstance()->getNeutral())
252 hist[(*pit)->getId()] = (*pit)->getHistorylist();
254 std::list<History*>::iterator hit[MAX_PLAYERS];
255 pit = Playerlist::getInstance()->begin();
256 for (; pit != Playerlist::getInstance()->end(); ++pit)
258 if (*pit == Playerlist::getInstance()->getNeutral())
260 hit[(*pit)->getId()] = hist[(*pit)->getId()]->begin();
263 //start off with an initial city list where all cities are neutral owned
264 LocationList<City*> *clist = new LocationList<City*>();
265 Citylist *cl = Citylist::getInstance();
266 for (Citylist::iterator it = cl->begin(); it != cl->end(); ++it)
267 clist->push_back(new City(**it));
268 for (LocationList<City*>::iterator it = clist->begin(); it != clist->end(); ++it)
270 (*it)->setOwner(Playerlist::getInstance()->getNeutral());
271 //is the city burned to begin with?
272 bool no_city_history = true;
273 pit = Playerlist::getInstance()->begin();
274 for (; pit != Playerlist::getInstance()->end(); ++pit)
275 if ((*pit)->conqueredCity(*it) == true)
276 no_city_history = false;
277 if ((*it)->isBurnt() == true && no_city_history)
278 (*it)->setBurnt(true);
280 (*it)->setBurnt(false);
283 unsigned int count = 0;
286 //now we see what cities we took this turn
287 pit = Playerlist::getInstance()->begin();
288 for (; pit != Playerlist::getInstance()->end(); ++pit)
290 if (*pit == Playerlist::getInstance()->getNeutral())
292 //dump everything up to the next turn
293 guint32 id = (*pit)->getId();
294 if (hit[id] == hist[id]->end())
296 for (; hit[id] != hist[id]->end(); hit[id]++)
298 if ((*hit[id])->getType() == History::START_TURN)
303 else if ((*hit[id])->getType() == History::CITY_WON)
306 city_id = dynamic_cast<History_CityWon*>(*hit[id])->getCityId();
307 //find city with this city id in clist
308 LocationList<City*>::iterator cit = clist->begin();
309 for (; cit != clist->end(); ++cit)
310 if ((*cit)->getId() == city_id)
312 (*cit)->setOwner(*pit);
316 else if ((*hit[id])->getType() == History::CITY_RAZED)
319 city_id = dynamic_cast<History_CityRazed*>(*hit[id])->getCityId();
320 //find city with this city id in clist
321 LocationList<City*>::iterator cit = clist->begin();
322 for (; cit != clist->end(); ++cit)
323 if ((*cit)->getId() == city_id)
325 //change the owner to neutral
326 (*cit)->setOwner(Playerlist::getInstance()->getNeutral());
327 (*cit)->setBurnt(true);
332 if (hit[id] == hist[id]->end())
335 if (count == Playerlist::getInstance()->size() - 2)
339 //and add it to the list
340 past_citylists.push_back(clist);
341 LocationList<City*> *new_clist = new LocationList<City*>();
342 for (LocationList<City*>::iterator it = clist->begin();
343 it != clist->end(); ++it)
344 new_clist->push_back(new City(**it));
346 if (last_turn == true)
350 past_citylists.erase(--past_citylists.end());
353 void HistoryReportDialog::set_parent_window(Gtk::Window &parent)
355 dialog->set_transient_for(parent);
356 //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
359 void HistoryReportDialog::hide()
364 void HistoryReportDialog::run()
366 historymap->resize();
367 historymap->draw(Playerlist::getActiveplayer());
373 void HistoryReportDialog::on_map_changed(Glib::RefPtr<Gdk::Pixmap> map)
375 map_image->property_pixmap() = map;
378 void HistoryReportDialog::on_turn_changed(Gtk::Scale *scale)
380 //tell the historymap to show another set of cities
381 guint32 turn = (guint32)turn_scale->get_value();
382 if (turn > past_citylists.size() - 1)
383 historymap->updateCities(Citylist::getInstance(), Ruinlist::getInstance());
385 historymap->updateCities(past_citylists[turn], past_ruinlists[turn]);
386 city_chart->set_x_indicator(turn);
387 ruin_chart->set_x_indicator(turn);
388 gold_chart->set_x_indicator(turn);
389 rank_chart->set_x_indicator(turn);
390 fill_in_turn_info(turn);
393 void HistoryReportDialog::update_window_title()
395 switch (history_notebook->get_current_page())
398 set_title(_("City History"));
401 set_title(_("Ruin History"));
404 set_title(_("Event History"));
407 set_title(_("Gold History"));
410 set_title(_("Winner History"));
415 void HistoryReportDialog::fill_in_turn_info(guint32 turn)
419 update_window_title();
421 //update the event list
422 //events_list->clear();
423 events_list_box->children().erase(events_list_box->children().begin(),
424 events_list_box->children().end());
425 if (turn <= past_eventlists.size() - 1)
427 std::list<NetworkHistory*> hist = past_eventlists[turn];
428 std::list<NetworkHistory*>::iterator hit = hist.begin();
429 for (; hit != hist.end(); hit++)
430 addHistoryEvent(*hit);
433 //update the gold chart
434 //on turn # you had # gold pieces
435 std::list<guint32> goldlist = *past_goldcounts.begin();
436 std::list<guint32>::iterator it = goldlist.begin();
438 for (; it != goldlist.end(); it++, count++)
446 turn == past_citylists.size() ?
447 s = String::ucompose(ngettext("On turn %1 you have %2 gold piece!",
448 "On turn %1 you have %2 gold pieces!",
449 count), turn, count) :
450 s = String::ucompose(ngettext("On turn %1 you had %2 gold piece!",
451 "On turn %1 you had %2 gold pieces!",
452 count), turn, count);
453 gold_label->set_text(s);
455 //update the city chart
456 std::list<guint32> citylist = *past_citycounts.begin();
457 it = citylist.begin();
459 for (; it != citylist.end(); it++, count++)
467 turn == past_citylists.size() ?
468 s = String::ucompose(ngettext("On turn %1 you have %2 city!",
469 "On turn %1 you have %2 cities!",
470 count), turn, count) :
471 s = String::ucompose(ngettext("On turn %1 you had %2 city!",
472 "On turn %1 you had %2 cities!",
473 count), turn, count);
474 city_label->set_text(s);
476 //update the ruin chart
477 std::list<guint32> ruinlist = *past_ruincounts.begin();
478 it = ruinlist.begin();
480 for (; it != ruinlist.end(); it++, count++)
488 turn == past_ruinlists.size() ?
489 s = String::ucompose(ngettext("By turn %1 you explored %2 ruin!",
490 "By turn %1 you explored %2 ruins!",
491 count), turn, count) :
492 s = String::ucompose(ngettext("By turn %1 you explored %2 ruin!",
493 "By turn %1 you explored %2 ruins!",
494 count), turn, count);
495 ruin_label->set_text(s);
497 //on turn # you were coming #
498 std::list<guint32> scores;
499 std::list<std::list<guint32> >::iterator rit = past_rankcounts.begin();
500 for (; rit != past_rankcounts.end(); rit++)
504 for (; it != (*rit).end(); it++, count++)
509 scores.push_back(*it);
514 turn == past_citylists.size() ?
515 s = String::ucompose(_("On turn %1 you are coming %2!"),
516 turn, ReportDialog::calculateRank(scores, *scores.begin())):
517 s = String::ucompose(_("On turn %1 you were coming %2!"),
518 turn, ReportDialog::calculateRank(scores, *scores.begin()));
519 winner_label->set_text(s);
522 void HistoryReportDialog::on_switch_page(GtkNotebookPage *page, guint number)
526 update_window_title();
529 void HistoryReportDialog::addHistoryEvent(NetworkHistory *event)
531 GraphicsCache *gc = GraphicsCache::getInstance();
532 Playerlist *pl = Playerlist::getInstance();
533 Player *p = event->getOwner();
535 History *history = event->getHistory();
537 Gtk::HBox *box = NULL;
540 Glib::RefPtr<Gdk::Pixbuf> shield = gc->getShieldPic(1, p)->to_pixbuf();
541 switch (history->getType())
543 case History::FOUND_SAGE:
545 History_FoundSage *ev = static_cast<History_FoundSage *>(history);
546 box = Box::ucompose(_("%1 %2 finds a sage!"), shield,
550 case History::HERO_EMERGES:
552 History_HeroEmerges *ev;
553 ev = static_cast<History_HeroEmerges *>(history);
554 box = Box::ucompose(_("%1 %2 emerges in %3"), shield,
555 ev->getHeroName(), ev->getCityName());
558 case History::HERO_QUEST_STARTED:
560 History_HeroQuestStarted *ev =
561 static_cast<History_HeroQuestStarted*>(history);
562 box = Box::ucompose(_("%1 %2 begins a quest!"), shield,
566 case History::HERO_QUEST_COMPLETED:
568 History_HeroQuestCompleted *ev
569 = static_cast<History_HeroQuestCompleted *>(history);
570 box = Box::ucompose(_("%1 %2 finishes a quest!"), shield,
574 case History::HERO_KILLED_IN_CITY:
576 History_HeroKilledInCity *ev =
577 static_cast<History_HeroKilledInCity *>(history);
578 box = Box::ucompose(_("%1 %2 is killed in %3!"), shield,
579 ev->getHeroName(), ev->getCityName());
582 case History::HERO_KILLED_IN_BATTLE:
584 History_HeroKilledInBattle *ev =
585 static_cast<History_HeroKilledInBattle *>(history);
586 box = Box::ucompose(_("%1 %2 is killed in battle!"), shield,
590 case History::HERO_KILLED_SEARCHING:
592 History_HeroKilledSearching *ev =
593 static_cast<History_HeroKilledSearching *>(history);
594 box = Box::ucompose(_("%1 %2 is killed while searching!"), shield,
598 case History::HERO_CITY_WON:
600 History_HeroCityWon *ev =
601 static_cast<History_HeroCityWon *>(history);
602 box = Box::ucompose(_("%1 %2 conquers %3!"), shield,
603 ev->getHeroName(), ev->getCityName());
606 case History::PLAYER_VANQUISHED:
608 box = Box::ucompose(_("%1 %2 utterly vanquished!"), shield,
612 case History::DIPLOMATIC_PEACE:
614 History_DiplomacyPeace *ev =
615 static_cast<History_DiplomacyPeace*>(history);
616 Player *opponent = pl->getPlayer(ev->getOpponentId());
617 box = Box::ucompose(_("%1 %2 at peace with %3 %4!"), shield,
619 gc->getShieldPic(1, opponent)->to_pixbuf(),
620 opponent->getName());
623 case History::DIPLOMATIC_WAR:
625 History_DiplomacyWar *ev =
626 static_cast<History_DiplomacyWar*>(history);
627 Player *opponent = pl->getPlayer(ev->getOpponentId());
628 box = Box::ucompose(_("%1 %2 at war with %3 %4!"), shield,
630 gc->getShieldPic(1, opponent)->to_pixbuf(),
631 opponent->getName());
634 case History::DIPLOMATIC_TREACHERY:
636 History_DiplomacyTreachery *ev =
637 static_cast<History_DiplomacyTreachery*>(history);
638 Player *opponent = pl->getPlayer(ev->getOpponentId());
639 box = Box::ucompose(_("%1 Treachery on %2 %3!"), shield,
640 gc->getShieldPic(1, opponent)->to_pixbuf(),
641 opponent->getName());
644 case History::HERO_FINDS_ALLIES:
646 History_HeroFindsAllies *ev =
647 static_cast<History_HeroFindsAllies*>(history);
648 box = Box::ucompose(_("%1 %2 finds allies!"), shield,
652 case History::HERO_RUIN_EXPLORED:
654 History_HeroRuinExplored *ev =
655 static_cast<History_HeroRuinExplored *>(history);
656 Ruinlist *rl = Ruinlist::getInstance();
657 box = Box::ucompose(_("%1 %2 explores %3!"), shield,
659 rl->getById(ev->getRuinId())->getName());
669 events_list_box->pack_start(*manage(box), Gtk::PACK_SHRINK, 0);
670 events_list_box->show_all();
673 void HistoryReportDialog::on_close_button()
676 //FIXME: find out why the page_switch events with crap data,
677 //and then remove this function, and the closing variable too.
680 void HistoryReportDialog::generatePastWinningCounts()
682 //go through the history list looking for score events, per player
683 Playerlist::iterator pit = Playerlist::getInstance()->begin();
684 pit = Playerlist::getInstance()->begin();
685 for (; pit != Playerlist::getInstance()->end(); ++pit)
687 if (*pit == Playerlist::getInstance()->getNeutral())
689 std::list<History*> *hist = (*pit)->getHistorylist();
690 std::list<History*>::iterator hit = hist->begin();
691 std::list<guint32> line;
692 for (; hit != hist->end(); hit++)
694 if ((*hit)->getType() == History::SCORE)
696 History_Score *event = static_cast<History_Score*>(*hit);
697 line.push_back (event->getScore());
700 line.push_back ((guint32)(*pit)->getScore());
701 if (*pit == d_player)
702 past_rankcounts.push_front(line);
704 past_rankcounts.push_back(line);
708 void HistoryReportDialog::generatePastCityCounts()
710 // go through the past city list
711 Playerlist::iterator pit = Playerlist::getInstance()->begin();
712 pit = Playerlist::getInstance()->begin();
713 for (; pit != Playerlist::getInstance()->end(); ++pit)
715 if (*pit == Playerlist::getInstance()->getNeutral())
717 //go through the past city lists, searching for cities owned by this
720 std::list<guint32> line;
721 for (unsigned int i = 0; i < past_citylists.size(); i++)
723 guint32 total_cities = 0;
724 LocationList<City*>::iterator it = past_citylists[i]->begin();
725 for (; it != past_citylists[i]->end(); it++)
727 if ((*it)->getOwner() == *pit)
730 line.push_back(total_cities);
733 line.push_back(Citylist::getInstance()->countCities(*pit));
734 if (*pit == d_player)
735 past_citycounts.push_front(line);
737 past_citycounts.push_back(line);
742 void HistoryReportDialog::generatePastGoldCounts()
744 //go through the history list looking for gold events, per player
745 Playerlist::iterator pit = Playerlist::getInstance()->begin();
746 pit = Playerlist::getInstance()->begin();
747 for (; pit != Playerlist::getInstance()->end(); ++pit)
749 if (*pit == Playerlist::getInstance()->getNeutral())
751 std::list<History*> *hist = (*pit)->getHistorylist();
752 std::list<History*>::iterator hit = hist->begin();
753 std::list<guint32> line;
754 for (; hit != hist->end(); hit++)
756 if ((*hit)->getType() == History::GOLD_TOTAL)
758 History_GoldTotal *event = static_cast<History_GoldTotal*>(*hit);
759 line.push_back (event->getGold());
762 line.push_back ((guint32)(*pit)->getGold());
763 if (*pit == d_player)
764 past_goldcounts.push_front(line);
766 past_goldcounts.push_back(line);
770 void HistoryReportDialog::generatePastRuinCounts()
772 //how many ruins did the players search at each turn?
774 Playerlist::iterator pit = Playerlist::getInstance()->begin();
775 pit = Playerlist::getInstance()->begin();
776 for (; pit != Playerlist::getInstance()->end(); ++pit)
778 if (*pit == Playerlist::getInstance()->getNeutral())
780 std::list<guint32> line;
781 for (unsigned int i = 0; i < past_citylists.size(); i++)
783 guint32 total_ruins = 0;
784 LocationList<Ruin*>::iterator it = past_ruinlists[i]->begin();
785 for (; it != past_ruinlists[i]->end(); it++)
788 if (ruin->isHidden() == true && ruin->getOwner() != *pit)
790 if (ruin->isSearched() == true &&
791 (*pit)->searchedRuin(ruin) == true)
793 ruin->setOwner(*pit);
797 line.push_back(total_ruins);
799 line.push_back(Ruinlist::getInstance()->countExploredRuins(*pit));
800 if (*pit == d_player)
801 past_ruincounts.push_front(line);
803 past_ruincounts.push_back(line);
807 void HistoryReportDialog::generatePastRuinlists()
809 //we don't do this per player
810 //we just count how many ruins are unexplored at every turn.
811 //how do we deal with hidden ruins?
812 //they should pop up when found.
813 bool last_turn = false;
815 //keep a set of pointers to remember how far we are into each player's history
816 std::list<History*> *hist[MAX_PLAYERS];
817 Playerlist::iterator pit = Playerlist::getInstance()->begin();
818 for (; pit != Playerlist::getInstance()->end(); ++pit)
820 if (*pit == Playerlist::getInstance()->getNeutral())
822 hist[(*pit)->getId()] = (*pit)->getHistorylist();
824 std::list<History*>::iterator hit[MAX_PLAYERS];
825 pit = Playerlist::getInstance()->begin();
826 for (; pit != Playerlist::getInstance()->end(); ++pit)
828 if (*pit == Playerlist::getInstance()->getNeutral())
830 hit[(*pit)->getId()] = hist[(*pit)->getId()]->begin();
833 //start off with an initial ruin list where all ruins are unexplored and hidden.
834 //all hidden ruins haven't been found yet, unless they started off that way.
835 LocationList<Ruin*> *rlist = new LocationList<Ruin*>();
836 Ruinlist *rl = Ruinlist::getInstance();
837 for (Ruinlist::iterator it = rl->begin(); it != rl->end(); ++it)
838 rlist->push_back(new Ruin(**it));
839 for (LocationList<Ruin*>::iterator it = rlist->begin(); it != rlist->end(); ++it)
841 //is the ruin searched to begin with?
842 bool no_ruin_history = true;
843 pit = Playerlist::getInstance()->begin();
844 for (; pit != Playerlist::getInstance()->end(); ++pit)
845 if ((*pit)->searchedRuin(*it) == true)
846 no_ruin_history = false;
847 if ((*it)->isSearched() == true && no_ruin_history)
848 (*it)->setSearched(true);
851 (*it)->setSearched(false);
852 if ((*it)->isHidden())
853 (*it)->setOwner(NULL);
857 unsigned int count = 0;
860 //now we see what ruins we took this turn
861 pit = Playerlist::getInstance()->begin();
862 for (; pit != Playerlist::getInstance()->end(); ++pit)
864 if (*pit == Playerlist::getInstance()->getNeutral())
866 //dump everything up to the next turn
867 guint32 id = (*pit)->getId();
868 if (hit[id] == hist[id]->end())
870 for (; hit[id] != hist[id]->end(); hit[id]++)
872 if ((*hit[id])->getType() == History::START_TURN)
877 //when a ruin becomes visible all of a sudden, we mark it as visible
878 else if ((*hit[id])->getType() == History::HERO_REWARD_RUIN)
882 dynamic_cast<History_HeroRewardRuin*>(*hit[id])->getRuinId();
883 //find ruin with this ruin id in rlist
884 LocationList<Ruin*>::iterator rit = rlist->begin();
885 for (; rit != rlist->end(); ++rit)
886 if ((*rit)->getId() == ruin_id)
888 (*rit)->setOwner(*pit);
892 else if ((*hit[id])->getType() == History::HERO_RUIN_EXPLORED)
896 dynamic_cast<History_HeroRuinExplored*>(*hit[id])->getRuinId();
897 //find ruin with this ruin id in rlist
898 LocationList<Ruin*>::iterator rit = rlist->begin();
899 for (; rit != rlist->end(); ++rit)
900 if ((*rit)->getId() == ruin_id)
902 (*rit)->setSearched(true);
907 if (hit[id] == hist[id]->end())
910 if (count == Playerlist::getInstance()->size() - 2)
914 //and add it to the list
915 past_ruinlists.push_back(rlist);
916 LocationList<Ruin*> *new_rlist = new LocationList<Ruin*>();
917 for (LocationList<Ruin*>::iterator it = rlist->begin();
918 it != rlist->end(); ++it)
919 new_rlist->push_back(new Ruin(**it));
921 if (last_turn == true)
925 past_ruinlists.erase(--past_ruinlists.end());