From 8037d33c9f429d4c0322da383cdda46776c3c14e Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 21 Apr 2011 05:25:01 +0300 Subject: Impliment attack filter. Add tab in social tab. --- src/gui/popupmenu.cpp | 182 ++++++++++++++++++++++++++++++++++++++ src/gui/popupmenu.h | 3 + src/gui/setup_other.cpp | 14 +++ src/gui/setup_other.h | 3 + src/gui/socialwindow.cpp | 160 ++++++++++++++++++++++++++++++++- src/gui/socialwindow.h | 4 + src/gui/viewport.cpp | 6 ++ src/gui/viewport.h | 2 + src/gui/widgets/avatarlistbox.cpp | 25 +++++- 9 files changed, 392 insertions(+), 7 deletions(-) (limited to 'src/gui') diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index 6c43fdfa1..06ee9a9b8 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -246,7 +246,32 @@ void PopupMenu::showPopup(int x, int y, Being *being) mBrowserBox->addRow(_("@@attack|Attack@@")); if (player_node->isGM()) + { + mBrowserBox->addRow("##3---"); mBrowserBox->addRow(_("@@admin-kick|Kick@@")); + } + + if (config.getBoolValue("enableAttackFilter")) + { + mBrowserBox->addRow("##3---"); + if (player_node->isInAttackList(name)) + { + mBrowserBox->addRow( + _("@@remove attack|Remove from attack list@@")); + } + else if (player_node->isInIgnoreAttackList(name)) + { + mBrowserBox->addRow( + _("@@remove attack|Remove from ignore list@@")); + } + else + { + mBrowserBox->addRow( + _("@@add attack|Add to attack list@@")); + mBrowserBox->addRow( + _("@@add attack ignore|Add to ignore list@@")); + } + } } break; @@ -1122,6 +1147,120 @@ void PopupMenu::handleLink(const std::string &link, { mTab->setNoAway(false); } + else if (link == "remove attack" && being) + { + if (player_node && being->getType() == Being::MONSTER) + { + player_node->removeAttackMob(being->getName()); + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + else if (link == "add attack" && being) + { + if (player_node && being->getType() == Being::MONSTER) + { + player_node->addAttackMob(being->getName()); + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + else if (link == "add attack ignore" && being) + { + if (player_node && being->getType() == Being::MONSTER) + { + player_node->addIgnoreAttackMob(being->getName()); + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + else if (link == "attack moveup") + { + if (player_node) + { + int idx = player_node->getAttackMobIndex(mNick); + if (idx > 0) + { + std::list mobs = player_node->getAttackMobs(); + std::list::iterator it = mobs.begin(); + std::list::iterator it2 = mobs.begin(); + while (it != mobs.end()) + { + if (*it == mNick) + { + -- it2; + mobs.splice(it2, mobs, it); + player_node->setAttackMobs(mobs); + player_node->rebuildAttackMobs(); + break; + } + ++ it; + ++ it2; + } + + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + } + else if (link == "attack movedown") + { + if (player_node) + { + int idx = player_node->getAttackMobIndex(mNick); + int size = player_node->getAttackMobsSize(); + if (idx + 1 < size) + { + std::list mobs = player_node->getAttackMobs(); + std::list::iterator it = mobs.begin(); + std::list::iterator it2 = mobs.begin(); + while (it != mobs.end()) + { + if (*it == mNick) + { + ++ it2; + if (it2 == mobs.end()) + break; + + mobs.splice(it, mobs, it2); + player_node->setAttackMobs(mobs); + player_node->rebuildAttackMobs(); + break; + } + ++ it; + ++ it2; + } + + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + } + else if (link == "attack remove") + { + if (player_node) + { + if (mNick.empty()) + { + if (player_node->isInAttackList(mNick)) + { + player_node->removeAttackMob(mNick); + player_node->addIgnoreAttackMob(mNick); + } + else + { + player_node->removeAttackMob(mNick); + player_node->addAttackMob(mNick); + } + } + else + { + player_node->removeAttackMob(mNick); + } + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } else if (link == "guild-pos" && !mNick.empty()) { showChangePos(getX(), getY()); @@ -1459,6 +1598,49 @@ void PopupMenu::showPopup(int x, int y, ProgressBar *b) showPopup(x, y); } +void PopupMenu::showAttackMonsterPopup(int x, int y, std::string name, + bool isAttack) +{ + if (!player_node) + return; + + mNick = name; + + mBrowserBox->clearRows(); + + if (name.empty()) + mBrowserBox->addRow(_("(default)")); + else + mBrowserBox->addRow(name); + if (isAttack) + { + int idx = player_node->getAttackMobIndex(name); + int size = player_node->getAttackMobsSize(); + if (idx > 0) + { + mBrowserBox->addRow(strprintf( + "@@attack moveup|%s@@", _("Move up"))); + } + if (idx + 1 < size) + { + mBrowserBox->addRow(strprintf( + "@@attack movedown|%s@@", _("Move down"))); + } + mBrowserBox->addRow(strprintf( + "@@attack remove|%s@@", _("Remove"))); + } + else + { + mBrowserBox->addRow(strprintf( + "@@attack remove|%s@@", _("Remove"))); + } + + mBrowserBox->addRow("##3---"); + mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel"))); + + showPopup(x, y); +} + void PopupMenu::showPopup(int x, int y) { setContentSize(mBrowserBox->getWidth() + 8, mBrowserBox->getHeight() + 8); diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h index 6dca1ff64..61720d417 100644 --- a/src/gui/popupmenu.h +++ b/src/gui/popupmenu.h @@ -117,6 +117,9 @@ class PopupMenu : public Popup, public LinkHandler void showSpellPopup(int x, int y, TextCommand *cmd); + void showAttackMonsterPopup(int x, int y, std::string name, + bool isAttack); + /** * Shows the related popup menu when right click on the chat * at the specified mouse coordinates. diff --git a/src/gui/setup_other.cpp b/src/gui/setup_other.cpp index 7a43b5480..bc1a07ed3 100644 --- a/src/gui/setup_other.cpp +++ b/src/gui/setup_other.cpp @@ -66,6 +66,7 @@ #define ACTION_SHOW_JOB_EXP "show job exp" #define ACTION_SHOW_BEING_POPUP "show being popup" #define ACTION_SHOW_EXTENDED_MINIMAPS "show extended minimaps" +#define ACTION_ENABLE_ATTACK_FILTER "attack filter" Setup_Other::Setup_Other(): mShowMonstersTakedDamage(config.getBoolValue("showMonstersTakedDamage")), @@ -94,6 +95,7 @@ Setup_Other::Setup_Other(): mShowJobExp(config.getBoolValue("showJobExp")), mShowBeingPopup(config.getBoolValue("showBeingPopup")), mShowExtMinimaps(config.getBoolValue("showExtMinimaps")), + mEnableAttackFilter(config.getBoolValue("enableAttackFilter")), mEditDialog(0) { setName(_("Misc")); @@ -187,6 +189,9 @@ Setup_Other::Setup_Other(): mShowExtMinimapsCheckBox = new CheckBox(_("Show extended minimaps"), mShowExtMinimaps, this, ACTION_SHOW_EXTENDED_MINIMAPS); + mEnableAttackFilterCheckBox = new CheckBox(_("Enable attack filter"), + mEnableAttackFilter, this, ACTION_ENABLE_ATTACK_FILTER); + // Do the layout LayoutHelper h(this); ContainerPlacer place = h.getPlacer(0, 0); @@ -205,6 +210,7 @@ Setup_Other::Setup_Other(): place(12, 8, mShowJobExpCheckBox, 10); place(12, 9, mShowBeingPopupCheckBox, 10); place(12, 10, mShowExtMinimapsCheckBox, 10); + place(12, 11, mEnableAttackFilterCheckBox, 10); place(0, 3, mFloorItemsHighlightCheckBox, 12); place(0, 4, mHighlightAttackRangeCheckBox, 12); place(0, 5, mHighlightMonsterAttackRangeCheckBox, 12); @@ -349,6 +355,10 @@ void Setup_Other::action(const gcn::ActionEvent &event) { mShowExtMinimaps = mShowExtMinimapsCheckBox->isSelected(); } + else if (event.getId() == ACTION_ENABLE_ATTACK_FILTER) + { + mEnableAttackFilter = mEnableAttackFilterCheckBox->isSelected(); + } } void Setup_Other::cancel() @@ -430,6 +440,9 @@ void Setup_Other::cancel() mShowExtMinimaps = config.getBoolValue("showExtMinimaps"); mShowExtMinimapsCheckBox->setSelected(mShowExtMinimaps); + + mEnableAttackFilter = config.getBoolValue("enableAttackFilter"); + mEnableAttackFilterCheckBox->setSelected(mEnableAttackFilter); } void Setup_Other::apply() @@ -460,6 +473,7 @@ void Setup_Other::apply() config.setValue("showJobExp", mShowJobExp); config.setValue("showBeingPopup", mShowBeingPopup); config.setValue("showExtMinimaps", mShowExtMinimaps); + config.setValue("enableAttackFilter", mEnableAttackFilter); logger->setDebugLog(mDebugLog); } diff --git a/src/gui/setup_other.h b/src/gui/setup_other.h index 44daa1237..8bf4fe659 100644 --- a/src/gui/setup_other.h +++ b/src/gui/setup_other.h @@ -122,6 +122,9 @@ class Setup_Other : public SetupTab, public gcn::ActionListener gcn::CheckBox *mShowExtMinimapsCheckBox; bool mShowExtMinimaps; + gcn::CheckBox *mEnableAttackFilterCheckBox; + bool mEnableAttackFilter; + EditDialog *mEditDialog; }; diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 8a134b5c3..c6ec12cd8 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -500,7 +500,6 @@ private: class NavigationTab : public SocialTab { - public: NavigationTab() { @@ -768,6 +767,141 @@ protected: }; +class AttackTab : public SocialTab +{ +public: + AttackTab() + { + mBeings = new BeingsListModal(); + + mList = new AvatarListBox(mBeings); + mScroll = new ScrollArea(mList); + + mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_AUTO); + mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS); + + setCaption(_("Atk")); + } + + ~AttackTab() + { + delete mList; + mList = 0; + delete mScroll; + mScroll = 0; + delete mBeings; + mBeings = 0; + } + + void invite() + { + } + + void leave() + { + } + + void updateList() + { + if (!socialWindow || !player_node) + return; + + std::vector *avatars = mBeings->getMembers(); + + std::list mobs = player_node->getAttackMobs(); + std::list::iterator i = mobs.begin(); + + std::vector::iterator ia = avatars->begin(); + + while (ia != avatars->end()) + { + delete *ia; + ++ ia; + } + + avatars->clear(); + Avatar *ava = new Avatar(_("Selected mobs")); + ava->setOnline(false); + ava->setLevel(-1); + ava->setType(MapItem::SEPARATOR); + ava->setX(0); + ava->setY(0); + avatars->push_back(ava); + + while (i != mobs.end()) + { + std::string name; + int level = -1; + if (*i == "") + { + name = _("(default)"); + level = 0; + } + else + { + name = *i; + } + Avatar *ava = new Avatar(name); + ava->setOnline(true); + ava->setLevel(level); + ava->setType(MapItem::MONSTER); + ava->setX(0); + ava->setY(0); + avatars->push_back(ava); + + ++ i; + } + + ava = new Avatar(_("Ignore mobs")); + ava->setOnline(false); + ava->setLevel(-1); + ava->setType(MapItem::SEPARATOR); + ava->setX(0); + ava->setY(0); + avatars->push_back(ava); + + mobs = player_node->getIgnoreAttackMobs(); + i = mobs.begin(); + + while (i != mobs.end()) + { + std::string name; + int level = -1; + if (*i == "") + { + name = _("(default)"); + level = 0; + } + else + { + name = *i; + } + Avatar *ava = new Avatar(name); + ava->setOnline(false); + ava->setLevel(level); + ava->setType(MapItem::MONSTER); + ava->setX(0); + ava->setY(0); + avatars->push_back(ava); + + ++ i; + } + + } + + void updateAvatar(std::string name _UNUSED_) + { + } + + void resetDamage(std::string name _UNUSED_) + { + } + +private: + BeingsListModal *mBeings; + +}; + class CreatePopup : public Popup, public LinkHandler { public: @@ -866,6 +1000,16 @@ SocialWindow::SocialWindow() : mNavigation = new NavigationTab(); mTabs->addTab(mNavigation, mNavigation->mScroll); + if (config.getBoolValue("enableAttackFilter")) + { + mAttackFilter = new AttackTab(); + mTabs->addTab(mAttackFilter, mAttackFilter->mScroll); + } + else + { + mAttackFilter = 0; + } + if (player_node && player_node->getParty()) addTab(player_node->getParty()); @@ -899,6 +1043,10 @@ SocialWindow::~SocialWindow() mCreatePopup = 0; delete mPlayers; mPlayers = 0; + delete mNavigation; + mNavigation = 0; + delete mAttackFilter; + mAttackFilter = 0; } bool SocialWindow::addTab(Guild *guild) @@ -1204,7 +1352,7 @@ void SocialWindow::updateActiveList() void SocialWindow::logic() { unsigned int nowTime = cur_time; - if (nowTime - mLastUpdateTime > 1 && mNeedUpdate) + if (mNeedUpdate && nowTime - mLastUpdateTime > 1) { mPlayers->updateList(); mNeedUpdate = false; @@ -1304,4 +1452,10 @@ void SocialWindow::prevTab() tab--; mTabs->setSelectedTab(tab); -} \ No newline at end of file +} + +void SocialWindow::updateAttackFilter() +{ + if (mAttackFilter) + mAttackFilter->updateList(); +} diff --git a/src/gui/socialwindow.h b/src/gui/socialwindow.h index 8d4e904f0..c9cd296dc 100644 --- a/src/gui/socialwindow.h +++ b/src/gui/socialwindow.h @@ -36,6 +36,7 @@ #define _UNUSED_ #endif +class AttackTab; class Button; class ConfirmDialog; class CreatePopup; @@ -120,6 +121,8 @@ public: void selectPortal(unsigned num); + void updateAttackFilter(); + protected: friend class SocialTab; @@ -139,6 +142,7 @@ protected: typedef std::map PartyMap; PartyMap mParties; + SocialTab *mAttackFilter; SocialTab *mPlayers; SocialTab *mNavigation; diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index ef33aa75b..e34dd658a 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -620,6 +620,12 @@ void Viewport::showPopup(int x, int y, ProgressBar *bar) mPopupMenu->showPopup(x, y, bar); } +void Viewport::showAttackMonsterPopup(std::string name, bool isAttack) +{ + mPopupMenu->showAttackMonsterPopup(getMouseX(), getMouseY(), + name, isAttack); +} + void Viewport::closePopupMenu() { if (mPopupMenu) diff --git a/src/gui/viewport.h b/src/gui/viewport.h index 1daa871d1..d6e0fc3dc 100644 --- a/src/gui/viewport.h +++ b/src/gui/viewport.h @@ -160,6 +160,8 @@ class Viewport : public WindowContainer, public gcn::MouseListener, void showSpellPopup(TextCommand *cmd); + void showAttackMonsterPopup(std::string name, bool isAttack); + /** * Shows the related popup menu when right click on the chat * at the specified mouse coordinates. diff --git a/src/gui/widgets/avatarlistbox.cpp b/src/gui/widgets/avatarlistbox.cpp index c1458d3fd..8309ad156 100644 --- a/src/gui/widgets/avatarlistbox.cpp +++ b/src/gui/widgets/avatarlistbox.cpp @@ -114,10 +114,13 @@ void AvatarListBox::draw(gcn::Graphics *gcnGraphics) if (!a) continue; - // Draw online status - Image *icon = a->getOnline() ? onlineIcon : offlineIcon; - if (icon) - graphics->drawImage(icon, 2, y + 1); + if (a->getType() != MapItem::SEPARATOR) + { + // Draw online status + Image *icon = a->getOnline() ? onlineIcon : offlineIcon; + if (icon) + graphics->drawImage(icon, 2, y + 1); + } if (a->getDisplayBold()) graphics->setFont(boldFont); @@ -316,6 +319,20 @@ void AvatarListBox::mousePressed(gcn::MouseEvent &event) model->getAvatarAt(selected)->getName()); } } + else if (ava->getType() == MapItem::MONSTER) + { + if (model->getAvatarAt(selected)->getLevel() == 0) + { + viewport->showAttackMonsterPopup("", + model->getAvatarAt(selected)->getOnline()); + } + else + { + viewport->showAttackMonsterPopup( + model->getAvatarAt(selected)->getName(), + model->getAvatarAt(selected)->getOnline()); + } + } else { Map *map = viewport->getMap(); -- cgit v1.2.3-70-g09d2