initial commit, lordsawar source, slightly modified
[lordsawar] / src / templelist.cpp
1 // Copyright (C) 2000, 2001, 2003 Michael Bartl
2 // Copyright (C) 2001, 2003, 2004, 2005 Ulf Lorenz
3 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
4 // Copyright (C) 2007 Ole Laursen
5 //
6 //  This program is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 3 of the License, or
9 //  (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU Library General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
19 //  02110-1301, USA.
20
21 #include <sigc++/functors/mem_fun.h>
22
23 #include "xmlhelper.h"
24 #include "templelist.h"
25 #include "playerlist.h"
26 #include "stack.h"
27 #include "GameMap.h"
28
29 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
30 #define debug(x)
31
32 std::string Templelist::d_tag = "templelist";
33 Templelist* Templelist::s_instance=0;
34
35 Templelist* Templelist::getInstance()
36 {
37     if (s_instance == 0)
38         s_instance = new Templelist();
39
40     return s_instance;
41 }
42
43 Templelist* Templelist::getInstance(XML_Helper* helper)
44 {
45     if (s_instance)
46         deleteInstance();
47
48     s_instance = new Templelist(helper);
49     return s_instance;
50 }
51
52 void Templelist::deleteInstance()
53 {
54     if (s_instance)
55         delete s_instance;
56
57     s_instance = 0;
58 }
59
60 Templelist::Templelist()
61 {
62 }
63
64 Templelist::Templelist(XML_Helper* helper)
65 {
66   helper->registerTag(Temple::d_tag, sigc::mem_fun(this, &Templelist::load));
67 }
68
69 bool Templelist::save(XML_Helper* helper) const
70 {
71     bool retval = true;
72
73     retval &= helper->openTag(Templelist::d_tag);
74
75     for (const_iterator it = begin(); it != end(); it++)
76         retval &= (*it)->save(helper);
77     
78     retval &= helper->closeTag();
79
80     return retval;
81 }
82
83 bool Templelist::load(std::string tag, XML_Helper* helper)
84 {
85     if (tag != Temple::d_tag)    
86     //what has happened?
87         return false;
88     
89     guint32 width = GameMap::getInstance()->getCityset()->getTempleTileWidth();
90     add(new Temple(helper, width));
91
92     return true;
93 }
94
95 static bool isFogged(void *t)
96 {
97   return ((Temple*)t)->isVisible(Playerlist::getViewingplayer()) == false;
98 }
99
100 Temple * Templelist::getNearestVisibleTemple(const Vector<int>& pos) const
101 {
102   std::list<bool (*)(void *)> filters;
103   filters.push_back(isFogged);
104   return getNearestObject(pos, &filters);
105 }
106
107 Temple* Templelist::getNearestVisibleAndUsefulTemple(Stack *s, 
108                                                      double percent_can_be_blessed) const
109 {
110   Vector<int> pos = s->getPos();
111   int diff = -1;
112   const_iterator diffit;
113
114   for (const_iterator it = begin(); it != end(); ++it)
115     {
116       Temple *temple = *it;
117       if (isFogged(temple))
118         continue;
119
120       if ((double)(s->size() - s->countArmiesBlessedAtTemple(temple->getId()))
121           < (double)s->size() * (percent_can_be_blessed / 100.0))
122         continue;
123
124       Vector<int> p = (*it)->getPos();
125       int delta = abs(p.x - pos.x);
126       if (delta < abs(p.y - pos.y))
127         delta = abs(p.y - pos.y);
128
129       if ((diff > delta) || (diff == -1))
130         {
131           diff = delta;
132           diffit = it;
133         }
134     }
135
136   if (diff == -1) return 0;
137   return (*diffit);
138
139 }
140
141 Temple* Templelist::getNearestVisibleAndUsefulTemple(Stack *stack, 
142                                                      double percent_can_be_blessed, 
143                                                      int dist) const
144 {
145   Vector<int> pos = stack->getPos();
146   Temple *t = getNearestVisibleAndUsefulTemple
147     (stack, percent_can_be_blessed);
148   if (!t)
149     return NULL;
150   if (t->getPos().x <= pos.x + dist && t->getPos().x >= pos.x - dist &&
151       t->getPos().y <= pos.y + dist && t->getPos().y >= pos.y - dist)
152     return t;
153   return NULL;
154 }
155
156 Temple* Templelist::getNearestVisibleTemple(const Vector<int>& pos, int dist) const
157 {
158   Temple *t = getNearestVisibleTemple(pos);
159   if (!t)
160     return NULL;
161   if (t->getPos().x <= pos.x + dist && t->getPos().x >= pos.x - dist &&
162       t->getPos().y <= pos.y + dist && t->getPos().y >= pos.y - dist)
163     return t;
164   return NULL;
165 }
166