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: SocialNavigationTab(const Widget2 * const widget,const Opaque showBackground)52 SocialNavigationTab(const Widget2 *const widget, 53 const Opaque showBackground) : 54 SocialTab(widget), 55 mBeings(new BeingsListModel) 56 { 57 createControls(mBeings, showBackground); 58 59 // TRANSLATORS: Navigation tab name in social window. 60 // TRANSLATORS: Should be small 61 setCaption(_("Nav")); 62 mMenuAction = "navigation"; 63 } 64 65 A_DELETE_COPY(SocialNavigationTab) 66 ~SocialNavigationTab()67 ~SocialNavigationTab() override final 68 { 69 delete2(mList) 70 delete2(mScroll) 71 delete2(mBeings) 72 } 73 updateList()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 selectIndex(const unsigned num)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 updateNames()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 getPortalIndex(const int x,const int y)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 addPortal(const int x,const int y)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 removePortal(const int x,const int y)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 310