summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/popupmenu.cpp182
-rw-r--r--src/gui/popupmenu.h3
-rw-r--r--src/gui/setup_other.cpp14
-rw-r--r--src/gui/setup_other.h3
-rw-r--r--src/gui/socialwindow.cpp160
-rw-r--r--src/gui/socialwindow.h4
-rw-r--r--src/gui/viewport.cpp6
-rw-r--r--src/gui/viewport.h2
-rw-r--r--src/gui/widgets/avatarlistbox.cpp25
9 files changed, 392 insertions, 7 deletions
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<std::string> mobs = player_node->getAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::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<std::string> mobs = player_node->getAttackMobs();
+ std::list<std::string>::iterator it = mobs.begin();
+ std::list<std::string>::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<Avatar*> *avatars = mBeings->getMembers();
+
+ std::list<std::string> mobs = player_node->getAttackMobs();
+ std::list<std::string>::iterator i = mobs.begin();
+
+ std::vector<Avatar*>::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<Party*, SocialTab*> 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();