summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/char_select.cpp65
-rw-r--r--src/gui/char_select.h12
-rw-r--r--src/gui/equipmentwindow.cpp1
-rw-r--r--src/gui/itemcontainer.cpp8
-rw-r--r--src/gui/login.cpp87
-rw-r--r--src/gui/login.h30
-rw-r--r--src/gui/register.cpp89
-rw-r--r--src/gui/register.h37
-rw-r--r--src/gui/unregisterdialog.cpp2
-rw-r--r--src/gui/viewport.cpp110
-rw-r--r--src/gui/viewport.h24
11 files changed, 323 insertions, 142 deletions
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index 09ce5b87..128a803e 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -42,9 +42,14 @@
#include "../logindata.h"
#include "../net/accountserver/account.h"
+#include "../net/charserverhandler.h"
+#include "../net/messageout.h"
#include "../utils/tostring.h"
+// Defined in main.cpp, used here for setting the char create dialog
+extern CharServerHandler charServerHandler;
+
/**
* Listener for confirming character deletion.
*/
@@ -155,14 +160,14 @@ void CharSelectDialog::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "new")
{
- //TODO: search the first free slot, and start CharCreateDialog
- // maybe add that search to the constructor
+ // TODO: Search the first free slot, and start CharCreateDialog
+ // maybe add that search to the constructor.
if (!(mCharInfo->getEntry()))
{
// Start new character dialog
- mCharInfo->lock();
- new CharCreateDialog(this, mCharInfo->getPos());
- mCharInfo->unlock();
+ CharCreateDialog *charCreateDialog =
+ new CharCreateDialog(this, mCharInfo->getPos());
+ charServerHandler.setCharCreateDialog(charCreateDialog);
}
}
else if (event.getId() == "delete")
@@ -344,14 +349,19 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot):
setLocationRelativeTo(getParent());
setVisible(true);
+ mNameField->requestFocus();
}
CharCreateDialog::~CharCreateDialog()
{
delete mPlayer;
+
+ // Make sure the char server handler knows that we're gone
+ charServerHandler.setCharCreateDialog(0);
}
-void CharCreateDialog::action(const gcn::ActionEvent &event)
+void
+CharCreateDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "create") {
if (getName().length() >= 4) {
@@ -362,15 +372,14 @@ void CharCreateDialog::action(const gcn::ActionEvent &event)
mPlayer->getHairStyle(),
mPlayer->getHairColor(),
0, // gender
- (int)mAttributeSlider[0]->getValue(), // STR
- (int)mAttributeSlider[1]->getValue(), // AGI
- (int)mAttributeSlider[2]->getValue(), // DEX
- (int)mAttributeSlider[3]->getValue(), // VIT
- (int)mAttributeSlider[4]->getValue(), // INT
- (int)mAttributeSlider[5]->getValue(), // WILL
- (int)mAttributeSlider[6]->getValue() // CHAR
+ (int) mAttributeSlider[0]->getValue(), // STR
+ (int) mAttributeSlider[1]->getValue(), // AGI
+ (int) mAttributeSlider[2]->getValue(), // DEX
+ (int) mAttributeSlider[3]->getValue(), // VIT
+ (int) mAttributeSlider[4]->getValue(), // INT
+ (int) mAttributeSlider[5]->getValue(), // WILL
+ (int) mAttributeSlider[6]->getValue() // CHAR
);
- scheduleDelete();
}
else {
new OkDialog("Error",
@@ -399,21 +408,23 @@ void CharCreateDialog::action(const gcn::ActionEvent &event)
}
}
-std::string CharCreateDialog::getName()
+const std::string&
+CharCreateDialog::getName()
{
return mNameField->getText();
}
void CharCreateDialog::UpdateSliders()
{
- for (int i=0; i<=6; i++)
+ for (int i = 0; i < 7; i++)
{
- // update captions
- mAttributeValue[i]->setCaption(toString((int)(mAttributeSlider[i]->getValue())));
+ // Update captions
+ mAttributeValue[i]->setCaption(
+ toString((int) (mAttributeSlider[i]->getValue())));
mAttributeValue[i]->adjustSize();
}
- // update distributed points
+ // Update distributed points
int pointsLeft = 70 - getDistributedPoints();
if (pointsLeft == 0)
{
@@ -425,24 +436,32 @@ void CharCreateDialog::UpdateSliders()
mCreateButton->setEnabled(false);
if (pointsLeft > 0)
{
- mAttributesLeft->setCaption(std::string("Please distribute " + toString(pointsLeft) + " points"));
+ mAttributesLeft->setCaption(std::string("Please distribute " +
+ toString(pointsLeft) + " points"));
}
else
{
- mAttributesLeft->setCaption(std::string("Please remove " + toString(-pointsLeft) + " points"));
+ mAttributesLeft->setCaption(std::string("Please remove " +
+ toString(-pointsLeft) + " points"));
}
}
mAttributesLeft->adjustSize();
}
+void
+CharCreateDialog::unlock()
+{
+ mCreateButton->setEnabled(true);
+}
+
int CharCreateDialog::getDistributedPoints()
{
int points = 0;
- for (int i=0; i<7; i++)
+ for (int i = 0; i < 7; i++)
{
- points += (int)mAttributeSlider[i]->getValue();
+ points += (int) mAttributeSlider[i]->getValue();
}
return points;
}
diff --git a/src/gui/char_select.h b/src/gui/char_select.h
index 5066897e..9d9184ea 100644
--- a/src/gui/char_select.h
+++ b/src/gui/char_select.h
@@ -114,9 +114,17 @@ class CharCreateDialog : public Window, public gcn::ActionListener
*/
~CharCreateDialog();
- void action(const gcn::ActionEvent &event);
+ void
+ action(const gcn::ActionEvent &event);
- std::string getName();
+ const std::string&
+ getName();
+
+ /**
+ * Unlocks the dialog, enabling the create character button again.
+ */
+ void
+ unlock();
private:
int getDistributedPoints();
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index ec525c47..ec84491e 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -30,7 +30,6 @@
#include "../resources/iteminfo.h"
#include "../resources/resourcemanager.h"
-#include "../resources/spriteset.h"
#include "../utils/tostring.h"
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp
index 308311b7..a176f226 100644
--- a/src/gui/itemcontainer.cpp
+++ b/src/gui/itemcontainer.cpp
@@ -35,7 +35,6 @@
#include "../resources/image.h"
#include "../resources/iteminfo.h"
#include "../resources/resourcemanager.h"
-#include "../resources/spriteset.h"
#include "../utils/tostring.h"
@@ -65,7 +64,8 @@ ItemContainer::logic()
int i = mInventory->getLastUsedSlot() + 1;
- if (i != mMaxItems) {
+ if (i != mMaxItems)
+ {
mMaxItems = i;
setWidth(getWidth());
}
@@ -192,9 +192,9 @@ ItemContainer::mousePressed(gcn::MouseEvent &event)
int my = event.getY();
int index = mx / gridWidth + ((my / gridHeight) * columns);
- if (index > INVENTORY_SIZE) {
+ if (index > INVENTORY_SIZE)
index = INVENTORY_SIZE - 1;
- }
+
setSelectedItem(mInventory->getItem(index));
}
}
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index 9df3b489..15ec6314 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -36,24 +36,6 @@
#include "passwordfield.h"
#include "textfield.h"
-void
-WrongDataNoticeListener::setTarget(gcn::TextField *textField)
-{
- mTarget = textField;
-}
-
-void
-WrongDataNoticeListener::action(const gcn::ActionEvent &event)
-{
- if (event.getId() == "ok")
- {
- // Reset the field
- mTarget->setText("");
- mTarget->setCaretPosition(0);
- mTarget->requestFocus();
- }
-}
-
LoginDialog::LoginDialog(LoginData *loginData):
Window("Login"), mLoginData(loginData)
{
@@ -66,28 +48,33 @@ LoginDialog::LoginDialog(LoginData *loginData):
mCancelButton = new Button("Cancel", "cancel", this);
mRegisterButton = new Button("Register", "register", this);
- setContentSize(200, 91);
+ const int width = 220;
+ const int height = 100;
+
+ setContentSize(width, height);
userLabel->setPosition(5, 5);
passLabel->setPosition(5, 14 + userLabel->getHeight());
mUserField->setPosition(65, 5);
mPassField->setPosition(65, 14 + userLabel->getHeight());
- mUserField->setWidth(130);
- mPassField->setWidth(130);
+ mUserField->setWidth(width - 70);
+ mPassField->setWidth(width - 70);
mKeepCheck->setPosition(4, 68);
mCancelButton->setPosition(
- 200 - mCancelButton->getWidth() - 5,
- 91 - mCancelButton->getHeight() - 5);
+ width - mCancelButton->getWidth() - 5,
+ height - mCancelButton->getHeight() - 5);
mOkButton->setPosition(
mCancelButton->getX() - mOkButton->getWidth() - 5,
- 91 - mOkButton->getHeight() - 5);
+ height - mOkButton->getHeight() - 5);
mRegisterButton->setPosition(
mKeepCheck->getX() + mKeepCheck->getWidth() + 10,
- 91 - mRegisterButton->getHeight() - 5);
+ height - mRegisterButton->getHeight() - 5);
mUserField->setActionEventId("ok");
mPassField->setActionEventId("ok");
+ mUserField->addKeyListener(this);
+ mPassField->addKeyListener(this);
mUserField->addActionListener(this);
mPassField->addActionListener(this);
mKeepCheck->addActionListener(this);
@@ -110,37 +97,27 @@ LoginDialog::LoginDialog(LoginData *loginData):
mPassField->requestFocus();
}
- mWrongDataNoticeListener = new WrongDataNoticeListener();
+ mOkButton->setEnabled(canSubmit());
}
LoginDialog::~LoginDialog()
{
- delete mWrongDataNoticeListener;
}
void
LoginDialog::action(const gcn::ActionEvent &event)
{
- if (event.getId() == "ok")
+ if (event.getId() == "ok" && canSubmit())
{
- // Check login
- if (mUserField->getText().empty())
- {
- mWrongDataNoticeListener->setTarget(mPassField);
- OkDialog *dlg = new OkDialog("Error", "Enter your username first");
- dlg->addActionListener(mWrongDataNoticeListener);
- }
- else
- {
- mLoginData->username = mUserField->getText();
- mLoginData->password = mPassField->getText();
- mLoginData->remember = mKeepCheck->isMarked();
-
- mOkButton->setEnabled(false);
- mRegisterButton->setEnabled(false);
-
- state = STATE_LOGIN_ATTEMPT;
- }
+ mLoginData->username = mUserField->getText();
+ mLoginData->password = mPassField->getText();
+ mLoginData->remember = mKeepCheck->isMarked();
+ mLoginData->registerLogin = false;
+
+ mOkButton->setEnabled(false);
+ mRegisterButton->setEnabled(false);
+
+ state = STATE_LOGIN_ATTEMPT;
}
else if (event.getId() == "cancel")
{
@@ -148,6 +125,24 @@ LoginDialog::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "register")
{
+ // Transfer these fields on to the register dialog
+ mLoginData->username = mUserField->getText();
+ mLoginData->password = mPassField->getText();
+
state = STATE_REGISTER;
}
}
+
+void
+LoginDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ mOkButton->setEnabled(canSubmit());
+}
+
+bool
+LoginDialog::canSubmit()
+{
+ return !mUserField->getText().empty() &&
+ !mPassField->getText().empty() &&
+ state == STATE_LOGIN;
+}
diff --git a/src/gui/login.h b/src/gui/login.h
index 05c0da31..d8ae7eaf 100644
--- a/src/gui/login.h
+++ b/src/gui/login.h
@@ -26,6 +26,7 @@
#include <iosfwd>
#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
#include "window.h"
#include "../guichanfwd.h"
@@ -33,22 +34,13 @@
class LoginData;
/**
- * Listener used for handling wrong data.
- */
-class WrongDataNoticeListener : public gcn::ActionListener {
- public:
- void setTarget(gcn::TextField *textField);
- void action(const gcn::ActionEvent &event);
- private:
- gcn::TextField *mTarget;
-};
-
-/**
* The login dialog.
*
* \ingroup Interface
*/
-class LoginDialog : public Window, public gcn::ActionListener {
+class LoginDialog : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
public:
/**
* Constructor
@@ -67,7 +59,19 @@ class LoginDialog : public Window, public gcn::ActionListener {
*/
void action(const gcn::ActionEvent &event);
+ /**
+ * Called when a key is pressed in one of the text fields.
+ */
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
private:
+ /**
+ * Returns whether submit can be enabled. This is true in the login
+ * state, when all necessary fields have some text.
+ */
+ bool
+ canSubmit();
+
gcn::TextField *mUserField;
gcn::TextField *mPassField;
gcn::CheckBox *mKeepCheck;
@@ -75,8 +79,6 @@ class LoginDialog : public Window, public gcn::ActionListener {
gcn::Button *mCancelButton;
gcn::Button *mRegisterButton;
- WrongDataNoticeListener *mWrongDataNoticeListener;
-
LoginData *mLoginData;
};
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index be15747d..c8e01a6c 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -41,6 +41,21 @@
#include "textfield.h"
#include "ok_dialog.h"
+void
+WrongDataNoticeListener::setTarget(gcn::TextField *textField)
+{
+ mTarget = textField;
+}
+
+void
+WrongDataNoticeListener::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok")
+ {
+ mTarget->requestFocus();
+ }
+}
+
RegisterDialog::RegisterDialog(LoginData *loginData):
Window("Register"),
mWrongDataNoticeListener(new WrongDataNoticeListener()),
@@ -50,28 +65,28 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
gcn::Label *passwordLabel = new gcn::Label("Password:");
gcn::Label *confirmLabel = new gcn::Label("Confirm:");
gcn::Label *emailLabel = new gcn::Label("Email:");
- mUserField = new TextField("player");
- mPasswordField = new PasswordField();
+ mUserField = new TextField(loginData->username);
+ mPasswordField = new PasswordField(loginData->password);
mConfirmField = new PasswordField();
mEmailField = new TextField();
mRegisterButton = new Button("Register", "register", this);
mCancelButton = new Button("Cancel", "cancel", this);
- const int width = 200;
+ const int width = 220;
const int height = 130;
setContentSize(width, height);
mUserField->setPosition(65, 5);
- mUserField->setWidth(130);
+ mUserField->setWidth(width - 70);
mPasswordField->setPosition(
65, mUserField->getY() + mUserField->getHeight() + 7);
- mPasswordField->setWidth(130);
+ mPasswordField->setWidth(mUserField->getWidth());
mConfirmField->setPosition(
65, mPasswordField->getY() + mPasswordField->getHeight() + 7);
- mConfirmField->setWidth(130);
+ mConfirmField->setWidth(mUserField->getWidth());
mEmailField->setPosition(
65, mConfirmField->getY() + mConfirmField->getHeight() + 7);
- mEmailField->setWidth(130);
+ mEmailField->setWidth(mUserField->getWidth());
userLabel->setPosition(5, mUserField->getY() + 1);
passwordLabel->setPosition(5, mPasswordField->getY() + 1);
@@ -79,11 +94,30 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
emailLabel->setPosition(5, mEmailField->getY() + 1);
mCancelButton->setPosition(
- width - 5 - mCancelButton->getWidth(),
- height - 5 - mCancelButton->getHeight());
+ width - mCancelButton->getWidth() - 5,
+ height - mCancelButton->getHeight() - 5);
mRegisterButton->setPosition(
- mCancelButton->getX() - 5 - mRegisterButton->getWidth(),
- mCancelButton->getY());
+ mCancelButton->getX() - mRegisterButton->getWidth() - 5,
+ height - mRegisterButton->getHeight() - 5);
+
+ mUserField->addKeyListener(this);
+ mPasswordField->addKeyListener(this);
+ mConfirmField->addKeyListener(this);
+ mEmailField->addKeyListener(this);
+
+ /* TODO:
+ * This is a quick and dirty way to respond to the ENTER key, regardless of
+ * which text field is selected. There may be a better way now with the new
+ * input system of Guichan 0.6.0. See also the login dialog.
+ */
+ mUserField->setActionEventId("register");
+ mPasswordField->setActionEventId("register");
+ mConfirmField->setActionEventId("register");
+ mEmailField->setActionEventId("register");
+ mUserField->addActionListener(this);
+ mPasswordField->addActionListener(this);
+ mConfirmField->addActionListener(this);
+ mEmailField->addActionListener(this);
add(userLabel);
add(passwordLabel);
@@ -100,6 +134,8 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
setVisible(true);
mUserField->requestFocus();
mUserField->setCaretPosition(mUserField->getText().length());
+
+ mRegisterButton->setEnabled(canSubmit());
}
RegisterDialog::~RegisterDialog()
@@ -114,7 +150,7 @@ RegisterDialog::action(const gcn::ActionEvent &event)
{
state = STATE_LOGIN;
}
- else if (event.getId() == "register")
+ else if (event.getId() == "register" && canSubmit())
{
const std::string user = mUserField->getText();
logger->log("RegisterDialog::register Username is %s", user.c_str());
@@ -122,14 +158,7 @@ RegisterDialog::action(const gcn::ActionEvent &event)
std::stringstream errorMsg;
int error = 0;
- // Check login
- if (user.empty())
- {
- // No username
- errorMsg << "Enter your username first.";
- error = 1;
- }
- else if (user.length() < LEN_MIN_USERNAME)
+ if (user.length() < LEN_MIN_USERNAME)
{
// Name too short
errorMsg << "The username needs to be at least "
@@ -178,9 +207,11 @@ RegisterDialog::action(const gcn::ActionEvent &event)
}
else if (error == 2)
{
- mWrongDataNoticeListener->setTarget(this->mPasswordField);
// Reset password confirmation
+ mPasswordField->setText("");
mConfirmField->setText("");
+
+ mWrongDataNoticeListener->setTarget(this->mPasswordField);
}
OkDialog *dlg = new OkDialog("Error", errorMsg.str());
@@ -191,7 +222,6 @@ RegisterDialog::action(const gcn::ActionEvent &event)
// No errors detected, register the new user.
mRegisterButton->setEnabled(false);
- mLoginData->port = (short)config.getValue("port", 0);
mLoginData->username = mUserField->getText();
mLoginData->password = mPasswordField->getText();
mLoginData->email = mEmailField->getText();
@@ -201,3 +231,18 @@ RegisterDialog::action(const gcn::ActionEvent &event)
}
}
}
+
+void
+RegisterDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ mRegisterButton->setEnabled(canSubmit());
+}
+
+bool
+RegisterDialog::canSubmit()
+{
+ return !mUserField->getText().empty() &&
+ !mPasswordField->getText().empty() &&
+ !mConfirmField->getText().empty() &&
+ state == STATE_REGISTER;
+}
diff --git a/src/gui/register.h b/src/gui/register.h
index 4ffe451f..088e8f9b 100644
--- a/src/gui/register.h
+++ b/src/gui/register.h
@@ -26,23 +26,39 @@
#include <iosfwd>
#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
#include "window.h"
#include "../guichanfwd.h"
class LoginData;
class OkDialog;
-class WrongDataNoticeListener;
/**
- * The login dialog.
+ * Listener used while dealing with wrong data. It is used to direct the focus
+ * to the field which contained wrong data when the Ok button was pressed on
+ * the error notice.
+ */
+class WrongDataNoticeListener : public gcn::ActionListener {
+ public:
+ void setTarget(gcn::TextField *textField);
+ void action(const gcn::ActionEvent &event);
+ private:
+ gcn::TextField *mTarget;
+};
+
+/**
+ * The registration dialog.
*
* \ingroup Interface
*/
-class RegisterDialog : public Window, public gcn::ActionListener {
+class RegisterDialog : public Window, public gcn::ActionListener,
+ public gcn::KeyListener
+{
public:
/**
- * Constructor
+ * Constructor. Name, password and server fields will be initialized to
+ * the information already present in the LoginData instance.
*
* @see Window::Window
*/
@@ -58,10 +74,19 @@ class RegisterDialog : public Window, public gcn::ActionListener {
*/
void action(const gcn::ActionEvent &event);
- // Made them public to have the possibility to request focus
- // from external functions.
+ /**
+ * Called when a key is pressed in one of the text fields.
+ */
+ void keyPressed(gcn::KeyEvent &keyEvent);
private:
+ /**
+ * Returns whether submit can be enabled. This is true in the register
+ * state, when all necessary fields have some text.
+ */
+ bool
+ canSubmit();
+
gcn::TextField *mUserField;
gcn::TextField *mPasswordField;
gcn::TextField *mConfirmField;
diff --git a/src/gui/unregisterdialog.cpp b/src/gui/unregisterdialog.cpp
index 9a09389d..5558e8fc 100644
--- a/src/gui/unregisterdialog.cpp
+++ b/src/gui/unregisterdialog.cpp
@@ -34,7 +34,7 @@
#include "button.h"
#include "checkbox.h"
-#include "login.h"
+#include "register.h"
#include "passwordfield.h"
#include "textfield.h"
#include "ok_dialog.h"
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index bc635cce..f3e9031c 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -28,15 +28,20 @@
#include "gui.h"
#include "popupmenu.h"
+#include "../simpleanimation.h"
#include "../beingmanager.h"
#include "../configuration.h"
#include "../flooritemmanager.h"
#include "../graphics.h"
#include "../localplayer.h"
#include "../map.h"
+#include "../monster.h"
#include "../npc.h"
-#include "../resources/monsterdb.h"
+#include "../resources/animation.h"
+#include "../resources/monsterinfo.h"
+#include "../resources/resourcemanager.h"
+#include "../resources/imageset.h"
#include "../utils/tostring.h"
@@ -60,11 +65,39 @@ Viewport::Viewport():
config.addListener("ScrollRadius", this);
mPopupMenu = new PopupMenu();
+
+ // Load target cursors
+ ResourceManager *resman = ResourceManager::getInstance();
+ mInRangeImages = resman->getImageSet(
+ "graphics/gui/target-cursor-blue.png", 44, 35);
+ mOutRangeImages = resman->getImageSet(
+ "graphics/gui/target-cursor-red.png", 44, 35);
+ Animation *animInRange = new Animation();
+ Animation *animOutRange = new Animation();
+
+ for (unsigned int i = 0; i < mInRangeImages->size(); ++i)
+ {
+ animInRange->addFrame(mInRangeImages->get(i), 75, 0, 0);
+ }
+
+ for (unsigned int j = 0; j < mOutRangeImages->size(); ++j)
+ {
+ animOutRange->addFrame(mOutRangeImages->get(j), 75, 0, 0);
+ }
+
+ mTargetCursorInRange = new SimpleAnimation(animInRange);
+ mTargetCursorOutRange = new SimpleAnimation(animOutRange);
}
Viewport::~Viewport()
{
delete mPopupMenu;
+
+ delete mTargetCursorInRange;
+ delete mTargetCursorOutRange;
+
+ mInRangeImages->decRef();
+ mOutRangeImages->decRef();
}
void
@@ -158,10 +191,12 @@ Viewport::draw(gcn::Graphics *gcnGraphics)
if (mMap)
{
mMap->draw(graphics, mCameraX, mCameraY, 0);
+ drawTargetCursor(graphics);
mMap->draw(graphics, mCameraX, mCameraY, 1);
mMap->draw(graphics, mCameraX, mCameraY, 2);
mMap->drawOverlay(graphics, mViewX, mViewY,
(int) config.getValue("OverlayDetail", 2));
+ drawTargetName(graphics);
}
// Find a path from the player to the mouse, and draw it. This is for debug
@@ -201,28 +236,6 @@ Viewport::draw(gcn::Graphics *gcnGraphics)
(*i)->drawEmotion(graphics, -mCameraX, -mCameraY);
}
- // Draw target marker if needed
- Being *target = player_node->getTarget();
- if (target)
- {
- graphics->setFont(speechFont);
- graphics->setColor(gcn::Color(255, 32, 32));
- int dy = (target->getType() == Being::PLAYER) ? 80 : 42;
-
- std::string mobName = "";
-
- if (target->mJob >= 1002)
- {
- int mobId = target->mJob - 1002;
- mobName = MonsterDB::get(mobId).getName();
-
- graphics->drawText(mobName,
- target->getPixelX() - mCameraX + 15,
- target->getPixelY() - mCameraY - dy,
- gcn::Graphics::CENTER);
- }
- }
-
// Draw contained widgets
WindowContainer::draw(gcnGraphics);
}
@@ -245,6 +258,57 @@ Viewport::logic()
mouseY + mCameraY);
mWalkTime = player_node->mWalkTime;
}
+
+ mTargetCursorInRange->update(10);
+ mTargetCursorOutRange->update(10);
+}
+
+void
+Viewport::drawTargetCursor(Graphics *graphics)
+{
+ // Draw target marker if needed
+ Being *target = player_node->getTarget();
+ if (target)
+ {
+ // Find whether target is in range
+ int rangeX = abs(target->mX - player_node->mX);
+ int rangeY = abs(target->mY - player_node->mY);
+ int attackRange = player_node->getAttackRange();
+
+ // Draw the target cursor, which one depends if the target is in range
+ if (rangeX > attackRange || rangeY > attackRange)
+ {
+ // Draw the out of range cursor
+ graphics->drawImage(mTargetCursorOutRange->getCurrentImage(),
+ target->getPixelX() - mCameraX,
+ target->getPixelY() - mCameraY);
+ }
+ else
+ {
+ // Draw the in range cursor
+ graphics->drawImage(mTargetCursorInRange->getCurrentImage(),
+ target->getPixelX() - mCameraX,
+ target->getPixelY() - mCameraY);
+ }
+ }
+}
+
+void
+Viewport::drawTargetName(Graphics *graphics)
+{
+ // Draw target marker if needed
+ Being *target = player_node->getTarget();
+ if (target && target->getType() == Being::MONSTER)
+ {
+ graphics->setFont(speechFont);
+ graphics->setColor(gcn::Color(255, 32, 32));
+
+ const MonsterInfo &mi = static_cast<Monster*>(target)->getInfo();
+ graphics->drawText(mi.getName(),
+ target->getPixelX() - mCameraX + 15,
+ target->getPixelY() - mCameraY - 42,
+ gcn::Graphics::CENTER);
+ }
}
void
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
index f1cadd98..84efeff3 100644
--- a/src/gui/viewport.h
+++ b/src/gui/viewport.h
@@ -33,8 +33,11 @@
class Map;
class Being;
class FloorItem;
+class ImageSet;
class Item;
class PopupMenu;
+class Graphics;
+class SimpleAnimation;
/**
* The viewport on the map. Displays the current map and handles mouse input
@@ -138,6 +141,18 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
*/
void showPopup(int x, int y, Being *being);
+ /**
+ * Draws range based target cursor
+ */
+ void
+ drawTargetCursor(Graphics *graphics);
+
+ /**
+ * Draws target name
+ */
+ void
+ drawTargetName(Graphics *graphics);
+
Map *mMap; /**< The current map. */
@@ -149,6 +164,15 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
int mCameraY; /**< Current viewpoint in tiles. */
bool mShowDebugPath; /**< Show a path from player to pointer. */
+ ImageSet *mInRangeImages; /**< Images of in range target cursor. */
+ ImageSet *mOutRangeImages; /**< Images of out of range target cursor.*/
+
+ /** Animated in range target cursor. */
+ SimpleAnimation *mTargetCursorInRange;
+
+ /** Animated out of range target cursor. */
+ SimpleAnimation *mTargetCursorOutRange;
+
bool mPlayerFollowMouse;
int mWalkTime;