summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2009-01-05 00:39:57 +0100
committerBjørn Lindeijer <bjorn@lindeijer.nl>2009-01-05 00:40:42 +0100
commit550a02997572b5d090b436b7c05d19c1823556a9 (patch)
tree65b6bf872711d67d1ed2b7e530bd47cb88a155af /src
parent8b6bfeb0a70d4f97cc2d20ce04fc240b65082cf1 (diff)
parent91387e410c9f9ea16c5b41bd1cc576cbd85cf835 (diff)
downloadmana-550a02997572b5d090b436b7c05d19c1823556a9.tar.gz
mana-550a02997572b5d090b436b7c05d19c1823556a9.tar.bz2
mana-550a02997572b5d090b436b7c05d19c1823556a9.tar.xz
mana-550a02997572b5d090b436b7c05d19c1823556a9.zip
Merged with 'master'
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/Makefile.am5
-rw-r--r--src/animatedsprite.cpp31
-rw-r--r--src/animatedsprite.h27
-rw-r--r--src/being.cpp204
-rw-r--r--src/being.h112
-rw-r--r--src/channelmanager.cpp45
-rw-r--r--src/channelmanager.h7
-rw-r--r--src/engine.cpp18
-rw-r--r--src/engine.h5
-rw-r--r--src/game.cpp158
-rw-r--r--src/gui/buy.cpp3
-rw-r--r--src/gui/char_select.cpp7
-rw-r--r--src/gui/chargedialog.cpp57
-rw-r--r--src/gui/chargedialog.h48
-rw-r--r--src/gui/chat.cpp56
-rw-r--r--src/gui/chat.h31
-rw-r--r--src/gui/debugwindow.cpp3
-rw-r--r--src/gui/equipmentwindow.cpp4
-rw-r--r--src/gui/gui.cpp47
-rw-r--r--src/gui/gui.h11
-rw-r--r--src/gui/guildwindow.cpp3
-rw-r--r--src/gui/help.cpp1
-rw-r--r--src/gui/inventorywindow.cpp5
-rw-r--r--src/gui/itemcontainer.cpp12
-rw-r--r--src/gui/itemshortcutcontainer.cpp6
-rw-r--r--src/gui/itemshortcutwindow.cpp5
-rw-r--r--src/gui/login.cpp7
-rw-r--r--src/gui/magic.cpp5
-rw-r--r--src/gui/minimap.cpp46
-rw-r--r--src/gui/ministatus.cpp3
-rw-r--r--src/gui/newskill.cpp193
-rw-r--r--src/gui/newskill.h69
-rw-r--r--src/gui/npc_text.cpp42
-rw-r--r--src/gui/npc_text.h22
-rw-r--r--src/gui/npclistdialog.cpp43
-rw-r--r--src/gui/npclistdialog.h26
-rw-r--r--src/gui/partywindow.cpp3
-rw-r--r--src/gui/sell.cpp3
-rw-r--r--src/gui/setup.cpp2
-rw-r--r--src/gui/setup_video.cpp29
-rw-r--r--src/gui/skill.cpp5
-rw-r--r--src/gui/status.cpp5
-rw-r--r--src/gui/trade.cpp3
-rw-r--r--src/gui/updatewindow.cpp47
-rw-r--r--src/gui/updatewindow.h13
-rw-r--r--src/gui/viewport.cpp4
-rw-r--r--src/gui/widgets/avatar.cpp16
-rw-r--r--src/gui/widgets/avatar.h8
-rw-r--r--src/gui/window.cpp18
-rw-r--r--src/gui/window.h17
-rw-r--r--src/imageparticle.h3
-rw-r--r--src/itemshortcut.cpp25
-rw-r--r--src/joystick.cpp42
-rw-r--r--src/joystick.h35
-rw-r--r--src/keyboardconfig.cpp11
-rw-r--r--src/keyboardconfig.h9
-rw-r--r--src/localplayer.cpp7
-rw-r--r--src/localplayer.h3
-rw-r--r--src/main.cpp82
-rw-r--r--src/monster.cpp32
-rw-r--r--src/net/beinghandler.cpp4
-rw-r--r--src/net/playerhandler.cpp18
-rw-r--r--src/particle.cpp75
-rw-r--r--src/particle.h89
-rw-r--r--src/player.cpp32
-rw-r--r--src/player.h34
-rw-r--r--src/properties.h15
-rw-r--r--src/resources/action.cpp11
-rw-r--r--src/resources/dye.cpp6
-rw-r--r--src/resources/dye.h6
-rw-r--r--src/resources/imageloader.cpp2
-rw-r--r--src/resources/imageloader.h3
-rw-r--r--src/resources/itemdb.cpp6
-rw-r--r--src/resources/mapreader.cpp37
-rw-r--r--src/resources/mapreader.h19
-rw-r--r--src/resources/monsterdb.cpp15
-rw-r--r--src/resources/monsterinfo.cpp3
-rw-r--r--src/resources/monsterinfo.h9
-rw-r--r--src/resources/resourcemanager.cpp65
-rw-r--r--src/resources/resourcemanager.h63
-rw-r--r--src/resources/spritedef.cpp31
-rw-r--r--src/resources/spritedef.h23
-rw-r--r--src/textparticle.h4
-rw-r--r--src/utils/mutex.h97
-rw-r--r--src/utils/strprintf.cpp6
86 files changed, 1245 insertions, 1221 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 43988ea6..60eaff74 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -77,8 +77,6 @@ SET(SRCS
gui/changeemaildialog.h
gui/changepassworddialog.cpp
gui/changepassworddialog.h
- gui/chargedialog.cpp
- gui/chargedialog.h
gui/char_select.cpp
gui/char_select.h
gui/chat.cpp
@@ -138,8 +136,6 @@ SET(SRCS
gui/minimap.h
gui/ministatus.cpp
gui/ministatus.h
- gui/newskill.cpp
- gui/newskill.h
gui/npclistdialog.cpp
gui/npclistdialog.h
gui/npcpostdialog.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index e953507a..6acf9d18 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,8 +29,6 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/changeemaildialog.h \
gui/changepassworddialog.cpp \
gui/changepassworddialog.h \
- gui/chargedialog.cpp \
- gui/chargedialog.h \
gui/char_select.cpp \
gui/char_select.h \
gui/chat.cpp \
@@ -90,8 +88,6 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/minimap.h \
gui/ministatus.cpp \
gui/ministatus.h \
- gui/newskill.cpp \
- gui/newskill.h \
gui/npclistdialog.cpp \
gui/npclistdialog.h \
gui/npcpostdialog.cpp \
@@ -282,6 +278,7 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
utils/strprintf.cpp \
utils/tostring.h \
utils/trim.h \
+ utils/mutex.h \
utils/xml.cpp \
utils/xml.h \
animatedsprite.cpp \
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
index b2bb1f28..203a82af 100644
--- a/src/animatedsprite.cpp
+++ b/src/animatedsprite.cpp
@@ -56,7 +56,8 @@ AnimatedSprite *AnimatedSprite::load(const std::string& filename, int variant)
{
ResourceManager *resman = ResourceManager::getInstance();
SpriteDef *s = resman->getSprite(filename, variant);
- if (!s) return NULL;
+ if (!s)
+ return NULL;
AnimatedSprite *as = new AnimatedSprite(s);
s->decRef();
return as;
@@ -67,22 +68,18 @@ AnimatedSprite::~AnimatedSprite()
mSprite->decRef();
}
-void
-AnimatedSprite::reset()
+void AnimatedSprite::reset()
{
mFrameIndex = 0;
mFrameTime = 0;
mLastTime = 0;
}
-void
-AnimatedSprite::play(SpriteAction spriteAction)
+void AnimatedSprite::play(SpriteAction spriteAction)
{
Action *action = mSprite->getAction(spriteAction);
if (!action)
- {
return;
- }
mAction = action;
Animation *animation = mAction->getAnimation(mDirection);
@@ -96,20 +93,15 @@ AnimatedSprite::play(SpriteAction spriteAction)
}
}
-void
-AnimatedSprite::update(int time)
+void AnimatedSprite::update(int time)
{
// Avoid freaking out at first frame or when tick_time overflows
if (time < mLastTime || mLastTime == 0)
- {
mLastTime = time;
- }
// If not enough time has passed yet, do nothing
if (time <= mLastTime || !mAnimation)
- {
return;
- }
unsigned int dt = time - mLastTime;
mLastTime = time;
@@ -121,13 +113,10 @@ AnimatedSprite::update(int time)
}
}
-bool
-AnimatedSprite::updateCurrentAnimation(unsigned int time)
+bool AnimatedSprite::updateCurrentAnimation(unsigned int time)
{
if (!mFrame || Animation::isTerminator(*mFrame))
- {
return false;
- }
mFrameTime += time;
@@ -137,9 +126,7 @@ AnimatedSprite::updateCurrentAnimation(unsigned int time)
mFrameIndex++;
if (mFrameIndex == mAnimation->getLength())
- {
mFrameIndex = 0;
- }
mFrame = mAnimation->getFrame(mFrameIndex);
@@ -154,8 +141,7 @@ AnimatedSprite::updateCurrentAnimation(unsigned int time)
return true;
}
-bool
-AnimatedSprite::draw(Graphics* graphics, int posX, int posY) const
+bool AnimatedSprite::draw(Graphics* graphics, int posX, int posY) const
{
if (!mFrame || !mFrame->image)
return false;
@@ -165,8 +151,7 @@ AnimatedSprite::draw(Graphics* graphics, int posX, int posY) const
posY + mFrame->offsetY);
}
-void
-AnimatedSprite::setDirection(SpriteDirection direction)
+void AnimatedSprite::setDirection(SpriteDirection direction)
{
if (mDirection != direction)
{
diff --git a/src/animatedsprite.h b/src/animatedsprite.h
index 405bf42e..41857d8f 100644
--- a/src/animatedsprite.h
+++ b/src/animatedsprite.h
@@ -50,7 +50,8 @@ class AnimatedSprite
* @param filename the file of the sprite to animate
* @param variant the sprite variant
*/
- static AnimatedSprite *load(std::string const &filename, int variant = 0);
+ static AnimatedSprite *load(const std::string &filename,
+ int variant = 0);
/**
* Destructor.
@@ -60,50 +61,42 @@ class AnimatedSprite
/**
* Resets the animated sprite.
*/
- void
- reset();
+ void reset();
/**
* Plays an action using the current direction
*/
- void
- play(SpriteAction action);
+ void play(SpriteAction action);
/**
* Inform the animation of the passed time so that it can output the
* correct animation frame.
*/
- void
- update(int time);
+ void update(int time);
/**
* Draw the current animation frame at the coordinates given in screen
* pixels.
*/
- bool
- draw(Graphics* graphics, int posX, int posY) const;
+ bool draw(Graphics* graphics, int posX, int posY) const;
/**
* gets the width in pixels of the image of the current frame
*/
- int
- getWidth() const;
+ int getWidth() const;
/**
* gets the height in pixels of the image of the current frame
*/
- int
- getHeight() const;
+ int getHeight() const;
/**
* Sets the direction.
*/
- void
- setDirection(SpriteDirection direction);
+ void setDirection(SpriteDirection direction);
private:
- bool
- updateCurrentAnimation(unsigned int dt);
+ bool updateCurrentAnimation(unsigned int dt);
SpriteDirection mDirection; /**< The sprite direction. */
int mLastTime; /**< The last time update was called. */
diff --git a/src/being.cpp b/src/being.cpp
index a267d033..d32ffa59 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -18,6 +18,7 @@
* along with The Mana World; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#include "being.h"
#include <cassert>
@@ -30,7 +31,10 @@
#include "log.h"
#include "map.h"
#include "particle.h"
+#include "sound.h"
+#include "localplayer.h"
+#include "resources/itemdb.h"
#include "resources/resourcemanager.h"
#include "resources/imageset.h"
#include "resources/iteminfo.h"
@@ -40,11 +44,18 @@
#include "utils/dtor.h"
#include "utils/tostring.h"
+#include "utils/xml.h"
namespace {
const bool debug_movement = true;
}
+#define HAIR_FILE "hair.xml"
+
+#include "utils/xml.h"
+
+#define BEING_EFFECTS_FILE "effects.xml"
+
int Being::instances = 0;
ImageSet *Being::emotionSet = NULL;
@@ -57,6 +68,9 @@ Being::Being(int id, int job, Map *map):
mSpriteDirection(DIRECTION_DOWN), mDirection(DOWN),
mMap(NULL),
mEquippedWeapon(NULL),
+ mHairStyle(0),
+ mHairColor(0),
+ mGender(GENDER_UNSPECIFIED),
mSpeechTime(0),
mSprites(VECTOREND_SPRITE, NULL),
mSpriteIDs(VECTOREND_SPRITE, 0),
@@ -108,6 +122,7 @@ void Being::setPosition(const Vector &pos)
{
mPos = pos;
mDest = pos;
+ mPath.clear();
}
void Being::adjustCourse(int srcX, int srcY, int dstX, int dstY)
@@ -286,6 +301,12 @@ void Being::setPath(const Path &path)
mPath = path;
}
+void Being::setHairStyle(int style, int color)
+{
+ mHairStyle = style < 0 ? mHairStyle : style % getHairStylesNr();
+ mHairColor = color < 0 ? mHairColor : color % getHairColorsNr();
+}
+
void Being::setSprite(int slot, int id, const std::string &color)
{
assert(slot >= BASE_SPRITE && slot < VECTOREND_SPRITE);
@@ -512,7 +533,7 @@ void Being::logic()
i != mChildParticleEffects.end();)
{
(*i)->setPosition(mPos.x, mPos.y);
- if (!(*i)->isAlive())
+ if ((*i)->isExtinct())
{
(*i)->kill();
i = mChildParticleEffects.erase(i);
@@ -596,3 +617,184 @@ int Being::getHeight() const
return 0;
}
}
+
+
+
+
+static int hairStylesNr;
+static int hairColorsNr;
+static std::vector<std::string> hairColors;
+
+static void
+initializeHair(void);
+
+int
+Being::getHairStylesNr(void)
+{
+ initializeHair();
+ return hairStylesNr;
+}
+
+int
+Being::getHairColorsNr(void)
+{
+ initializeHair();
+ return hairColorsNr;
+}
+
+std::string
+Being::getHairColor(int index)
+{
+ initializeHair();
+ if (index < 0 || index >= hairColorsNr)
+ return "#000000";
+
+ return hairColors[index];
+}
+
+static bool hairInitialized = false;
+
+static void
+initializeHair(void)
+{
+ if (hairInitialized)
+ return;
+
+ // Hairstyles are encoded as negative numbers. Count how far negative we can go.
+ int hairstylesCtr = -1;
+ while (ItemDB::get(hairstylesCtr).getSprite(GENDER_MALE) != "error.xml")
+ --hairstylesCtr;
+
+ hairStylesNr = -hairstylesCtr; // done.
+ if (hairStylesNr == 0)
+ hairStylesNr = 1; // No hair style -> no hair
+
+ hairColorsNr = 0;
+
+ XML::Document doc(HAIR_FILE);
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "colors"))
+ {
+ logger->log("Error loading being hair configuration file");
+ } else {
+ for_each_xml_child_node(node, root)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "color"))
+ {
+ int index = atoi(XML::getProperty(node, "id", "-1").c_str());
+ std::string value = XML::getProperty(node, "value", "");
+
+ if (index >= 0 && value != "") {
+ if (index >= hairColorsNr) {
+ hairColorsNr = index + 1;
+ hairColors.resize(hairColorsNr, "#000000");
+ }
+ hairColors[index] = value;
+ }
+ }
+ }
+ } // done initializing
+
+ if (hairColorsNr == 0) { // No colours -> black only
+ hairColorsNr = 1;
+ hairColors.resize(hairColorsNr, "#000000");
+ }
+
+ hairInitialized = 1;
+}
+
+
+
+struct EffectDescription {
+ std::string mGFXEffect;
+ std::string mSFXEffect;
+};
+
+static EffectDescription *default_effect = NULL;
+static std::map<int, EffectDescription *> effects;
+static bool effects_initialized = false;
+
+static EffectDescription *
+getEffectDescription(xmlNodePtr node, int *id)
+{
+ EffectDescription *ed = new EffectDescription;
+
+ *id = atoi(XML::getProperty(node, "id", "-1").c_str());
+ ed->mSFXEffect = XML::getProperty(node, "audio", "");
+ ed->mGFXEffect = XML::getProperty(node, "particle", "");
+
+ return ed;
+}
+
+static EffectDescription *
+getEffectDescription(int effectId)
+{
+ if (!effects_initialized)
+ {
+ XML::Document doc(BEING_EFFECTS_FILE);
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "being-effects"))
+ {
+ logger->log("Error loading being effects file: "
+ BEING_EFFECTS_FILE);
+ return NULL;
+ }
+
+ for_each_xml_child_node(node, root)
+ {
+ int id;
+
+ if (xmlStrEqual(node->name, BAD_CAST "effect"))
+ {
+ EffectDescription *EffectDescription =
+ getEffectDescription(node, &id);
+ effects[id] = EffectDescription;
+ } else if (xmlStrEqual(node->name, BAD_CAST "default"))
+ {
+ EffectDescription *EffectDescription =
+ getEffectDescription(node, &id);
+
+ if (default_effect)
+ delete default_effect;
+
+ default_effect = EffectDescription;
+ }
+ }
+
+ effects_initialized = true;
+ } // done initializing
+
+ EffectDescription *ed = effects[effectId];
+
+ if (!ed)
+ return default_effect;
+ else
+ return ed;
+}
+
+void
+Being::internalTriggerEffect(int effectId, bool sfx, bool gfx)
+{
+ logger->log("Special effect #%d on %s", effectId,
+ getId() == player_node->getId() ? "self" : "other");
+
+ EffectDescription *ed = getEffectDescription(effectId);
+
+ if (!ed) {
+ logger->log("Unknown special effect and no default recorded");
+ return;
+ }
+
+ if (gfx && ed->mGFXEffect != "") {
+ Particle *selfFX;
+
+ selfFX = particleEngine->addEffect(ed->mGFXEffect, 0, 0);
+ controlParticle(selfFX);
+ }
+
+ if (sfx && ed->mSFXEffect != "") {
+ sound.playSfx(ed->mSFXEffect);
+ }
+}
diff --git a/src/being.h b/src/being.h
index bf11e3ed..aeb03564 100644
--- a/src/being.h
+++ b/src/being.h
@@ -33,9 +33,6 @@
#include "animatedsprite.h"
#include "vector.h"
-#define NR_HAIR_STYLES 8
-#define NR_HAIR_COLORS 10
-
class AnimatedSprite;
class Equipment;
class ItemInfo;
@@ -46,6 +43,12 @@ class ImageSet;
class Particle;
class SpeechBubble;
+enum Gender {
+ GENDER_MALE = 0,
+ GENDER_FEMALE = 1,
+ GENDER_UNSPECIFIED = 2
+};
+
class Being : public Sprite
{
public:
@@ -127,14 +130,14 @@ class Being : public Sprite
const Vector &getDestination() const { return mDest; }
/**
- * Adjusts course to expected stat point.
+ * Adjusts course to expected start point.
*/
- void adjustCourse(int, int);
+ void adjustCourse(int srcX, int srcY);
/**
* Adjusts course to expected start and end points.
*/
- void adjustCourse(int, int, int, int);
+ void adjustCourse(int srcX, int srcY, int destX, int destY);
/**
* Puts a "speech balloon" above this being for the specified amount
@@ -150,58 +153,78 @@ class Being : public Sprite
*
* @param amount The amount of damage.
*/
- virtual void
- takeDamage(int amount);
+ virtual void takeDamage(int amount);
/**
* Handles an attack of another being by this being.
*/
- virtual void
- handleAttack();
+ virtual void handleAttack();
/**
* Returns the name of the being.
*/
- const std::string&
- getName() const { return mName; }
+ const std::string &getName() const
+ { return mName; }
/**
* Sets the name for the being.
*
* @param name The name that should appear.
*/
- void
- setName(const std::string &name) { mName = name; }
+ void setName(const std::string &name) { mName = name; }
+
+ /**
+ * Sets the gender for this being.
+ */
+ virtual void setGender(Gender gender) { mGender = gender; }
+
+ /**
+ * Gets the hair color for this being.
+ */
+ int getHairColor() const
+ { return mHairColor; }
+
+ /**
+ * Gets the hair style for this being.
+ */
+ int getHairStyle() const
+ { return mHairStyle; }
+
+ /**
+ * Sets the hair style and color for this being.
+ *
+ * NOTE: This method was necessary for convenience in the 0.0 client.
+ * It should be removed here since the server can provide the hair ID
+ * and coloring the same way it does for other equipment pieces. Then
+ * Being::setSprite can be used instead.
+ */
+ virtual void setHairStyle(int style, int color);
/**
* Sets visible equipments for this being.
*/
- virtual void
- setSprite(int slot, int id, const std::string &color = "");
+ virtual void setSprite(int slot, int id,
+ const std::string &color = "");
/**
* Performs being logic.
*/
- virtual void
- logic();
+ virtual void logic();
/**
* Draws the speech text above the being.
*/
- void
- drawSpeech(Graphics* graphics, int offsetX, int offsetY);
+ void drawSpeech(Graphics* graphics, int offsetX, int offsetY);
/**
* Draws the emotion picture above the being.
*/
- void
- drawEmotion(Graphics *graphics, int offsetX, int offsetY);
+ void drawEmotion(Graphics *graphics, int offsetX, int offsetY);
/**
* Draws the name text below the being.
*/
- virtual void
- drawName(Graphics *, int, int) {};
+ virtual void drawName(Graphics *, int, int) {};
/**
* Returns the type of the being.
@@ -222,14 +245,12 @@ class Being : public Sprite
/**
* Gets the being id.
*/
- Uint16
- getId() const { return mId; }
+ Uint16 getId() const { return mId; }
/**
* Sets the sprite id.
*/
- void
- setId(Uint16 id) { mId = id; }
+ void setId(Uint16 id) { mId = id; }
/**
* Sets the map the being is on
@@ -239,8 +260,7 @@ class Being : public Sprite
/**
* Sets the current action.
*/
- virtual void
- setAction(Action action, int attackType = 0);
+ virtual void setAction(Action action, int attackType = 0);
/**
* Gets the current action.
@@ -278,7 +298,8 @@ class Being : public Sprite
int getPixelY() const { return (int) mPos.y; }
/**
- * Sets the position of this being.
+ * Sets the position of this being. When the being was walking, it also
+ * clears the destination and the path.
*/
void setPosition(const Vector &pos);
@@ -330,6 +351,22 @@ class Being : public Sprite
*/
const Path &getPath() const { return mPath; }
+ /**
+ * Triggers a visual effect, such as `level up'
+ *
+ * Only draws the visual effect, does not play sound effects
+ *
+ * \param effectId ID of the effect to trigger
+ */
+ virtual void
+ triggerEffect(int effectId) { internalTriggerEffect(effectId, false, true); }
+
+ static int getHairColorsNr(void);
+
+ static int getHairStylesNr(void);
+
+ static std::string getHairColor(int index);
+
protected:
/**
* Sets the new path for this being.
@@ -342,6 +379,16 @@ class Being : public Sprite
virtual Map::BlockType getBlockType() const
{ return Map::BLOCKTYPE_NONE; }
+ /**
+ * Trigger visual effect, with components
+ *
+ * \param effectId ID of the effect to trigger
+ * \param sfx Whether to trigger sound effects
+ * \param gfx Whether to trigger graphical effects
+ */
+ void
+ internalTriggerEffect(int effectId, bool sfx, bool gfx);
+
Uint16 mId; /**< Unique being id */
Uint8 mSpriteDirection; /**< Facing direction */
Uint8 mDirection; /**< Walking direction */
@@ -353,6 +400,9 @@ class Being : public Sprite
Path mPath;
std::string mSpeech;
+ int mHairStyle;
+ int mHairColor;
+ Gender mGender;
Uint32 mSpeechTime;
std::vector<AnimatedSprite*> mSprites;
diff --git a/src/channelmanager.cpp b/src/channelmanager.cpp
index a332edbb..2a3f4eff 100644
--- a/src/channelmanager.cpp
+++ b/src/channelmanager.cpp
@@ -19,8 +19,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <list>
-
#include "channelmanager.h"
#include "channel.h"
@@ -28,7 +26,6 @@
ChannelManager::ChannelManager()
{
-
}
ChannelManager::~ChannelManager()
@@ -37,39 +34,43 @@ ChannelManager::~ChannelManager()
mChannels.clear();
}
-Channel* ChannelManager::findById(int id)
+Channel *ChannelManager::findById(int id) const
{
- Channel* channel;
- for(std::list<Channel*>::iterator itr = mChannels.begin();
- itr != mChannels.end();
- itr++)
+ Channel *channel = 0;
+ for (std::list<Channel*>::const_iterator itr = mChannels.begin(),
+ end = mChannels.end();
+ itr != end;
+ itr++)
{
- channel = (*itr);
- if(channel->getId() == id)
+ Channel *c = (*itr);
+ if (channel->getId() == id)
{
- return channel;
+ channel = c;
+ break;
}
}
- return NULL;
+ return channel;
}
-Channel *ChannelManager::findByName(std::string const &name)
+Channel *ChannelManager::findByName(const std::string &name) const
{
- Channel* channel;
- if(name != "")
+ Channel *channel = 0;
+ if (!name.empty())
{
- for(std::list<Channel*>::iterator itr = mChannels.begin();
- itr != mChannels.end();
- itr++)
+ for (std::list<Channel*>::const_iterator itr = mChannels.begin(),
+ end = mChannels.end();
+ itr != end;
+ itr++)
{
- channel = (*itr);
- if(channel->getName() == name)
+ Channel *c = (*itr);
+ if (c->getName() == name)
{
- return channel;
+ channel = c;
+ break;
}
}
}
- return NULL;
+ return channel;
}
void ChannelManager::addChannel(Channel *channel)
diff --git a/src/channelmanager.h b/src/channelmanager.h
index c19c548a..e42a5960 100644
--- a/src/channelmanager.h
+++ b/src/channelmanager.h
@@ -32,10 +32,13 @@ class ChannelManager
public:
ChannelManager();
~ChannelManager();
- Channel* findById(int id);
- Channel *findByName(std::string const &name);
+
+ Channel *findById(int id) const;
+ Channel *findByName(const std::string &name) const;
+
void addChannel(Channel *channel);
void removeChannel(Channel *channel);
+
private:
std::list<Channel*> mChannels;
};
diff --git a/src/engine.cpp b/src/engine.cpp
index ba5ce5e3..f191280e 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -89,17 +89,12 @@ void Engine::changeMap(const std::string &mapPath)
if (newMap->hasProperty("minimap"))
{
mapImage = resman->getImage(newMap->getProperty("minimap"));
-
- // Set the title for the Minimap
- if (newMap->hasProperty("mapname"))
- {
- minimap->setCaption(newMap->getProperty("mapname"));
- }
- else
- {
- minimap->setCaption("Unknown");
- logger->log("WARNING: Map file '%s' defines a minimap image but does not define a 'mapname' property", map_path.c_str());
- }
+ }
+ if (newMap->hasProperty("name"))
+ {
+ minimap->setCaption(newMap->getProperty("name"));
+ } else {
+ minimap->setCaption("Map");
}
minimap->setMapImage(mapImage);
beingManager->setMap(newMap);
@@ -124,6 +119,7 @@ void Engine::changeMap(const std::string &mapPath)
}
mCurrentMap = newMap;
+ mMapName = mapPath;
}
void Engine::logic()
diff --git a/src/engine.h b/src/engine.h
index dbee1258..f676a271 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -23,6 +23,7 @@
#define _ENGINE_H
#include <iosfwd>
+#include <string>
class Map;
@@ -48,6 +49,9 @@ class Engine
*/
Map *getCurrentMap() { return mCurrentMap; }
+ const std::string &getCurrentMapName() { return mMapName; }
+
+
/**
* Sets the currently active map.
*/
@@ -60,6 +64,7 @@ class Engine
private:
Map *mCurrentMap;
+ std::string mMapName;
};
extern Engine *engine;
diff --git a/src/game.cpp b/src/game.cpp
index 8ea0d420..942c517c 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -47,7 +47,6 @@
#include "gui/buddywindow.h"
#include "gui/buy.h"
#include "gui/buysell.h"
-//#include "gui/chargedialog.h"
#include "gui/chat.h"
#include "gui/confirm_dialog.h"
#include "gui/debugwindow.h"
@@ -120,11 +119,9 @@ NpcTextDialog *npcTextDialog;
NpcPostDialog *npcPostDialog;
SkillDialog *skillDialog;
MagicDialog *magicDialog;
-//NewSkillDialog *newSkillWindow;
Setup* setupWindow;
Minimap *minimap;
EquipmentWindow *equipmentWindow;
-//ChargeDialog *chargeDialog;
TradeWindow *tradeWindow;
BuddyWindow *buddyWindow;
GuildWindow *guildWindow;
@@ -208,11 +205,9 @@ void createGuiWindows()
npcPostDialog = new NpcPostDialog();
skillDialog = new SkillDialog();
magicDialog = new MagicDialog();
- //newSkillWindow = new NewSkillDialog();
setupWindow = new Setup();
minimap = new Minimap();
equipmentWindow = new EquipmentWindow(player_node->mEquipment.get());
- //chargeDialog = new ChargeDialog();
tradeWindow = new TradeWindow;
buddyWindow = new BuddyWindow();
guildWindow = new GuildWindow();
@@ -222,17 +217,21 @@ void createGuiWindows()
partyWindow = new PartyWindow();
// Initialize window positions
- //chargeDialog->setPosition(
- // graphics->getWidth() - 5 - chargeDialog->getWidth(),
- // graphics->getHeight() - chargeDialog->getHeight() - 15);
-
//buddyWindow->setPosition(10, minimap->getHeight() + 30);
// Set initial window visibility
- chatWindow->setVisible(true);
- miniStatusWindow->setVisible(true);
- menuWindow->setVisible(true);
- itemShortcutWindow->setVisible(true);
+ chatWindow->setVisible((bool) config.getValue(
+ chatWindow->getWindowName() + "Visible", true));
+ miniStatusWindow->setVisible((bool) config.getValue(
+ miniStatusWindow->getWindowName() + "Visible",
+ true));
+ buyDialog->setVisible(false);
+ sellDialog->setVisible(false);
+ tradeWindow->setVisible(false);
+ menuWindow->setVisible((bool) config.getValue(
+ menuWindow->getWindowName() + "Visible", true));
+ itemShortcutWindow->setVisible((bool) config.getValue(
+ itemShortcutWindow->getWindowName() + "Visible", true));
if (config.getValue("logToChat", 0))
{
@@ -261,8 +260,6 @@ void destroyGuiWindows()
delete setupWindow;
delete minimap;
delete equipmentWindow;
- //delete chargeDialog;
- //delete newSkillWindow;
delete tradeWindow;
delete buddyWindow;
delete guildWindow;
@@ -316,9 +313,7 @@ Game::Game():
// TODO: The user should be able to choose which one to use
// Open the first device
if (Joystick::getNumberOfJoysticks() > 0)
- {
joystick = new Joystick(0);
- }
Net::registerHandler(mBeingHandler.get());
Net::registerHandler(mBuySellHandler.get());
@@ -358,11 +353,14 @@ Game::~Game()
SDL_RemoveTimer(mSecondsCounterId);
}
-bool saveScreenshot(SDL_Surface *screenshot)
+static bool saveScreenshot()
{
static unsigned int screenshotCount = 0;
+ SDL_Surface *screenshot = graphics->getScreenshot();
+
// Search for an unused screenshot name
+ std::stringstream filenameSuffix;
std::stringstream filename;
std::fstream testExists;
bool found = false;
@@ -370,29 +368,37 @@ bool saveScreenshot(SDL_Surface *screenshot)
do {
screenshotCount++;
filename.str("");
+ filenameSuffix.str("");
+ filename << PHYSFS_getUserDir();
#if (defined __USE_UNIX98 || defined __FreeBSD__)
- filename << PHYSFS_getUserDir() << ".tmw/";
+ filenameSuffix << ".tmw/";
#elif defined __APPLE__
- filename << PHYSFS_getUserDir() << "Desktop/";
+ filenameSuffix << "Desktop/";
#endif
- filename << "TMW_Screenshot_" << screenshotCount << ".png";
+ filenameSuffix << "TMW_Screenshot_" << screenshotCount << ".png";
+ filename << filenameSuffix.str();
testExists.open(filename.str().c_str(), std::ios::in);
found = !testExists.is_open();
testExists.close();
} while (!found);
- if (ImageWriter::writePNG(screenshot, filename.str()))
+ const bool success = ImageWriter::writePNG(screenshot, filename.str());
+
+ if (success)
{
std::stringstream chatlogentry;
- chatlogentry << "Screenshot saved to " << filename.str().c_str();
+ chatlogentry << "Screenshot saved to ~/" << filenameSuffix.str();
chatWindow->chatLog(chatlogentry.str(), BY_SERVER);
- return true;
}
else
{
chatWindow->chatLog("Saving screenshot failed!", BY_SERVER);
- return false;
+ logger->log("Error: could not save screenshot.");
}
+
+ SDL_FreeSurface(screenshot);
+
+ return success;
}
void Game::optionChanged(const std::string &name)
@@ -462,9 +468,9 @@ void Game::logic()
{
if (!disconnectedDialog)
{
- disconnectedDialog = new
- OkDialog("Network Error",
- "The connection to the server was lost, the program will now quit");
+ disconnectedDialog = new OkDialog("Network Error",
+ "The connection to the server was lost, "
+ "the program will now quit");
disconnectedDialog->addActionListener(&exitListener);
disconnectedDialog->requestMoveToTop();
}
@@ -474,10 +480,8 @@ void Game::logic()
void Game::handleInput()
{
- if (joystick != NULL)
- {
+ if (joystick)
joystick->update();
- }
// Events
SDL_Event event;
@@ -530,17 +534,6 @@ void Game::handleInput()
used = true;
break;
- case SDLK_F2: requestedWindow = statusWindow; break;
- case SDLK_F3: requestedWindow = inventoryWindow; break;
- case SDLK_F4: requestedWindow = equipmentWindow; break;
- case SDLK_F5: requestedWindow = skillDialog; break;
- case SDLK_F6: requestedWindow = minimap; break;
- case SDLK_F7: requestedWindow = chatWindow; break;
- case SDLK_F8: requestedWindow = itemShortcutWindow; break;
- case SDLK_F9: requestedWindow = setupWindow; break;
- case SDLK_F10: requestedWindow = debugWindow; break;
- //case SDLK_F11: requestedWindow = newSkillWindow; break;
-
case SDLK_RETURN:
// Input chat window
if (chatWindow->isInputFocused() ||
@@ -564,10 +557,12 @@ void Game::handleInput()
{
setupWindow->action(gcn::ActionEvent(NULL, "cancel"));
}
-/* else if (guildWindow->isVisible())
+ /*
+ else if (guildWindow->isVisible())
{
// TODO: Check if a dialog is open and close it if so
- }*/
+ }
+ */
// Else, open the chat edit box
else
{
@@ -596,15 +591,19 @@ void Game::handleInput()
&& !guildWindow->isWindowFocused())
{
const int tKey = keyboard.getKeyIndex(event.key.keysym.sym);
- // Checks if any item shortcut is pressed.
- for (int i = KeyboardConfig::KEY_SHORTCUT_0;
- i <= KeyboardConfig::KEY_SHORTCUT_9;
- i++)
+ // Do not activate shortcuts if tradewindow is visible
+ if (!tradeWindow->isVisible())
{
- if (tKey == i) {
- itemShortcut->useItem(
- i - KeyboardConfig::KEY_SHORTCUT_0);
- break;
+ // Checks if any item shortcut is pressed.
+ for (int i = KeyboardConfig::KEY_SHORTCUT_0;
+ i <= KeyboardConfig::KEY_SHORTCUT_9;
+ i++)
+ {
+ if (tKey == i && !used) {
+ itemShortcut->useItem(
+ i - KeyboardConfig::KEY_SHORTCUT_0);
+ break;
+ }
}
}
switch (tKey) {
@@ -669,6 +668,34 @@ void Game::handleInput()
buddyWindow->setVisible(false);
}
break;
+
+ case KeyboardConfig::KEY_WINDOW_STATUS:
+ requestedWindow = statusWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_INVENTORY:
+ requestedWindow = inventoryWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_EQUIPMENT:
+ requestedWindow = equipmentWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SKILL:
+ requestedWindow = skillDialog;
+ break;
+ case KeyboardConfig::KEY_WINDOW_MINIMAP:
+ requestedWindow = minimap;
+ break;
+ case KeyboardConfig::KEY_WINDOW_CHAT:
+ requestedWindow = chatWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SHORTCUT:
+ requestedWindow = itemShortcutWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SETUP:
+ requestedWindow = setupWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_DEBUG:
+ requestedWindow = debugWindow;
+ break;
}
}
@@ -694,15 +721,7 @@ void Game::handleInput()
{
case SDLK_p:
// Screenshot (picture, hence the p)
- {
- SDL_Surface *screenshot = graphics->getScreenshot();
- if (!saveScreenshot(screenshot))
- {
- logger->log(
- "Error: could not save Screenshot.");
- }
- SDL_FreeSurface(screenshot);
- }
+ saveScreenshot();
used = true;
break;
@@ -775,11 +794,11 @@ void Game::handleInput()
}
} // End while
+
// If the user is configuring the keys then don't respond.
if (!keyboard.isEnabled())
- {
- return;
- }
+ return;
+
// Moving player around
if (player_node->mAction != Being::DEAD &&
!chatWindow->isInputFocused())
@@ -816,7 +835,8 @@ void Game::handleInput()
direction |= Being::RIGHT;
}
- // First if player is pressing key for the direction he is already going
+ // First if player is pressing key for the direction he is already
+ // going
if (direction == player_node->getWalkingDir())
{
player_node->setWalkingDir(direction);
@@ -838,8 +858,8 @@ void Game::handleInput()
// Target the nearest player if 'q' is pressed
if (keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER))
{
- Being *target =
- beingManager->findNearestLivingBeing(player_node, 20, Being::PLAYER);
+ Being *target = beingManager->findNearestLivingBeing(
+ player_node, 20, Being::PLAYER);
if (target)
{
@@ -850,8 +870,8 @@ void Game::handleInput()
// Target the nearest monster if 'a' pressed
if (keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST))
{
- Being *target =
- beingManager->findNearestLivingBeing(x, y, 20, Being::MONSTER);
+ Being *target = beingManager->findNearestLivingBeing(
+ x, y, 20, Being::MONSTER);
if (target)
{
diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp
index a948b136..008c7bb9 100644
--- a/src/gui/buy.cpp
+++ b/src/gui/buy.cpp
@@ -40,6 +40,7 @@ BuyDialog::BuyDialog():
Window(_("Buy")),
mMoney(0), mAmountItems(0), mMaxItems(0)
{
+ setWindowName("Buy");
setResizable(true);
setMinWidth(260);
setMinHeight(230);
@@ -85,7 +86,7 @@ BuyDialog::BuyDialog():
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
- loadWindowState("Buy");
+ loadWindowState();
setLocationRelativeTo(getParent());
}
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index 3adfbc08..67cb3c7b 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -266,7 +266,8 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot):
Window(_("Create Character"), true, parent), mSlot(slot)
{
mPlayer = new Player(0, 0, NULL);
- mPlayer->setHairStyle(rand() % NR_HAIR_STYLES, rand() % NR_HAIR_COLORS);
+ mPlayer->setHairStyle(rand() % Being::getHairStylesNr(),
+ rand() % Being::getHairColorsNr());
mPlayer->setGender(GENDER_MALE);
mNameField = new TextField("");
@@ -422,13 +423,13 @@ CharCreateDialog::action(const gcn::ActionEvent &event)
mPlayer->setHairStyle(-1, mPlayer->getHairColor() + 1);
}
else if (event.getId() == "prevcolor") {
- mPlayer->setHairStyle(-1, mPlayer->getHairColor() + NR_HAIR_COLORS - 1);
+ mPlayer->setHairStyle(-1, mPlayer->getHairColor() + Being::getHairColorsNr() - 1);
}
else if (event.getId() == "nextstyle") {
mPlayer->setHairStyle(mPlayer->getHairStyle() + 1, -1);
}
else if (event.getId() == "prevstyle") {
- mPlayer->setHairStyle(mPlayer->getHairStyle() + NR_HAIR_STYLES - 1, -1);
+ mPlayer->setHairStyle(mPlayer->getHairStyle() + Being::getHairStylesNr() - 1, -1);
}
else if (event.getId() == "statslider") {
UpdateSliders();
diff --git a/src/gui/chargedialog.cpp b/src/gui/chargedialog.cpp
deleted file mode 100644
index 1c9edf45..00000000
--- a/src/gui/chargedialog.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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
- */
-
- /* The window supported by this class shows player stats and keeps a charging
- * action bar in queue.
- */
-
-#include "chargedialog.h"
-
-#include "progressbar.h"
-
-#include "../localplayer.h"
-
-ChargeDialog::ChargeDialog():
- Window("")
-{
- setContentSize(180, 70);
- mProgBar = new ProgressBar(0.0f, 140, 25, 128, 128, 128);
- mProgBar->setPosition(20, 40);
- add(mProgBar);
- setVisible(true);
-}
-
-// update the dialog
-void ChargeDialog::logic()
-{
- // calculate time since the last attack was made
- player_node->mLastAttackTime += .01; // this a hack until someone explains
- // to me how to work the timer
- if (player_node->mLastAttackTime > 1)
- {
- player_node->mLastAttackTime = 1;
- }
-
- // reset the progress bar to display accurate time since attack
- mProgBar->setProgress(player_node->mLastAttackTime);
-
- Window::logic();
-}
diff --git a/src/gui/chargedialog.h b/src/gui/chargedialog.h
deleted file mode 100644
index 9517ef6a..00000000
--- a/src/gui/chargedialog.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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
- */
-
-#ifndef _TMW_CHARGE_H
-#define _TMW_CHARGE_H
-
-#include "window.h"
-
-class ProgressBar;
-
-#define CHARGE_TIME 1000 // time in milliseconds it takes to charge up an attack
-
-/**
- * \ingroup Interface
- */
-class ChargeDialog : public Window
-{
- public:
- /**
- * Constructor.
- */
- ChargeDialog();
-
- void logic();
-
- private:
- ProgressBar* mProgBar;
-};
-
-#endif
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index c94429c8..888dd27d 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -52,11 +52,12 @@ ChatWindow::ChatWindow():
Window("Chat"),
mTmpVisible(false)
{
+ setWindowName("Chat");
setResizable(true);
- setDefaultSize(0, (windowContainer->getHeight() - 105), 400, 100);
+ setDefaultSize(0, windowContainer->getHeight() - 123, 600, 123);
setOpaque(false);
- mChatInput = new ChatInput();
+ mChatInput = new ChatInput;
mChatInput->setActionEventId("chatinput");
mChatInput->addActionListener(this);
@@ -88,7 +89,7 @@ ChatWindow::ChatWindow():
mChatInput->addKeyListener(this);
mCurHist = mHistory.end();
- loadWindowState("Chat");
+ loadWindowState();
}
ChatWindow::~ChatWindow()
@@ -97,7 +98,7 @@ ChatWindow::~ChatWindow()
delete mChatTabs;
}
-const std::string& ChatWindow::getFocused() const
+const std::string &ChatWindow::getFocused() const
{
return mChatTabs->getSelectedTab()->getCaption();
}
@@ -151,8 +152,7 @@ void ChatWindow::logic()
}
}
-void
-ChatWindow::chatLog(std::string line, int own, std::string channelName)
+void ChatWindow::chatLog(std::string line, int own, std::string channelName)
{
if(channelName.empty())
channelName = getFocused();
@@ -240,8 +240,7 @@ ChatWindow::chatLog(std::string line, int own, std::string channelName)
scroll->logic();
}
-void
-ChatWindow::action(const gcn::ActionEvent &event)
+void ChatWindow::action(const gcn::ActionEvent &event)
{
if (event.getId() == "chatinput")
{
@@ -274,8 +273,7 @@ ChatWindow::action(const gcn::ActionEvent &event)
}
}
-void
-ChatWindow::requestChatFocus()
+void ChatWindow::requestChatFocus()
{
// Make sure chatWindow is visible
if (!isVisible())
@@ -295,13 +293,12 @@ ChatWindow::requestChatFocus()
mChatInput->requestFocus();
}
-bool
-ChatWindow::isInputFocused()
+bool ChatWindow::isInputFocused()
{
return mChatInput->isFocused();
}
-void ChatWindow::chatSend(std::string const &msg)
+void ChatWindow::chatSend(const std::string &msg)
{
if (msg.empty()) return;
@@ -327,20 +324,17 @@ void ChatWindow::chatSend(std::string const &msg)
}
}
-void
-ChatWindow::removeChannel(short channelId)
+void ChatWindow::removeChannel(short channelId)
{
removeChannel(channelManager->findById(channelId));
}
-void
-ChatWindow::removeChannel(const std::string &channelName)
+void ChatWindow::removeChannel(const std::string &channelName)
{
removeChannel(channelManager->findByName(channelName));
}
-void
-ChatWindow::removeChannel(Channel *channel)
+void ChatWindow::removeChannel(Channel *channel)
{
if (channel)
{
@@ -356,8 +350,7 @@ ChatWindow::removeChannel(Channel *channel)
}
}
-void
-ChatWindow::createNewChannelTab(const std::string &channelName)
+void ChatWindow::createNewChannelTab(const std::string &channelName)
{
// Create new channel
BrowserBox *textOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
@@ -384,8 +377,9 @@ ChatWindow::createNewChannelTab(const std::string &channelName)
logic();
}
-void
-ChatWindow::sendToChannel(short channelId, const std::string &user, const std::string &msg)
+void ChatWindow::sendToChannel(short channelId,
+ const std::string &user,
+ const std::string &msg)
{
Channel *channel = channelManager->findById(channelId);
if (channel)
@@ -395,8 +389,7 @@ ChatWindow::sendToChannel(short channelId, const std::string &user, const std::s
}
}
-void
-ChatWindow::keyPressed(gcn::KeyEvent &event)
+void ChatWindow::keyPressed(gcn::KeyEvent &event)
{
if (event.getKey().getValue() == Key::DOWN &&
mCurHist != mHistory.end())
@@ -421,15 +414,13 @@ ChatWindow::keyPressed(gcn::KeyEvent &event)
}
}
-void
-ChatWindow::setInputText(std::string input_str)
+void ChatWindow::setInputText(std::string input_str)
{
mChatInput->setText(input_str + " ");
requestChatFocus();
}
-void
-ChatWindow::setVisible(bool isVisible)
+void ChatWindow::setVisible(bool isVisible)
{
Window::setVisible(isVisible);
@@ -440,11 +431,8 @@ ChatWindow::setVisible(bool isVisible)
mTmpVisible = false;
}
-bool
-ChatWindow::tabExists(const std::string &tabName)
+bool ChatWindow::tabExists(const std::string &tabName)
{
Tab *tab = mChatTabs->getTab(tabName);
- if (tab)
- return true;
- return false;
+ return tab != 0;
}
diff --git a/src/gui/chat.h b/src/gui/chat.h
index a41b11fb..8ca0e4c9 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -118,41 +118,34 @@ class ChatWindow : public Window,
* @param msg The message text which is to be sent.
*
*/
- void chatSend(std::string const &msg);
+ void chatSend(const std::string &msg);
/** Called to remove the channel from the channel manager */
- void
- removeChannel(short channelId);
+ void removeChannel(short channelId);
- void
- removeChannel(const std::string &channelName);
+ void removeChannel(const std::string &channelName);
- void
- removeChannel(Channel *channel);
+ void removeChannel(Channel *channel);
/** Called to create a new channel tab */
- void
- createNewChannelTab(const std::string &channelName);
+ void createNewChannelTab(const std::string &channelName);
/** Called to output text to a specific channel */
- void
- sendToChannel(short channel, const std::string &user, const std::string &msg);
+ void sendToChannel(short channel,
+ const std::string &user,
+ const std::string &msg);
/** Called when key is pressed */
- void
- keyPressed(gcn::KeyEvent &event);
+ void keyPressed(gcn::KeyEvent &event);
/** Called to set current text */
- void
- setInputText(std::string input_str);
+ void setInputText(std::string input_str);
/** Override to reset mTmpVisible */
- void
- setVisible(bool visible);
+ void setVisible(bool visible);
/** Check if tab with that name already exists */
- bool
- tabExists(const std::string &tabName);
+ bool tabExists(const std::string &tabName);
void logic();
diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp
index d92c3575..36e4c8e1 100644
--- a/src/gui/debugwindow.cpp
+++ b/src/gui/debugwindow.cpp
@@ -39,10 +39,11 @@
DebugWindow::DebugWindow():
Window("Debug")
{
+ setWindowName("Debug");
setResizable(true);
setCloseButton(true);
setDefaultSize(0, 0, 400, 100);
- loadWindowState("Debug");
+ loadWindowState();
mFPSLabel = new gcn::Label("[0 FPS]");
mFPSLabel->setPosition(0,0);
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index aee262d0..6848b4d8 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -51,15 +51,15 @@ static const int boxPosition[][2] = {
};
EquipmentWindow::EquipmentWindow(Equipment *equipment):
-
Window(_("Equipment")),
mEquipment(equipment),
mBackground(NULL),
mSelected(-1)
{
+ setWindowName("Equipment");
setCloseButton(true);
setDefaultSize(5, 195, 216, 260);
- loadWindowState("Equipment");
+ loadWindowState();
mUnequip = new Button(_("Unequip"), "unequip", this);
gcn::Rectangle const &area = getChildrenArea();
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 930d4939..dc6306b4 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -37,6 +37,7 @@
#include "../graphics.h"
#include "../log.h"
+#include "../resources/image.h"
#include "../resources/imageset.h"
#include "../resources/resourcemanager.h"
#include "../resources/imageloader.h"
@@ -74,6 +75,8 @@ class GuiConfigListener : public ConfigListener
Gui::Gui(Graphics *graphics):
mCustomCursor(false),
mMouseCursors(NULL),
+ mMouseCursorAlpha(1.0f),
+ mMouseInactivityTimer(0),
mCursorType(CURSOR_POINTER)
{
logger->log("Initializing GUI...");
@@ -157,32 +160,47 @@ Gui::~Gui()
delete hitBlueFont;
delete hitYellowFont;
- if (mMouseCursors) {
+ if (mMouseCursors)
mMouseCursors->decRef();
- }
delete mGuiFont;
delete speechFont;
delete viewport;
- delete mTop;
+ delete getTop();
delete guiInput;
}
-void
-Gui::draw()
+void Gui::logic()
+{
+ // Fade out mouse cursor after extended inactivity
+ if (mMouseInactivityTimer < 100 * 15) {
+ ++mMouseInactivityTimer;
+ mMouseCursorAlpha = std::min(1.0f, mMouseCursorAlpha + 0.05f);
+ } else {
+ mMouseCursorAlpha = std::max(0.0f, mMouseCursorAlpha - 0.005f);
+ }
+
+ gcn::Gui::logic();
+}
+
+void Gui::draw()
{
- mGraphics->pushClipArea(mTop->getDimension());
- mTop->draw(mGraphics);
+ mGraphics->pushClipArea(getTop()->getDimension());
+ getTop()->draw(mGraphics);
int mouseX, mouseY;
Uint8 button = SDL_GetMouseState(&mouseX, &mouseY);
- if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS || button & SDL_BUTTON(1)) &&
- mCustomCursor)
+ if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS || button & SDL_BUTTON(1))
+ && mCustomCursor
+ && mMouseCursorAlpha > 0.0f)
{
+ Image *mouseCursor = mMouseCursors->get(mCursorType);
+ mouseCursor->setAlpha(mMouseCursorAlpha);
+
static_cast<Graphics*>(mGraphics)->drawImage(
- mMouseCursors->get(mCursorType),
+ mouseCursor,
mouseX - 15,
mouseY - 17);
}
@@ -190,8 +208,7 @@ Gui::draw()
mGraphics->popClipArea();
}
-void
-Gui::setUseCustomCursor(bool customCursor)
+void Gui::setUseCustomCursor(bool customCursor)
{
if (customCursor != mCustomCursor)
{
@@ -224,3 +241,9 @@ Gui::setUseCustomCursor(bool customCursor)
}
}
}
+
+void Gui::handleMouseMoved(const gcn::MouseInput &mouseInput)
+{
+ gcn::Gui::handleMouseMoved(mouseInput);
+ mMouseInactivityTimer = 0;
+}
diff --git a/src/gui/gui.h b/src/gui/gui.h
index a07d236f..7d390df9 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -59,6 +59,12 @@ class Gui : public gcn::Gui
~Gui();
/**
+ * Performs logic of the GUI. Overridden to track mouse pointer
+ * activity.
+ */
+ void logic();
+
+ /**
* Draws the whole Gui by calling draw functions down in the
* Gui hierarchy. It also draws the mouse pointer.
*/
@@ -95,11 +101,16 @@ class Gui : public gcn::Gui
CURSOR_TOTAL
};
+ protected:
+ void handleMouseMoved(const gcn::MouseInput &mouseInput);
+
private:
GuiConfigListener *mConfigListener;
gcn::Font *mGuiFont; /**< The global GUI font */
bool mCustomCursor; /**< Show custom cursor */
ImageSet *mMouseCursors; /**< Mouse cursor images */
+ float mMouseCursorAlpha;
+ int mMouseInactivityTimer;
int mCursorType;
};
diff --git a/src/gui/guildwindow.cpp b/src/gui/guildwindow.cpp
index ae9684df..0596c75e 100644
--- a/src/gui/guildwindow.cpp
+++ b/src/gui/guildwindow.cpp
@@ -49,6 +49,7 @@ GuildWindow::GuildWindow():
Window(_("Guild")),
mFocus(false)
{
+ setWindowName("Guild");
setCaption(_("Guild"));
setResizable(false);
setCloseButton(true);
@@ -73,7 +74,7 @@ GuildWindow::GuildWindow():
layout.setColWidth(0, 48);
layout.setColWidth(1, 65);
- loadWindowState("Guild");
+ loadWindowState();
}
GuildWindow::~GuildWindow()
diff --git a/src/gui/help.cpp b/src/gui/help.cpp
index ffe9c02d..290679b9 100644
--- a/src/gui/help.cpp
+++ b/src/gui/help.cpp
@@ -31,6 +31,7 @@ HelpWindow::HelpWindow():
Window("Help")
{
setContentSize(455, 350);
+ setWindowName("Help");
mBrowserBox = new BrowserBox();
mBrowserBox->setOpaque(false);
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index 0fda7945..1e3c4084 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -53,6 +53,7 @@ InventoryWindow::InventoryWindow():
Window(_("Inventory")),
mSplit(false)
{
+ setWindowName("Inventory");
setResizable(false);
setCloseButton(true);
// LEEOR/TODO: Since this window is not resizable, do we really need to set these
@@ -60,7 +61,7 @@ InventoryWindow::InventoryWindow():
setMinWidth(375);
setMinHeight(283);
// If you adjust these defaults, don't forget to adjust the trade window's.
- setDefaultSize(115, 25, 375, 283);
+ setDefaultSize(115, 30, 375, 283);
addKeyListener(this);
mUseButton = new Button(_("Use"), "use", this);
@@ -82,7 +83,7 @@ InventoryWindow::InventoryWindow():
layout.setColWidth(2, 48);
layout.setRowHeight(0, Layout::AUTO_SET);
- loadWindowState("Inventory");
+ loadWindowState();
}
void InventoryWindow::logic()
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp
index 5fb99ffc..141b4360 100644
--- a/src/gui/itemcontainer.cpp
+++ b/src/gui/itemcontainer.cpp
@@ -82,8 +82,7 @@ ItemContainer::~ItemContainer()
mSelImg->decRef();
}
-void
-ItemContainer::draw(gcn::Graphics *graphics)
+void ItemContainer::draw(gcn::Graphics *graphics)
{
Graphics *g = static_cast<Graphics*>(graphics);
@@ -147,8 +146,7 @@ ItemContainer::draw(gcn::Graphics *graphics)
}
}
-void
-ItemContainer::selectNone()
+void ItemContainer::selectNone()
{
setSelectedItem(NULL);
}
@@ -324,8 +322,7 @@ int ItemContainer::getSlotIndex(const int posX, const int posY) const
return Inventory::NO_SLOT_INDEX;
}
-void
-ItemContainer::keyAction()
+void ItemContainer::keyAction()
{
// If there is no highlight then return.
if (!mHighlightedItem)
@@ -362,8 +359,7 @@ ItemContainer::keyAction()
}
}
-void
-ItemContainer::moveHighlight(int direction)
+void ItemContainer::moveHighlight(int direction)
{
if (!mHighlightedItem)
{
diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp
index 76104e12..e0604c78 100644
--- a/src/gui/itemshortcutcontainer.cpp
+++ b/src/gui/itemshortcutcontainer.cpp
@@ -85,7 +85,7 @@ ItemShortcutContainer::draw(gcn::Graphics *graphics)
// Draw item keyboard shortcut.
const char *key = SDL_GetKeyName(
- (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_0+i));
+ (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_0 + i));
g->drawText(key, itemX + 2, itemY + 2, gcn::Graphics::LEFT);
if (itemShortcut->getItem(i) < 0)
@@ -96,9 +96,11 @@ ItemShortcutContainer::draw(gcn::Graphics *graphics)
// Draw item icon.
Image* image = item->getImage();
if (image) {
+ // TODO: Have label indicate equipped status
+ const std::string label = toString(item->getQuantity());
g->drawImage(image, itemX, itemY);
g->drawText(
- toString(item->getQuantity()),
+ label,
itemX + mBoxWidth / 2,
itemY + mBoxHeight - 14,
gcn::Graphics::CENTER);
diff --git a/src/gui/itemshortcutwindow.cpp b/src/gui/itemshortcutwindow.cpp
index e4d352fe..e21f421b 100644
--- a/src/gui/itemshortcutwindow.cpp
+++ b/src/gui/itemshortcutwindow.cpp
@@ -28,13 +28,14 @@ static const int SCROLL_PADDING = 0;
ItemShortcutWindow::ItemShortcutWindow()
{
+ setWindowName("ItemShortcut");
// no title presented, title bar is padding so window can be moved.
gcn::Window::setTitleBarHeight(gcn::Window::getPadding());
setShowTitle(false);
setResizable(true);
setDefaultSize(758, 174, 42, 426);
- mItems = new ItemShortcutContainer();
+ mItems = new ItemShortcutContainer;
const int border = SCROLL_PADDING * 2 + getPadding() * 2;
setMinWidth(mItems->getBoxWidth() + border);
@@ -49,7 +50,7 @@ ItemShortcutWindow::ItemShortcutWindow()
add(mScrollArea);
- loadWindowState("ItemShortcut");
+ loadWindowState();
}
ItemShortcutWindow::~ItemShortcutWindow()
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index 24c55e37..b4289984 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -71,12 +71,9 @@ LoginDialog::LoginDialog(LoginData *loginData) : Window(_("Login")), mLoginData(
setLocationRelativeTo(getParent());
setVisible(true);
- if (mUserField->getText().empty())
- {
+ if (mUserField->getText().empty()) {
mUserField->requestFocus();
- }
- else
- {
+ } else {
mPassField->requestFocus();
}
diff --git a/src/gui/magic.cpp b/src/gui/magic.cpp
index ca7b5489..2c81321b 100644
--- a/src/gui/magic.cpp
+++ b/src/gui/magic.cpp
@@ -35,8 +35,9 @@
MagicDialog::MagicDialog():
Window(_("Magic"))
{
+ setWindowName("Magic");
setCloseButton(true);
- setDefaultSize(255, 25, 175, 225);
+ setDefaultSize(255, 30, 175, 225);
gcn::Button *spellButton1 = new Button(_("Cast Test Spell 1"), "spell_1", this);
gcn::Button *spellButton2 = new Button(_("Cast Test Spell 2"), "spell_2", this);
@@ -53,7 +54,7 @@ MagicDialog::MagicDialog():
update();
setLocationRelativeTo(getParent());
- loadWindowState(_("Magic"));
+ loadWindowState();
}
MagicDialog::~MagicDialog()
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp
index 501530f1..f7749755 100644
--- a/src/gui/minimap.cpp
+++ b/src/gui/minimap.cpp
@@ -34,8 +34,9 @@ Minimap::Minimap():
Window(_("MiniMap")),
mMapImage(NULL)
{
- setDefaultSize(0, 0, 100, 100);
- loadWindowState("MiniMap");
+ setWindowName("MiniMap");
+ setDefaultSize(5, 25, 100, 100);
+ loadWindowState();
// LEEOR: The Window class needs to modified to accept
// setAlignment calls.
setAlignment(gcn::Graphics::CENTER);
@@ -44,49 +45,50 @@ Minimap::Minimap():
Minimap::~Minimap()
{
if (mMapImage)
- {
mMapImage->decRef();
- }
}
void Minimap::setMapImage(Image *img)
{
if (mMapImage)
- {
mMapImage->decRef();
- }
mMapImage = img;
- if (mMapImage)
- {
+ if (mMapImage) {
mMapImage->setAlpha(0.7);
- setSize( mMapImage->getWidth() + 6, mMapImage->getHeight() + 23 );
- setVisible(true);
+ setContentSize(mMapImage->getWidth(), mMapImage->getHeight());
}
- else
- {
- setVisible(false);
- }
-
}
void Minimap::draw(gcn::Graphics *graphics)
{
Window::draw(graphics);
+ const gcn::Rectangle a = getChildrenArea();
+
+ int mapOriginX = a.x;
+ int mapOriginY = a.y;
+
if (mMapImage)
{
- static_cast<Graphics*>(graphics)->drawImage(
- mMapImage, getPadding(), getTitleBarHeight());
+ if (mMapImage->getWidth() > a.width ||
+ mMapImage->getHeight() > a.height)
+ {
+ const Vector &pos = player_node->getPosition();
+ mapOriginX += (a.width - (int) (pos.x / 32)) / 2;
+ mapOriginY += (a.height - (int) (pos.y / 32)) / 2;
+ }
+ static_cast<Graphics*>(graphics)->
+ drawImage(mMapImage, mapOriginX, mapOriginY);
}
- Beings &beings = beingManager->getAll();
- BeingIterator bi;
+ const Beings &beings = beingManager->getAll();
+ Beings::const_iterator bi;
for (bi = beings.begin(); bi != beings.end(); bi++)
{
- Being *being = (*bi);
+ const Being *being = (*bi);
int dotSize = 2;
switch (being->getType()) {
@@ -116,8 +118,8 @@ void Minimap::draw(gcn::Graphics *graphics)
const Vector &pos = being->getPosition();
graphics->fillRectangle(gcn::Rectangle(
- (int) pos.x / 64 + getPadding() - offset,
- (int) pos.y / 64 + getTitleBarHeight() - offset,
+ (int) pos.x / 64 + mapOriginX - offset,
+ (int) pos.x / 64 + mapOriginY - offset,
dotSize, dotSize));
}
}
diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp
index 424c3558..86e5a8f1 100644
--- a/src/gui/ministatus.cpp
+++ b/src/gui/ministatus.cpp
@@ -32,8 +32,7 @@
#include "../utils/tostring.h"
-MiniStatusWindow::MiniStatusWindow():
- Window()
+MiniStatusWindow::MiniStatusWindow()
{
setResizable(false);
setMovable(false);
diff --git a/src/gui/newskill.cpp b/src/gui/newskill.cpp
deleted file mode 100644
index 20fc01bd..00000000
--- a/src/gui/newskill.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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
- */
-
- /* This file implements the new skill dialog for use under the latest
- * version of the skill system as of 2005/02/20
- */
-
-#include "newskill.h"
-
-#include <guichan/widgets/label.hpp>
-
-#include "button.h"
-#include "progressbar.h"
-
-#include "../graphics.h"
-
-const char *skill_name[] = {
- // 0-99
- // weapon skills 0-9
- "Short Blades", "Long Blades", "Hammers", "Archery", "Whip",
- "Staves", "Throwing", "Piercing", "Hand to Hand", NULL,
- // magic skills 10-19
- "Epyri (Fire)", "Merene (Water)", "Geon (Earth)", "Izurial (Air)",
- "Lumine (Light)", "Tenebrae (Dark)", "Chronos (Time)", "Teless (Space)",
- "Gen (Mana)", NULL,
- // craft skills 20-29
- "Metalworking", "Woodworking", "Jeweler", "Cook", "Tailor",
- "Alchemist", "Artisan", "Synthesis", NULL, NULL,
- // general skills 30-39
- "Running", "Searching", "Sneak", "Trading", "Intimidate",
- "Athletics", NULL, NULL, NULL,NULL,
- // combat skills 40-49
- "Dodge", "Accuracy", "Critical", "Block", "Parry", "Diehard", "Magic Aura",
- "Counter", NULL, NULL,
- // resistance skills 50-59
- "Poison", "Silence", "Petrify", "Paralyze", "Blind", "Slow", "Zombie",
- "Critical", NULL, NULL,
- // element reistance 60-69
- "Heat (Fire)", "Chill (Water)", "Stone (Earth)", "Wind (Air)",
- "Shine (Light)", "Shadow (Dark)", "Decay (Time)", "Chaos (Space)", NULL,
- NULL,
- // hunting skills 70-79
- "Insects", "Birds", "Lizards", "Amorphs", "Undead", "Machines", "Arcana",
- "Humanoids", "Plantoids", NULL,
- // stats 80-89
- "Strength", "Fortitude", "Vitality", "Menality", "Awareness", "Mana",
- "Dexterity", NULL, NULL, NULL,
- // unused (reserved) 90-99
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-
-NewSkillDialog::NewSkillDialog():
- Window("Skills")
-{
- startPoint = 0;
- for (int i = 0; i < N_SKILL_CAT_SIZE; i++)
- {
- mSkillLabel[i] = new gcn::Label("Empty ");
- mSkillLevel[i] = new gcn::Label("00000");
- mSkillbar[i] = new ProgressBar(0.0f,100,15,0,0,255);
- mSkillLevel[i]->setAlignment(Graphics::RIGHT);
- add(mSkillLabel[i],40,5+i*25);
- add(mSkillLevel[i],150,5+i*25);
- add(mSkillbar[i],180,5+i*25);
- }
- // initialize the skills
- for (int i = 0; i < N_SKILL; i++)
- {
- mPlayerSkill[i].level = 0;
- mPlayerSkill[i].exp = 0;
- }
- resetNSD();
-
- // create controls
- Button *catButton[N_SKILL_CAT];
- catButton[0] = new Button("Weapons", "g1", this);
- catButton[1] = new Button("Magic", "g2", this);
- catButton[2] = new Button("Craft", "g3", this);
- catButton[3] = new Button("General", "g4", this);
- catButton[4] = new Button("Combat", "g5", this);
- catButton[5] = new Button("E. Resist", "g6", this);
- catButton[6] = new Button("S. Resist", "g7", this);
- catButton[7] = new Button("Hunting", "g8", this);
- catButton[8] = new Button("Stat", "g9", this);
-
- setContentSize(350, 250);
-
- for (int i = 0; i < 9; ++i) {
- catButton[i]->setDimension(gcn::Rectangle(0, 0, 60, 20));
- catButton[i]->setPosition(290, 20 * i);
- add(catButton[i]);
- }
-
- Button *closeButton = new Button("Close", "close", this);
- closeButton->setDimension(gcn::Rectangle(0,0,60,20));
- closeButton->setPosition(290, 230);
- add(closeButton);
-
- // finsihing touches
- setLocationRelativeTo(getParent());
-}
-
-void NewSkillDialog::action(const gcn::ActionEvent &event)
-{
- int osp = startPoint;
- if (event.getId() == "close")
- {
- setVisible(false);
- }
- else if (event.getId() == "g1") // weapons group 0-9
- {
- startPoint =0;
- }
- else if (event.getId() == "g2") // magic group 10-19
- {
- startPoint =10;
- }
- else if (event.getId() == "g3") // craft group 20-29
- {
- startPoint =20;
- }
- else if (event.getId() == "g4") // general group 30-39
- {
- startPoint =30;
- }
- else if (event.getId() == "g5") // combat group 40-49
- {
- startPoint =40;
- }
- else if (event.getId() == "g6") // e. resist group 50-59
- {
- startPoint =50;
- }
- else if (event.getId() == "g7") // s resist group 60-69
- {
- startPoint =60;
- }
- else if (event.getId() == "g8") // hunting group 70-79
- {
- startPoint =70;
- }
- else if (event.getId() == "g9") // stats group 80-89
- {
- startPoint =80;
- }
- if (osp != startPoint)
- {
- resetNSD();
- }
-}
-
-void NewSkillDialog::resetNSD()
-{
- for (int a = 0; a < N_SKILL_CAT_SIZE; a++)
- {
- if (skill_name[a + startPoint])
- {
- mSkillLabel[a]->setCaption(skill_name[a + startPoint]);
- mSkillLabel[a]->setVisible(true);
- char tmp[5];
- sprintf(tmp, "%d", mPlayerSkill[a+startPoint].level);
- mSkillLevel[a]->setCaption(tmp);
- mSkillLevel[a]->setVisible(true);
- mSkillbar[a]->setProgress(0.0f);
- mSkillbar[a]->setVisible(true);
- }
- else
- {
- mSkillLevel[a]->setVisible(false);
- mSkillLabel[a]->setVisible(false);
- mSkillbar[a]->setVisible(false);
- }
- }
-}
diff --git a/src/gui/newskill.h b/src/gui/newskill.h
deleted file mode 100644
index 49476e5e..00000000
--- a/src/gui/newskill.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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
- */
-
-#ifndef _TMW_NSKILL_H
-#define _TMW_NSKILL_H
-
-#include <guichan/actionlistener.hpp>
-
-#include "window.h"
-
-#include "../guichanfwd.h"
-
-class ProgressBar;
-
-#define N_SKILL 100 // skill count constant
-#define N_SKILL_CAT 9 // skill category count
-#define N_SKILL_CAT_SIZE 10 // skill category maximum size
-
-struct nSkill {
- short level;
- short exp;
-};
-
-/**
- * Dialog showing the skills in the planned skill model.
- *
- * \ingroup Interface
- */
-class NewSkillDialog : public Window, public gcn::ActionListener
-{
- public:
- /**
- * Constructor.
- */
- NewSkillDialog();
-
- // action listener
- void action(const gcn::ActionEvent &event);
-
- private:
- void resetNSD(); // updates the values in the dialog box
-
- // members
- int startPoint; // starting point of skill listing
- ProgressBar *mSkillbar[N_SKILL_CAT_SIZE];
- gcn::Label *mSkillLabel[N_SKILL_CAT_SIZE];
- gcn::Label *mSkillLevel[N_SKILL_CAT_SIZE];
- nSkill mPlayerSkill[N_SKILL]; // pointer to an array of skill values
-};
-
-#endif
diff --git a/src/gui/npc_text.cpp b/src/gui/npc_text.cpp
index c593feb1..c9ace303 100644
--- a/src/gui/npc_text.cpp
+++ b/src/gui/npc_text.cpp
@@ -34,10 +34,16 @@
NpcTextDialog::NpcTextDialog():
Window(_("NPC"))
{
+ setResizable(true);
+
+ setMinWidth(200);
+ setMinHeight(150);
+
mTextBox = new TextBox;
mTextBox->setEditable(false);
- gcn::ScrollArea *scrollArea = new ScrollArea(mTextBox);
- Button *okButton = new Button(_("Ok"), "ok", this);
+
+ scrollArea = new ScrollArea(mTextBox);
+ okButton = new Button(_("OK"), "ok", this);
setContentSize(260, 175);
scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
@@ -54,20 +60,36 @@ NpcTextDialog::NpcTextDialog():
setLocationRelativeTo(getParent());
}
-void
-NpcTextDialog::setText(const std::string &text)
+void NpcTextDialog::setText(const std::string &text)
+{
+ mText = text;
+ mTextBox->setTextWrapped(mText);
+}
+
+void NpcTextDialog::addText(const std::string &text)
{
- mTextBox->setTextWrapped(text);
+ setText(mText + text + "\n");
}
-void
-NpcTextDialog::addText(const std::string &text)
+void NpcTextDialog::widgetResized(const gcn::Event &event)
{
- mTextBox->setTextWrapped(mTextBox->getText() + text + "\n");
+ Window::widgetResized(event);
+
+ const gcn::Rectangle &area = getChildrenArea();
+ const int width = area.width;
+ const int height = area.height;
+
+ scrollArea->setDimension(gcn::Rectangle(
+ 5, 5, width - 10, height - 15 - okButton->getHeight()));
+ okButton->setPosition(
+ width - 5 - okButton->getWidth(),
+ height - 5 - okButton->getHeight());
+
+ // Set the text again so that it gets wrapped according to the new size
+ mTextBox->setTextWrapped(mText);
}
-void
-NpcTextDialog::action(const gcn::ActionEvent &event)
+void NpcTextDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok")
{
diff --git a/src/gui/npc_text.h b/src/gui/npc_text.h
index 2c9771d3..76161f88 100644
--- a/src/gui/npc_text.h
+++ b/src/gui/npc_text.h
@@ -45,18 +45,23 @@ class NpcTextDialog : public Window, public gcn::ActionListener
NpcTextDialog();
/**
+ * Called when resizing the window
+ *
+ * @param event The calling event
+ */
+ void widgetResized(const gcn::Event &event);
+
+ /**
* Called when receiving actions from the widgets.
*/
- void
- action(const gcn::ActionEvent &event);
+ void action(const gcn::ActionEvent &event);
/**
* Sets the text shows in the dialog.
*
* @param string The new text.
*/
- void
- setText(const std::string &string);
+ void setText(const std::string &string);
/**
* Adds the text to the text shows in the dialog. Also adds a newline
@@ -64,11 +69,14 @@ class NpcTextDialog : public Window, public gcn::ActionListener
*
* @param string The text to add.
*/
- void
- addText(const std::string &string);
+ void addText(const std::string &string);
private:
+ gcn::Button *okButton;
+ gcn::ScrollArea *scrollArea;
TextBox *mTextBox;
+
+ std::string mText;
};
-#endif
+#endif // _TMW_NPC_TEXT_H
diff --git a/src/gui/npclistdialog.cpp b/src/gui/npclistdialog.cpp
index 918031b4..c55255ea 100644
--- a/src/gui/npclistdialog.cpp
+++ b/src/gui/npclistdialog.cpp
@@ -34,10 +34,15 @@
NpcListDialog::NpcListDialog():
Window(_("NPC"))
{
+ setResizable(true);
+
+ setMinWidth(200);
+ setMinHeight(150);
+
mItemList = new ListBox(this);
- ScrollArea *scrollArea = new ScrollArea(mItemList);
- Button *okButton = new Button(_("Ok"), "ok", this);
- Button *cancelButton = new Button(_("Cancel"), "cancel", this);
+ scrollArea = new ScrollArea(mItemList);
+ okButton = new Button(_("OK"), "ok", this);
+ cancelButton = new Button(_("Cancel"), "cancel", this);
setContentSize(260, 175);
scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
@@ -61,31 +66,45 @@ NpcListDialog::NpcListDialog():
setLocationRelativeTo(getParent());
}
-int
-NpcListDialog::getNumberOfElements()
+int NpcListDialog::getNumberOfElements()
{
return mItems.size();
}
-std::string
-NpcListDialog::getElementAt(int i)
+std::string NpcListDialog::getElementAt(int i)
{
return mItems[i];
}
-void NpcListDialog::addItem(std::string const &item)
+void NpcListDialog::addItem(const std::string &item)
{
mItems.push_back(item);
}
-void
-NpcListDialog::reset()
+void NpcListDialog::reset()
{
mItems.clear();
}
-void
-NpcListDialog::action(const gcn::ActionEvent &event)
+void NpcListDialog::widgetResized(const gcn::Event &event)
+{
+ Window::widgetResized(event);
+
+ const gcn::Rectangle &area = getChildrenArea();
+ const int width = area.width;
+ const int height = area.height;
+
+ scrollArea->setDimension(gcn::Rectangle(
+ 5, 5, width - 10, height - 15 - okButton->getHeight()));
+ cancelButton->setPosition(
+ width - 5 - cancelButton->getWidth(),
+ height - 5 - cancelButton->getHeight());
+ okButton->setPosition(
+ cancelButton->getX() - 5 - okButton->getWidth(),
+ cancelButton->getY());
+}
+
+void NpcListDialog::action(const gcn::ActionEvent &event)
{
int choice = 0;
diff --git a/src/gui/npclistdialog.h b/src/gui/npclistdialog.h
index e21f9e8c..65281f58 100644
--- a/src/gui/npclistdialog.h
+++ b/src/gui/npclistdialog.h
@@ -49,38 +49,44 @@ class NpcListDialog : public Window, public gcn::ActionListener,
NpcListDialog();
/**
+ * Called when resizing the window
+ *
+ * @param event The calling event
+ */
+ void widgetResized(const gcn::Event &event);
+
+ /**
* Called when receiving actions from the widgets.
*/
- void
- action(const gcn::ActionEvent &event);
+ void action(const gcn::ActionEvent &event);
/**
* Returns the number of items in the choices list.
*/
- int
- getNumberOfElements();
+ int getNumberOfElements();
/**
* Returns the name of item number i of the choices list.
*/
- std::string
- getElementAt(int i);
+ std::string getElementAt(int i);
/**
* Adds an item to the option list.
*/
- void addItem(std::string const &);
+ void addItem(const std::string &);
/**
* Resets the list by removing all items.
*/
- void
- reset();
+ void reset();
private:
gcn::ListBox *mItemList;
+ gcn::ScrollArea *scrollArea;
+ gcn::Button *okButton;
+ gcn::Button *cancelButton;
std::vector<std::string> mItems;
};
-#endif
+#endif // _TMW_GUI_NPCLISTDIALOG_H
diff --git a/src/gui/partywindow.cpp b/src/gui/partywindow.cpp
index 262e3b2e..c4a1c780 100644
--- a/src/gui/partywindow.cpp
+++ b/src/gui/partywindow.cpp
@@ -29,6 +29,7 @@
PartyWindow::PartyWindow() : Window(_("Party"))
{
+ setWindowName("Party");
setVisible(false);
setResizable(false);
setCaption(_("Party"));
@@ -37,7 +38,7 @@ PartyWindow::PartyWindow() : Window(_("Party"))
setMinHeight(200);
setDefaultSize(620, 300, 110, 200);
- loadWindowState("Party");
+ loadWindowState();
}
PartyWindow::~PartyWindow()
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp
index 30e78368..24391458 100644
--- a/src/gui/sell.cpp
+++ b/src/gui/sell.cpp
@@ -44,6 +44,7 @@ SellDialog::SellDialog():
Window(_("Sell")),
mMaxItems(0), mAmountItems(0)
{
+ setWindowName("Sell");
setResizable(true);
setMinWidth(260);
setMinHeight(230);
@@ -90,7 +91,7 @@ SellDialog::SellDialog():
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
- loadWindowState("Sell");
+ loadWindowState();
setLocationRelativeTo(getParent());
}
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index 2a60308b..e062f674 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -43,6 +43,7 @@ extern Window *helpWindow;
extern Window *skillDialog;
extern Window *magicDialog;
extern Window *guildWindow;
+extern Window *itemShortcutWindow;
Setup::Setup():
Window(_("Setup"))
@@ -117,5 +118,6 @@ void Setup::action(const gcn::ActionEvent &event)
skillDialog->resetToDefaultSize();
magicDialog->resetToDefaultSize();
guildWindow->resetToDefaultSize();
+ itemShortcutWindow->resetToDefaultSize();
}
}
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index 51cee8e3..bac342a0 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -106,8 +106,8 @@ Setup_Video::Setup_Video():
mCustomCursorEnabled(config.getValue("customcursor", 1)),
mVisibleNamesEnabled(config.getValue("visiblenames", 1)),
mOpacity(config.getValue("guialpha", 0.8)),
- mFps((int)config.getValue("fpslimit", 60)),
- mModeListModel(new ModeListModel()),
+ mFps((int) config.getValue("fpslimit", 0)),
+ mModeListModel(new ModeListModel),
mModeList(new ListBox(mModeListModel)),
mFsCheckBox(new CheckBox(_("Full screen"), mFullScreenEnabled)),
mOpenGLCheckBox(new CheckBox(_("OpenGL"), mOpenGLEnabled)),
@@ -116,13 +116,13 @@ Setup_Video::Setup_Video():
mAlphaSlider(new Slider(0.2, 1.0)),
mFpsCheckBox(new CheckBox(_("FPS Limit:"))),
mFpsSlider(new Slider(10, 200)),
- mFpsField(new TextField()),
- mOriginalScrollLaziness((int) config.getValue("ScrollLaziness", 32)),
+ mFpsField(new TextField),
+ mOriginalScrollLaziness((int) config.getValue("ScrollLaziness", 16)),
mScrollLazinessSlider(new Slider(1, 64)),
- mScrollLazinessField(new TextField()),
- mOriginalScrollRadius((int) config.getValue("ScrollRadius", 32)),
+ mScrollLazinessField(new TextField),
+ mOriginalScrollRadius((int) config.getValue("ScrollRadius", 0)),
mScrollRadiusSlider(new Slider(0, 128)),
- mScrollRadiusField(new TextField()),
+ mScrollRadiusField(new TextField),
mOverlayDetail((int) config.getValue("OverlayDetail", 2)),
mOverlayDetailSlider(new Slider(0, 2)),
mOverlayDetailField(new gcn::Label(""))
@@ -189,7 +189,7 @@ Setup_Video::Setup_Video():
mScrollRadiusSlider->setDimension(gcn::Rectangle(10, 140, 75, 10));
gcn::Label *scrollRadiusLabel = new gcn::Label(_("Scroll radius"));
scrollRadiusLabel->setPosition(90, 140);
- mScrollRadiusField->setPosition(180, 140);
+ mScrollRadiusField->setPosition(mFpsField->getX(), 140);
mScrollRadiusField->setWidth(30);
mScrollRadiusField->setText(toString(mOriginalScrollRadius));
mScrollRadiusSlider->setValue(mOriginalScrollRadius);
@@ -197,7 +197,7 @@ Setup_Video::Setup_Video():
mScrollLazinessSlider->setDimension(gcn::Rectangle(10, 160, 75, 10));
gcn::Label *scrollLazinessLabel = new gcn::Label(_("Scroll laziness"));
scrollLazinessLabel->setPosition(90, 160);
- mScrollLazinessField->setPosition(180, 160);
+ mScrollLazinessField->setPosition(mFpsField->getX(), 160);
mScrollLazinessField->setWidth(30);
mScrollLazinessField->setText(toString(mOriginalScrollLaziness));
mScrollLazinessSlider->setValue(mOriginalScrollLaziness);
@@ -253,9 +253,18 @@ void Setup_Video::apply()
bool fullscreen = mFsCheckBox->isSelected();
if (fullscreen != (config.getValue("screen", 0) == 1))
{
+ /* The OpenGL test is only necessary on Windows, since switching
+ * to/from full screen works fine on Linux. On Windows we'd have to
+ * reinitialize the OpenGL state and reload all textures.
+ *
+ * See http://libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode
+ */
+
+#ifdef WIN32
// checks for opengl usage
if (!(config.getValue("opengl", 0) == 1))
{
+#endif
if (!graphics->setFullscreen(fullscreen))
{
fullscreen = !fullscreen;
@@ -269,10 +278,12 @@ void Setup_Video::apply()
logger->error(error.str());
}
}
+#ifdef WIN32
} else {
new OkDialog(_("Switching to full screen"),
_("Restart needed for changes to take effect."));
}
+#endif
config.setValue("screen", fullscreen ? 1 : 0);
}
diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp
index 49bacaf0..6d747641 100644
--- a/src/gui/skill.cpp
+++ b/src/gui/skill.cpp
@@ -43,8 +43,9 @@
SkillDialog::SkillDialog():
Window(_("Skills"))
{
+ setWindowName("Skills");
setCloseButton(true);
- setDefaultSize(windowContainer->getWidth() - 255, 25, 275, 425);
+ setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425);
TabbedArea *panel = new TabbedArea();
panel->setDimension(gcn::Rectangle(5, 5, 270, 420));
@@ -69,7 +70,7 @@ SkillDialog::SkillDialog():
update();
setLocationRelativeTo(getParent());
- loadWindowState(_("Skills"));
+ loadWindowState();
}
SkillDialog::~SkillDialog()
diff --git a/src/gui/status.cpp b/src/gui/status.cpp
index 43f81135..283a771b 100644
--- a/src/gui/status.cpp
+++ b/src/gui/status.cpp
@@ -36,11 +36,12 @@ StatusWindow::StatusWindow(LocalPlayer *player):
Window(player->getName()),
mPlayer(player)
{
+ setWindowName("Status");
setResizable(true);
setCloseButton(true);
setDefaultSize((windowContainer->getWidth() - 365) / 2,
- (windowContainer->getHeight() - 255) / 2, 365, 280);
- loadWindowState("Status");
+ (windowContainer->getHeight() - 255) / 2, 365, 275);
+ loadWindowState();
// ----------------------
// Status Part
diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp
index 38064f48..7d5051c7 100644
--- a/src/gui/trade.cpp
+++ b/src/gui/trade.cpp
@@ -53,6 +53,7 @@ TradeWindow::TradeWindow():
mPartnerInventory(new Inventory),
mStatus(PREPARING)
{
+ setWindowName("Trade");
setResizable(true);
setDefaultSize(115, 197, 332, 209);
@@ -102,7 +103,7 @@ TradeWindow::TradeWindow():
layout.setColWidth(0, Layout::AUTO_SET);
layout.setColWidth(1, Layout::AUTO_SET);
- loadWindowState("Trade");
+ loadWindowState();
}
TradeWindow::~TradeWindow()
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index ff1e600c..997a9b82 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -47,7 +47,7 @@
/**
* Calculates the Alder-32 checksum for the given file.
*/
-unsigned long fadler32(FILE *file)
+static unsigned long fadler32(FILE *file)
{
// Obtain file size
fseek(file, 0, SEEK_END);
@@ -146,15 +146,9 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost,
UpdaterWindow::~UpdaterWindow()
{
if (mThread)
- {
- SDL_WaitThread(mThread, NULL);
- mThread = NULL;
- }
+ SDL_WaitThread(mThread, NULL);
- if (mMemoryBuffer)
- {
- free(mMemoryBuffer);
- }
+ free(mMemoryBuffer);
// Remove possibly leftover temporary download
::remove((mUpdatesDir + "/download.temp").c_str());
@@ -169,8 +163,9 @@ void UpdaterWindow::setProgress(float p)
void UpdaterWindow::setLabel(const std::string &str)
{
- mLabel->setCaption(str);
- mLabel->adjustSize();
+ // Do delayed label text update, since Guichan isn't thread-safe
+ MutexLocker lock(&mLabelMutex);
+ mNewLabelCaption = str;
}
void UpdaterWindow::enable()
@@ -315,6 +310,17 @@ int UpdaterWindow::downloadThread(void *ptr)
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
+ struct curl_slist *pHeaders = NULL;
+ if (uw->mDownloadStatus != UPDATE_RESOURCES)
+ {
+ // Make sure the resources2.txt and news.txt aren't cached,
+ // in order to always get the latest version.
+ pHeaders = curl_slist_append(pHeaders, "pragma: no-cache");
+ pHeaders =
+ curl_slist_append(pHeaders, "Cache-Control: no-cache");
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pHeaders);
+ }
+
if ((res = curl_easy_perform(curl)) != 0)
{
uw->mDownloadStatus = UPDATE_ERROR;
@@ -339,6 +345,11 @@ int UpdaterWindow::downloadThread(void *ptr)
curl_easy_cleanup(curl);
+ if (uw->mDownloadStatus != UPDATE_RESOURCES)
+ {
+ curl_slist_free_all(pHeaders);
+ }
+
if (!uw->mStoreInMemory)
{
// Don't check resources2.txt checksum
@@ -413,6 +424,17 @@ void UpdaterWindow::logic()
// Update Scroll logic
mScrollArea->logic();
+ // Synchronize label caption when necessary
+ {
+ MutexLocker lock(&mLabelMutex);
+
+ if (mLabel->getCaption() != mNewLabelCaption)
+ {
+ mLabel->setCaption(mNewLabelCaption);
+ mLabel->adjustSize();
+ }
+ }
+
switch (mDownloadStatus)
{
case UPDATE_ERROR:
@@ -434,7 +456,8 @@ void UpdaterWindow::logic()
mBrowserBox->addRow("##1 It is strongly recommended that");
mBrowserBox->addRow("##1 you try again later");
mBrowserBox->addRow(mCurlError);
- mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll());
+ mScrollArea->setVerticalScrollAmount(
+ mScrollArea->getVerticalMaxScroll());
mDownloadStatus = UPDATE_COMPLETE;
break;
case UPDATE_NEWS:
diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h
index d7e3c4c7..a7dfe2cb 100644
--- a/src/gui/updatewindow.h
+++ b/src/gui/updatewindow.h
@@ -30,12 +30,13 @@
#include "../guichanfwd.h"
+#include "../utils/mutex.h"
+
class BrowserBox;
class Button;
class ProgressBar;
class ScrollArea;
-struct SDL_mutex;
struct SDL_Thread;
/**
@@ -88,7 +89,7 @@ class UpdaterWindow : public Window, public gcn::ActionListener
int updateState;
- protected:
+private:
void download();
/**
@@ -133,6 +134,12 @@ class UpdaterWindow : public Window, public gcn::ActionListener
/** The file currently downloading. */
std::string mCurrentFile;
+ /** The new label caption to be set in the logic method. */
+ std::string mNewLabelCaption;
+
+ /** The mutex used to guard access to mNewLabelCaption. */
+ Mutex mLabelMutex;
+
/** The Adler32 checksum of the file currently downloading. */
unsigned long mCurrentChecksum;
@@ -164,7 +171,7 @@ class UpdaterWindow : public Window, public gcn::ActionListener
Button *mCancelButton; /**< Button to stop the update process. */
Button *mPlayButton; /**< Button to start playing. */
ProgressBar *mProgressBar; /**< Update progress bar. */
- BrowserBox* mBrowserBox; /**< Box to display news. */
+ BrowserBox *mBrowserBox; /**< Box to display news. */
ScrollArea *mScrollArea; /**< Used to scroll news box. */
};
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index a6092c7a..a746fb03 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -61,8 +61,8 @@ Viewport::Viewport():
setOpaque(false);
addMouseListener(this);
- mScrollLaziness = (int) config.getValue("ScrollLaziness", 32);
- mScrollRadius = (int) config.getValue("ScrollRadius", 32);
+ mScrollLaziness = (int) config.getValue("ScrollLaziness", 16);
+ mScrollRadius = (int) config.getValue("ScrollRadius", 0);
mScrollCenterOffsetX = (int) config.getValue("ScrollCenterOffsetX", 0);
mScrollCenterOffsetY = (int) config.getValue("ScrollCenterOffsetY", 0);
mVisibleNames = config.getValue("visiblenames", 1);
diff --git a/src/gui/widgets/avatar.cpp b/src/gui/widgets/avatar.cpp
index 68ce5243..9fcd00a6 100644
--- a/src/gui/widgets/avatar.cpp
+++ b/src/gui/widgets/avatar.cpp
@@ -33,23 +33,17 @@ Avatar::Avatar(const std::string &name):
mLabel = new gcn::Label(name);
mLabel->setSize(85, 12);
mLabel->setPosition(25, 0);
- mStatusOffline = ResourceManager::getInstance()->getImage("graphics/gui/circle-gray.png");
- mStatusOnline = ResourceManager::getInstance()->getImage("graphics/gui/circle-green.png");
+ ResourceManager *resman = ResourceManager::getInstance();
+ mStatusOffline = resman->getImage("graphics/gui/circle-gray.png");
+ mStatusOnline = resman->getImage("graphics/gui/circle-green.png");
mStatus = new Icon(mStatusOffline);
mStatus->setSize(25, 12);
mStatus->setPosition(0, 0);
}
-void Avatar::setOnline(bool status)
+void Avatar::setOnline(bool online)
{
- if (status)
- {
- mStatus->setImage(mStatusOnline);
- }
- else
- {
- mStatus->setImage(mStatusOffline);
- }
+ mStatus->setImage(online ? mStatusOnline : mStatusOffline);
}
void Avatar::draw(gcn::Graphics *g)
diff --git a/src/gui/widgets/avatar.h b/src/gui/widgets/avatar.h
index 0f657895..c6151020 100644
--- a/src/gui/widgets/avatar.h
+++ b/src/gui/widgets/avatar.h
@@ -33,18 +33,18 @@ class Avatar : public gcn::Widget
{
public:
/**
- * Constructor
+ * Constructor.
* @param name Character name
*/
Avatar(const std::string &name);
/**
- * Set the avatar online status
+ * Set the avatar online status.
*/
- void setOnline(bool status);
+ void setOnline(bool online);
/**
- * Draws the Avatar
+ * Draws the avatar.
*/
void draw(gcn::Graphics *g);
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index e498236a..582e4a67 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -129,12 +129,13 @@ Window::~Window()
{
logger->log("UNLOAD: Window::~Window(\"%s\")", getCaption().c_str());
- std::string const &name = mConfigName;
+ const std::string &name = mWindowName;
if (!name.empty())
{
// Saving X, Y and Width and Height for resizables in the config
config.setValue(name + "WinX", getX());
config.setValue(name + "WinY", getY());
+ config.setValue(name + "Visible", isVisible());
if (mGrip)
{
@@ -179,10 +180,9 @@ void Window::setWindowContainer(WindowContainer *wc)
void Window::draw(gcn::Graphics *graphics)
{
- if(mAlphaChanged)
+ if (mAlphaChanged)
setGuiAlpha();
-
Graphics *g = static_cast<Graphics*>(graphics);
//g->drawImageRect(0, 0, getWidth(), getHeight(), border);
@@ -248,7 +248,7 @@ void Window::setMaxHeight(unsigned int height)
void Window::setResizable(bool r)
{
- if ((bool)mGrip == r) return;
+ if ((bool) mGrip == r) return;
if (r)
{
@@ -269,7 +269,7 @@ void Window::widgetResized(const gcn::Event &event)
{
if (mGrip)
{
- gcn::Rectangle const &area = getChildrenArea();
+ const gcn::Rectangle area = getChildrenArea();
mGrip->setPosition(getWidth() - mGrip->getWidth() - area.x,
getHeight() - mGrip->getHeight() - area.y);
}
@@ -467,12 +467,14 @@ void Window::mouseDragged(gcn::MouseEvent &event)
}
}
-void Window::loadWindowState(std::string const &name)
+void Window::loadWindowState()
{
- mConfigName = name;
+ const std::string &name = mWindowName;
+ assert(!name.empty());
setPosition((int) config.getValue(name + "WinX", mDefaultX),
(int) config.getValue(name + "WinY", mDefaultY));
+ setVisible((bool) config.getValue(name + "Visible", false));
if (mGrip)
{
@@ -497,7 +499,7 @@ void Window::setDefaultSize(int defaultX, int defaultY,
void Window::resetToDefaultSize()
{
setPosition(mDefaultX, mDefaultY);
- setContentSize(mDefaultWidth, mDefaultHeight);
+ setSize(mDefaultWidth, mDefaultHeight);
}
int Window::getResizeHandles(gcn::MouseEvent &event)
diff --git a/src/gui/window.h b/src/gui/window.h
index 22355572..6f49e062 100644
--- a/src/gui/window.h
+++ b/src/gui/window.h
@@ -153,8 +153,7 @@ class Window : public gcn::Window, gcn::WidgetListener
*
* @return The parent window or <code>NULL</code> if there is none.
*/
- Window*
- getParentWindow() { return mParent; }
+ Window *getParentWindow() { return mParent; }
/**
* Schedule this window for deletion. It will be deleted at the start
@@ -192,13 +191,23 @@ class Window : public gcn::Window, gcn::WidgetListener
void mouseExited(gcn::MouseEvent &event);
/**
+ * Sets the name of the window. This is not the window title.
+ */
+ void setWindowName(const std::string &name) { mWindowName = name; }
+
+ /**
+ * Returns the name of the window. This is not the window title.
+ */
+ const std::string &getWindowName() { return mWindowName; }
+
+ /**
* Reads the position (and the size for resizable windows) in the
* configuration based on the given string.
* Uses the default values when config values are missing.
* Don't forget to set these default values and resizable before
* calling this function.
*/
- void loadWindowState(std::string const &);
+ void loadWindowState();
/**
* Set the default win pos and size.
@@ -267,7 +276,7 @@ class Window : public gcn::Window, gcn::WidgetListener
ResizeGrip *mGrip; /**< Resize grip */
Window *mParent; /**< The parent window */
Layout *mLayout; /**< Layout handler */
- std::string mConfigName; /**< Name used for saving window-related data */
+ std::string mWindowName; /**< Name of the window */
bool mShowTitle; /**< Window has a title bar */
bool mModal; /**< Window is modal */
bool mCloseButton; /**< Window has a close button */
diff --git a/src/imageparticle.h b/src/imageparticle.h
index 91c5426c..c18b30b8 100644
--- a/src/imageparticle.h
+++ b/src/imageparticle.h
@@ -49,8 +49,7 @@ class ImageParticle : public Particle
/**
* Draws the particle image
*/
- virtual void
- draw(Graphics *graphics, int offsetX, int offsetY) const;
+ virtual void draw(Graphics *graphics, int offsetX, int offsetY) const;
protected:
Image *mImage; /**< The image used for this particle. */
diff --git a/src/itemshortcut.cpp b/src/itemshortcut.cpp
index a89da974..bea14864 100644
--- a/src/itemshortcut.cpp
+++ b/src/itemshortcut.cpp
@@ -61,14 +61,8 @@ void ItemShortcut::save()
{
for (int i = 0; i < SHORTCUT_ITEMS; i++)
{
- if (mItems[i])
- {
- config.setValue("shortcut" + toString(i), mItems[i]);
- }
- else
- {
- config.setValue("shortcut" + toString(i), -1);
- }
+ const int itemId = mItems[i] ? mItems[i] : -1;
+ config.setValue("shortcut" + toString(i), itemId);
}
}
@@ -77,9 +71,20 @@ void ItemShortcut::useItem(int index)
if (mItems[index])
{
Item *item = player_node->searchForItem(mItems[index]);
- if (item && item->getQuantity()) {
+ if (item && item->getQuantity())
+ {
// TODO: Fix this (index vs. pointer mismatch)
- //player_node->useItem(item);
+ /*
+ if (item->isEquipment()) {
+ if (item->isEquipped()) {
+ player_node->unequipItem(item);
+ } else {
+ player_node->equipItem(item);
+ }
+ } else {
+ player_node->useItem(item);
+ }
+ */
}
}
}
diff --git a/src/joystick.cpp b/src/joystick.cpp
index b69537cf..b05e9b5f 100644
--- a/src/joystick.cpp
+++ b/src/joystick.cpp
@@ -24,12 +24,17 @@
#include "configuration.h"
#include "log.h"
+#include <cassert>
+
int Joystick::joystickCount = 0;
void Joystick::init()
{
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
- //SDL_JoystickEventState(SDL_ENABLE);
+
+ // Have SDL call SDL_JoystickUpdate() automatically
+ SDL_JoystickEventState(SDL_ENABLE);
+
joystickCount = SDL_NumJoysticks();
logger->log("%i joysticks/gamepads found", joystickCount);
for (int i = 0; i < joystickCount; i++)
@@ -37,11 +42,11 @@ void Joystick::init()
}
Joystick::Joystick(int no):
- mDirection(0), mCalibrating(false)
+ mDirection(0),
+ mCalibrating(false),
+ mEnabled(false)
{
- // TODO Bail out here?
- if (no > joystickCount)
- return;
+ assert(no < joystickCount);
mJoystick = SDL_JoystickOpen(no);
@@ -66,50 +71,39 @@ Joystick::Joystick(int no):
Joystick::~Joystick()
{
- SDL_JoystickClose(mJoystick);
+ SDL_JoystickClose(mJoystick);
}
void Joystick::update()
{
mDirection = 0;
- SDL_JoystickUpdate();
-
// When calibrating, don't bother the outside with our state
if (mCalibrating) {
doCalibration();
return;
};
- if (!mEnabled) return;
+ if (!mEnabled)
+ return;
// X-Axis
int position = SDL_JoystickGetAxis(mJoystick, 0);
if (position >= mRightTolerance)
- {
mDirection |= RIGHT;
- }
else if (position <= mLeftTolerance)
- {
mDirection |= LEFT;
- }
// Y-Axis
position = SDL_JoystickGetAxis(mJoystick, 1);
if (position <= mUpTolerance)
- {
mDirection |= UP;
- }
else if (position >= mDownTolerance)
- {
mDirection |= DOWN;
- }
// Buttons
for (int i = 0; i < MAX_BUTTONS; i++)
- {
mButtons[i] = (SDL_JoystickGetButton(mJoystick, i) == 1);
- }
}
void Joystick::startCalibration()
@@ -126,24 +120,16 @@ void Joystick::doCalibration()
// X-Axis
int position = SDL_JoystickGetAxis(mJoystick, 0);
if (position > mRightTolerance)
- {
mRightTolerance = position;
- }
else if (position < mLeftTolerance)
- {
mLeftTolerance = position;
- }
// Y-Axis
position = SDL_JoystickGetAxis(mJoystick, 1);
if (position > mDownTolerance)
- {
mDownTolerance = position;
- }
else if (position < mUpTolerance)
- {
mUpTolerance = position;
- }
}
void Joystick::finishCalibration()
@@ -157,5 +143,5 @@ void Joystick::finishCalibration()
bool Joystick::buttonPressed(unsigned char no) const
{
- return (no < MAX_BUTTONS) ? mButtons[no] : false;
+ return (mEnabled && no < MAX_BUTTONS) ? mButtons[no] : false;
}
diff --git a/src/joystick.h b/src/joystick.h
index 4cc1babd..ee029915 100644
--- a/src/joystick.h
+++ b/src/joystick.h
@@ -35,7 +35,12 @@ class Joystick
/**
* Directions, to be used as bitmask values.
*/
- enum { UP = 1, DOWN = 2, LEFT = 4, RIGHT = 8 };
+ enum {
+ UP = 1,
+ DOWN = 2,
+ LEFT = 4,
+ RIGHT = 8
+ };
/**
* Initializes the joystick subsystem.
@@ -55,33 +60,27 @@ class Joystick
~Joystick();
- bool
- isEnabled() const { return mEnabled; }
+ bool isEnabled() const { return mEnabled; }
- void
- setEnabled(bool enabled) { mEnabled = enabled; }
+ void setEnabled(bool enabled) { mEnabled = enabled; }
/**
* Updates the direction and button information.
*/
- void
- update();
+ void update();
- void
- startCalibration();
+ void startCalibration();
- void
- finishCalibration();
+ void finishCalibration();
- bool
- isCalibrating() const { return mCalibrating; }
+ bool isCalibrating() const { return mCalibrating; }
bool buttonPressed(unsigned char no) const;
- bool isUp() const { return mDirection & UP; };
- bool isDown() const { return mDirection & DOWN; };
- bool isLeft() const { return mDirection & LEFT; };
- bool isRight() const { return mDirection & RIGHT; };
+ bool isUp() const { return mEnabled && (mDirection & UP); };
+ bool isDown() const { return mEnabled && (mDirection & DOWN); };
+ bool isLeft() const { return mEnabled && (mDirection & LEFT); };
+ bool isRight() const { return mEnabled && (mDirection & RIGHT); };
protected:
unsigned char mDirection;
@@ -97,4 +96,4 @@ class Joystick
void doCalibration();
};
-#endif
+#endif // _TMW_JOYSTICK_H
diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp
index 37d5f276..3e4e52c4 100644
--- a/src/keyboardconfig.cpp
+++ b/src/keyboardconfig.cpp
@@ -56,7 +56,16 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = {
{"keyShortcut6", SDLK_6, "Item Shortcut 6"},
{"keyShortcut7", SDLK_7, "Item Shortcut 7"},
{"keyShortcut8", SDLK_8, "Item Shortcut 8"},
- {"keyShortcut9", SDLK_9, "Item Shortcut 9"}
+ {"keyShortcut9", SDLK_9, "Item Shortcut 9"},
+ {"keyWindowStatus", SDLK_F2, "Status Window"},
+ {"keyWindowInventory", SDLK_F3, "Inventory Window"},
+ {"keyWindowEquipment", SDLK_F4, "Equipment WIndow"},
+ {"keyWindowSkill", SDLK_F5, "Skill Window"},
+ {"keyWindowMinimap", SDLK_F6, "Minimap Window"},
+ {"keyWindowChat", SDLK_F7, "Chat Window"},
+ {"keyWindowShortcut", SDLK_F8, "Item Shortcut Window"},
+ {"keyWindowSetup", SDLK_F9, "Setup Window"},
+ {"keyWindowDebug", SDLK_F10, "Debug Window"}
};
void KeyboardConfig::init()
diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h
index d9886150..729bad5a 100644
--- a/src/keyboardconfig.h
+++ b/src/keyboardconfig.h
@@ -165,6 +165,15 @@ class KeyboardConfig
KEY_SHORTCUT_7,
KEY_SHORTCUT_8,
KEY_SHORTCUT_9,
+ KEY_WINDOW_STATUS,
+ KEY_WINDOW_INVENTORY,
+ KEY_WINDOW_EQUIPMENT,
+ KEY_WINDOW_SKILL,
+ KEY_WINDOW_MINIMAP,
+ KEY_WINDOW_CHAT,
+ KEY_WINDOW_SHORTCUT,
+ KEY_WINDOW_SETUP,
+ KEY_WINDOW_DEBUG,
KEY_TOTAL
};
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 14d253c0..ffb4aac9 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -353,10 +353,7 @@ void LocalPlayer::setDestination(Uint16 x, Uint16 y)
void LocalPlayer::setWalkingDir(int dir)
{
- if (mWalkingDir != dir)
- {
- mWalkingDir = dir;
- }
+ mWalkingDir = dir;
// If we're not already walking, start walking.
if (mAction != WALK && dir
@@ -368,7 +365,7 @@ void LocalPlayer::setWalkingDir(int dir)
void LocalPlayer::stopWalking(bool sendToServer)
{
- if(mAction == WALK && mWalkingDir){
+ if (mAction == WALK && mWalkingDir) {
mWalkingDir = 0;
mLocalWalkTime = 0;
Being::setDestination(getPosition().x,getPosition().y);
diff --git a/src/localplayer.h b/src/localplayer.h
index 5dce5ebe..0b9ba712 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -290,8 +290,6 @@ class LocalPlayer : public Player
int getHP() const
{ return mHP; }
- Uint32 mCharId;
-
int getMaxHP() const
{ return mMaxHP; }
@@ -360,7 +358,6 @@ class LocalPlayer : public Player
std::pair<int, int> getExperience(int skill);
- float mLastAttackTime; /**< Used to synchronize the charge dialog */
Inventory *mInventory;
const std::auto_ptr<Equipment> mEquipment;
diff --git a/src/main.cpp b/src/main.cpp
index 700e5676..2d6b08a8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -140,16 +140,15 @@ struct Options
printHelp(false),
printVersion(false),
skipUpdate(false),
- chooseDefault(false),
serverPort(0)
{};
bool printHelp;
bool printVersion;
bool skipUpdate;
- bool chooseDefault;
- std::string playername;
+ std::string username;
std::string password;
+ std::string character;
std::string configPath;
std::string updateHost;
std::string dataPath;
@@ -169,7 +168,7 @@ void setUpdatesDir()
// If updatesHost is currently empty, fill it from config file
if (updateHost.empty()) {
updateHost =
- config.getValue("updatehost", "http://updates.thanaworld.org");
+ config.getValue("updatehost", "http://updates.themanaworld.org");
}
// Remove any trailing slash at the end of the update host
@@ -455,10 +454,9 @@ void printHelp()
" -d --data : Directory to load game data from\n"
" -U --username : Login with this username\n"
" -P --password : Login with this password\n"
- " -D --default : Bypass the login process with default settings\n"
" -s --server : Login Server name or IP\n"
" -o --port : Login Server Port\n"
- " -p --playername : Login with this player\n"
+ " -c --character : Login with this character\n"
" -C --configfile : Configuration file to use\n"
" -H --updatehost : Use this update host\n";
}
@@ -475,7 +473,7 @@ void printVersion()
void parseOptions(int argc, char *argv[], Options &options)
{
- const char *optstring = "hvud:U:P:Dp:s:o:C:H:";
+ const char *optstring = "hvud:U:P:Dc:s:o:C:H:";
const struct option long_options[] = {
{ "help", no_argument, 0, 'h' },
@@ -484,17 +482,15 @@ void parseOptions(int argc, char *argv[], Options &options)
{ "data", required_argument, 0, 'd' },
{ "username", required_argument, 0, 'U' },
{ "password", required_argument, 0, 'P' },
- { "default", no_argument, 0, 'D' },
{ "server", required_argument, 0, 's' },
{ "port", required_argument, 0, 'o' },
- { "playername", required_argument, 0, 'p' },
+ { "character", required_argument, 0, 'c' },
{ "configfile", required_argument, 0, 'C' },
{ "updatehost", required_argument, 0, 'H' },
{ 0 }
};
while (optind < argc) {
-
int result = getopt_long(argc, argv, optstring, long_options, NULL);
if (result == -1)
@@ -515,22 +511,19 @@ void parseOptions(int argc, char *argv[], Options &options)
options.dataPath = optarg;
break;
case 'U':
- options.playername = optarg;
+ options.username = optarg;
break;
case 'P':
options.password = optarg;
break;
- case 'D':
- options.chooseDefault = true;
- break;
case 's':
options.serverName = optarg;
break;
case 'o':
options.serverPort = (short)atoi(optarg);
break;
- case 'p':
- options.playername = optarg;
+ case 'c':
+ options.character = optarg;
break;
case 'C':
options.configPath = optarg;
@@ -855,7 +848,7 @@ int main(int argc, char *argv[])
loginData.port = options.serverPort;
}
- loginData.username = options.playername;
+ loginData.username = options.username;
if (loginData.username.empty()) {
if (config.getValue("remember", 0)) {
loginData.username = config.getValue("username", "");
@@ -920,7 +913,16 @@ int main(int argc, char *argv[])
}
}
- graphics->drawImage(login_wallpaper, 0, 0);
+ if (graphics->getWidth() > login_wallpaper->getWidth() ||
+ graphics->getHeight() > login_wallpaper->getHeight())
+ {
+ graphics->setColor(gcn::Color(64, 64, 64));
+ graphics->fillRectangle(gcn::Rectangle(
+ 0, 0, graphics->getWidth(), graphics->getHeight()));
+ }
+ graphics->drawImage(login_wallpaper,
+ (graphics->getWidth() - login_wallpaper->getWidth()) / 2,
+ (graphics->getHeight() - login_wallpaper->getHeight()) / 2);
gui->draw();
graphics->updateScreen();
@@ -980,16 +982,16 @@ int main(int argc, char *argv[])
logger->log("State: CHOOSE_SERVER");
// Allow changing this using a server choice dialog
- // We show the dialog box only if the command-line options
- // weren't set.
+ // We show the dialog box only if the command-line
+ // options weren't set.
if (options.serverName.empty() && options.serverPort == 0) {
currentDialog = new ServerDialog(&loginData);
} else {
state = STATE_CONNECT_ACCOUNT;
- // Reset options so that cancelling or connect timeout
- // will show the server dialog
- options.serverName = "";
+ // Reset options so that cancelling or connect
+ // timeout will show the server dialog.
+ options.serverName.clear();
options.serverPort = 0;
}
break;
@@ -999,7 +1001,8 @@ int main(int argc, char *argv[])
logger->log("Trying to connect to account server...");
accountServerConnection->connect(loginData.hostname,
loginData.port);
- currentDialog = new ConnectionDialog(STATE_SWITCH_ACCOUNTSERVER_ATTEMPT);
+ currentDialog = new ConnectionDialog(
+ STATE_SWITCH_ACCOUNTSERVER_ATTEMPT);
break;
case STATE_UPDATE:
@@ -1017,11 +1020,15 @@ int main(int argc, char *argv[])
case STATE_LOGIN:
logger->log("State: LOGIN");
- currentDialog = new LoginDialog(&loginData);
- // TODO: Restore autologin
- //if (!loginData.password.empty()) {
- // accountLogin(&loginData);
- //}
+ if (options.username.empty()
+ || options.password.empty()) {
+ currentDialog = new LoginDialog(&loginData);
+ } else {
+ state = STATE_LOGIN_ATTEMPT;
+ // Clear the password so that when login fails, the
+ // dialog will show up next time.
+ options.password.clear();
+ }
break;
case STATE_LOADDATA:
@@ -1080,20 +1087,15 @@ int main(int argc, char *argv[])
case STATE_CHAR_SELECT:
logger->log("State: CHAR_SELECT");
currentDialog =
- new CharSelectDialog(&charInfo, &loginData);
+ new CharSelectDialog(&charInfo, &loginData);
if (((CharSelectDialog*) currentDialog)->
- selectByName(options.playername))
- options.chooseDefault = true;
- else
- ((CharSelectDialog*) currentDialog)->selectByName(
- config.getValue("lastCharacter", ""));
-
- if (options.chooseDefault)
- {
+ selectByName(options.character)) {
((CharSelectDialog*) currentDialog)->action(
gcn::ActionEvent(NULL, "ok"));
- options.chooseDefault = false;
+ } else {
+ ((CharSelectDialog*) currentDialog)->selectByName(
+ config.getValue("lastCharacter", ""));
}
break;
@@ -1106,7 +1108,7 @@ int main(int argc, char *argv[])
case STATE_CHANGEEMAIL:
logger->log("State: CHANGE EMAIL");
currentDialog = new OkDialog("Email Address change",
- "Email Address changed successfully!");
+ "Email Address changed successfully!");
currentDialog->addActionListener(&accountListener);
currentDialog = NULL; // OkDialog deletes itself
loginData.email = loginData.newEmail;
diff --git a/src/monster.cpp b/src/monster.cpp
index a62c1f4c..c472a21b 100644
--- a/src/monster.cpp
+++ b/src/monster.cpp
@@ -35,12 +35,26 @@ Monster::Monster(Uint16 id, Uint16 job, Map *map):
Being(id, job, map)
{
const MonsterInfo& info = getInfo();
- std::string filename = info.getSprite();
- if (filename.empty())
- filename = "error.xml";
- mSprites[BASE_SPRITE] =
- AnimatedSprite::load("graphics/sprites/" + filename);
+ // Setup Monster sprites
+ int c = BASE_SPRITE;
+ const std::list<std::string> &sprites = info.getSprites();
+ for (std::list<std::string>::const_iterator i = sprites.begin();
+ i != sprites.end();
+ i++)
+ {
+ if (c == VECTOREND_SPRITE) break;
+
+ std::string file = "graphics/sprites/" + *i;
+ mSprites[c] = AnimatedSprite::load(file);
+ c++;
+ }
+
+ // Ensure that something is shown
+ if (c == BASE_SPRITE)
+ {
+ mSprites[c] = AnimatedSprite::load("graphics/sprites/error.xml");
+ }
const std::list<std::string> &particleEffects = info.getParticleEffects();
for (std::list<std::string>::const_iterator i = particleEffects.begin();
@@ -111,7 +125,13 @@ Monster::setAction(Action action, int attackType)
if (currentAction != ACTION_INVALID)
{
- mSprites[BASE_SPRITE]->play(currentAction);
+ for (int i = 0; i < VECTOREND_SPRITE; i++)
+ {
+ if (mSprites[i])
+ {
+ mSprites[i]->play(currentAction);
+ }
+ }
mAction = action;
}
}
diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp
index 72371da5..f96cdcd5 100644
--- a/src/net/beinghandler.cpp
+++ b/src/net/beinghandler.cpp
@@ -32,6 +32,7 @@
#include "../localplayer.h"
#include "../log.h"
#include "../main.h"
+#include "../npc.h"
#include "../particle.h"
#include "../sound.h"
@@ -268,7 +269,7 @@ void BeingHandler::handleBeingAttackMessage(MessageIn &msg)
int attackType = msg.readInt8();
if (!being) return;
-
+
switch (direction)
{
case DIRECTION_UP: being->setDirection(Being::UP); break;
@@ -347,3 +348,4 @@ void BeingHandler::handleBeingDirChangeMessage(MessageIn &msg)
case DIRECTION_RIGHT: being->setDirection(Being::RIGHT); break;
}
}
+
diff --git a/src/net/playerhandler.cpp b/src/net/playerhandler.cpp
index ad271f15..beb59250 100644
--- a/src/net/playerhandler.cpp
+++ b/src/net/playerhandler.cpp
@@ -50,6 +50,11 @@ extern BuyDialog *buyDialog;
extern SellDialog *sellDialog;
extern Window *buySellDialog;
+/* Max. distance we are willing to scroll after a teleport;
+ * everything beyond will reset the port hard.
+ */
+static const int MAP_TELEPORT_SCROLL_DISTANCE = 8 * 32;
+
/**
* Listener used for handling the overweigth message.
*/
@@ -292,6 +297,7 @@ PlayerHandler::handleMapChangeMessage(MessageIn &msg)
const std::string mapName = msg.readString();
const unsigned short x = msg.readInt16();
const unsigned short y = msg.readInt16();
+ const bool nearby = (engine->getCurrentMapName() == mapName);
logger->log("Changing map to %s (%d, %d)", mapName.c_str(), x, y);
@@ -301,8 +307,16 @@ PlayerHandler::handleMapChangeMessage(MessageIn &msg)
current_npc = 0;
const Vector &playerPos = player_node->getPosition();
- const float scrollOffsetX = x - (int) playerPos.x;
- const float scrollOffsetY = y - (int) playerPos.y;
+ float scrollOffsetX = 0.0f;
+ float scrollOffsetY = 0.0f;
+
+ /* Scroll if neccessary */
+ if (!nearby
+ || (abs(x - (int) playerPos.x) > MAP_TELEPORT_SCROLL_DISTANCE)
+ || (abs(y - (int) playerPos.y) > MAP_TELEPORT_SCROLL_DISTANCE)) {
+ scrollOffsetX = x - (int) playerPos.x;
+ scrollOffsetY = y - (int) playerPos.y;
+ }
player_node->setAction(Being::STAND);
player_node->setPosition(x, y);
diff --git a/src/particle.cpp b/src/particle.cpp
index 8a15a132..c6e242bd 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -68,12 +68,21 @@ Particle::Particle(Map *map):
mMomentum(1.0f)
{
Particle::particleCount++;
- if (mMap) setSpriteIterator(mMap->addSprite(this));
+ if (mMap)
+ setSpriteIterator(mMap->addSprite(this));
}
+Particle::~Particle()
+{
+ // Remove from map sprite list
+ if (mMap)
+ mMap->removeSprite(mSpriteIterator);
+ // Delete child emitters and child particles
+ clear();
+ Particle::particleCount--;
+}
-void
-Particle::setupEngine()
+void Particle::setupEngine()
{
Particle::maxCount = (int)config.getValue("particleMaxCount", 3000);
Particle::fastPhysics = (int)config.getValue("particleFastPhysics", 0);
@@ -82,17 +91,17 @@ Particle::setupEngine()
logger->log("Particle engine set up");
}
-void Particle::draw(Graphics *, int, int) const {}
+void Particle::draw(Graphics *, int, int) const
+{
+}
-bool
-Particle::update()
+bool Particle::update()
{
- if (!mMap) return false;
+ if (!mMap)
+ return false;
if (mLifetimeLeft == 0)
- {
mAlive = false;
- }
Vector oldPos = mPos;
@@ -222,9 +231,8 @@ Particle::update()
return true;
}
-Particle*
-Particle::addEffect(const std::string &particleEffectFile,
- int pixelX, int pixelY, int rotation)
+Particle *Particle::addEffect(const std::string &particleEffectFile,
+ int pixelX, int pixelY, int rotation)
{
Particle *newParticle = NULL;
@@ -298,11 +306,9 @@ Particle::addEffect(const std::string &particleEffectFile,
return newParticle;
}
-
-Particle*
-Particle::addTextSplashEffect(const std::string &text,
- int colorR, int colorG, int colorB,
- gcn::Font *font, int x, int y)
+Particle *Particle::addTextSplashEffect(const std::string &text,
+ int colorR, int colorG, int colorB,
+ gcn::Font *font, int x, int y)
{
Particle *newParticle = new TextParticle(mMap, text, colorR, colorG, colorB,
font);
@@ -320,11 +326,10 @@ Particle::addTextSplashEffect(const std::string &text,
return newParticle;
}
-Particle*
-Particle::addTextRiseFadeOutEffect(const std::string &text,
- int colorR, int colorG, int colorB,
- gcn::Font *font,
- int x, int y)
+Particle *Particle::addTextRiseFadeOutEffect(const std::string &text,
+ int colorR, int colorG, int colorB,
+ gcn::Font *font,
+ int x, int y)
{
Particle *newParticle = new TextParticle(mMap, text, colorR, colorG, colorB, font);
newParticle->setPosition(x, y, 0);
@@ -339,32 +344,18 @@ Particle::addTextRiseFadeOutEffect(const std::string &text,
return newParticle;
}
-void
-Particle::setMap(Map *map)
+void Particle::setMap(Map *map)
{
mMap = map;
- if (mMap) setSpriteIterator(mMap->addSprite(this));
+ if (mMap)
+ setSpriteIterator(mMap->addSprite(this));
}
-
-Particle::~Particle()
-{
- // Remove from map sprite list
- if (mMap) mMap->removeSprite(mSpriteIterator);
- // Delete child emitters and child particles
- clear();
- Particle::particleCount--;
-}
-
-
-void
-Particle::clear()
+void Particle::clear()
{
- std::for_each(mChildEmitters.begin(), mChildEmitters.end(),
- make_dtor(mChildEmitters));
+ delete_all(mChildEmitters);
mChildEmitters.clear();
- std::for_each(mChildParticles.begin(), mChildParticles.end(),
- make_dtor(mChildParticles));
+ delete_all(mChildParticles);
mChildParticles.clear();
}
diff --git a/src/particle.h b/src/particle.h
index 4a11c4cb..af0caf21 100644
--- a/src/particle.h
+++ b/src/particle.h
@@ -67,22 +67,19 @@ class Particle : public Sprite
/**
* Deletes all child particles and emitters.
*/
- void
- clear();
+ void clear();
/**
* Gives a particle the properties of an engine root particle and loads
* the particle-related config settings.
*/
- void
- setupEngine();
+ void setupEngine();
/**
* Updates particle position, returns false when the particle should
* be deleted.
*/
- virtual bool
- update();
+ virtual bool update();
/**
* Draws the particle image.
@@ -92,8 +89,7 @@ class Particle : public Sprite
/**
* Necessary for sorting with the other sprites.
*/
- virtual int
- getPixelY() const
+ virtual int getPixelY() const
{ return (int) (mPos.y + mPos.z) - 64; }
/**
@@ -105,46 +101,40 @@ class Particle : public Sprite
* Creates a child particle that hosts some emitters described in the
* particleEffectFile.
*/
- Particle*
- addEffect(const std::string &particleEffectFile,
- int pixelX, int pixelY, int rotation = 0);
+ Particle *addEffect(const std::string &particleEffectFile,
+ int pixelX, int pixelY, int rotation = 0);
/**
* Creates a standalone text particle.
*/
- Particle*
- addTextSplashEffect(const std::string &text,
- int colorR, int colorG, int colorB,
- gcn::Font *font, int x, int y);
+ Particle *addTextSplashEffect(const std::string &text,
+ int colorR, int colorG, int colorB,
+ gcn::Font *font, int x, int y);
/**
* Creates a standalone text particle.
*/
- Particle*
- addTextRiseFadeOutEffect(const std::string &text,
- int colorR, int colorG, int colorB,
- gcn::Font *font,
- int x, int y);
+ Particle *addTextRiseFadeOutEffect(const std::string &text,
+ int colorR, int colorG, int colorB,
+ gcn::Font *font,
+ int x, int y);
/**
* Adds an emitter to the particle.
*/
- void
- addEmitter (ParticleEmitter* emitter)
+ void addEmitter (ParticleEmitter* emitter)
{ mChildEmitters.push_back(emitter); }
/**
* Sets the position in 3 dimensional space in pixels relative to map.
*/
- void
- setPosition(float x, float y, float z)
+ void setPosition(float x, float y, float z)
{ mPos.x = x; mPos.y = y; mPos.z = z; }
/**
* Sets the position in 2 dimensional space in pixels relative to map.
*/
- void
- setPosition(float x, float y)
+ void setPosition(float x, float y)
{ mPos.x = x; mPos.y = y; }
/**
@@ -156,50 +146,45 @@ class Particle : public Sprite
/**
* Changes the particle position relative
*/
- void
- moveBy(float x, float y, float z)
+ void moveBy(float x, float y, float z)
{ mPos.x += x; mPos.y += y; mPos.z += z; }
- void
- moveBy (Vector change)
+ void moveChildren(Vector change);
+
+ void moveBy (Vector change)
{ mPos += change; }
/**
* Sets the time in game ticks until the particle is destroyed.
*/
- void
- setLifetime(int lifetime)
+ void setLifetime(int lifetime)
{ mLifetimeLeft = lifetime; mLifetimePast = 0; }
/**
* Sets the age of the pixel in game ticks where the particle has
* faded in completely.
*/
- void
- setFadeOut(int fadeOut)
+ void setFadeOut(int fadeOut)
{ mFadeOut = fadeOut; }
/**
* Sets the remaining particle lifetime where the particle starts to
* fade out.
*/
- void
- setFadeIn(int fadeIn)
+ void setFadeIn(int fadeIn)
{ mFadeIn = fadeIn; }
/**
* Sets the alpha value of the particle
*/
- void
- setAlpha(float alpha)
+ void setAlpha(float alpha)
{ mAlpha = alpha; }
/**
* Sets the sprite iterator of the particle on the current map to make
* it easier to remove the particle from the map when it is destroyed.
*/
- void
- setSpriteIterator(std::list<Sprite*>::iterator spriteIterator)
+ void setSpriteIterator(std::list<Sprite*>::iterator spriteIterator)
{ mSpriteIterator = spriteIterator; }
/**
@@ -212,44 +197,38 @@ class Particle : public Sprite
/**
* Sets the current velocity in 3 dimensional space.
*/
- void
- setVelocity(float x, float y, float z)
+ void setVelocity(float x, float y, float z)
{ mVelocity.x = x; mVelocity.y = y; mVelocity.z = z; }
/**
* Sets the downward acceleration.
*/
- void
- setGravity(float gravity)
+ void setGravity(float gravity)
{ mGravity = gravity; }
/**
* Sets the ammount of random vector changes
*/
- void
- setRandomness(int r)
+ void setRandomness(int r)
{ mRandomness = r; }
/**
* Sets the ammount of velocity particles retain after
* hitting the ground.
*/
- void
- setBounce(float bouncieness)
+ void setBounce(float bouncieness)
{ mBounce = bouncieness; }
/**
* Sets the flag if the particle is supposed to be moved by its parent
*/
- void
- setFollow(bool follow)
+ void setFollow(bool follow)
{ mFollow = follow; }
/**
* Gets the flag if the particle is supposed to be moved by its parent
*/
- bool
- doesFollow()
+ bool doesFollow()
{ return mFollow; }
/**
@@ -271,6 +250,12 @@ class Particle : public Sprite
{ return mAlive; }
/**
+ * Determines whether the particle and its children are all dead
+ */
+ bool isExtinct()
+ { return !isAlive() && mChildParticles.empty(); }
+
+ /**
* Manually marks the particle for deletion.
*/
void kill()
diff --git a/src/player.cpp b/src/player.cpp
index 648b330a..19486d6e 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -35,10 +35,7 @@
#include "gui/gui.h"
Player::Player(int id, int job, Map *map):
- Being(id, job, map),
- mGender(GENDER_UNSPECIFIED),
- mHairStyle(0),
- mHairColor(0)
+ Being(id, job, map)
{
}
@@ -67,7 +64,7 @@ void Player::setGender(Gender gender)
{
if (gender != mGender)
{
- mGender = gender;
+ Being::setGender(gender);
/* Human base sprite. When implementing different races remove this
* line and set the base sprite when setting the race of the player
@@ -88,28 +85,13 @@ void Player::setGender(Gender gender)
void Player::setHairStyle(int style, int color)
{
- style = style < 0 ? mHairStyle : style % NR_HAIR_STYLES;
- color = color < 0 ? mHairColor : color % NR_HAIR_COLORS;
+ style = style < 0 ? mHairStyle : style % getHairStylesNr();
+ color = color < 0 ? mHairColor : color % getHairColorsNr();
if (style == mHairStyle && color == mHairColor) return;
- mHairStyle = style;
- mHairColor = color;
+ Being::setHairStyle(style, color);
- static char const *const colors[NR_HAIR_COLORS] =
- {
- "#8c4b41,da9041,ffffff", // light brown
- "#06372b,489e25,fdedcc", // green
- "#5f0b33,91191c,f9ad81", // red
- "#602486,934cc3,fdc689", // purple
- "#805e74,c6b09b,ffffff", // gray
- "#8c6625,dab425,ffffff", // yellow
- "#1d2d6d,1594a3,fdedcc", // blue
- "#831f2d,be4f2d,f8cc8b", // brown
- "#432482,584bbc,dae8e5", // light blue
- "#460850,611967,e7b4ae", // dark purple
- };
-
- setSprite(HAIR_SPRITE, style * -1, colors[color]);
+ setSprite(HAIR_SPRITE, style * -1, getHairColor(color));
setAction(mAction);
}
@@ -198,3 +180,5 @@ void Player::setInParty(bool value)
{
mInParty = value;
}
+
+
diff --git a/src/player.h b/src/player.h
index 068e3cf5..6880ca20 100644
--- a/src/player.h
+++ b/src/player.h
@@ -28,12 +28,6 @@ class Graphics;
class Map;
class Guild;
-enum Gender {
- GENDER_MALE = 0,
- GENDER_FEMALE = 1,
- GENDER_UNSPECIFIED = 2
-};
-
/**
* A player being. Players have their name drawn beneath them. This class also
* implements player-specific loading of base sprite, hair sprite and equipment
@@ -61,24 +55,7 @@ class Player : public Being
void setGender(Gender);
/**
- * Gets the hair color for this player.
- */
- int getHairColor() const
- { return mHairColor; }
-
- /**
- * Gets the hair style for this player.
- */
- int getHairStyle() const
- { return mHairStyle; }
-
- /**
* Sets the hair style and color for this player.
- *
- * NOTE: This method was necessary for convenience in the 0.0 client.
- * It should be removed here since the server can provide the hair ID
- * and coloring the same way it does for other equipment pieces. Then
- * Being::setSprite can be used instead.
*/
void setHairStyle(int style, int color);
@@ -139,10 +116,15 @@ class Player : public Being
// Character guild information
std::map<int, Guild*> mGuilds;
+ /**
+ * Triggers a visual/audio effect, such as `level up'
+ *
+ * \param effect_id ID of the effect to trigger
+ */
+ virtual void
+ triggerEffect(int effectId) { internalTriggerEffect(effectId, true, true); }
+
private:
- Gender mGender;
- Uint8 mHairStyle;
- Uint8 mHairColor;
bool mInParty;
};
diff --git a/src/properties.h b/src/properties.h
index 2eafeeca..a593e8c2 100644
--- a/src/properties.h
+++ b/src/properties.h
@@ -35,8 +35,7 @@ class Properties
/**
* Destructor.
*/
- virtual
- ~Properties() {}
+ virtual ~Properties() {}
/**
* Get a map property.
@@ -46,8 +45,8 @@ class Properties
* @return the value of the given property or the given default when it
* doesn't exist.
*/
- const std::string&
- getProperty(const std::string &name, const std::string &def = "") const
+ const std::string &getProperty(const std::string &name,
+ const std::string &def = "") const
{
PropertyMap::const_iterator i = mProperties.find(name);
return (i != mProperties.end()) ? i->second : def;
@@ -61,7 +60,7 @@ class Properties
* @return the value of the given property, or 0.0f when it doesn't
* exist.
*/
- float getFloatProperty(std::string const &name, float def = 0.0f) const
+ float getFloatProperty(const std::string &name, float def = 0.0f) const
{
PropertyMap::const_iterator i = mProperties.find(name);
float ret = def;
@@ -81,8 +80,7 @@ class Properties
* @return <code>true</code> when a property is defined,
* <code>false</code> otherwise.
*/
- bool
- hasProperty(const std::string &name) const
+ bool hasProperty(const std::string &name) const
{
return (mProperties.find(name) != mProperties.end());
}
@@ -93,8 +91,7 @@ class Properties
* @param name The name of the property.
* @param value The value of the property.
*/
- void
- setProperty(const std::string &name, const std::string &value)
+ void setProperty(const std::string &name, const std::string &value)
{
mProperties[name] = value;
}
diff --git a/src/resources/action.cpp b/src/resources/action.cpp
index ffbbffb2..bbea45c9 100644
--- a/src/resources/action.cpp
+++ b/src/resources/action.cpp
@@ -21,8 +21,6 @@
#include "action.h"
-#include <algorithm>
-
#include "animation.h"
#include "../utils/dtor.h"
@@ -34,12 +32,10 @@ Action::Action()
Action::~Action()
{
- std::for_each(mAnimations.begin(), mAnimations.end(),
- make_dtor(mAnimations));
+ delete_all(mAnimations);
}
-Animation*
-Action::getAnimation(int direction) const
+Animation *Action::getAnimation(int direction) const
{
Animations::const_iterator i = mAnimations.find(direction);
@@ -53,8 +49,7 @@ Action::getAnimation(int direction) const
return (i == mAnimations.end()) ? NULL : i->second;
}
-void
-Action::setAnimation(int direction, Animation *animation)
+void Action::setAnimation(int direction, Animation *animation)
{
mAnimations[direction] = animation;
}
diff --git a/src/resources/dye.cpp b/src/resources/dye.cpp
index 3be105d8..d180d725 100644
--- a/src/resources/dye.cpp
+++ b/src/resources/dye.cpp
@@ -26,7 +26,7 @@
#include "../log.h"
-Palette::Palette(std::string const &description)
+Palette::Palette(const std::string &description)
{
int size = description.length();
if (size == 0) return;
@@ -109,7 +109,7 @@ void Palette::getColor(int intensity, int color[3]) const
color[2] = ((255 - t) * b1 + t * b2) / 255;
}
-Dye::Dye(std::string const &description)
+Dye::Dye(const std::string &description)
{
for (int i = 0; i < 7; ++i)
mPalettes[i] = 0;
@@ -175,7 +175,7 @@ void Dye::update(int color[3]) const
mPalettes[i - 1]->getColor(cmax, color);
}
-void Dye::instantiate(std::string &target, std::string const &palettes)
+void Dye::instantiate(std::string &target, const std::string &palettes)
{
std::string::size_type next_pos = target.find('|');
if (next_pos == std::string::npos || palettes.empty()) return;
diff --git a/src/resources/dye.h b/src/resources/dye.h
index 528a1d91..f0bd7aab 100644
--- a/src/resources/dye.h
+++ b/src/resources/dye.h
@@ -36,7 +36,7 @@ class Palette
* The string is either a file name or a sequence of hexadecimal RGB
* values separated by ',' and starting with '#'.
*/
- Palette(std::string const &);
+ Palette(const std::string &);
/**
* Gets a pixel color depending on its intensity.
@@ -63,7 +63,7 @@ class Dye
* The parts of string are separated by semi-colons. Each part starts
* by an uppercase letter, followed by a colon and then a palette name.
*/
- Dye(std::string const &);
+ Dye(const std::string &);
/**
* Destroys the associated palettes.
@@ -79,7 +79,7 @@ class Dye
* Fills the blank in a dye placeholder with some palette names.
*/
static void instantiate(std::string &target,
- std::string const &palettes);
+ const std::string &palettes);
private:
diff --git a/src/resources/imageloader.cpp b/src/resources/imageloader.cpp
index 29458ba3..835ba100 100644
--- a/src/resources/imageloader.cpp
+++ b/src/resources/imageloader.cpp
@@ -88,7 +88,7 @@ void ProxyImage::convertToDisplayFormat()
mSDLImage = NULL;
}
-gcn::Image *ImageLoader::load(std::string const &filename, bool convert)
+gcn::Image *ImageLoader::load(const std::string &filename, bool convert)
{
ResourceManager *resman = ResourceManager::getInstance();
ProxyImage *i = new ProxyImage(resman->loadSDLSurface(filename));
diff --git a/src/resources/imageloader.h b/src/resources/imageloader.h
index 7979fd2f..821a0254 100644
--- a/src/resources/imageloader.h
+++ b/src/resources/imageloader.h
@@ -61,7 +61,8 @@ class ProxyImage : public gcn::Image
class ImageLoader : public gcn::ImageLoader
{
public:
- gcn::Image *load(std::string const &filename, bool convertToDisplayFormat);
+ gcn::Image *load(const std::string &filename,
+ bool convertToDisplayFormat);
};
#endif
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 01688619..04828d1b 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -176,10 +176,10 @@ void ItemDB::load()
CHECK_PARAM(name, "");
CHECK_PARAM(image, "");
- // CHECK_PARAM(description, "");
- // CHECK_PARAM(effect, "");
+ CHECK_PARAM(description, "");
+ CHECK_PARAM(effect, "");
// CHECK_PARAM(type, 0);
- CHECK_PARAM(weight, 0);
+ // CHECK_PARAM(weight, 0);
// CHECK_PARAM(slot, 0);
#undef CHECK_PARAM
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index cec74717..949d7913 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -43,9 +43,8 @@ const unsigned int DEFAULT_TILE_HEIGHT = 32;
* Inflates either zlib or gzip deflated memory. The inflated memory is
* expected to be freed by the caller.
*/
-int
-inflateMemory(unsigned char *in, unsigned int inLength,
- unsigned char *&out, unsigned int &outLength)
+int inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out, unsigned int &outLength)
{
int bufferSize = 256 * 1024;
int ret;
@@ -109,9 +108,8 @@ inflateMemory(unsigned char *in, unsigned int inLength,
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
-int
-inflateMemory(unsigned char *in, unsigned int inLength,
- unsigned char *&out)
+int inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out)
{
unsigned int outLength = 0;
int ret = inflateMemory(in, inLength, out, outLength);
@@ -143,8 +141,7 @@ inflateMemory(unsigned char *in, unsigned int inLength,
return outLength;
}
-Map*
-MapReader::readMap(const std::string &filename)
+Map *MapReader::readMap(const std::string &filename)
{
// Load the file through resource manager
ResourceManager *resman = ResourceManager::getInstance();
@@ -201,8 +198,7 @@ MapReader::readMap(const std::string &filename)
return map;
}
-Map*
-MapReader::readMap(xmlNodePtr node, const std::string &path)
+Map *MapReader::readMap(xmlNodePtr node, const std::string &path)
{
// Take the filename off the path
const std::string pathDir = path.substr(0, path.rfind("/") + 1);
@@ -280,8 +276,7 @@ MapReader::readMap(xmlNodePtr node, const std::string &path)
return map;
}
-void
-MapReader::readProperties(xmlNodePtr node, Properties* props)
+void MapReader::readProperties(xmlNodePtr node, Properties *props)
{
for_each_xml_child_node(childNode, node)
{
@@ -311,8 +306,7 @@ static void setTile(Map *map, MapLayer *layer, int x, int y, int gid)
}
}
-void
-MapReader::readLayer(xmlNodePtr node, Map *map)
+void MapReader::readLayer(xmlNodePtr node, Map *map)
{
// Layers are not necessarily the same size as the map
const int w = XML::getProperty(node, "width", map->getWidth());
@@ -406,7 +400,13 @@ MapReader::readLayer(xmlNodePtr node, Map *map)
setTile(map, layer, x, y, gid);
x++;
- if (x == w) {x = 0; y++;}
+ if (x == w) {
+ x = 0; y++;
+
+ // When we're done, don't crash on too much data
+ if (y == h)
+ break;
+ }
}
free(binData);
}
@@ -440,10 +440,9 @@ MapReader::readLayer(xmlNodePtr node, Map *map)
}
}
-Tileset*
-MapReader::readTileset(xmlNodePtr node,
- const std::string &path,
- Map *map)
+Tileset *MapReader::readTileset(xmlNodePtr node,
+ const std::string &path,
+ Map *map)
{
if (xmlHasProp(node, BAD_CAST "source"))
{
diff --git a/src/resources/mapreader.h b/src/resources/mapreader.h
index 0142eb45..04e83b99 100644
--- a/src/resources/mapreader.h
+++ b/src/resources/mapreader.h
@@ -39,15 +39,13 @@ class MapReader
/**
* Read an XML map from a file.
*/
- static Map*
- readMap(const std::string &filename);
+ static Map *readMap(const std::string &filename);
/**
* Read an XML map from a parsed XML tree. The path is used to find the
* location of referenced tileset images.
*/
- static Map*
- readMap(xmlNodePtr node, const std::string &path);
+ static Map *readMap(xmlNodePtr node, const std::string &path);
private:
/**
@@ -57,26 +55,23 @@ class MapReader
* @param props The Properties instance to which the properties will
* be assigned.
*/
- static void
- readProperties(xmlNodePtr node, Properties* props);
+ static void readProperties(xmlNodePtr node, Properties* props);
/**
* Reads a map layer and adds it to the given map.
*/
- static void
- readLayer(xmlNodePtr node, Map *map);
+ static void readLayer(xmlNodePtr node, Map *map);
/**
* Reads a tile set.
*/
- static Tileset*
- readTileset(xmlNodePtr node, const std::string &path, Map *map);
+ static Tileset *readTileset(xmlNodePtr node, const std::string &path,
+ Map *map);
/**
* Gets an integer property from an xmlNodePtr.
*/
- static int
- getProperty(xmlNodePtr node, const char* name, int def);
+ static int getProperty(xmlNodePtr node, const char* name, int def);
};
#endif
diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp
index 1d198a96..ed4acd38 100644
--- a/src/resources/monsterdb.cpp
+++ b/src/resources/monsterdb.cpp
@@ -19,8 +19,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <algorithm>
-
#include "monsterdb.h"
#include "resourcemanager.h"
@@ -44,7 +42,7 @@ MonsterDB::load()
if (mLoaded)
return;
- mUnknown.setSprite("error.xml");
+ mUnknown.addSprite("error.xml");
mUnknown.setName("unnamed");
logger->log("Initializing monster database...");
@@ -94,7 +92,7 @@ MonsterDB::load()
{
if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite"))
{
- currentInfo->setSprite((const char*) spriteNode->xmlChildrenNode->content);
+ currentInfo->addSprite((const char*) spriteNode->xmlChildrenNode->content);
}
else if (xmlStrEqual(spriteNode->name, BAD_CAST "sound"))
{
@@ -147,19 +145,16 @@ MonsterDB::load()
mLoaded = true;
}
-void
-MonsterDB::unload()
+void MonsterDB::unload()
{
- for_each(mMonsterInfos.begin(), mMonsterInfos.end(),
- make_dtor(mMonsterInfos));
+ delete_all(mMonsterInfos);
mMonsterInfos.clear();
mLoaded = false;
}
-const MonsterInfo&
-MonsterDB::get(int id)
+const MonsterInfo &MonsterDB::get(int id)
{
MonsterInfoIterator i = mMonsterInfos.find(id);
diff --git a/src/resources/monsterinfo.cpp b/src/resources/monsterinfo.cpp
index bac9c35f..1e982213 100644
--- a/src/resources/monsterinfo.cpp
+++ b/src/resources/monsterinfo.cpp
@@ -23,8 +23,7 @@
#include "../utils/dtor.h"
-MonsterInfo::MonsterInfo():
- mSprite("error.xml")
+MonsterInfo::MonsterInfo()
{
}
diff --git a/src/resources/monsterinfo.h b/src/resources/monsterinfo.h
index f13c2f7c..88f6fb2b 100644
--- a/src/resources/monsterinfo.h
+++ b/src/resources/monsterinfo.h
@@ -67,7 +67,8 @@ class MonsterInfo
setName(const std::string &name) { mName = name; }
void
- setSprite(const std::string &filename) { mSprite = filename; }
+ addSprite(const std::string &filename)
+ { mSprites.push_back(filename); }
void
setTargetCursorSize(Being::TargetCursorSize targetCursorSize)
@@ -82,8 +83,8 @@ class MonsterInfo
const std::string&
getName() const { return mName; }
- const std::string&
- getSprite() const { return mSprite; }
+ const std::list<std::string>&
+ getSprites() const { return mSprites; }
Being::TargetCursorSize
getTargetCursorSize() const { return mTargetCursorSize; }
@@ -106,7 +107,7 @@ class MonsterInfo
private:
std::string mName;
- std::string mSprite;
+ std::list<std::string> mSprites;
Being::TargetCursorSize mTargetCursorSize;
std::map<MonsterSoundEvent, std::vector<std::string>* > mSounds;
std::map<int, MonsterAttack*> mMonsterAttacks;
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 8ee64452..bebd17f8 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -93,8 +93,7 @@ ResourceManager::~ResourceManager()
}
}
-void
-ResourceManager::cleanUp(Resource *res)
+void ResourceManager::cleanUp(Resource *res)
{
logger->log("ResourceManager::~ResourceManager() cleaning up %d "
"reference%s to %s",
@@ -126,24 +125,22 @@ void ResourceManager::cleanOrphans()
else
{
logger->log("ResourceManager::release(%s)", res->mIdPath.c_str());
- delete res;
ResourceIterator toErase = iter;
++iter;
mOrphanedResources.erase(toErase);
+ delete res; // delete only after removal from list, to avoid issues in recursion
}
}
mOldestOrphan = oldest;
}
-bool
-ResourceManager::setWriteDir(const std::string &path)
+bool ResourceManager::setWriteDir(const std::string &path)
{
return (bool) PHYSFS_setWriteDir(path.c_str());
}
-bool
-ResourceManager::addToSearchPath(const std::string &path, bool append)
+bool ResourceManager::addToSearchPath(const std::string &path, bool append)
{
logger->log("Adding to PhysicsFS: %s", path.c_str());
if (!PHYSFS_addToSearchPath(path.c_str(), append ? 1 : 0)) {
@@ -153,8 +150,7 @@ ResourceManager::addToSearchPath(const std::string &path, bool append)
return true;
}
-void
-ResourceManager::searchAndAddArchives(const std::string &path,
+void ResourceManager::searchAndAddArchives(const std::string &path,
const std::string &ext,
bool append)
{
@@ -180,31 +176,27 @@ ResourceManager::searchAndAddArchives(const std::string &path,
PHYSFS_freeList(list);
}
-bool
-ResourceManager::mkdir(const std::string &path)
+bool ResourceManager::mkdir(const std::string &path)
{
return (bool) PHYSFS_mkdir(path.c_str());
}
-bool
-ResourceManager::exists(const std::string &path)
+bool ResourceManager::exists(const std::string &path)
{
return PHYSFS_exists(path.c_str());
}
-bool
-ResourceManager::isDirectory(const std::string &path)
+bool ResourceManager::isDirectory(const std::string &path)
{
return PHYSFS_isDirectory(path.c_str());
}
-std::string
-ResourceManager::getPath(const std::string &file)
+std::string ResourceManager::getPath(const std::string &file)
{
// get the real path to the file
const char* tmp = PHYSFS_getRealDir(file.c_str());
std::string path;
-
+
// if the file is not in the search path, then its NULL
if (tmp)
{
@@ -215,11 +207,12 @@ ResourceManager::getPath(const std::string &file)
// if not found in search path return the default path
path = std::string(TMW_DATADIR) + std::string("data") + "/" + file;
}
-
+
return path;
}
-Resource *ResourceManager::get(std::string const &idPath, generator fun, void *data)
+Resource *ResourceManager::get(const std::string &idPath, generator fun,
+ void *data)
{
// Check if the id exists, and return the value if it does.
ResourceIterator resIter = mResources.find(idPath);
@@ -270,20 +263,18 @@ struct ResourceLoader
}
};
-Resource *ResourceManager::load(std::string const &path, loader fun)
+Resource *ResourceManager::load(const std::string &path, loader fun)
{
ResourceLoader l = { this, path, fun };
return get(path, ResourceLoader::load, &l);
}
-Music*
-ResourceManager::getMusic(const std::string &idPath)
+Music *ResourceManager::getMusic(const std::string &idPath)
{
return static_cast<Music*>(load(idPath, Music::load));
}
-SoundEffect*
-ResourceManager::getSoundEffect(const std::string &idPath)
+SoundEffect *ResourceManager::getSoundEffect(const std::string &idPath)
{
return static_cast<SoundEffect*>(load(idPath, SoundEffect::load));
}
@@ -314,7 +305,7 @@ struct DyedImageLoader
}
};
-Image *ResourceManager::getImage(std::string const &idPath)
+Image *ResourceManager::getImage(const std::string &idPath)
{
DyedImageLoader l = { this, idPath };
return static_cast<Image*>(get(idPath, DyedImageLoader::load, &l));
@@ -336,8 +327,8 @@ struct ImageSetLoader
}
};
-ImageSet*
-ResourceManager::getImageSet(const std::string &imagePath, int w, int h)
+ImageSet *ResourceManager::getImageSet(const std::string &imagePath,
+ int w, int h)
{
ImageSetLoader l = { this, imagePath, w, h };
std::stringstream ss;
@@ -356,8 +347,7 @@ struct SpriteDefLoader
}
};
-SpriteDef *ResourceManager::getSprite
- (std::string const &path, int variant)
+SpriteDef *ResourceManager::getSprite(const std::string &path, int variant)
{
SpriteDefLoader l = { path, variant };
std::stringstream ss;
@@ -383,23 +373,21 @@ void ResourceManager::release(Resource *res)
mResources.erase(resIter);
}
-ResourceManager*
-ResourceManager::getInstance()
+ResourceManager *ResourceManager::getInstance()
{
// Create a new instance if necessary.
- if (instance == NULL) instance = new ResourceManager();
+ if (!instance)
+ instance = new ResourceManager();
return instance;
}
-void
-ResourceManager::deleteInstance()
+void ResourceManager::deleteInstance()
{
delete instance;
instance = NULL;
}
-void*
-ResourceManager::loadFile(const std::string &fileName, int &fileSize)
+void *ResourceManager::loadFile(const std::string &fileName, int &fileSize)
{
// Attempt to open the specified file using PhysicsFS
PHYSFS_file *file = PHYSFS_openRead(fileName.c_str());
@@ -451,8 +439,7 @@ ResourceManager::loadTextFile(const std::string &fileName)
return lines;
}
-SDL_Surface*
-ResourceManager::loadSDLSurface(const std::string& filename)
+SDL_Surface *ResourceManager::loadSDLSurface(const std::string& filename)
{
int fileSize;
void *buffer = loadFile(filename, fileSize);
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index 66813a9c..e70dfb9d 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -64,8 +64,7 @@ class ResourceManager
* @param path The path of the directory to be added.
* @return <code>true</code> on success, <code>false</code> otherwise.
*/
- bool
- setWriteDir(const std::string &path);
+ bool setWriteDir(const std::string &path);
/**
* Adds a directory or archive to the search path. If append is true
@@ -74,37 +73,33 @@ class ResourceManager
*
* @return <code>true</code> on success, <code>false</code> otherwise.
*/
- bool
- addToSearchPath(const std::string &path, bool append);
+ bool addToSearchPath(const std::string &path, bool append);
/**
* Searches for zip files and adds them to the search path.
*/
- void
- searchAndAddArchives(const std::string &path,
- const std::string &ext,
- bool append);
+ void searchAndAddArchives(const std::string &path,
+ const std::string &ext,
+ bool append);
/**
* Creates a directory in the write path
*/
- bool
- mkdir(const std::string &path);
+ bool mkdir(const std::string &path);
/**
* Checks whether the given file or directory exists in the search path
*/
- bool
- exists(const std::string &path);
+ bool exists(const std::string &path);
/**
* Checks whether the given path is a directory.
*/
- bool
- isDirectory(const std::string &path);
-
+ bool isDirectory(const std::string &path);
+
/**
- * Returns the real path to a file
+ * Returns the real path to a file. Note that this method will always
+ * return a path, it does not check whether the file exists.
*
* @param file The file to get the real path to.
* @return The real path.
@@ -120,7 +115,7 @@ class ResourceManager
* @return A valid resource or <code>NULL</code> if the resource could
* not be generated.
*/
- Resource *get(std::string const &idPath, generator fun, void *data);
+ Resource *get(const std::string &idPath, generator fun, void *data);
/**
* Loads a resource from a file and adds it to the resource map.
@@ -130,41 +125,37 @@ class ResourceManager
* @return A valid resource or <code>NULL</code> if the resource could
* not be loaded.
*/
- Resource *load(std::string const &path, loader fun);
+ Resource *load(const std::string &path, loader fun);
/**
* Convenience wrapper around ResourceManager::get for loading
* images.
*/
- Image*
- getImage(const std::string &idPath);
+ Image *getImage(const std::string &idPath);
/**
* Convenience wrapper around ResourceManager::get for loading
* songs.
*/
- Music*
- getMusic(const std::string &idPath);
+ Music *getMusic(const std::string &idPath);
/**
* Convenience wrapper around ResourceManager::get for loading
* samples.
*/
- SoundEffect*
- getSoundEffect(const std::string &idPath);
+ SoundEffect *getSoundEffect(const std::string &idPath);
/**
* Creates a image set based on the image referenced by the given
* path and the supplied sprite sizes
*/
- ImageSet*
- getImageSet(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
* variant.
*/
- SpriteDef *getSprite(std::string const &path, int variant = 0);
+ SpriteDef *getSprite(const std::string &path, int variant = 0);
/**
* Releases a resource, placing it in the set of orphaned resources.
@@ -181,41 +172,35 @@ class ResourceManager
* @return An allocated byte array containing the data that was loaded,
* or <code>NULL</code> on fail.
*/
- void*
- loadFile(const std::string &fileName, int &fileSize);
+ void *loadFile(const std::string &fileName, int &fileSize);
/**
* Retrieves the contents of a text file.
*/
- std::vector<std::string>
- loadTextFile(const std::string &fileName);
+ std::vector<std::string> loadTextFile(const std::string &fileName);
/**
* Loads the given filename as an SDL surface. The returned surface is
* expected to be freed by the caller using SDL_FreeSurface.
*/
- SDL_Surface*
- loadSDLSurface(const std::string& filename);
+ SDL_Surface *loadSDLSurface(const std::string& filename);
/**
* Returns an instance of the class, creating one if it does not
* already exist.
*/
- static ResourceManager*
- getInstance();
+ static ResourceManager *getInstance();
/**
* Deletes the class instance if it exists.
*/
- static void
- deleteInstance();
+ static void deleteInstance();
private:
/**
* Deletes the resource after logging a cleanup message.
*/
- static void
- cleanUp(Resource *resource);
+ static void cleanUp(Resource *resource);
void cleanOrphans();
diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp
index 5aea55fa..f5b763ea 100644
--- a/src/resources/spritedef.cpp
+++ b/src/resources/spritedef.cpp
@@ -33,8 +33,7 @@
#include "../log.h"
#include "../utils/xml.h"
-Action*
-SpriteDef::getAction(SpriteAction action) const
+Action *SpriteDef::getAction(SpriteAction action) const
{
Actions::const_iterator i = mActions.find(action);
@@ -47,7 +46,7 @@ SpriteDef::getAction(SpriteAction action) const
return i->second;
}
-SpriteDef *SpriteDef::load(std::string const &animationFile, int variant)
+SpriteDef *SpriteDef::load(const std::string &animationFile, int variant)
{
std::string::size_type pos = animationFile.find('|');
std::string palettes;
@@ -122,7 +121,7 @@ void SpriteDef::loadSprite(xmlNodePtr spriteNode, int variant,
}
}
-void SpriteDef::loadImageSet(xmlNodePtr node, std::string const &palettes)
+void SpriteDef::loadImageSet(xmlNodePtr node, const std::string &palettes)
{
const std::string name = XML::getProperty(node, "name", "");
@@ -147,8 +146,7 @@ void SpriteDef::loadImageSet(xmlNodePtr node, std::string const &palettes)
mImageSets[name] = imageSet;
}
-void
-SpriteDef::loadAction(xmlNodePtr node, int variant_offset)
+void SpriteDef::loadAction(xmlNodePtr node, int variant_offset)
{
const std::string actionName = XML::getProperty(node, "name", "");
const std::string imageSetName = XML::getProperty(node, "imageset", "");
@@ -188,10 +186,9 @@ SpriteDef::loadAction(xmlNodePtr node, int variant_offset)
}
}
-void
-SpriteDef::loadAnimation(xmlNodePtr animationNode,
- Action *action, ImageSet *imageSet,
- int variant_offset)
+void SpriteDef::loadAnimation(xmlNodePtr animationNode,
+ Action *action, ImageSet *imageSet,
+ int variant_offset)
{
const std::string directionName =
XML::getProperty(animationNode, "direction", "");
@@ -268,8 +265,7 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
} // for frameNode
}
-void
-SpriteDef::includeSprite(xmlNodePtr includeNode)
+void SpriteDef::includeSprite(xmlNodePtr includeNode)
{
// TODO: Perform circular dependency check, since it's easy to crash the
// client this way.
@@ -290,8 +286,7 @@ SpriteDef::includeSprite(xmlNodePtr includeNode)
loadSprite(rootNode, 0);
}
-void
-SpriteDef::substituteAction(SpriteAction complete, SpriteAction with)
+void SpriteDef::substituteAction(SpriteAction complete, SpriteAction with)
{
if (mActions.find(complete) == mActions.end())
{
@@ -325,8 +320,7 @@ SpriteDef::~SpriteDef()
}
}
-SpriteAction
-SpriteDef::makeSpriteAction(const std::string& action)
+SpriteAction SpriteDef::makeSpriteAction(const std::string &action)
{
if (action == "" || action == "default") {
return ACTION_DEFAULT;
@@ -408,8 +402,7 @@ SpriteDef::makeSpriteAction(const std::string& action)
}
}
-SpriteDirection
-SpriteDef::makeSpriteDirection(const std::string& direction)
+SpriteDirection SpriteDef::makeSpriteDirection(const std::string& direction)
{
if (direction == "" || direction == "default") {
return DIRECTION_DEFAULT;
@@ -428,5 +421,5 @@ SpriteDef::makeSpriteDirection(const std::string& direction)
}
else {
return DIRECTION_INVALID;
- };
+ }
}
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
index 56b9a713..0c3e443b 100644
--- a/src/resources/spritedef.h
+++ b/src/resources/spritedef.h
@@ -81,7 +81,7 @@ class SpriteDef : public Resource
/**
* Loads a sprite definition file.
*/
- static SpriteDef *load(std::string const &file, int variant);
+ static SpriteDef *load(const std::string &file, int variant);
/**
* Returns the specified action.
@@ -91,8 +91,7 @@ class SpriteDef : public Resource
/**
* Converts a string into a SpriteAction enum.
*/
- static SpriteAction
- makeSpriteAction(const std::string &action);
+ static SpriteAction makeSpriteAction(const std::string &action);
private:
/**
@@ -114,27 +113,24 @@ class SpriteDef : public Resource
/**
* Loads an imageset element.
*/
- void loadImageSet(xmlNodePtr node, std::string const &palettes);
+ void loadImageSet(xmlNodePtr node, const std::string &palettes);
/**
* Loads an action element.
*/
- void
- loadAction(xmlNodePtr node, int variant_offset);
+ void loadAction(xmlNodePtr node, int variant_offset);
/**
* Loads an animation element.
*/
- void
- loadAnimation(xmlNodePtr animationNode,
- Action *action, ImageSet *imageSet,
- int variant_offset);
+ void loadAnimation(xmlNodePtr animationNode,
+ Action *action, ImageSet *imageSet,
+ int variant_offset);
/**
* Include another sprite into this one.
*/
- void
- includeSprite(xmlNodePtr includeNode);
+ void includeSprite(xmlNodePtr includeNode);
/**
* Complete missing actions by copying existing ones.
@@ -145,8 +141,7 @@ class SpriteDef : public Resource
* When there are no animations defined for the action "complete", its
* animations become a copy of those of the action "with".
*/
- void
- substituteAction(SpriteAction complete, SpriteAction with);
+ void substituteAction(SpriteAction complete, SpriteAction with);
/**
* Converts a string into a SpriteDirection enum.
diff --git a/src/textparticle.h b/src/textparticle.h
index 3a0ba674..d56dbf84 100644
--- a/src/textparticle.h
+++ b/src/textparticle.h
@@ -37,11 +37,11 @@ class TextParticle : public Particle
TextParticle(Map *map, const std::string &text,
int colorR, int colorG, int colorB,
gcn::Font *font);
+
/**
* Draws the particle image.
*/
- virtual void
- draw(Graphics *graphics, int offsetX, int offsetY) const;
+ virtual void draw(Graphics *graphics, int offsetX, int offsetY) const;
// hack to improve text visibility
virtual int getPixelY() const
diff --git a/src/utils/mutex.h b/src/utils/mutex.h
new file mode 100644
index 00000000..62c6b4e1
--- /dev/null
+++ b/src/utils/mutex.h
@@ -0,0 +1,97 @@
+/*
+ * The Mana World
+ * Copyright 2008 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
+ */
+
+#ifndef TMW_MUTEX_H
+#define TMW_MUTEX_H
+
+#include <SDL_thread.h>
+
+#include "../log.h"
+
+/**
+ * A mutex provides mutual exclusion of access to certain data that is
+ * accessed by multiple threads.
+ */
+class Mutex
+{
+public:
+ Mutex();
+ ~Mutex();
+
+ void lock();
+ void unlock();
+
+private:
+ Mutex(const Mutex&); // prevent copying
+ Mutex& operator=(const Mutex&);
+
+ SDL_mutex *mMutex;
+};
+
+/**
+ * A convenience class for locking a mutex.
+ */
+class MutexLocker
+{
+public:
+ MutexLocker(Mutex *mutex);
+ ~MutexLocker();
+
+private:
+ Mutex *mMutex;
+};
+
+
+inline Mutex::Mutex()
+{
+ mMutex = SDL_CreateMutex();
+}
+
+inline Mutex::~Mutex()
+{
+ SDL_DestroyMutex(mMutex);
+}
+
+inline void Mutex::lock()
+{
+ if (SDL_mutexP(mMutex) == -1)
+ logger->log("Mutex locking failed: %s", SDL_GetError());
+}
+
+inline void Mutex::unlock()
+{
+ if (SDL_mutexV(mMutex) == -1)
+ logger->log("Mutex unlocking failed: %s", SDL_GetError());
+}
+
+
+inline MutexLocker::MutexLocker(Mutex *mutex):
+ mMutex(mutex)
+{
+ mMutex->lock();
+}
+
+inline MutexLocker::~MutexLocker()
+{
+ mMutex->unlock();
+}
+
+#endif // TMW_MUTEX_H
diff --git a/src/utils/strprintf.cpp b/src/utils/strprintf.cpp
index c8a8a247..c5d7a595 100644
--- a/src/utils/strprintf.cpp
+++ b/src/utils/strprintf.cpp
@@ -19,10 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _TMW_UTILS_TOSTRING_H
-#define _TMW_UTILS_TOSTRING_H
-
#include <cstdarg>
+#include <cstdio>
#include "strprintf.h"
@@ -47,5 +45,3 @@ std::string strprintf(char const *format, ...)
delete [] buf2;
return res;
}
-
-#endif