summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/Makefile.am6
-rw-r--r--src/animatedsprite.cpp1
-rw-r--r--src/being.cpp14
-rw-r--r--src/being.h4
-rw-r--r--src/engine.cpp4
-rw-r--r--src/floor_item.cpp1
-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
-rw-r--r--src/localplayer.cpp1
-rw-r--r--src/localplayer.h12
-rw-r--r--src/logindata.h4
-rw-r--r--src/main.cpp101
-rw-r--r--src/monster.h1
-rw-r--r--src/net/charserverhandler.cpp24
-rw-r--r--src/net/charserverhandler.h13
-rw-r--r--src/net/equipmenthandler.cpp5
-rw-r--r--src/net/loginhandler.cpp2
-rw-r--r--src/net/protocol.h1
-rw-r--r--src/npc.cpp2
-rw-r--r--src/resources/animation.h1
-rw-r--r--src/resources/image.cpp124
-rw-r--r--src/resources/image.h6
-rw-r--r--src/resources/imageset.cpp (renamed from src/resources/spriteset.cpp)18
-rw-r--r--src/resources/imageset.h (renamed from src/resources/spriteset.h)23
-rw-r--r--src/resources/monsterdb.h2
-rw-r--r--src/resources/monsterinfo.h157
-rw-r--r--src/resources/resourcemanager.cpp22
-rw-r--r--src/resources/resourcemanager.h8
-rw-r--r--src/resources/spritedef.cpp34
-rw-r--r--src/resources/spritedef.h10
-rw-r--r--src/simpleanimation.cpp50
-rw-r--r--src/simpleanimation.h65
-rw-r--r--src/tileset.h8
-rw-r--r--src/tmw.rc2
44 files changed, 781 insertions, 416 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4b5bad01..e28e235e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -268,10 +268,10 @@ SET(SRCS
resources/sdlimageloader.h
resources/soundeffect.cpp
resources/soundeffect.h
- resources/spriteset.cpp
resources/spritedef.h
resources/spritedef.cpp
- resources/spriteset.h
+ resources/imageset.h
+ resources/imageset.cpp
utils/base64.cpp
utils/base64.h
utils/dtor.h
@@ -330,6 +330,8 @@ SET(SRCS
player.h
properties.h
serverinfo.h
+ simpleanimation.cpp
+ simpleanimation.h
sound.cpp
sound.h
sprite.h
diff --git a/src/Makefile.am b/src/Makefile.am
index da1bc44d..f1f51b79 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -222,8 +222,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \
resources/soundeffect.cpp \
resources/spritedef.h \
resources/spritedef.cpp \
- resources/spriteset.h \
- resources/spriteset.cpp \
+ resources/imageset.h \
+ resources/imageset.cpp \
resources/buddylist.h \
resources/buddylist.cpp \
utils/base64.cpp \
@@ -284,6 +284,8 @@ tmw_SOURCES = gui/widgets/dropdown.cpp \
player.h \
properties.h \
serverinfo.h \
+ simpleanimation.cpp \
+ simpleanimation.h \
sound.cpp \
sound.h \
sprite.h \
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
index 3d1979a9..7260a512 100644
--- a/src/animatedsprite.cpp
+++ b/src/animatedsprite.cpp
@@ -30,7 +30,6 @@
#include "resources/animation.h"
#include "resources/image.h"
#include "resources/resourcemanager.h"
-#include "resources/spriteset.h"
#include "utils/xml.h"
diff --git a/src/being.cpp b/src/being.cpp
index e4a1e9fc..682daddb 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -34,7 +34,7 @@
#include "map.h"
#include "resources/resourcemanager.h"
-#include "resources/spriteset.h"
+#include "resources/imageset.h"
#include "gui/gui.h"
@@ -42,7 +42,7 @@
#include "utils/tostring.h"
int Being::instances = 0;
-Spriteset *Being::emotionset = NULL;
+ImageSet *Being::emotionSet = NULL;
Being::Being(Uint16 id, Uint16 job, Map *map):
mJob(job),
@@ -72,8 +72,8 @@ Being::Being(Uint16 id, Uint16 job, Map *map):
{
// Load the emotion set
ResourceManager *rm = ResourceManager::getInstance();
- emotionset = rm->getSpriteset("graphics/sprites/emotions.png", 30, 32);
- if (!emotionset) logger->error("Unable to load emotions spriteset!");
+ emotionSet = rm->getImageSet("graphics/sprites/emotions.png", 30, 32);
+ if (!emotionSet) logger->error("Unable to load emotions!");
}
instances++;
@@ -89,8 +89,8 @@ Being::~Being()
if (instances == 0)
{
- emotionset->decRef();
- emotionset = NULL;
+ emotionSet->decRef();
+ emotionSet = NULL;
}
}
@@ -515,7 +515,7 @@ Being::drawEmotion(Graphics *graphics, int offsetX, int offsetY)
int px = mPx + offsetX + 3;
int py = mPy + offsetY - 60;
- graphics->drawImage(emotionset->get(mEmotion - 1), px, py);
+ graphics->drawImage(emotionSet->get(mEmotion - 1), px, py);
}
void
diff --git a/src/being.h b/src/being.h
index c3cba247..332f1b4a 100644
--- a/src/being.h
+++ b/src/being.h
@@ -41,7 +41,7 @@ class Equipment;
class Item;
class Map;
class Graphics;
-class Spriteset;
+class ImageSet;
/**
* A position along a being's path.
@@ -397,7 +397,7 @@ class Being : public Sprite
Uint16 mStepTime;
static int instances; /**< Number of Being instances */
- static Spriteset *emotionset; /**< Emoticons used by beings */
+ static ImageSet *emotionSet; /**< Emoticons used by beings */
};
#endif
diff --git a/src/engine.cpp b/src/engine.cpp
index a3097d49..31bec9ff 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -44,7 +44,6 @@
#include "resources/mapreader.h"
#include "resources/monsterdb.h"
#include "resources/resourcemanager.h"
-#include "resources/spriteset.h"
#include "utils/dtor.h"
#include "utils/tostring.h"
@@ -77,7 +76,8 @@ void Engine::changeMap(const std::string &mapPath)
// Notify the minimap and beingManager about the map change
Image *mapImage = NULL;
- if (newMap->hasProperty("minimap")) {
+ if (newMap->hasProperty("minimap"))
+ {
ResourceManager *resman = ResourceManager::getInstance();
mapImage = resman->getImage(newMap->getProperty("minimap"));
}
diff --git a/src/floor_item.cpp b/src/floor_item.cpp
index f33f7eb4..5d83e1dd 100644
--- a/src/floor_item.cpp
+++ b/src/floor_item.cpp
@@ -27,7 +27,6 @@
#include "resources/itemdb.h"
#include "resources/iteminfo.h"
-#include "resources/spriteset.h"
FloorItem::FloorItem(unsigned int id,
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;
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 7f595ef1..97371677 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -38,6 +38,7 @@ LocalPlayer *player_node = NULL;
LocalPlayer::LocalPlayer():
Player(65535, 0, NULL),
+ mAttackRange(0),
mInventory(new Inventory()),
mAttributeBase(NB_BASE_ATTRIBUTES, 0),
mAttributeEffective(NB_BASE_ATTRIBUTES, 0),
diff --git a/src/localplayer.h b/src/localplayer.h
index 299cf85a..fb7703dd 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -153,6 +153,16 @@ class LocalPlayer : public Player
void pickUp(FloorItem *item);
/**
+ * Sets the attack range.
+ */
+ void setAttackRange(int range) { mAttackRange = range; }
+
+ /**
+ * Gets the attack range.
+ */
+ int getAttackRange() const { return mAttackRange; }
+
+ /**
* Sents a trade request to the given being.
*/
void trade(Being *being) const;
@@ -213,6 +223,8 @@ class LocalPlayer : public Player
int getMaxHP() const
{ return mMaxHP; }
+ Uint16 mAttackRange;
+
void setHP(int value)
{ mHP = value; }
diff --git a/src/logindata.h b/src/logindata.h
index 0a01331c..fbbbb573 100644
--- a/src/logindata.h
+++ b/src/logindata.h
@@ -36,8 +36,8 @@ struct LoginData
int session_ID1;
int session_ID2;
- bool remember;
- bool registerLogin;
+ bool remember; /**< Whether to store the username and host. */
+ bool registerLogin; /**< Whether an account is being registered. */
void clear()
{
diff --git a/src/main.cpp b/src/main.cpp
index aad6a68c..bbbf0fd1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -30,9 +30,13 @@
#include <vector>
#include <SDL_image.h>
-#include <guichan/actionlistener.hpp>
+#ifdef WIN32
+#include <SDL_syswm.h>
+#endif
+#include <guichan/actionlistener.hpp>
#include <guichan/sdl/sdlinput.hpp>
+#include <guichan/widgets/label.hpp>
#include <libxml/parser.h>
@@ -63,11 +67,11 @@
#include "gui/login.h"
#include "gui/quitdialog.h"
#include "gui/ok_dialog.h"
+#include "gui/progressbar.h"
#include "gui/register.h"
#include "gui/updatewindow.h"
#include "gui/textfield.h"
-
#include "net/charserverhandler.h"
#include "net/connection.h"
#include "net/loginhandler.h"
@@ -86,7 +90,6 @@
#include "resources/itemdb.h"
#include "resources/monsterdb.h"
#include "resources/resourcemanager.h"
-#include "resources/spriteset.h"
#include "utils/dtor.h"
#include "utils/tostring.h"
@@ -103,23 +106,13 @@ unsigned char screen_mode;
Sound sound;
Music *bgm;
-Configuration config; /**< Xml file configuration reader */
+Configuration config; /**< XML file configuration reader */
Logger *logger; /**< Log object */
Net::Connection *accountServerConnection = 0;
Net::Connection *gameServerConnection = 0;
Net::Connection *chatServerConnection = 0;
-namespace {
- struct ErrorListener : public gcn::ActionListener
- {
- void action(const gcn::ActionEvent &event)
- {
- state = STATE_CHOOSE_SERVER;
- }
- } errorListener;
-}
-
/**
* A structure holding the values of various options that can be passed from
* the command line.
@@ -131,12 +124,14 @@ struct Options
*/
Options():
printHelp(false),
+ printVersion(false),
skipUpdate(false),
chooseDefault(false),
serverPort(0)
{};
bool printHelp;
+ bool printVersion;
bool skipUpdate;
bool chooseDefault;
std::string playername;
@@ -237,7 +232,16 @@ void initEngine()
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
SDL_WM_SetCaption("The Mana World", NULL);
- SDL_WM_SetIcon(IMG_Load(TMW_DATADIR "data/icons/tmw-icon.png"), NULL);
+#ifdef WIN32
+ static SDL_SysWMinfo pInfo;
+ SDL_GetWMInfo(&pInfo);
+ HICON icon = LoadIcon(GetModuleHandle(NULL), "A");
+ SetClassLong(pInfo.window, GCL_HICON, (LONG) icon);
+#else
+ SDL_Surface *icon = IMG_Load(TMW_DATADIR "data/icons/tmw.png");
+ SDL_SetAlpha(icon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
+ SDL_WM_SetIcon(icon, NULL);
+#endif
ResourceManager *resman = ResourceManager::getInstance();
@@ -356,6 +360,7 @@ void printHelp()
"tmw\n\n"
"Options:\n"
" -h --help : Display this help\n"
+ " -v --version : Display the version\n"
" -u --skipupdate : Skip the update process\n"
" -U --username : Login with this username\n"
" -P --password : Login with this password\n"
@@ -366,12 +371,23 @@ void printHelp()
" -C --configfile : Configuration file to use\n";
}
+void printVersion()
+{
+#ifdef PACKAGE_VERSION
+ std::cout << "The Mana World version " << PACKAGE_VERSION << std::endl;
+#else
+ std::cout << "The Mana World version " <<
+ "(local build?, PACKAGE_VERSION is not defined)" << std::endl;
+#endif
+}
+
void parseOptions(int argc, char *argv[], Options &options)
{
- const char *optstring = "huU:P:Dp:s:o:C:";
+ const char *optstring = "hvuU:P:Dp:s:o:C:";
const struct option long_options[] = {
{ "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'v' },
{ "skipupdate", no_argument, 0, 'u' },
{ "username", required_argument, 0, 'U' },
{ "password", required_argument, 0, 'P' },
@@ -395,6 +411,9 @@ void parseOptions(int argc, char *argv[], Options &options)
case 'h':
options.printHelp = true;
break;
+ case 'v':
+ options.printVersion = true;
+ break;
case 'u':
options.skipUpdate = true;
break;
@@ -449,6 +468,16 @@ LoginHandler loginHandler;
LogoutHandler logoutHandler;
LockedArray<LocalPlayer*> charInfo(MAX_SLOT + 1);
+namespace {
+ struct ErrorListener : public gcn::ActionListener
+ {
+ void action(const gcn::ActionEvent &event)
+ {
+ state = STATE_CHOOSE_SERVER;
+ }
+ } errorListener;
+}
+
// TODO Find some nice place for these functions
void accountLogin(LoginData *loginData)
{
@@ -466,15 +495,17 @@ void accountLogin(LoginData *loginData)
// Clear the password, avoids auto login when returning to login
loginData->password = "";
- //remove _M or _F from username after a login for registration purpose
+ // Remove _M or _F from username after a login for registration purpose
if (loginData->registerLogin)
{
- loginData->registerLogin = false;
- loginData->username = loginData->username.substr(0, loginData->username.length() - 2);
+ loginData->username =
+ loginData->username.substr(0, loginData->username.length() - 2);
}
+
// TODO This is not the best place to save the config, but at least better
// than the login gui window
- if (loginData->remember) {
+ if (loginData->remember)
+ {
config.setValue("host", loginData->hostname);
config.setValue("username", loginData->username);
}
@@ -557,7 +588,7 @@ void logoutThenExit()
logoutHandler.reset();
logoutHandler.setScenario(LOGOUT_EXIT);
- //Can't logout if we were not logged in ...
+ // Can't logout if we were not logged in ...
if (accountServerConnection->isConnected())
{
Net::AccountServer::logout();
@@ -616,10 +647,6 @@ void initXML()
/** Main */
int main(int argc, char *argv[])
{
-#ifdef PACKAGE_VERSION
- std::cout << "The Mana World v" << PACKAGE_VERSION << std::endl;
-#endif
-
// Parse command line options
Options options;
parseOptions(argc, argv, options);
@@ -628,6 +655,11 @@ int main(int argc, char *argv[])
printHelp();
return 0;
}
+ else if (options.printVersion)
+ {
+ printVersion();
+ return 0;
+ }
// Initialize PhysicsFS
PHYSFS_init(argv[0]);
@@ -647,10 +679,16 @@ int main(int argc, char *argv[])
initConfiguration(options);
initEngine();
+ Game *game = NULL;
Window *currentDialog = NULL;
QuitDialog* quitDialog = NULL;
Image *login_wallpaper = NULL;
- Game *game = NULL;
+
+ gcn::Container *top = static_cast<gcn::Container*>(gui->getTop());
+#ifdef PACKAGE_VERSION
+ gcn::Label *versionLabel = new gcn::Label(PACKAGE_VERSION);
+ top->add(versionLabel, 2, 2);
+#endif
sound.playMusic(TMW_DATADIR "data/music/Magick - Real.ogg");
@@ -715,8 +753,8 @@ int main(int argc, char *argv[])
guiInput->pushInput(event);
}
- gui->logic();
Net::flush();
+ gui->logic();
if (!login_wallpaper)
{
@@ -729,10 +767,6 @@ int main(int argc, char *argv[])
}
graphics->drawImage(login_wallpaper, 0, 0);
-#ifdef PACKAGE_VERSION
- graphics->setFont(gui->getFont());
- graphics->drawText(PACKAGE_VERSION, 0, 0);
-#endif
gui->draw();
graphics->updateScreen();
@@ -759,7 +793,6 @@ int main(int argc, char *argv[])
accountServerConnection->isConnected())
{
reconnectAccount(token);
-
state = STATE_WAIT;
}
@@ -936,6 +969,10 @@ int main(int argc, char *argv[])
Net::ChatServer::connect(chatServerConnection, token);
sound.fadeOutMusic(1000);
+#ifdef PACKAGE_VERSION
+ delete versionLabel;
+ versionLabel = NULL;
+#endif
currentDialog = NULL;
logger->log("State: GAME");
diff --git a/src/monster.h b/src/monster.h
index 18fa703e..39bbf3d7 100644
--- a/src/monster.h
+++ b/src/monster.h
@@ -43,7 +43,6 @@ class Monster : public Being
*/
virtual void handleAttack();
- protected:
/**
* Returns the MonsterInfo, with static data about this monster.
*/
diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp
index 34fc188d..820aaea4 100644
--- a/src/net/charserverhandler.cpp
+++ b/src/net/charserverhandler.cpp
@@ -34,11 +34,13 @@
#include "../main.h"
#include "../gui/ok_dialog.h"
+#include "../gui/char_select.h"
extern Net::Connection *gameServerConnection;
extern Net::Connection *chatServerConnection;
-CharServerHandler::CharServerHandler()
+CharServerHandler::CharServerHandler():
+ mCharCreateDialog(0)
{
static const Uint16 _messages[] = {
APMSG_CHAR_CREATE_RESPONSE,
@@ -99,6 +101,13 @@ CharServerHandler::handleMessage(MessageIn &msg)
mCharInfo->unlock();
mCharInfo->select(slot);
mCharInfo->setEntry(tempPlayer);
+
+ // Close the character create dialog
+ if (mCharCreateDialog)
+ {
+ mCharCreateDialog->scheduleDelete();
+ mCharCreateDialog = 0;
+ }
break;
case APMSG_CHAR_SELECT_RESPONSE:
@@ -154,6 +163,9 @@ CharServerHandler::handleCharCreateResponse(MessageIn &msg)
}
new OkDialog("Error", message);
}
+
+ if (mCharCreateDialog)
+ mCharCreateDialog->unlock();
}
void
@@ -177,15 +189,20 @@ CharServerHandler::handleCharSelectResponse(MessageIn &msg)
// Keep the selected character and delete the others
player_node = mCharInfo->getEntry();
+ int slot = mCharInfo->getPos();
mCharInfo->unlock();
mCharInfo->select(0);
do {
LocalPlayer *tmp = mCharInfo->getEntry();
if (tmp != player_node)
+ {
delete tmp;
+ mCharInfo->setEntry(0);
+ }
mCharInfo->next();
} while (mCharInfo->getPos());
+ mCharInfo->select(slot);
mCharInfo->clear(); //player_node will be deleted by ~Game
@@ -204,8 +221,11 @@ CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
tempPlayer->setHairColor(msg.readByte());
tempPlayer->setLevel(msg.readByte());
tempPlayer->setMoney(msg.readLong());
- for (int i = 0; i < 7; i++) {
+
+ for (int i = 0; i < 7; i++)
+ {
tempPlayer->setAttributeBase(i, msg.readByte());
}
+
return tempPlayer;
}
diff --git a/src/net/charserverhandler.h b/src/net/charserverhandler.h
index 342641d7..4a4fe0c3 100644
--- a/src/net/charserverhandler.h
+++ b/src/net/charserverhandler.h
@@ -28,9 +28,13 @@
#include "../lockedarray.h"
+class CharCreateDialog;
class LocalPlayer;
class LoginData;
+/**
+ * Deals with incoming messages related to character selection.
+ */
class CharServerHandler : public MessageHandler
{
public:
@@ -45,6 +49,14 @@ class CharServerHandler : public MessageHandler
mCharInfo = charInfo;
}
+ /**
+ * Sets the character create dialog. The handler will clean up this
+ * dialog when a new character is succesfully created, and will unlock
+ * the dialog when a new character failed to be created.
+ */
+ void setCharCreateDialog(CharCreateDialog *window)
+ { mCharCreateDialog = window; }
+
protected:
void
handleCharCreateResponse(MessageIn &msg);
@@ -53,6 +65,7 @@ class CharServerHandler : public MessageHandler
handleCharSelectResponse(MessageIn &msg);
LockedArray<LocalPlayer*> *mCharInfo;
+ CharCreateDialog *mCharCreateDialog;
LocalPlayer*
readPlayerData(MessageIn &msg, int &slot);
diff --git a/src/net/equipmenthandler.cpp b/src/net/equipmenthandler.cpp
index 1c0fd4ca..c0072a45 100644
--- a/src/net/equipmenthandler.cpp
+++ b/src/net/equipmenthandler.cpp
@@ -43,6 +43,7 @@ EquipmentHandler::EquipmentHandler()
0x01d7,
SMSG_PLAYER_UNEQUIP,
SMSG_PLAYER_ARROW_EQUIP,
+ SMSG_PLAYER_ATTACK_RANGE,
0
};
handledMessages = _messages;
@@ -191,6 +192,10 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
index, equipPoint, type, position);
break;
+ case SMSG_PLAYER_ATTACK_RANGE:
+ player_node->setAttackRange(msg.readShort());
+ break;
+
case SMSG_PLAYER_ARROW_EQUIP:
itemId = msg.readShort();
diff --git a/src/net/loginhandler.cpp b/src/net/loginhandler.cpp
index c68a620a..90f2dbd5 100644
--- a/src/net/loginhandler.cpp
+++ b/src/net/loginhandler.cpp
@@ -88,7 +88,7 @@ void LoginHandler::handleMessage(MessageIn &msg)
{
switch (errMsg) {
case REGISTER_INVALID_VERSION:
- errorMessage = "Client has an insufficient version number to login.";
+ errorMessage = "Client has an insufficient version number to login.";
break;
case ERRMSG_INVALID_ARGUMENT:
errorMessage = "Wrong username, password or email address";
diff --git a/src/net/protocol.h b/src/net/protocol.h
index a9ee0e5b..b5dc2996 100644
--- a/src/net/protocol.h
+++ b/src/net/protocol.h
@@ -44,6 +44,7 @@
#define SMSG_PLAYER_EQUIPMENT 0x00a4
#define SMSG_PLAYER_EQUIP 0x00aa
#define SMSG_PLAYER_UNEQUIP 0x00ac
+#define SMSG_PLAYER_ATTACK_RANGE 0x013a
#define SMSG_PLAYER_ARROW_EQUIP 0x013c
#define SMSG_PLAYER_ARROW_MESSAGE 0x013b
#define SMSG_PLAYER_SKILLS 0x010f
diff --git a/src/npc.cpp b/src/npc.cpp
index ccd085b6..2d291104 100644
--- a/src/npc.cpp
+++ b/src/npc.cpp
@@ -28,8 +28,6 @@
#include "gui/gui.h"
-class Spriteset;
-
NPC *current_npc = 0;
NPC::NPC(Uint16 id, Uint16 job, Map *map):
diff --git a/src/resources/animation.h b/src/resources/animation.h
index 54142bcb..d0d11c69 100644
--- a/src/resources/animation.h
+++ b/src/resources/animation.h
@@ -29,7 +29,6 @@
#include <libxml/tree.h>
class Image;
-class Spriteset;
/**
* A single frame in an animation, with a delay and an offset.
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 58325213..a27783d4 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -80,7 +80,7 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
tmpImage = IMG_Load_RW(rw, 1);
}
- if (tmpImage == NULL) {
+ if (!tmpImage) {
logger->log("Error, image load failed: %s", IMG_GetError());
return NULL;
}
@@ -99,87 +99,28 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
amask = 0xff000000;
#endif
- // Convert the image to a 32 bit software surface for processing
- SDL_Surface *formatImage = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, 32,
- rmask, gmask, bmask, amask);
-
- if (formatImage == NULL) {
- logger->log("Error, image load failed: not enough memory");
- SDL_FreeSurface(tmpImage);
- return NULL;
- }
-
- SDL_Surface *image = SDL_ConvertSurface(
- tmpImage, formatImage->format, SDL_SWSURFACE);
-
- SDL_FreeSurface(formatImage);
-
- if (image == NULL) {
- logger->log("Error, image load failed: not enough memory");
- return NULL;
- }
-
- bool hasPink = false;
- bool hasAlpha = false;
- int i;
- Uint32 pink = SDL_MapRGB(image->format, 255, 0, 255);
-
- // Figure out whether the image has pink pixels
- for (i = 0; i < image->w * image->h; ++i)
- {
- if (((Uint32*)image->pixels)[i] == pink)
- {
- hasPink = true;
- break;
- }
- }
-
- // Figure out whether the image uses its alpha layer
- for (i = 0; i < image->w * image->h; ++i)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(
- ((Uint32*)image->pixels)[i],
- image->format,
- &r, &g, &b, &a);
-
- if (a != 255)
- {
- hasAlpha = true;
- break;
- }
- }
-
- SDL_FreeSurface(image);
-
- if (hasPink && !hasAlpha) {
- SDL_SetColorKey(tmpImage, SDL_SRCCOLORKEY,
- SDL_MapRGB(tmpImage->format, 255, 0, 255));
- } else if (hasAlpha) {
- SDL_SetAlpha(tmpImage, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
- }
-
#ifdef USE_OPENGL
if (mUseOpenGL)
{
int width = tmpImage->w;
int height = tmpImage->h;
- int realWidth = 1, realHeight = 1;
+ int realWidth = powerOfTwo(width);
+ int realHeight = powerOfTwo(height);
- while (realWidth < width && realWidth < 1024) {
- realWidth *= 2;
- }
-
- while (realHeight < height && realHeight < 1024) {
- realHeight *= 2;
+ if (realWidth < width || realHeight < height)
+ {
+ logger->log("Warning: image too large, cropping to %dx%d texture!",
+ tmpImage->w, tmpImage->h);
}
+ // Make sure the alpha channel is not used, but copied to destination
SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE);
+
SDL_Surface *oldImage = tmpImage;
- tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, 32,
- rmask, gmask, bmask, amask);
+ tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight,
+ 32, rmask, gmask, bmask, amask);
- if (tmpImage == NULL) {
+ if (!tmpImage) {
logger->log("Error, image convert failed: out of memory");
return NULL;
}
@@ -189,8 +130,6 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
GLuint texture;
glGenTextures(1, &texture);
- logger->log("Binding texture %d (%dx%d)",
- texture, tmpImage->w, tmpImage->h);
glBindTexture(GL_TEXTURE_2D, texture);
if (SDL_MUSTLOCK(tmpImage)) {
@@ -246,8 +185,27 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
}
#endif
- // Set color key and alpha blending optins, and convert the surface to the
- // current display format
+ bool hasAlpha = false;
+
+ // Figure out whether the image uses its alpha layer
+ for (int i = 0; i < tmpImage->w * tmpImage->h; ++i)
+ {
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(
+ ((Uint32*) tmpImage->pixels)[i],
+ tmpImage->format,
+ &r, &g, &b, &a);
+
+ if (a != 255)
+ {
+ hasAlpha = true;
+ break;
+ }
+ }
+
+ SDL_Surface *image;
+
+ // Convert the surface to the current display format
if (hasAlpha) {
image = SDL_DisplayFormatAlpha(tmpImage);
}
@@ -256,7 +214,7 @@ Image* Image::load(void *buffer, unsigned int bufferSize,
}
SDL_FreeSurface(tmpImage);
- if (image == NULL) {
+ if (!image) {
logger->log("Error: Image convert failed.");
return NULL;
}
@@ -315,10 +273,22 @@ float Image::getAlpha()
}
#ifdef USE_OPENGL
-void Image::setLoadAsOpenGL(bool useOpenGL)
+void
+Image::setLoadAsOpenGL(bool useOpenGL)
{
Image::mUseOpenGL = useOpenGL;
}
+
+int
+Image::powerOfTwo(int input)
+{
+ int value = 1;
+ while (value < input && value < 1024)
+ {
+ value <<= 1;
+ }
+ return value;
+}
#endif
//============================================================================
diff --git a/src/resources/image.h b/src/resources/image.h
index 03bf0cbc..cad21dcd 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -126,6 +126,12 @@ class Image : public Resource
#ifdef USE_OPENGL
Image(const std::string &idPath, GLuint glimage, int width, int height,
int texWidth, int texHeight);
+
+ /**
+ * Returns the first power of two equal or bigger than the input.
+ */
+ static int
+ powerOfTwo(int input);
#endif
Image(const std::string &idPath, SDL_Surface *image);
diff --git a/src/resources/spriteset.cpp b/src/resources/imageset.cpp
index 96bcef0c..677c024b 100644
--- a/src/resources/spriteset.cpp
+++ b/src/resources/imageset.cpp
@@ -21,7 +21,7 @@
* $Id$
*/
-#include "spriteset.h"
+#include "imageset.h"
#include "../log.h"
@@ -29,7 +29,7 @@
#include "../utils/dtor.h"
-Spriteset::Spriteset(const std::string& idPath,
+ImageSet::ImageSet(const std::string& idPath,
Image *img,
int width, int height):
Resource(idPath)
@@ -38,28 +38,28 @@ Spriteset::Spriteset(const std::string& idPath,
{
for (int x = 0; x + width <= img->getWidth(); x += width)
{
- mSpriteset.push_back(img->getSubImage(x, y, width, height));
+ mImages.push_back(img->getSubImage(x, y, width, height));
}
}
mWidth = width;
mHeight = height;
}
-Spriteset::~Spriteset()
+ImageSet::~ImageSet()
{
- for_each(mSpriteset.begin(), mSpriteset.end(), make_dtor(mSpriteset));
+ for_each(mImages.begin(), mImages.end(), make_dtor(mImages));
}
Image*
-Spriteset::get(size_type i)
+ImageSet::get(size_type i)
{
- if (i >= mSpriteset.size())
+ if (i >= mImages.size())
{
- logger->log("Warning: Sprite #%i does not exist in this spriteset", i);
+ logger->log("Warning: Sprite #%i does not exist in this image set", i);
return NULL;
}
else
{
- return mSpriteset[i];
+ return mImages[i];
}
}
diff --git a/src/resources/spriteset.h b/src/resources/imageset.h
index 7f6b42df..3469a3bb 100644
--- a/src/resources/spriteset.h
+++ b/src/resources/imageset.h
@@ -21,8 +21,8 @@
* $Id$
*/
-#ifndef _TMW_SPRITESET_H
-#define _TMW_SPRITESET_H
+#ifndef _TMW_IMAGESET_H
+#define _TMW_IMAGESET_H
#include <vector>
@@ -33,21 +33,19 @@ class Image;
/**
* Stores a set of subimages originating from a single image.
- *
- * TODO: Should probably be renamed to ImageSet or TileSet.
*/
-class Spriteset : public Resource
+class ImageSet : public Resource
{
public:
/*
* Cuts the passed image in a grid of sub images.
*/
- Spriteset(const std::string &idPath, Image *img, int w, int h);
+ ImageSet(const std::string &idPath, Image *img, int w, int h);
/**
* Destructor.
*/
- ~Spriteset();
+ ~ImageSet();
int getWidth() { return mWidth; };
@@ -56,14 +54,13 @@ class Spriteset : public Resource
typedef std::vector<Image*>::size_type size_type;
Image* get(size_type i);
- size_type size() { return mSpriteset.size(); }
+ size_type size() { return mImages.size(); }
private:
- // Vector storing the whole spriteset.
- std::vector<Image*> mSpriteset;
- // Height and width of the images in the spriteset
- int mHeight;
- int mWidth;
+ std::vector<Image*> mImages;
+
+ int mHeight; /**< Height of the images in the image set. */
+ int mWidth; /**< Width of the images in the image set. */
};
#endif
diff --git a/src/resources/monsterdb.h b/src/resources/monsterdb.h
index 048638c2..46a33b06 100644
--- a/src/resources/monsterdb.h
+++ b/src/resources/monsterdb.h
@@ -39,7 +39,7 @@ namespace MonsterDB
void
unload();
- const MonsterInfo& get (int id);
+ const MonsterInfo& get(int id);
typedef std::map<int, MonsterInfo*> MonsterInfos;
typedef MonsterInfos::iterator MonsterInfoIterator;
diff --git a/src/resources/monsterinfo.h b/src/resources/monsterinfo.h
index 413dafa0..05d4c014 100644
--- a/src/resources/monsterinfo.h
+++ b/src/resources/monsterinfo.h
@@ -1,74 +1,83 @@
-/*
- * The Mana World
- * Copyright 2004 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * The Mana World is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: monsterinfo.h 2650 2006-09-03 15:00:47Z b_lindeijer $
- */
-
-#ifndef _TMW_MONSTERINFO_H_
-#define _TMW_MONSTERINFO_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-
-enum SoundEvent
-{
- EVENT_HIT,
- EVENT_MISS,
- EVENT_HURT,
- EVENT_DIE
-};
-
-
-class MonsterInfo
-{
- public:
- MonsterInfo();
-
- ~MonsterInfo();
-
- void
- setName(std::string name) { mName = name; } ;
-
- void
- setSprite(std::string filename) { mSprite = filename; }
-
- void
- addSound (SoundEvent event, std::string filename);
-
- const std::string&
- getName () const { return mName; };
-
- const std::string&
- getSprite () const { return mSprite; };
-
- std::string
- getSound (SoundEvent event) const;
-
- private:
-
- std::string mName;
- std::string mSprite;
-
- std::map<SoundEvent, std::vector<std::string>* > mSounds;
-};
-
-#endif
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id: monsterinfo.h 2650 2006-09-03 15:00:47Z b_lindeijer $
+ */
+
+#ifndef _TMW_MONSTERINFO_H_
+#define _TMW_MONSTERINFO_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+enum SoundEvent
+{
+ EVENT_HIT,
+ EVENT_MISS,
+ EVENT_HURT,
+ EVENT_DIE
+};
+
+/**
+ * Holds information about a certain type of monster. This includes the name
+ * of the monster, the sprite to display and the sounds the monster makes.
+ *
+ * @see MonsterDB
+ */
+class MonsterInfo
+{
+ public:
+ /**
+ * Constructor.
+ */
+ MonsterInfo();
+
+ /**
+ * Destructor.
+ */
+ ~MonsterInfo();
+
+ void
+ setName(std::string name) { mName = name; } ;
+
+ void
+ setSprite(std::string filename) { mSprite = filename; }
+
+ void
+ addSound (SoundEvent event, std::string filename);
+
+ const std::string&
+ getName () const { return mName; };
+
+ const std::string&
+ getSprite () const { return mSprite; };
+
+ std::string
+ getSound (SoundEvent event) const;
+
+ private:
+ std::string mName;
+ std::string mSprite;
+
+ std::map<SoundEvent, std::vector<std::string>* > mSounds;
+};
+
+#endif
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 2059a5c3..448e7f80 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -31,7 +31,7 @@
#include "image.h"
#include "music.h"
#include "soundeffect.h"
-#include "spriteset.h"
+#include "imageset.h"
#include "spritedef.h"
#include "../log.h"
@@ -46,7 +46,7 @@ ResourceManager::ResourceManager()
ResourceManager::~ResourceManager()
{
- // Release any remaining spritedefs first because they depend on spritesets
+ // Release any remaining spritedefs first because they depend on image sets
ResourceIterator iter = mResources.begin();
while (iter != mResources.end())
{
@@ -63,11 +63,11 @@ ResourceManager::~ResourceManager()
}
}
- // Release any remaining spritesets first because they depend on images
+ // Release any remaining image sets first because they depend on images
iter = mResources.begin();
while (iter != mResources.end())
{
- if (dynamic_cast<Spriteset*>(iter->second) != 0)
+ if (dynamic_cast<ImageSet*>(iter->second) != 0)
{
cleanUp(iter->second);
ResourceIterator toErase = iter;
@@ -232,8 +232,8 @@ ResourceManager::getSoundEffect(const std::string &idPath)
return dynamic_cast<SoundEffect*>(get(SOUND_EFFECT, idPath));
}
-Spriteset*
-ResourceManager::getSpriteset(const std::string &imagePath, int w, int h)
+ImageSet*
+ResourceManager::getImageSet(const std::string &imagePath, int w, int h)
{
std::stringstream ss;
ss << imagePath << "[" << w << "x" << h << "]";
@@ -243,7 +243,7 @@ ResourceManager::getSpriteset(const std::string &imagePath, int w, int h)
if (resIter != mResources.end()) {
resIter->second->incRef();
- return dynamic_cast<Spriteset*>(resIter->second);
+ return dynamic_cast<ImageSet*>(resIter->second);
}
Image *img = getImage(imagePath);
@@ -252,13 +252,13 @@ ResourceManager::getSpriteset(const std::string &imagePath, int w, int h)
return NULL;
}
- Spriteset *spriteset = new Spriteset(idPath, img, w, h);
- spriteset->incRef();
- mResources[idPath] = spriteset;
+ ImageSet *imageSet = new ImageSet(idPath, img, w, h);
+ imageSet->incRef();
+ mResources[idPath] = imageSet;
img->decRef();
- return spriteset;
+ return imageSet;
}
SpriteDef*
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index e176e337..db29e6d3 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -33,7 +33,7 @@ class Resource;
class Image;
class Music;
class SoundEffect;
-class Spriteset;
+class ImageSet;
class SpriteDef;
/**
@@ -143,11 +143,11 @@ class ResourceManager
getSoundEffect(const std::string &idPath);
/**
- * Creates a spriteset based on the image referenced by the given
+ * Creates a image set based on the image referenced by the given
* path and the supplied sprite sizes
*/
- Spriteset*
- getSpriteset(const std::string &imagePath, int w, int h);
+ ImageSet*
+ getImageSet(const std::string &imagePath, int w, int h);
/**
* Creates a sprite definition based on a given path and the supplied
diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp
index feb6f8f8..d29bd847 100644
--- a/src/resources/spritedef.cpp
+++ b/src/resources/spritedef.cpp
@@ -28,7 +28,7 @@
#include "animation.h"
#include "action.h"
#include "resourcemanager.h"
-#include "spriteset.h"
+#include "imageset.h"
#include "image.h"
#include "../utils/xml.h"
@@ -135,30 +135,30 @@ SpriteDef::loadImageSet(xmlNodePtr node)
std::string imageSrc = XML::getProperty(node, "src", "");
ResourceManager *resman = ResourceManager::getInstance();
- Spriteset *spriteset = resman->getSpriteset(imageSrc, width, height);
+ ImageSet *imageSet = resman->getImageSet(imageSrc, width, height);
- if (!spriteset)
+ if (!imageSet)
{
logger->error("Couldn't load imageset!");
}
- mSpritesets[name] = spriteset;
+ mImageSets[name] = imageSet;
}
void
SpriteDef::loadAction(xmlNodePtr node, int variant_offset)
{
const std::string actionName = XML::getProperty(node, "name", "");
- const std::string imagesetName = XML::getProperty(node, "imageset", "");
+ const std::string imageSetName = XML::getProperty(node, "imageset", "");
- SpritesetIterator si = mSpritesets.find(imagesetName);
- if (si == mSpritesets.end())
+ ImageSetIterator si = mImageSets.find(imageSetName);
+ if (si == mImageSets.end())
{
logger->log("Warning: imageset \"%s\" not defined in %s",
- imagesetName.c_str(), getIdPath().c_str());
+ imageSetName.c_str(), getIdPath().c_str());
return;
}
- Spriteset *imageset = si->second;
+ ImageSet *imageSet = si->second;
SpriteAction actionType = makeSpriteAction(actionName);
if (actionType == ACTION_INVALID)
@@ -183,14 +183,14 @@ SpriteDef::loadAction(xmlNodePtr node, int variant_offset)
{
if (xmlStrEqual(animationNode->name, BAD_CAST "animation"))
{
- loadAnimation(animationNode, action, imageset, variant_offset);
+ loadAnimation(animationNode, action, imageSet, variant_offset);
}
}
}
void
SpriteDef::loadAnimation(xmlNodePtr animationNode,
- Action *action, Spriteset *imageset,
+ Action *action, ImageSet *imageSet,
int variant_offset)
{
std::string directionName =
@@ -215,8 +215,8 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
int delay = XML::getProperty(frameNode, "delay", 0);
int offsetX = XML::getProperty(frameNode, "offsetX", 0);
int offsetY = XML::getProperty(frameNode, "offsetY", 0);
- offsetY -= imageset->getHeight() - 32;
- offsetX -= imageset->getWidth() / 2 - 16;
+ offsetY -= imageSet->getHeight() - 32;
+ offsetX -= imageSet->getWidth() / 2 - 16;
if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
{
@@ -228,7 +228,7 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
continue;
}
- Image *img = imageset->get(index + variant_offset);
+ Image *img = imageSet->get(index + variant_offset);
if (!img)
{
@@ -251,7 +251,7 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
while (end >= start)
{
- Image *img = imageset->get(start + variant_offset);
+ Image *img = imageSet->get(start + variant_offset);
if (!img)
{
@@ -296,8 +296,8 @@ SpriteDef::substituteAction(SpriteAction complete, SpriteAction with)
SpriteDef::~SpriteDef()
{
- for (SpritesetIterator i = mSpritesets.begin();
- i != mSpritesets.end(); ++i)
+ for (ImageSetIterator i = mImageSets.begin();
+ i != mImageSets.end(); ++i)
{
i->second->decRef();
}
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
index 057129ad..6d335b02 100644
--- a/src/resources/spritedef.h
+++ b/src/resources/spritedef.h
@@ -32,7 +32,7 @@
#include <libxml/tree.h>
class Action;
-class Spriteset;
+class ImageSet;
enum SpriteAction
{
@@ -111,7 +111,7 @@ class SpriteDef : public Resource
*/
void
loadAnimation(xmlNodePtr animationNode,
- Action *action, Spriteset *imageset,
+ Action *action, ImageSet *imageSet,
int variant_offset);
/**
@@ -140,12 +140,12 @@ class SpriteDef : public Resource
makeSpriteDirection(const std::string &direction);
- typedef std::map<std::string, Spriteset*> Spritesets;
- typedef Spritesets::iterator SpritesetIterator;
+ typedef std::map<std::string, ImageSet*> ImageSets;
+ typedef ImageSets::iterator ImageSetIterator;
typedef std::map<SpriteAction, Action*> Actions;
- Spritesets mSpritesets;
+ ImageSets mImageSets;
Actions mActions;
Action *mAction;
SpriteDirection mDirection;
diff --git a/src/simpleanimation.cpp b/src/simpleanimation.cpp
new file mode 100644
index 00000000..5fc35bcd
--- /dev/null
+++ b/src/simpleanimation.cpp
@@ -0,0 +1,50 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#include "simpleanimation.h"
+
+
+void SimpleAnimation::update(unsigned int timePassed)
+{
+ mAnimationTime += timePassed;
+ while (mAnimationTime > mCurrentFrame->delay)
+ {
+ mAnimationTime -= mCurrentFrame->delay;
+ mAnimationPhase++;
+ if (mAnimationPhase >= mAnimation->getLength())
+ {
+ mAnimationPhase = 0;
+ }
+ mCurrentFrame = mAnimation->getFrame(mAnimationPhase);
+ }
+}
+
+Image *SimpleAnimation::getCurrentImage() const
+{
+ return mCurrentFrame->image;
+}
+
+SimpleAnimation::~SimpleAnimation()
+{
+ delete mAnimation;
+}
diff --git a/src/simpleanimation.h b/src/simpleanimation.h
new file mode 100644
index 00000000..a56c31da
--- /dev/null
+++ b/src/simpleanimation.h
@@ -0,0 +1,65 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#ifndef _TMW_SIMPLEANIMAION_H
+#define _TMW_SIMPLEANIMAION_H
+
+#include "resources/animation.h"
+
+class Frame;
+
+/**
+ * This class is a leightweight alternative to the AnimatedSprite class.
+ * It hosts a looping animation without actions and directions.
+ */
+class SimpleAnimation
+{
+ public:
+ SimpleAnimation(Animation *animation):
+ mAnimation(animation),
+ mAnimationTime(0),
+ mAnimationPhase(0),
+ mCurrentFrame(mAnimation->getFrame(0))
+ {};
+
+ ~SimpleAnimation();
+
+ void update(unsigned int timePassed);
+
+ Image *getCurrentImage() const;
+
+ private:
+ /** The hosted animation. */
+ Animation *mAnimation;
+
+ /** Time in game ticks the current frame is shown. */
+ unsigned int mAnimationTime;
+
+ /** Index of current animation frame. */
+ unsigned int mAnimationPhase;
+
+ /** Current animation frame. */
+ Frame *mCurrentFrame;
+};
+
+#endif
diff --git a/src/tileset.h b/src/tileset.h
index 27bc28c3..7521a3e5 100644
--- a/src/tileset.h
+++ b/src/tileset.h
@@ -24,19 +24,19 @@
#ifndef _TMW_TILESET_H_
#define _TMW_TILESET_H_
-#include "resources/spriteset.h"
+#include "resources/imageset.h"
/**
- * A tileset, which is basically just a spriteset but it stores a firstgid.
+ * A tileset, which is basically just an image set but it stores a firstgid.
*/
-class Tileset : public Spriteset
+class Tileset : public ImageSet
{
public:
/**
* Constructor.
*/
Tileset(Image *img, int w, int h, int firstGid):
- Spriteset("", img, w, h),
+ ImageSet("", img, w, h),
mFirstGid(firstGid)
{
}
diff --git a/src/tmw.rc b/src/tmw.rc
index ee5f99cd..673b2387 100644
--- a/src/tmw.rc
+++ b/src/tmw.rc
@@ -2,7 +2,7 @@
#include "winver.h"
-A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "data/icons/tmw-icon.ico"
+A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "data/icons/tmw.ico"
1 VERSIONINFO
FILEVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD