initial commit, lordsawar source, slightly modified
[lordsawar] / src / Threat.cpp
1 // Copyright (C) 2004 John Farrell
2 // Copyright (C) 2004, 2005 Ulf Lorenz
3 // Copyright (C) 2005 Andrea Paternesi
4 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
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 "Threat.h"
22 #include "stackreflist.h"
23 #include <iostream>
24 #include "city.h"
25 #include "ruin.h"
26 #include "stack.h"
27 #include "playerlist.h"
28 #include "AI_Analysis.h"
29
30 using namespace std;
31
32 Threat::Threat(City *c)
33     :Ownable(*c), d_city(c), d_ruin(0), d_danger(0), d_value(0), d_strength(0)
34 {
35     d_stacks = new StackReflist();
36     calculateStrength();
37 }
38
39 Threat::Threat(Stack *s)
40     :Ownable(*s), d_city(0), d_ruin(0), d_danger(0), d_value(0), d_strength(0)
41 {
42     d_stacks = new StackReflist();
43     d_stacks->addStack(new Stack(*s));
44     d_strength += AI_Analysis::assessStackStrength(s);
45 }
46
47 Threat::Threat(Ruin *r)
48     :Ownable((Player *)0), d_city(0), d_ruin(r), d_danger(0), d_value(0), d_strength(0)
49 {
50     d_stacks = new StackReflist();
51 }
52
53 Threat::~Threat()
54 {
55   for (StackReflist::iterator i = d_stacks->begin(); i != d_stacks->end(); i++)
56     delete *i;
57   d_stacks->clear();
58   delete d_stacks;
59 }
60
61 std::string Threat::toString() const
62 {
63     if (d_city)
64     {
65         return d_city->getName() + " owned by " + d_owner->getName();
66     }
67     else if (d_ruin)
68     {
69         return d_ruin->getName();
70     }
71     else
72     {
73         return "stack owned by " + d_owner->getName();
74     }
75 }
76
77 bool Threat::Near(Vector<int> pos, Player *p) const
78 {
79     if (p != d_owner)
80         return false;
81
82     if (d_city)
83     {
84         return d_city->contains(pos);
85     }
86     else if (d_ruin)
87     {
88         return d_ruin->contains(pos);
89     }
90     else
91         for (StackReflist::const_iterator it = d_stacks->begin();
92             it != d_stacks->end(); ++it)
93         {
94             Vector<int> spos = (*it)->getPos();
95             if (abs(pos.x - spos.x) <= 1 && abs(pos.y - spos.y <= 1))
96                 return true;
97         }
98
99     return false;
100 }
101
102 void Threat::addStack(Stack *stack)
103 {
104     d_stacks->addStack(new Stack (*stack));
105     if (d_city && d_city->getOwner() != Playerlist::getInstance()->getNeutral())
106       d_strength += AI_Analysis::assessStackStrength(stack);
107 }
108
109 // this is the strength of the threat to us
110 void Threat::calculateStrength()
111 {
112   // neutral cities poses a small threat
113   if (d_city)
114     if (d_city->getOwner() == Playerlist::getInstance()->getNeutral())
115       {
116         d_strength = 0.3;
117         return;
118       }
119   float score = 0.0;
120   for (StackReflist::const_iterator i = d_stacks->begin(); 
121        i != d_stacks->end(); ++i)
122     score += AI_Analysis::assessStackStrength(*i);
123
124   d_strength = score;
125 }
126
127 void Threat::calculateValue()
128 {
129   float score = 0.0;
130   score += d_danger;
131   d_value = score;
132 }
133
134 Vector<int> Threat::getClosestPoint(Vector<int> location) const
135 {
136   Vector<int> result(-1,-1);
137   if (d_city)
138     result = d_city->getNearestPos(location);
139   else if (d_ruin)
140     result = d_ruin->getPos();
141   else
142     {
143       int min_dist = -1;
144       for (StackReflist::const_iterator it = d_stacks->begin();
145            it != d_stacks->end(); ++it)
146         {
147           Vector<int> spos = (*it)->getPos();
148
149           int distance = dist(spos, location);
150           if (distance < min_dist || min_dist == -1)
151             {
152               result = spos;
153               min_dist = distance;
154             }
155         }
156     }
157
158   return result;
159 }
160
161 void Threat::deleteStack(guint32 id)
162 {
163     d_stacks->removeStack(id);
164     if (d_city && d_city->getOwner() != Playerlist::getInstance()->getNeutral())
165       calculateStrength();
166 }
167 void Threat::deleteStack(Stack* s)
168 {
169   d_stacks->removeStack(s->getId());
170   if (d_city && d_city->getOwner() != Playerlist::getInstance()->getNeutral())
171     calculateStrength();
172 }
173           
174 void Threat::addDanger(float danger)
175
176   d_danger += danger; 
177   calculateValue();
178 }