initial commit, lordsawar source, slightly modified
[lordsawar] / src / questmap.cpp
1 //  Copyright (C) 2007, 2008, 2009 Ben Asselstine
2 //
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.
7 //
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.
12 //
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 
16 //  02110-1301, USA.
17
18 #include "questmap.h"
19
20 #include "gui/image-helpers.h"
21 #include "Quest.h"
22 #include "QuestsManager.h"
23 #include "playerlist.h"
24 #include "GraphicsCache.h"
25 #include "stacklist.h"
26 #include "playerlist.h"
27 #include "player.h"
28 #include "maptile.h"
29 #include "citylist.h"
30 #include "GameMap.h"
31
32 QuestMap::QuestMap(Quest *q)
33 {
34     quest = q;
35     d_target.x = -1;
36     d_target.y = -1;
37 }
38
39
40 void QuestMap::draw_stacks(Player *p, std::list< Vector<int> > targets)
41 {
42   Gdk::Color cross_color = p->getColor();
43   int size = int(pixels_per_tile) > 1 ? int(pixels_per_tile) : 1;
44         
45   for (std::list< Vector<int> >::iterator it= targets.begin(); it != targets.end(); it++)
46   {
47       Vector<int> pos = (*it);
48
49       // don't draw stacks in cities, they could hardly be identified
50       Maptile* mytile = GameMap::getInstance()->getTile(pos);
51       if (mytile->getBuilding() == Maptile::CITY)
52           continue;
53
54       pos = mapToSurface(pos);
55       draw_line(pos.x - size, pos.y, pos.x + size, pos.y, cross_color);
56       draw_line(pos.x, pos.y - size, pos.x, pos.y + size, cross_color);
57   }
58 }
59 void QuestMap::draw_target(Vector<int> start, Vector<int> target)
60 {
61   Vector<int> end;
62   end = target;
63
64   start = mapToSurface(start);
65   end = mapToSurface(end);
66
67
68   start += Vector<int>(int(pixels_per_tile/2), int(pixels_per_tile/2));
69   end += Vector<int>(int(pixels_per_tile/2), int(pixels_per_tile/2));
70   Gdk::Color box_color = Gdk::Color();
71   box_color.set_rgb_p(252.0/255.0, 160.0/255.0, 0);
72   int xsize = 8;
73   int ysize = 8;
74   //draw an 8 by 8 box, with a smaller box inside of it
75   draw_rect(end.x - (xsize / 2), end.y - (ysize / 2), 
76             xsize, ysize, box_color);
77   xsize = 4;
78   ysize = 4;
79   draw_filled_rect(end.x - (xsize / 2), end.y - (ysize / 2), 
80                    xsize, ysize, box_color);
81
82   xsize = 8;
83   ysize = 8;
84   //which corner do we connect the line to?
85   if (start.x >= end.x)
86     {
87       //westerly
88       if (start.y >= end.y)
89         //northerly
90         //line is heading northwesterly.  
91         //connect to the southeastern corner of the box.
92         end += Vector<int>((xsize / 2) - 1, (ysize / 2) - 1);
93       else
94         //southerly
95         //line is heading southwesterly.  
96         //connect to the northeastern corner of the box.
97         end += Vector<int>((xsize / 2) - 1, -(ysize / 2));
98     }
99   else
100     {
101       //easterly
102       if (start.y >= end.y)
103         //northerly
104         //line is heading northeasterly.
105         //connect to the southwestern corner of the box.
106         end += Vector<int>(-(xsize / 2), (ysize / 2) - 1);
107       else
108         //southerly
109         //line is heading southeasterly.
110         //connect to the northwestern corner of the box.
111         end += Vector<int>(-(xsize / 2), -(ysize / 2));
112     }
113   draw_line(start.x, start.y, end.x, end.y, box_color);
114 }
115
116 void QuestMap::after_draw()
117 {
118   GraphicsCache *gc = GraphicsCache::getInstance();
119   if (!quest)
120     {
121       draw_cities(true);
122       map_changed.emit(surface);
123       return;
124     }
125   Hero *hero = quest->getHero();
126   Player *p = hero->getOwner();
127
128
129
130   Vector<int> start = p->getStacklist()->getPosition (quest->getHeroId ());
131
132   if (quest->isPendingDeletion() == false)
133     {
134       std::list< Vector<int> > targets = quest->getTargets();
135       switch (quest->getType ())
136         {
137           case Quest::PILLAGEGOLD:
138             draw_cities(true);
139             break;
140           case Quest::KILLARMIES:
141           case Quest::KILLARMYTYPE:
142             draw_cities(false);
143             //for each target draw a plus sign
144             draw_stacks(quest->getHero()->getOwner(), targets);
145             break;
146           case Quest::KILLHERO:
147           case Quest::CITYSACK:
148           case Quest::CITYOCCUPY:
149           case Quest::CITYRAZE:
150             draw_cities(false);
151             //the target list should only have one position in it
152             //draw an orange line to the target and put a box around it.
153             std::list< Vector<int> >::iterator it = targets.begin();
154             if (targets.size() > 0)
155               draw_target(start, *it);
156             break;
157         }
158     }
159
160   draw_target();
161
162   // draw the hero picture
163
164   start = mapToSurface (start);
165
166   start += Vector<int>(int (pixels_per_tile / 2), int (pixels_per_tile / 2));
167
168   PixMask *heropic = gc->getSmallHeroPic (true);
169   heropic->blit_centered(surface, start);
170   map_changed.emit(surface);
171 }
172
173 void QuestMap::draw_target()
174 {
175   if (d_target.x == -1 && d_target.y == -1)
176     return;
177   Player *p = quest->getHero()->getOwner();
178   Stacklist *sl = p->getStacklist();
179   Vector<int> start = sl->getPosition (quest->getHeroId ());
180   draw_target(start, d_target);
181   map_changed.emit(surface);
182 }