1 |
|
|
/* |
2 |
|
|
* The ManaPlus Client |
3 |
|
|
* Copyright (C) 2011-2019 The ManaPlus Developers |
4 |
|
|
* Copyright (C) 2019-2021 Andrei Karas |
5 |
|
|
* |
6 |
|
|
* This file is part of The ManaPlus Client. |
7 |
|
|
* |
8 |
|
|
* This program is free software; you can redistribute it and/or modify |
9 |
|
|
* it under the terms of the GNU General Public License as published by |
10 |
|
|
* the Free Software Foundation; either version 2 of the License, or |
11 |
|
|
* any later version. |
12 |
|
|
* |
13 |
|
|
* This program is distributed in the hope that it will be useful, |
14 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
|
|
* GNU General Public License for more details. |
17 |
|
|
* |
18 |
|
|
* You should have received a copy of the GNU General Public License |
19 |
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 |
|
|
*/ |
21 |
|
|
|
22 |
|
|
#ifndef GUI_WIDGETS_TABS_SOCIALNAVIGATIONTAB_H |
23 |
|
|
#define GUI_WIDGETS_TABS_SOCIALNAVIGATIONTAB_H |
24 |
|
|
|
25 |
|
|
#include "gui/widgets/tabs/socialtab.h" |
26 |
|
|
|
27 |
|
|
#include "actormanager.h" |
28 |
|
|
#include "configuration.h" |
29 |
|
|
|
30 |
|
|
#include "gui/models/beingslistmodel.h" |
31 |
|
|
|
32 |
|
|
#include "gui/windows/outfitwindow.h" |
33 |
|
|
|
34 |
|
|
#include "being/localplayer.h" |
35 |
|
|
|
36 |
|
|
#include "input/keyboardconfig.h" |
37 |
|
|
|
38 |
|
|
#include "utils/delete2.h" |
39 |
|
|
#include "utils/gettext.h" |
40 |
|
|
|
41 |
|
|
#include "resources/map/map.h" |
42 |
|
|
#include "resources/map/mapitem.h" |
43 |
|
|
#include "resources/map/speciallayer.h" |
44 |
|
|
|
45 |
|
|
#include "localconsts.h" |
46 |
|
|
|
47 |
|
|
class Avatar; |
48 |
|
|
|
49 |
|
|
class SocialNavigationTab final : public SocialTab |
50 |
|
|
{ |
51 |
|
|
public: |
52 |
|
1 |
SocialNavigationTab(const Widget2 *const widget, |
53 |
|
1 |
const Opaque showBackground) : |
54 |
|
|
SocialTab(widget), |
55 |
✓✗ |
2 |
mBeings(new BeingsListModel) |
56 |
|
|
{ |
57 |
✓✗ |
1 |
createControls(mBeings, showBackground); |
58 |
|
|
|
59 |
|
|
// TRANSLATORS: Navigation tab name in social window. |
60 |
|
|
// TRANSLATORS: Should be small |
61 |
✓✗✓✗
|
4 |
setCaption(_("Nav")); |
62 |
|
2 |
mMenuAction = "navigation"; |
63 |
|
1 |
} |
64 |
|
|
|
65 |
|
|
A_DELETE_COPY(SocialNavigationTab) |
66 |
|
|
|
67 |
|
2 |
~SocialNavigationTab() override final |
68 |
|
2 |
{ |
69 |
✓✗ |
1 |
delete2(mList) |
70 |
✓✗ |
1 |
delete2(mScroll) |
71 |
✓✗ |
2 |
delete2(mBeings) |
72 |
|
2 |
} |
73 |
|
|
|
74 |
|
|
void updateList() override final |
75 |
|
|
{ |
76 |
|
|
if ((socialWindow == nullptr) || (localPlayer == nullptr)) |
77 |
|
|
return; |
78 |
|
|
|
79 |
|
|
const Map *const map = socialWindow->getMap(); |
80 |
|
|
if ((map == nullptr) || map->empty()) |
81 |
|
|
return; |
82 |
|
|
|
83 |
|
|
if (socialWindow->getProcessedPortals()) |
84 |
|
|
return; |
85 |
|
|
|
86 |
|
|
STD_VECTOR<Avatar*> *const avatars = mBeings->getMembers(); |
87 |
|
|
STD_VECTOR<MapItem*> portals = map->getPortals(); |
88 |
|
|
|
89 |
|
|
STD_VECTOR<MapItem*>::const_iterator i = portals.begin(); |
90 |
|
|
const SpecialLayer *const specialLayer = map->getSpecialLayer(); |
91 |
|
|
|
92 |
|
|
STD_VECTOR<Avatar*>::iterator ia = avatars->begin(); |
93 |
|
|
|
94 |
|
|
while (ia != avatars->end()) |
95 |
|
|
{ |
96 |
|
|
delete *ia; |
97 |
|
|
++ ia; |
98 |
|
|
} |
99 |
|
|
|
100 |
|
|
avatars->clear(); |
101 |
|
|
|
102 |
|
|
int online = 0; |
103 |
|
|
int total = 0; |
104 |
|
|
|
105 |
|
|
int idx = 0; |
106 |
|
|
while (i != portals.end()) |
107 |
|
|
{ |
108 |
|
|
MapItem *portal = *i; |
109 |
|
|
if (portal == nullptr) |
110 |
|
|
continue; |
111 |
|
|
|
112 |
|
|
const int x = portal->getX(); |
113 |
|
|
const int y = portal->getY(); |
114 |
|
|
|
115 |
|
|
const std::string name = strprintf("%s [%d %d]", |
116 |
|
|
portal->getComment().c_str(), x, y); |
117 |
|
|
|
118 |
|
|
Avatar *const ava = new Avatar(name); |
119 |
|
|
if (localPlayer != nullptr) |
120 |
|
|
ava->setOnline(localPlayer->isReachable(x, y, true)); |
121 |
|
|
else |
122 |
|
|
ava->setOnline(false); |
123 |
|
|
ava->setLevel(-1); |
124 |
|
|
ava->setType(portal->getType()); |
125 |
|
|
ava->setX(x); |
126 |
|
|
ava->setY(y); |
127 |
|
|
avatars->push_back(ava); |
128 |
|
|
|
129 |
|
|
if (ava->getOnline()) |
130 |
|
|
online ++; |
131 |
|
|
total ++; |
132 |
|
|
|
133 |
|
|
if (config.getBoolValue("drawHotKeys") |
134 |
|
|
&& idx < 80 && (outfitWindow != nullptr)) |
135 |
|
|
{ |
136 |
|
|
Being *const being = actorManager |
137 |
|
|
->findPortalByTile(x, y); |
138 |
|
|
if (being != nullptr) |
139 |
|
|
{ |
140 |
|
|
being->setName(KeyboardConfig::getKeyShortString( |
141 |
|
|
OutfitWindow::keyName(idx))); |
142 |
|
|
} |
143 |
|
|
|
144 |
|
|
if (specialLayer != nullptr) |
145 |
|
|
{ |
146 |
|
|
portal = specialLayer->getTile( |
147 |
|
|
ava->getX(), ava->getY()); |
148 |
|
|
if (portal != nullptr) |
149 |
|
|
{ |
150 |
|
|
portal->setName(KeyboardConfig::getKeyShortString( |
151 |
|
|
OutfitWindow::keyName(idx))); |
152 |
|
|
} |
153 |
|
|
} |
154 |
|
|
} |
155 |
|
|
|
156 |
|
|
++i; |
157 |
|
|
idx ++; |
158 |
|
|
} |
159 |
|
|
if (socialWindow != nullptr) |
160 |
|
|
socialWindow->setProcessedPortals(true); |
161 |
|
|
|
162 |
|
|
// TRANSLATORS: social window label |
163 |
|
|
mCounterString = strprintf(_("Portals: %u/%u"), |
164 |
|
|
CAST_U32(online), |
165 |
|
|
CAST_U32(total)); |
166 |
|
|
updateCounter(); |
167 |
|
|
} |
168 |
|
|
|
169 |
|
|
void selectIndex(const unsigned num) override final |
170 |
|
|
{ |
171 |
|
|
if (localPlayer == nullptr) |
172 |
|
|
return; |
173 |
|
|
|
174 |
|
|
STD_VECTOR<Avatar*> *const avatars = mBeings->getMembers(); |
175 |
|
|
if (avatars->size() <= CAST_SIZE(num)) |
176 |
|
|
return; |
177 |
|
|
|
178 |
|
|
const Avatar *const ava = avatars->at(num); |
179 |
|
|
if (ava != nullptr) |
180 |
|
|
localPlayer->navigateTo(ava->getX(), ava->getY()); |
181 |
|
|
} |
182 |
|
|
|
183 |
|
|
void updateNames() |
184 |
|
|
{ |
185 |
|
|
if (socialWindow == nullptr) |
186 |
|
|
return; |
187 |
|
|
|
188 |
|
|
STD_VECTOR<Avatar*> *const avatars = mBeings->getMembers(); |
189 |
|
|
|
190 |
|
|
const Map *const map = socialWindow->getMap(); |
191 |
|
|
if (map == nullptr) |
192 |
|
|
return; |
193 |
|
|
|
194 |
|
|
STD_VECTOR<Avatar*>::const_iterator i = avatars->begin(); |
195 |
|
|
const STD_VECTOR<Avatar*>::const_iterator i_end = avatars->end(); |
196 |
|
|
while (i != i_end) |
197 |
|
|
{ |
198 |
|
|
Avatar *const ava = *i; |
199 |
|
|
if (ava == nullptr) |
200 |
|
|
break; |
201 |
|
|
|
202 |
|
|
const MapItem *const item = map->findPortalXY( |
203 |
|
|
ava->getX(), ava->getY()); |
204 |
|
|
if (item != nullptr) |
205 |
|
|
{ |
206 |
|
|
const std::string name = strprintf("%s [%d %d]", |
207 |
|
|
item->getComment().c_str(), |
208 |
|
|
item->getX(), item->getY()); |
209 |
|
|
ava->setName(name); |
210 |
|
|
ava->setOriginalName(name); |
211 |
|
|
} |
212 |
|
|
|
213 |
|
|
++i; |
214 |
|
|
} |
215 |
|
|
} |
216 |
|
|
|
217 |
|
|
int getPortalIndex(const int x, const int y) |
218 |
|
|
{ |
219 |
|
|
if (socialWindow == nullptr) |
220 |
|
|
return -1; |
221 |
|
|
|
222 |
|
|
STD_VECTOR<Avatar*> *const avatars = mBeings->getMembers(); |
223 |
|
|
const Map *const map = socialWindow->getMap(); |
224 |
|
|
if (map == nullptr) |
225 |
|
|
return -1; |
226 |
|
|
|
227 |
|
|
STD_VECTOR<Avatar*>::const_iterator i = avatars->begin(); |
228 |
|
|
const STD_VECTOR<Avatar*>::const_iterator i_end = avatars->end(); |
229 |
|
|
unsigned num = 0; |
230 |
|
|
while (i != i_end) |
231 |
|
|
{ |
232 |
|
|
const Avatar *const ava = *i; |
233 |
|
|
if (ava == nullptr) |
234 |
|
|
break; |
235 |
|
|
|
236 |
|
|
if (ava->getX() == x && ava->getY() == y) |
237 |
|
|
return num; |
238 |
|
|
|
239 |
|
|
++i; |
240 |
|
|
num ++; |
241 |
|
|
} |
242 |
|
|
return -1; |
243 |
|
|
} |
244 |
|
|
|
245 |
|
|
void addPortal(const int x, const int y) |
246 |
|
|
{ |
247 |
|
|
if ((socialWindow == nullptr) || (localPlayer == nullptr)) |
248 |
|
|
return; |
249 |
|
|
|
250 |
|
|
const Map *const map = socialWindow->getMap(); |
251 |
|
|
if (map == nullptr) |
252 |
|
|
return; |
253 |
|
|
|
254 |
|
|
STD_VECTOR<Avatar*> *const avatars = mBeings->getMembers(); |
255 |
|
|
const MapItem *const portal = map->findPortalXY(x, y); |
256 |
|
|
if (portal == nullptr) |
257 |
|
|
return; |
258 |
|
|
|
259 |
|
|
const std::string name = strprintf("%s [%d %d]", |
260 |
|
|
portal->getComment().c_str(), x, y); |
261 |
|
|
|
262 |
|
|
Avatar *const ava = new Avatar(name); |
263 |
|
|
if (localPlayer != nullptr) |
264 |
|
|
ava->setOnline(localPlayer->isReachable(x, y, true)); |
265 |
|
|
else |
266 |
|
|
ava->setOnline(false); |
267 |
|
|
ava->setLevel(-1); |
268 |
|
|
ava->setType(portal->getType()); |
269 |
|
|
ava->setX(x); |
270 |
|
|
ava->setY(y); |
271 |
|
|
avatars->push_back(ava); |
272 |
|
|
} |
273 |
|
|
|
274 |
|
|
void removePortal(const int x, const int y) |
275 |
|
|
{ |
276 |
|
|
if ((socialWindow == nullptr) || (localPlayer == nullptr)) |
277 |
|
|
return; |
278 |
|
|
|
279 |
|
|
const Map *const map = socialWindow->getMap(); |
280 |
|
|
if (map == nullptr) |
281 |
|
|
return; |
282 |
|
|
|
283 |
|
|
STD_VECTOR<Avatar*> *const avatars = mBeings->getMembers(); |
284 |
|
|
STD_VECTOR<Avatar*>::iterator i = avatars->begin(); |
285 |
|
|
const STD_VECTOR<Avatar*>::iterator i_end = avatars->end(); |
286 |
|
|
|
287 |
|
|
while (i != i_end) |
288 |
|
|
{ |
289 |
|
|
Avatar *ava = (*i); |
290 |
|
|
|
291 |
|
|
if (ava == nullptr) |
292 |
|
|
break; |
293 |
|
|
|
294 |
|
|
if (ava->getX() == x && ava->getY() == y) |
295 |
|
|
{ |
296 |
|
|
delete ava; |
297 |
|
|
avatars->erase(i); |
298 |
|
|
return; |
299 |
|
|
} |
300 |
|
|
|
301 |
|
|
++ i; |
302 |
|
|
} |
303 |
|
|
} |
304 |
|
|
|
305 |
|
|
private: |
306 |
|
|
BeingsListModel *mBeings; |
307 |
|
|
}; |
308 |
|
|
|
309 |
|
|
#endif // GUI_WIDGETS_TABS_SOCIALNAVIGATIONTAB_H |