summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/animatedsprite.cpp382
-rw-r--r--src/animatedsprite.h178
-rw-r--r--src/animation.cpp387
-rw-r--r--src/animation.h135
-rw-r--r--src/being.cpp169
-rw-r--r--src/being.h11
-rw-r--r--src/configuration.cpp56
-rw-r--r--src/engine.cpp15
-rw-r--r--src/game.cpp30
-rw-r--r--src/gui/browserbox.h1
-rw-r--r--src/gui/chat.cpp81
-rw-r--r--src/gui/chat.h9
-rw-r--r--src/gui/gui.cpp7
-rw-r--r--src/gui/setup_video.cpp1
-rw-r--r--src/gui/updatewindow.cpp2
-rw-r--r--src/main.cpp29
-rw-r--r--src/monster.cpp4
-rw-r--r--src/npc.cpp2
-rw-r--r--src/openglgraphics.cpp2
-rw-r--r--src/player.cpp47
-rw-r--r--src/resources/image.h2
-rw-r--r--src/resources/itemmanager.cpp4
-rw-r--r--src/resources/mapreader.cpp214
-rw-r--r--src/resources/openglsdlimageloader.cpp6
25 files changed, 943 insertions, 833 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 13ec7308..42671f64 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -183,6 +183,8 @@ tmw_SOURCES = graphic/imagerect.h \
resources/buddylist.cpp \
utils/dtor.h \
utils/tostring.h \
+ animatedsprite.cpp \
+ animatedsprite.h \
animation.cpp \
animation.h \
base64.cpp \
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
new file mode 100644
index 00000000..d1201042
--- /dev/null
+++ b/src/animatedsprite.cpp
@@ -0,0 +1,382 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id: animation.cpp 2430 2006-07-24 00:13:24Z b_lindeijer $
+ */
+
+#include "animatedsprite.h"
+
+#include "animation.h"
+#include "graphics.h"
+#include "log.h"
+
+#include "resources/resourcemanager.h"
+#include "resources/spriteset.h"
+
+AnimatedSprite::AnimatedSprite(const std::string& animationFile, int variant):
+ mAction(NULL),
+ mDirection(DIRECTION_DOWN),
+ mLastTime(0),
+ mSpeed(1.0f)
+{
+ int size;
+ ResourceManager *resman = ResourceManager::getInstance();
+ char *data = (char*)resman->loadFile(animationFile.c_str(), size);
+
+ if (!data) {
+ logger->error("Animation: Could not find " + animationFile + "!");
+ }
+
+ xmlDocPtr doc = xmlParseMemory(data, size);
+ free(data);
+
+ if (!doc) {
+ logger->error("Animation: Error while parsing animation definition file!");
+ }
+
+ xmlNodePtr node = xmlDocGetRootElement(doc);
+ if (!node || !xmlStrEqual(node->name, BAD_CAST "sprite")) {
+ logger->error("Animation: this is not a valid animation definition file!");
+ }
+
+ // Get the variant
+ int variant_num = getProperty(node, "variants", 0);
+ int variant_offset = getProperty(node, "variant_offset", 0);
+
+ if (variant_num > 0 && variant < variant_num ) {
+ variant_offset *= variant;
+ } else {
+ variant_offset = 0;
+ }
+
+ for (node = node->xmlChildrenNode; node != NULL; node = node->next)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "imageset"))
+ {
+ int width = getProperty(node, "width", 0);
+ int height = getProperty(node, "height", 0);
+ std::string name = getProperty(node, "name", "");
+ std::string imageSrc = getProperty(node, "src", "");
+
+ Spriteset *spriteset =
+ resman->getSpriteset(imageSrc, width, height);
+
+ if (!spriteset) {
+ logger->error("Couldn't load spriteset!");
+ }
+
+ mSpritesets[name] = spriteset;
+ }
+ // get action
+ else if (xmlStrEqual(node->name, BAD_CAST "action"))
+ {
+ std::string name = getProperty(node, "name", "");
+ std::string imageset = getProperty(node, "imageset", "");
+
+ if (name.empty())
+ {
+ logger->log("Warning: unnamed action in %s",
+ animationFile.c_str());
+ }
+ if (mSpritesets.find(imageset) == mSpritesets.end()) {
+ logger->log("Warning: imageset \"%s\" not defined in %s",
+ imageset.c_str(),
+ animationFile.c_str());
+
+ // skip loading animations
+ continue;
+ }
+
+ Action *action = new Action();
+
+ action->setSpriteset(mSpritesets[imageset]);
+ mActions[makeSpriteAction(name)] = action;
+
+ // get animations
+ for (xmlNodePtr animationNode = node->xmlChildrenNode;
+ animationNode != NULL;
+ animationNode = animationNode->next)
+ {
+ // We're only interested in animations
+ if (!xmlStrEqual(animationNode->name, BAD_CAST "animation"))
+ continue;
+
+ std::string dir = getProperty(animationNode, "direction", "");
+ Animation *animation = new Animation();
+ action->setAnimation(makeSpriteDirection(dir), animation);
+
+ // Get animation phases
+ for (xmlNodePtr phaseNode = animationNode->xmlChildrenNode;
+ phaseNode != NULL;
+ phaseNode = phaseNode->next)
+ {
+ int delay = getProperty(phaseNode, "delay", 0);
+
+ if (xmlStrEqual(phaseNode->name, BAD_CAST "frame"))
+ {
+ int index = getProperty(phaseNode, "index", -1);
+ int offsetX = getProperty(phaseNode, "offsetX", 0);
+ int offsetY = getProperty(phaseNode, "offsetY", 0);
+
+ offsetY -= mSpritesets[imageset]->getHeight() - 32;
+ offsetX -= mSpritesets[imageset]->getWidth() / 2 - 16;
+ animation->addPhase(index + variant_offset, delay,
+ offsetX, offsetY);
+ }
+ else if (xmlStrEqual(phaseNode->name, BAD_CAST "sequence"))
+ {
+ int start = getProperty(phaseNode, "start", 0);
+ int end = getProperty(phaseNode, "end", 0);
+ int offsetY = -mSpritesets[imageset]->getHeight() + 32;
+ int offsetX = -mSpritesets[imageset]->getWidth() / 2 + 16;
+ while (end >= start)
+ {
+ animation->addPhase(start + variant_offset,
+ delay, offsetX, offsetY);
+ start++;
+ }
+ }
+ } // for phaseNode
+ } // for animationNode
+ } // if "<imageset>" else if "<action>"
+ } // for node
+
+ // Complete missing actions
+ substituteAction(ACTION_WALK, ACTION_STAND);
+ substituteAction(ACTION_WALK, ACTION_RUN);
+ substituteAction(ACTION_ATTACK, ACTION_STAND);
+ substituteAction(ACTION_ATTACK_SWING, ACTION_ATTACK);
+ substituteAction(ACTION_ATTACK_STAB, ACTION_ATTACK_SWING);
+ substituteAction(ACTION_ATTACK_BOW, ACTION_ATTACK_STAB);
+ substituteAction(ACTION_ATTACK_THROW, ACTION_ATTACK_SWING);
+ substituteAction(ACTION_CAST_MAGIC, ACTION_ATTACK_SWING);
+ substituteAction(ACTION_USE_ITEM, ACTION_CAST_MAGIC);
+ substituteAction(ACTION_SIT, ACTION_STAND);
+ substituteAction(ACTION_SLEEP, ACTION_SIT);
+ substituteAction(ACTION_HURT, ACTION_STAND);
+ substituteAction(ACTION_DEAD, ACTION_HURT);
+
+ // Play the stand animation by default
+ play(ACTION_STAND);
+
+ xmlFreeDoc(doc);
+}
+
+int
+AnimatedSprite::getProperty(xmlNodePtr node, const char* name, int def)
+{
+ int &ret = def;
+
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+ if (prop) {
+ ret = atoi((char*)prop);
+ xmlFree(prop);
+ }
+
+ return ret;
+}
+
+std::string
+AnimatedSprite::getProperty(xmlNodePtr node, const char* name,
+ const std::string& def)
+{
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+ if (prop) {
+ std::string val = (char*)prop;
+ xmlFree(prop);
+ return val;
+ }
+
+ return def;
+}
+
+void
+AnimatedSprite::substituteAction(SpriteAction complete,
+ SpriteAction with)
+{
+ if (mActions.find(complete) == mActions.end())
+ {
+ ActionIterator i = mActions.find(with);
+ if (i != mActions.end()) {
+ mActions[complete] = i->second;
+ }
+ }
+}
+
+AnimatedSprite::~AnimatedSprite()
+{
+ for (SpritesetIterator i = mSpritesets.begin(); i != mSpritesets.end(); ++i)
+ {
+ i->second->decRef();
+ }
+ mSpritesets.clear();
+}
+
+void
+AnimatedSprite::reset()
+{
+ // Reset all defined actions (because of aliases, some will be resetted
+ // multiple times)
+ for (ActionIterator i = mActions.begin(); i != mActions.end(); ++i)
+ {
+ //TODO: If resetting everything is really a nice way of fixing the
+ // synchronization issues, finish implementing this.
+ //i->second->reset();
+ }
+}
+
+void
+AnimatedSprite::play(SpriteAction action, int time)
+{
+ ActionIterator i = mActions.find(action);
+
+ if (i == mActions.end())
+ {
+ logger->log("Warning: no action \"%u\" defined!", action);
+ mAction = NULL;
+ return;
+ }
+
+ if (mAction != i->second)
+ {
+ mAction = i->second;
+ mLastTime = 0;
+ }
+
+ if (!mAction || !time)
+ mSpeed = 1.0f;
+ else {
+ int animationLength = mAction->getAnimation(mDirection)->getLength();
+ mSpeed = (float) animationLength / 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 have passed yet, do nothing
+ if (time > mLastTime && mAction)
+ {
+ Animation *animation = mAction->getAnimation(mDirection);
+ animation->update((unsigned int)((time - mLastTime) * mSpeed));
+ mLastTime = time;
+ }
+}
+
+bool
+AnimatedSprite::draw(Graphics* graphics, Sint32 posX, Sint32 posY) const
+{
+ if (!mAction)
+ return false;
+
+ Animation *animation = mAction->getAnimation(mDirection);
+ int phase = animation->getCurrentPhase();
+ if (phase < 0)
+ return false;
+
+ Spriteset *spriteset = mAction->getSpriteset();
+ Image *image = spriteset->get(phase);
+ Sint32 offsetX = animation->getOffsetX();
+ Sint32 offsetY = animation->getOffsetY();
+ return graphics->drawImage(image, posX + offsetX, posY + offsetY);
+}
+
+int
+AnimatedSprite::getWidth() const
+{
+ return mAction ? mAction->getSpriteset()->getWidth() : 0;
+}
+
+int
+AnimatedSprite::getHeight() const
+{
+ return mAction ? mAction->getSpriteset()->getHeight() : 0;
+}
+
+SpriteAction
+AnimatedSprite::makeSpriteAction(const std::string& action)
+{
+ if (action == "stand") {
+ return ACTION_STAND;
+ }
+ else if (action == "walk") {
+ return ACTION_WALK;
+ }
+ else if (action == "run") {
+ return ACTION_RUN;
+ }
+ else if (action == "attack") {
+ return ACTION_ATTACK;
+ }
+ else if (action == "attack_swing") {
+ return ACTION_ATTACK_SWING;
+ }
+ else if (action == "attack_stab") {
+ return ACTION_ATTACK_STAB;
+ }
+ else if (action == "attack_bow") {
+ return ACTION_ATTACK_BOW;
+ }
+ else if (action == "attack_throw") {
+ return ACTION_ATTACK_THROW;
+ }
+ else if (action == "cast_magic") {
+ return ACTION_CAST_MAGIC;
+ }
+ else if (action == "use_item") {
+ return ACTION_USE_ITEM;
+ }
+ else if (action == "sit") {
+ return ACTION_SIT;
+ }
+ else if (action == "sleep") {
+ return ACTION_SLEEP;
+ }
+ else if (action == "hurt") {
+ return ACTION_HURT;
+ }
+ else if (action == "dead") {
+ return ACTION_DEAD;
+ }
+ else {
+ return ACTION_DEFAULT;
+ }
+}
+
+SpriteDirection
+AnimatedSprite::makeSpriteDirection(const std::string& direction)
+{
+ if (direction == "up") {
+ return DIRECTION_UP;
+ }
+ else if (direction == "left") {
+ return DIRECTION_LEFT;
+ }
+ else if (direction == "right") {
+ return DIRECTION_RIGHT;
+ }
+ else {
+ return DIRECTION_DOWN;
+ }
+}
diff --git a/src/animatedsprite.h b/src/animatedsprite.h
new file mode 100644
index 00000000..89394d6c
--- /dev/null
+++ b/src/animatedsprite.h
@@ -0,0 +1,178 @@
+/*
+ * The Mana World
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id: animation.h 2430 2006-07-24 00:13:24Z b_lindeijer $
+ */
+
+#ifndef _TMW_ANIMATEDSPRITE_H
+#define _TMW_ANIMATEDSPRITE_H
+
+#include <map>
+#include <string>
+#include <SDL_types.h>
+
+#include <libxml/tree.h>
+
+class Action;
+class Graphics;
+class Spriteset;
+
+enum SpriteAction
+{
+ ACTION_DEFAULT = 0,
+ ACTION_STAND,
+ ACTION_WALK,
+ ACTION_RUN,
+ ACTION_ATTACK,
+ ACTION_ATTACK_SWING,
+ ACTION_ATTACK_STAB,
+ ACTION_ATTACK_BOW,
+ ACTION_ATTACK_THROW,
+ ACTION_CAST_MAGIC,
+ ACTION_USE_ITEM,
+ ACTION_SIT,
+ ACTION_SLEEP,
+ ACTION_HURT,
+ ACTION_DEAD
+};
+
+enum SpriteDirection
+{
+ DIRECTION_DOWN = 0,
+ DIRECTION_UP,
+ DIRECTION_LEFT,
+ DIRECTION_RIGHT
+};
+
+/**
+ * Defines a class to load an animation.
+ */
+class AnimatedSprite
+{
+ public:
+ /**
+ * Constructor.
+ */
+ AnimatedSprite(const std::string& animationFile, int variant);
+
+ /**
+ * Destructor.
+ */
+ ~AnimatedSprite();
+
+ /**
+ * Resets the animated sprite. This is used to synchronize several
+ * animated sprites.
+ */
+ void
+ reset();
+
+ /**
+ * Plays an action using the current direction that will have a
+ * duration of the specified time, 0 means default.
+ */
+ void
+ play(SpriteAction action, int time = 0);
+
+ /**
+ * Inform the animation of the passed time so that it can output the
+ * correct animation phase.
+ */
+ void update(int time);
+
+ /**
+ * Draw the current animation phase at the coordinates given in screen
+ * pixels.
+ */
+ bool
+ draw(Graphics* graphics, Sint32 posX, Sint32 posY) const;
+
+ /**
+ * gets the width in pixels of the current animation phase.
+ */
+ int
+ getWidth() const;
+
+ /**
+ * gets the height in pixels of the current animation phase.
+ */
+ int
+ getHeight() const;
+
+ /**
+ * Sets the direction.
+ */
+ void
+ setDirection(SpriteDirection direction)
+ {
+ mDirection = direction;
+ }
+
+ private:
+ /**
+ * 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);
+
+ /**
+ * Gets an integer property from an xmlNodePtr.
+ *
+ * TODO: Same function is present in MapReader. Should probably be
+ * TODO: shared in a static utility class.
+ */
+ static int
+ getProperty(xmlNodePtr node, const char *name, int def);
+
+ /**
+ * Gets a string property from an xmlNodePtr.
+ */
+ static std::string
+ getProperty(xmlNodePtr node, const char *name, const std::string &def);
+
+ /**
+ * Converts a string into a SpriteAction enum.
+ */
+ static SpriteAction
+ makeSpriteAction(const std::string &action);
+
+ /**
+ * Converts a string into a SpriteDirection enum.
+ */
+ static SpriteDirection
+ makeSpriteDirection(const std::string &direction);
+
+
+ typedef std::map<std::string, Spriteset*> Spritesets;
+ typedef Spritesets::iterator SpritesetIterator;
+
+ typedef std::map<SpriteAction, Action*> Actions;
+ typedef Actions::iterator ActionIterator;
+
+ Spritesets mSpritesets;
+ Actions mActions;
+ Action *mAction;
+ SpriteDirection mDirection;
+ int mLastTime;
+ float mSpeed;
+};
+
+#endif
diff --git a/src/animation.cpp b/src/animation.cpp
index 313fd25c..1213d0d6 100644
--- a/src/animation.cpp
+++ b/src/animation.cpp
@@ -23,13 +23,9 @@
#include "animation.h"
-#include <cassert>
+#include <algorithm>
-#include "log.h"
-
-#include "resources/image.h"
-#include "resources/resourcemanager.h"
-#include "resources/spriteset.h"
+#include "utils/dtor.h"
Animation::Animation():
mTime(0)
@@ -41,17 +37,20 @@ void
Animation::update(unsigned int time)
{
mTime += time;
- if (!mAnimationPhases.empty())
+ if (mAnimationPhases.empty())
+ return;
+
+ unsigned int delay = iCurrentPhase->delay;
+ if (!delay)
+ return;
+
+ while (mTime > delay)
{
- unsigned int delay = iCurrentPhase->delay;
- while (mTime > delay && delay > 0)
+ mTime -= delay;
+ iCurrentPhase++;
+ if (iCurrentPhase == mAnimationPhases.end())
{
- mTime -= delay;
- iCurrentPhase++;
- if (iCurrentPhase == mAnimationPhases.end())
- {
- iCurrentPhase = mAnimationPhases.begin();
- }
+ iCurrentPhase = mAnimationPhases.begin();
}
}
}
@@ -59,25 +58,15 @@ Animation::update(unsigned int time)
int
Animation::getCurrentPhase() const
{
- if (mAnimationPhases.empty())
- {
- return -1;
- }
- else
- {
- return iCurrentPhase->image;
- }
+ return mAnimationPhases.empty() ? -1 : iCurrentPhase->image;
}
void
Animation::addPhase(int image, unsigned int delay, int offsetX, int offsetY)
{
//add new phase to animation list
- AnimationPhase newPhase;
- newPhase.image = image;
- newPhase.delay = delay;
- newPhase.offsetX = offsetX;
- newPhase.offsetY = offsetY;
+ AnimationPhase newPhase = { image, delay, offsetX, offsetY };
+
mAnimationPhases.push_back(newPhase);
//reset animation circle
iCurrentPhase = mAnimationPhases.begin();
@@ -86,14 +75,14 @@ Animation::addPhase(int image, unsigned int delay, int offsetX, int offsetY)
int
Animation::getLength()
{
+ if (mAnimationPhases.empty())
+ return 0;
+
std::list<AnimationPhase>::iterator i;
int length = 0;
- if (!mAnimationPhases.empty())
+ for (i = mAnimationPhases.begin(); i != mAnimationPhases.end(); i++)
{
- for (i = mAnimationPhases.begin(); i != mAnimationPhases.end(); i++)
- {
- length += (*i).delay;
- }
+ length += i->delay;
}
return length;
}
@@ -105,352 +94,32 @@ Action::Action():
Action::~Action()
{
- for (AnimationIterator i = mAnimations.begin(); i != mAnimations.end(); i++)
- {
- delete i->second;
- }
+ std::for_each(mAnimations.begin(), mAnimations.end(), make_dtor(mAnimations));
mAnimations.clear();
}
Animation*
-Action::getAnimation(const std::string& direction) const
+Action::getAnimation(int direction) const
{
- Animation *animation = NULL;
Animations::const_iterator i = mAnimations.find(direction);
// When the direction isn't defined, try the default
if (i == mAnimations.end())
{
- i = mAnimations.find("default");
+ i = mAnimations.find(0);
}
- if (i != mAnimations.end())
- {
- animation = i->second;
- }
-
- return animation;
+ return (i == mAnimations.end()) ? NULL : i->second;
}
void
-Action::setAnimation(const std::string& direction, Animation *animation)
+Action::setAnimation(int direction, Animation *animation)
{
// Set first direction as default direction
if (mAnimations.empty())
{
- mAnimations["default"] = animation;
+ mAnimations[0] = animation;
}
mAnimations[direction] = animation;
}
-
-
-AnimatedSprite::AnimatedSprite(const std::string& animationFile, int variant):
- mAction(NULL),
- mDirection("down"),
- mLastTime(0),
- mSpeed(1.0f)
-{
- int size;
- ResourceManager *resman = ResourceManager::getInstance();
- char *data = (char*)resman->loadFile(animationFile.c_str(), size);
-
- if (!data) {
- logger->error("Animation: Could not find " + animationFile + "!");
- }
-
- xmlDocPtr doc = xmlParseMemory(data, size);
- free(data);
-
- if (!doc)
- {
- logger->error("Animation: Error while parsing animation definition file!");
- return;
- }
-
- xmlNodePtr node = xmlDocGetRootElement(doc);
- if (!node || !xmlStrEqual(node->name, BAD_CAST "sprite"))
- {
- logger->error("Animation: this is not a valid animation definition file!");
- return;
- }
-
- // Get the variant
- int variant_num = getProperty(node, "variants", 0);
- int variant_offset = getProperty(node, "variant_offset", 0);
-
- if (variant_num > 0 && variant < variant_num )
- {
- variant_offset *= variant;
- }
- else
- {
- variant_offset = 0;
- }
-
- for (node = node->xmlChildrenNode; node != NULL; node = node->next)
- {
- if (xmlStrEqual(node->name, BAD_CAST "imageset"))
- {
- int width = getProperty(node, "width", 0);
- int height = getProperty(node, "height", 0);
- std::string name = getProperty(node, "name", "");
- std::string imageSrc = getProperty(node, "src", "");
-
- Spriteset *spriteset =
- resman->getSpriteset(imageSrc, width, height);
-
- if (!spriteset)
- {
- logger->error("Couldn't load spriteset!");
- }
- else
- {
- mSpritesets[name] = spriteset;
- }
- }
- // get action
- else if (xmlStrEqual(node->name, BAD_CAST "action"))
- {
- std::string name = getProperty(node, "name", "");
- std::string imageset = getProperty(node, "imageset", "");
-
- if (name.length() == 0)
- {
- logger->log("Warning: unnamed action in %s",
- animationFile.c_str());
- }
-
- Action *action = new Action();
-
- if (mSpritesets.find(imageset) != mSpritesets.end())
- {
- action->setSpriteset(mSpritesets[imageset]);
- mActions[name] = action;
- }
- else
- {
- logger->log("Warning: imageset \"%s\" not defined in %s",
- imageset.c_str(),
- animationFile.c_str());
-
- // Discard action and skip loading animations
- delete action;
- continue;
- }
-
- // get animations
- for (xmlNodePtr animationNode = node->xmlChildrenNode;
- animationNode != NULL;
- animationNode = animationNode->next)
- {
- if (xmlStrEqual(animationNode->name, BAD_CAST "animation"))
- {
- std::string direction =
- getProperty(animationNode, "direction", "");
-
- Animation *animation = new Animation();
-
- // Get animation phases
- for (xmlNodePtr phaseNode = animationNode->xmlChildrenNode;
- phaseNode != NULL;
- phaseNode = phaseNode->next)
- {
- int delay = getProperty(phaseNode, "delay", 0);
-
- if (xmlStrEqual(phaseNode->name, BAD_CAST "frame"))
- {
- int index = getProperty(phaseNode, "index", -1);
- int offsetX = getProperty(phaseNode, "offsetX", 0);
- int offsetY = getProperty(phaseNode, "offsetY", 0);
-
- offsetY = offsetY - mSpritesets[imageset]->getHeight() + 32;
- offsetX = offsetX - mSpritesets[imageset]->getWidth() / 2 + 16;
- animation->addPhase(index + variant_offset, delay,
- offsetX, offsetY);
- }
- else if (xmlStrEqual(phaseNode->name, BAD_CAST "sequence"))
- {
- int start = getProperty(phaseNode, "start", 0);
- int end = getProperty(phaseNode, "end", 0);
- int offsetY = 0 - mSpritesets[imageset]->getHeight() + 32;
- int offsetX = 0 - mSpritesets[imageset]->getWidth() / 2 + 16;
- while (end >= start)
- {
- animation->addPhase(start + variant_offset,
- delay, offsetX, offsetY);
- start++;
- }
- }
- } // for phaseNode
- action->setAnimation(direction, animation);
- } // if "<animation>"
- } // for animationNode
- } // if "<imageset>" else if "<action>"
- } // for node
-
- // Complete missing actions
- substituteAction("walk", "stand");
- substituteAction("walk", "run");
- substituteAction("attack", "stand");
- substituteAction("attack_swing", "attack");
- substituteAction("attack_stab", "attack_swing");
- substituteAction("attack_bow", "attack_stab");
- substituteAction("attack_throw", "attack_swing");
- substituteAction("cast_magic", "attack_swing");
- substituteAction("use_item", "cast_magic");
- substituteAction("sit", "stand");
- substituteAction("sleeping", "sit");
- substituteAction("hurt", "stand");
- substituteAction("dead", "hurt");
-
- // Play the stand animation by default
- play("stand");
-
- xmlFreeDoc(doc);
-}
-
-int
-AnimatedSprite::getProperty(xmlNodePtr node, const char* name, int def)
-{
- xmlChar *prop = xmlGetProp(node, BAD_CAST name);
- if (prop) {
- int val = atoi((char*)prop);
- xmlFree(prop);
- return val;
- }
- else {
- return def;
- }
-}
-
-std::string
-AnimatedSprite::getProperty(xmlNodePtr node, const char* name,
- const std::string& def)
-{
- xmlChar *prop = xmlGetProp(node, BAD_CAST name);
- if (prop) {
- std::string val = (char*)prop;
- xmlFree(prop);
- return val;
- }
- else {
- return def;
- }
-}
-
-void
-AnimatedSprite::substituteAction(const std::string& complete,
- const std::string& with)
-{
- if (mActions.find(complete) == mActions.end())
- {
- mActions[complete] = mActions[with];
- }
-}
-
-AnimatedSprite::~AnimatedSprite()
-{
- for (SpritesetIterator i = mSpritesets.begin(); i != mSpritesets.end(); ++i)
- {
- i->second->decRef();
- }
- mSpritesets.clear();
-}
-
-void
-AnimatedSprite::play(const std::string& action)
-{
- Actions::iterator iAction;
- iAction = mActions.find(action);
-
- if (iAction == mActions.end())
- {
- logger->log("Warning: no action \"%s\" defined!", action.c_str());
- mAction = NULL;
- return;
- }
-
- if (mAction != iAction->second)
- {
- mAction = iAction->second;
- mLastTime = 0;
- }
-
- mSpeed = 1.0f;
-}
-
-void
-AnimatedSprite::play(const std::string& action, int time)
-{
- play(action);
-
- if (mAction != NULL)
- {
- Animation *animation = mAction->getAnimation(mDirection);
- int animationLength = animation->getLength();
- mSpeed = (float) animationLength / 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 have passed yet, do nothing
- if (time > mLastTime)
- {
- if (mAction != NULL)
- {
- Animation *animation = mAction->getAnimation(mDirection);
- animation->update((unsigned int)((time - mLastTime) * mSpeed));
- mLastTime = time;
- }
- }
-}
-
-bool
-AnimatedSprite::draw(Graphics* graphics, Sint32 posX, Sint32 posY) const
-{
- if (mAction != NULL)
- {
- Animation *animation = mAction->getAnimation(mDirection);
-
- if (animation->getCurrentPhase() >= 0)
- {
- Spriteset *spriteset = mAction->getSpriteset();
- Image *image = spriteset->get(animation->getCurrentPhase());
- Sint32 offsetX = animation->getOffsetX();
- Sint32 offsetY = animation->getOffsetY();
- return graphics->drawImage(image, posX + offsetX, posY + offsetY);
- }
- }
-
- return false;
-}
-
-int
-AnimatedSprite::getWidth() const
-{
- if (mAction != NULL)
- {
- Spriteset *spriteset = mAction->getSpriteset();
- return spriteset->getWidth();
- }
-
- return 0;
-}
-
-int
-AnimatedSprite::getHeight() const
-{
- if (mAction != NULL)
- {
- Spriteset *spriteset = mAction->getSpriteset();
- return spriteset->getHeight();
- }
-
- return 0;
-}
diff --git a/src/animation.h b/src/animation.h
index c5adb873..c5b277b7 100644
--- a/src/animation.h
+++ b/src/animation.h
@@ -26,12 +26,9 @@
#include <list>
#include <map>
-#include <string>
#include <libxml/tree.h>
-#include "graphics.h"
-
class Image;
class Spriteset;
@@ -58,16 +55,32 @@ class Animation
*/
Animation();
- void addPhase(int image, unsigned int delay, int offsetX, int offsetY);
+ void
+ addPhase(int image, unsigned int delay, int offsetX, int offsetY);
+
+ void
+ update(unsigned int time);
- void update(unsigned int time);
+ int
+ getCurrentPhase() const;
- int getCurrentPhase() const;
+ /**
+ * Returns the x offset of the current frame.
+ */
+ int
+ getOffsetX() const { return (*iCurrentPhase).offsetX; };
- int getOffsetX() const { return (*iCurrentPhase).offsetX; };
- int getOffsetY() const { return (*iCurrentPhase).offsetY; };
+ /**
+ * Returns the y offset of the current frame.
+ */
+ int
+ getOffsetY() const { return (*iCurrentPhase).offsetY; };
- int getLength();
+ /**
+ * Returns the length of this animation.
+ */
+ int
+ getLength();
protected:
std::list<AnimationPhase> mAnimationPhases;
@@ -104,114 +117,16 @@ class Action
getSpriteset() const { return mSpriteset; }
void
- setAnimation(const std::string& direction, Animation *animation);
+ setAnimation(int direction, Animation *animation);
Animation*
- getAnimation(const std::string& direction) const;
+ getAnimation(int direction) const;
protected:
Spriteset *mSpriteset;
- typedef std::map<std::string, Animation*> Animations;
+ typedef std::map<int, Animation*> Animations;
typedef Animations::iterator AnimationIterator;
Animations mAnimations;
};
-/**
- * Defines a class to load an animation.
- */
-class AnimatedSprite
-{
- public:
- /**
- * Constructor.
- */
- AnimatedSprite(const std::string& animationFile, int variant);
-
- /**
- * Destructor.
- */
- ~AnimatedSprite();
-
- /**
- * Sets a new action using the current direction.
- */
- void
- play(const std::string& action);
-
- /**
- * Plays an action in a specified time.
- */
- void
- play(const std::string& action, int time);
-
- /**
- * Inform the animation of the passed time so that it can output the
- * correct animation phase.
- */
- void update(int time);
-
- /**
- * Draw the current animation phase at the coordinates given in screen
- * pixels.
- */
- bool
- draw(Graphics* graphics, Sint32 posX, Sint32 posY) const;
-
- /**
- * gets the width in pixels of the current animation phase.
- */
- int
- getWidth() const;
-
- /**
- * gets the height in pixels of the current animation phase.
- */
- int
- getHeight() const;
-
- /**
- * Sets the direction.
- */
- void
- setDirection(const std::string& direction)
- {
- mDirection = direction;
- }
-
- protected:
- /**
- * When there are no animations defined for the action "complete", its
- * animations become a copy of those of the action "with".
- */
- void
- substituteAction(const std::string& complete,
- const std::string& with);
-
- typedef std::map<std::string, Spriteset*> Spritesets;
- typedef Spritesets::iterator SpritesetIterator;
- Spritesets mSpritesets;
- typedef std::map<std::string, Action*> Actions;
- Actions mActions;
- Action *mAction;
- std::string mDirection;
- int mLastTime;
- float mSpeed;
-
- private:
- /**
- * Gets an integer property from an xmlNodePtr.
- *
- * TODO: Same function is present in MapReader. Should probably be
- * TODO: shared in a static utility class.
- */
- static int
- getProperty(xmlNodePtr node, const char* name, int def);
-
- /**
- * Gets a string property from an xmlNodePtr.
- */
- static std::string
- getProperty(xmlNodePtr node, const char* name, const std::string& def);
-};
-
#endif
diff --git a/src/being.cpp b/src/being.cpp
index 8a55f2e2..1ca8929a 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -22,6 +22,9 @@
*/
#include "being.h"
+#include <algorithm>
+
+#include "animatedsprite.h"
#include "equipment.h"
#include "game.h"
#include "graphics.h"
@@ -32,6 +35,7 @@
#include "gui/gui.h"
+#include "utils/dtor.h"
#include "utils/tostring.h"
extern Spriteset *emotionset;
@@ -65,14 +69,7 @@ Being::Being(Uint32 id, Uint16 job, Map *map):
Being::~Being()
{
- for (int i = 0; i < VECTOREND_SPRITE; i++)
- {
- if (mSprites[i] != NULL)
- {
- delete mSprites[i];
- }
- }
-
+ std::for_each(mSprites.begin(), mSprites.end(), make_dtor(mSprites));
clearPath();
setMap(NULL);
}
@@ -164,66 +161,65 @@ Being::setMap(Map *map)
}
void
-Being::setAction(Action action)
+Being::setAction(Uint8 action)
{
- if (action != mAction)
+ SpriteAction currentAction = ACTION_STAND;
+ switch (action)
{
- std::string currentAction = "stand";
- switch (action)
- {
- case WALK:
- currentAction = "walk";
- break;
- case SIT:
- currentAction = "sit";
- break;
- case ATTACK:
- if (getType() == MONSTER)
- {
- currentAction = "dead";
- }else{
- switch (getWeapon())
- {
- case 2:
- currentAction = "attack_bow";
- break;
- case 1:
- currentAction = "attack_stab";
- break;
- case 0:
- currentAction = "attack";
- break;
- }
- };
- break;
- case MONSTER_ATTACK:
- currentAction = "attack";
- break;
- case DEAD:
- currentAction = "dead";
- break;
- default:
- currentAction = "stand";
- break;
- }
-
- for (int i = 0; i < VECTOREND_SPRITE; i++)
- {
- if (mSprites[i] != NULL)
+ case WALK:
+ currentAction = ACTION_WALK;
+ break;
+ case SIT:
+ currentAction = ACTION_SIT;
+ break;
+ case ATTACK:
+ if (getType() == MONSTER)
{
- if (currentAction == "attack" ||
- currentAction == "attack_stab" ||
- currentAction == "attack_bow")
- {
- mSprites[i]->play(currentAction, mAttackSpeed);
- }
- else
+ currentAction = ACTION_DEAD;
+ }
+ else {
+ switch (getWeapon())
{
- mSprites[i]->play(currentAction);
+ case 2:
+ currentAction = ACTION_ATTACK_BOW;
+ break;
+ case 1:
+ currentAction = ACTION_ATTACK_STAB;
+ break;
+ case 0:
+ currentAction = ACTION_ATTACK;
+ break;
}
- }
+ };
+ break;
+ case MONSTER_ATTACK:
+ currentAction = ACTION_ATTACK;
+ break;
+ case DEAD:
+ currentAction = ACTION_DEAD;
+ break;
+ default:
+ currentAction = ACTION_STAND;
+ break;
+ }
+
+ for (int i = 0; i < VECTOREND_SPRITE; i++)
+ {
+ if (!mSprites[i])
+ continue;
+
+ if (currentAction == ACTION_ATTACK ||
+ currentAction == ACTION_ATTACK_STAB ||
+ currentAction == ACTION_ATTACK_BOW)
+ {
+ mSprites[i]->play(currentAction, mAttackSpeed);
+ }
+ else
+ {
+ mSprites[i]->play(currentAction);
}
}
+
mAction = action;
}
@@ -231,29 +227,37 @@ void
Being::setDirection(Uint8 direction)
{
mDirection = direction;
- std::string dir;
+ SpriteDirection dir = getSpriteDirection();
- if (direction & UP)
+ for (int i = 0; i < VECTOREND_SPRITE; i++)
{
- dir = "up";
+ if (mSprites[i] != NULL)
+ mSprites[i]->setDirection(dir);
}
- else if (direction & RIGHT)
+}
+
+SpriteDirection
+Being::getSpriteDirection() const
+{
+ SpriteDirection dir;
+
+ if (mDirection & UP)
{
- dir = "right";
+ dir = DIRECTION_UP;
}
- else if (direction & DOWN)
+ else if (mDirection & RIGHT)
{
- dir = "down";
+ dir = DIRECTION_RIGHT;
}
- else
+ else if (mDirection & DOWN)
{
- dir = "left";
+ dir = DIRECTION_DOWN;
}
-
- for (int i = 0; i < VECTOREND_SPRITE; i++)
- {
- if (mSprites[i] != NULL) mSprites[i]->setDirection(dir);
+ else {
+ dir = DIRECTION_LEFT;
}
+
+ return dir;
}
void
@@ -329,10 +333,6 @@ Being::draw(Graphics *graphics, int offsetX, int offsetY)
int px = mPx + offsetX;
int py = mPy + offsetY;
- //what are these two lines good for? please add a comment.
- unsigned char dir = 0;
- while (!(mDirection & (1 << dir))) dir++;
-
for (int i = 0; i < VECTOREND_SPRITE; i++)
{
if (mSprites[i] != NULL)
@@ -345,14 +345,13 @@ Being::draw(Graphics *graphics, int offsetX, int offsetY)
void
Being::drawEmotion(Graphics *graphics, Sint32 offsetX, Sint32 offsetY)
{
- int px = mPx + offsetX;
- int py = mPy + offsetY;
+ if (!mEmotion)
+ return;
- if (mEmotion)
- {
- graphics->drawImage(emotionset->get(mEmotion - 1),
- px + 3, py - 60);
- }
+ int px = mPx + offsetX + 3;
+ int py = mPy + offsetY - 60;
+
+ graphics->drawImage(emotionset->get(mEmotion - 1), px, py);
}
void
diff --git a/src/being.h b/src/being.h
index 478bc018..0735efe9 100644
--- a/src/being.h
+++ b/src/being.h
@@ -29,13 +29,14 @@
#include <SDL_types.h>
#include <vector>
-#include "animation.h"
#include "sprite.h"
#include "map.h"
+#include "animatedsprite.h"
#define NR_HAIR_STYLES 7
#define NR_HAIR_COLORS 10
+class AnimatedSprite;
class Equipment;
class Item;
class Map;
@@ -290,7 +291,7 @@ class Being : public Sprite
/**
* Sets the current action.
*/
- void setAction(Action action);
+ void setAction(Uint8 action);
/**
* Sets the current direction.
@@ -347,6 +348,12 @@ class Being : public Sprite
*/
int getOffset(char pos, char neg) const;
+ /**
+ * Returns the sprite direction of this being.
+ */
+ SpriteDirection
+ getSpriteDirection() const;
+
Uint32 mId; /**< Unique sprite id */
Uint16 mWeapon; /**< Weapon picture id */
Uint16 mWalkSpeed; /**< Walking speed */
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 9c3ff008..8bb0b8ca 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -57,18 +57,18 @@ void Configuration::init(const std::string &filename)
for (node = node->xmlChildrenNode; node != NULL; node = node->next)
{
- if (xmlStrEqual(node->name, BAD_CAST "option"))
- {
- xmlChar *name = xmlGetProp(node, BAD_CAST "name");
- xmlChar *value = xmlGetProp(node, BAD_CAST "value");
+ if (!xmlStrEqual(node->name, BAD_CAST "option"))
+ continue;
- if (name && value) {
- mOptions[(const char*)name] = (const char*)value;
- }
+ xmlChar *name = xmlGetProp(node, BAD_CAST "name");
+ xmlChar *value = xmlGetProp(node, BAD_CAST "value");
- if (name) xmlFree(name);
- if (value) xmlFree(value);
+ if (name && value) {
+ mOptions[(const char*)name] = (const char*)value;
}
+
+ if (name) xmlFree(name);
+ if (value) xmlFree(value);
}
xmlFreeDoc(doc);
@@ -89,31 +89,29 @@ void Configuration::write()
xmlTextWriterPtr writer = xmlNewTextWriterFilename(mConfigPath.c_str(), 0);
- if (writer)
- {
- logger->log("Configuration::write() writing configuration...");
+ if (!writer) {
+ logger->log("Configuration::write() error while creating writer");
+ return;
+ }
- xmlTextWriterSetIndent(writer, 1);
- xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
- xmlTextWriterStartElement(writer, BAD_CAST "configuration");
+ logger->log("Configuration::write() writing configuration...");
- for (OptionIterator i = mOptions.begin(); i != mOptions.end(); i++)
- {
- xmlTextWriterStartElement(writer, BAD_CAST "option");
- xmlTextWriterWriteAttribute(writer,
- BAD_CAST "name", BAD_CAST i->first.c_str());
- xmlTextWriterWriteAttribute(writer,
- BAD_CAST "value", BAD_CAST i->second.c_str());
- xmlTextWriterEndElement(writer);
- }
+ xmlTextWriterSetIndent(writer, 1);
+ xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
+ xmlTextWriterStartElement(writer, BAD_CAST "configuration");
- xmlTextWriterEndDocument(writer);
- xmlFreeTextWriter(writer);
- }
- else
+ for (OptionIterator i = mOptions.begin(); i != mOptions.end(); i++)
{
- logger->log("Configuration::write() error while creating writer");
+ xmlTextWriterStartElement(writer, BAD_CAST "option");
+ xmlTextWriterWriteAttribute(writer,
+ BAD_CAST "name", BAD_CAST i->first.c_str());
+ xmlTextWriterWriteAttribute(writer,
+ BAD_CAST "value", BAD_CAST i->second.c_str());
+ xmlTextWriterEndElement(writer);
}
+
+ xmlTextWriterEndDocument(writer);
+ xmlFreeTextWriter(writer);
}
void Configuration::setValue(const std::string &key, std::string value)
diff --git a/src/engine.cpp b/src/engine.cpp
index c6a4e55c..84574b26 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -25,7 +25,6 @@
#include <list>
-#include "animation.h"
#include "being.h"
#include "beingmanager.h"
#include "flooritemmanager.h"
@@ -34,7 +33,6 @@
#include "main.h"
#include "localplayer.h"
#include "log.h"
-#include "main.h"
#include "map.h"
#include "sound.h"
@@ -63,8 +61,6 @@ Spriteset *itemset;
Spriteset *emotionset;
Spriteset *npcset;
std::vector<Spriteset *> weaponset;
-AnimatedSprite *animatedSprite;
-
Engine::Engine(Network *network):
mShowDebugPath(false),
@@ -104,16 +100,11 @@ Engine::~Engine()
emotionset->decRef();
itemset->decRef();
- std::vector<Spriteset *>::iterator iter;
- for (iter = weaponset.begin(); iter != weaponset.end(); ++iter)
- {
- (*iter)->decRef();
- }
+ std::for_each(weaponset.begin(), weaponset.end(),
+ std::mem_fun(&Spriteset::decRef));
weaponset.clear();
delete itemDb;
-
- delete animatedSprite;
}
void Engine::changeMap(const std::string &mapPath)
@@ -219,12 +210,12 @@ void Engine::draw(Graphics *graphics)
player_node->mX, player_node->mY,
mouseTileX, mouseTileY);
+ graphics->setColor(gcn::Color(255, 0, 0));
for (PathIterator i = debugPath.begin(); i != debugPath.end(); i++)
{
int squareX = i->x * 32 - map_x + 12;
int squareY = i->y * 32 - map_y + 12;
- graphics->setColor(gcn::Color(255, 0, 0));
graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8));
graphics->drawText(
toString(mCurrentMap->getMetaTile(i->x, i->y)->Gcost),
diff --git a/src/game.cpp b/src/game.cpp
index fab88aa9..eada1128 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -167,8 +167,7 @@ int get_elapsed_time(int start_time)
void createGuiWindows(Network *network)
{
// Create dialogs
- chatWindow = new ChatWindow(
- config.getValue("homeDir", "") + std::string("/chatlog.txt"), network);
+ chatWindow = new ChatWindow(network);
menuWindow = new MenuWindow();
statusWindow = new StatusWindow(player_node);
miniStatusWindow = new MiniStatusWindow();
@@ -359,29 +358,16 @@ void Game::logic()
gameTime = tick_time;
fpsLimit = (int)config.getValue("fpslimit", 50);
- if (fpsLimit)
- {
- delta = 1000 / fpsLimit;
- }
- else
- {
- delta = 0;
- }
+ delta = fpsLimit ? 1000 / fpsLimit : 0;
// Update the screen when application is active, delay otherwise
- if (SDL_GetAppState() & SDL_APPACTIVE)
+ if (SDL_GetAppState() & SDL_APPACTIVE &&
+ (abs(tick_time * 10 - drawTime) >= delta))
{
- if (abs(tick_time * 10 - drawTime) >= delta)
- {
- frame++;
- engine->draw(graphics);
- graphics->updateScreen();
- drawTime += delta;
- }
- else
- {
- SDL_Delay(10);
- }
+ frame++;
+ engine->draw(graphics);
+ graphics->updateScreen();
+ drawTime += delta;
}
else
{
diff --git a/src/gui/browserbox.h b/src/gui/browserbox.h
index 95b181ad..a2c9dd9b 100644
--- a/src/gui/browserbox.h
+++ b/src/gui/browserbox.h
@@ -31,6 +31,7 @@
#include <guichan/mouselistener.hpp>
#include "../guichanfwd.h"
+#include "../main.h"
class LinkHandler;
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index 133e5e3a..592439fc 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -35,18 +35,16 @@
#include "../game.h"
#include "../localplayer.h"
-#include "../log.h"
#include "../net/messageout.h"
#include "../net/protocol.h"
-ChatWindow::ChatWindow(const std::string &logfile, Network *network):
+ChatWindow::ChatWindow(Network *network):
Window(""),
mNetwork(network),
mTmpVisible(false)
{
setWindowName("Chat");
- mChatlogFile.open(logfile.c_str(), std::ios::out | std::ios::app);
mItems = 0;
mItemsKeep = 20;
@@ -76,12 +74,6 @@ ChatWindow::ChatWindow(const std::string &logfile, Network *network):
mCurHist = mHistory.end();
}
-ChatWindow::~ChatWindow()
-{
- mChatlogFile.flush();
- mChatlogFile.close();
-}
-
void
ChatWindow::logic()
{
@@ -251,44 +243,12 @@ ChatWindow::isFocused()
void
ChatWindow::chatSend(const std::string &nick, std::string msg)
{
- // Prepare command
- if (msg.substr(0, 1) == "/")
- {
- /* Some messages are managed client side, while others
- * require server handling by proper packet. Probably
- * those if elses should be replaced by protocol calls */
- if (msg.substr(0, IS_ANNOUNCE_LENGTH) == IS_ANNOUNCE)
- {
- msg.erase(0, IS_ANNOUNCE_LENGTH);
- MessageOut outMsg;
- outMsg.writeShort(0x0099);
- outMsg.writeShort(msg.length() + 4);
- outMsg.writeString(msg, msg.length());
- }
- else if (msg.substr(0, IS_HELP_LENGTH) == IS_HELP)
- {
- chatLog("-- Help --", BY_SERVER);
- chatLog("/help : Display this help.", BY_SERVER);
- chatLog("/announce : Global announcement (GM only)", BY_SERVER);
- chatLog("/where : Display map name", BY_SERVER);
- chatLog("/who : Display number of online users", BY_SERVER);
- }
- else if (msg.substr(0, IS_WHERE_LENGTH) == IS_WHERE)
- {
- chatLog(map_path, BY_SERVER);
- }
- else if (msg.substr(0, IS_WHO_LENGTH) == IS_WHO)
- {
- MessageOut outMsg;
- outMsg.writeShort(0x00c1);
- }
- else
- {
- chatLog("Unknown command", BY_SERVER);
- }
- }
+ /* Some messages are managed client side, while others
+ * require server handling by proper packet. Probably
+ * those if elses should be replaced by protocol calls */
+
// Prepare ordinary message
- else {
+ if (msg.substr(0, 1) != "/") {
msg = nick + " : " + msg;
MessageOut outMsg;
@@ -296,6 +256,35 @@ ChatWindow::chatSend(const std::string &nick, std::string msg)
outMsg.writeShort(msg.length() + 4);
outMsg.writeString(msg, msg.length());
}
+ else if (msg.substr(0, IS_ANNOUNCE_LENGTH) == IS_ANNOUNCE)
+ {
+ msg.erase(0, IS_ANNOUNCE_LENGTH);
+ MessageOut outMsg;
+ outMsg.writeShort(0x0099);
+ outMsg.writeShort(msg.length() + 4);
+ outMsg.writeString(msg, msg.length());
+ }
+ else if (msg.substr(0, IS_HELP_LENGTH) == IS_HELP)
+ {
+ chatLog("-- Help --", BY_SERVER);
+ chatLog("/help : Display this help.", BY_SERVER);
+ chatLog("/announce : Global announcement (GM only)", BY_SERVER);
+ chatLog("/where : Display map name", BY_SERVER);
+ chatLog("/who : Display number of online users", BY_SERVER);
+ }
+ else if (msg.substr(0, IS_WHERE_LENGTH) == IS_WHERE)
+ {
+ chatLog(map_path, BY_SERVER);
+ }
+ else if (msg.substr(0, IS_WHO_LENGTH) == IS_WHO)
+ {
+ MessageOut outMsg;
+ outMsg.writeShort(0x00c1);
+ }
+ else
+ {
+ chatLog("Unknown command", BY_SERVER);
+ }
}
std::string
diff --git a/src/gui/chat.h b/src/gui/chat.h
index addfb6b5..20841873 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -24,7 +24,6 @@
#ifndef _TMW_CHAT_H
#define _TMW_CHAT_H
-#include <fstream>
#include <list>
#include <string>
@@ -117,12 +116,7 @@ class ChatWindow : public Window, public gcn::ActionListener,
/**
* Constructor.
*/
- ChatWindow(const std::string &logfile, Network *network);
-
- /**
- * Destructor.
- */
- ~ChatWindow();
+ ChatWindow(Network *network);
/**
* Logic (updates components' size)
@@ -195,7 +189,6 @@ class ChatWindow : public Window, public gcn::ActionListener,
private:
Network *mNetwork;
- std::ofstream mChatlogFile;
bool mTmpVisible;
/** One item in the chat log */
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 88998f7a..026f24bd 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -32,10 +32,6 @@
// constant as well as guichan does
#include <guichan/sdl/sdlinput.hpp>
-#ifdef USE_OPENGL
-#include "../resources/openglsdlimageloader.h"
-#endif
-
#include "focushandler.h"
#include "popupmenu.h"
#include "window.h"
@@ -57,6 +53,9 @@
#include "../resources/image.h"
#include "../resources/resourcemanager.h"
#include "../resources/sdlimageloader.h"
+#ifdef USE_OPENGL
+#include "../resources/openglsdlimageloader.h"
+#endif
// Guichan stuff
Gui *gui;
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index 9eb94520..7ac226d3 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -42,6 +42,7 @@
#include "../configuration.h"
#include "../graphics.h"
#include "../log.h"
+#include "../main.h"
#include "../utils/tostring.h"
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index 9188b6de..8c69d3ef 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -300,7 +300,7 @@ int UpdaterWindow::downloadThread(void *ptr)
// Any existing file with this name is deleted first, otherwise the
// rename will fail on Windows.
::remove(newName.c_str());
- rename(outFilename.c_str(), newName.c_str());
+ ::rename(outFilename.c_str(), newName.c_str());
}
}
diff --git a/src/main.cpp b/src/main.cpp
index ce68b7bb..a4ef29ee 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -43,7 +43,6 @@
#define NOGDI
#endif
-#include "animation.h"
#include "configuration.h"
#include "game.h"
#include "graphics.h"
@@ -216,15 +215,6 @@ void init_engine()
resman->addToSearchPath("data", true);
resman->addToSearchPath(TMW_DATADIR "data", true);
- int width, height, bpp;
- bool fullscreen, hwaccel;
-
- width = (int)config.getValue("screenwidth", 800);
- height = (int)config.getValue("screenheight", 600);
- bpp = 0;
- fullscreen = ((int)config.getValue("screen", 0) == 1);
- hwaccel = ((int)config.getValue("hwaccel", 0) == 1);
-
#ifdef USE_OPENGL
bool useOpenGL = (config.getValue("opengl", 0) == 1);
@@ -232,16 +222,18 @@ void init_engine()
Image::setLoadAsOpenGL(useOpenGL);
// Create the graphics context
- if (useOpenGL) {
- graphics = new OpenGLGraphics();
- } else {
- graphics = new Graphics();
- }
+ graphics = useOpenGL ? new OpenGLGraphics() : new Graphics();
#else
// Create the graphics context
graphics = new Graphics();
#endif
+ int width = (int)config.getValue("screenwidth", 800);
+ int height = (int)config.getValue("screenheight", 600);
+ int bpp = 0;
+ bool fullscreen = ((int)config.getValue("screen", 0) == 1);
+ bool hwaccel = ((int)config.getValue("hwaccel", 0) == 1);
+
// Try to set the desired video mode
if (!graphics->setVideoMode(width, height, bpp, fullscreen, hwaccel))
{
@@ -299,11 +291,8 @@ void exit_engine()
delete gui;
delete graphics;
- std::vector<Spriteset *>::iterator iter;
- for (iter = hairset.begin(); iter != hairset.end(); ++iter)
- {
- (*iter)->decRef();
- }
+ std::for_each(hairset.begin(), hairset.end(),
+ std::mem_fun(&Spriteset::decRef));
hairset.clear();
playerset[0]->decRef();
diff --git a/src/monster.cpp b/src/monster.cpp
index 43823e50..8a7e2f32 100644
--- a/src/monster.cpp
+++ b/src/monster.cpp
@@ -23,10 +23,8 @@
#include "monster.h"
+#include "animatedsprite.h"
#include "game.h"
-#include "log.h"
-
-#include "resources/resourcemanager.h"
#include "utils/tostring.h"
diff --git a/src/npc.cpp b/src/npc.cpp
index 54205ad3..a82490ae 100644
--- a/src/npc.cpp
+++ b/src/npc.cpp
@@ -23,6 +23,8 @@
#include "npc.h"
+#include "animatedsprite.h"
+
#include "net/messageout.h"
#include "net/protocol.h"
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index 2a6c931d..05bbb6b3 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -21,6 +21,8 @@
* $Id$
*/
+#include "main.h"
+
#ifdef USE_OPENGL
#include "openglgraphics.h"
diff --git a/src/player.cpp b/src/player.cpp
index 05825f6e..3fe608c7 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -23,8 +23,7 @@
#include "player.h"
-#include "animation.h"
-#include "equipment.h"
+#include "animatedsprite.h"
#include "game.h"
#include "graphics.h"
@@ -91,11 +90,13 @@ Player::setSex(Uint8 sex)
delete mSprites[BASE_SPRITE];
if (sex == 0)
{
- mSprites[BASE_SPRITE] = new AnimatedSprite("graphics/sprites/player_male_base.xml", 0);
+ mSprites[BASE_SPRITE] = new AnimatedSprite(
+ "graphics/sprites/player_male_base.xml", 0);
}
else
{
- mSprites[BASE_SPRITE] = new AnimatedSprite("graphics/sprites/player_female_base.xml", 0);
+ mSprites[BASE_SPRITE] = new AnimatedSprite(
+ "graphics/sprites/player_female_base.xml", 0);
}
}
Being::setSex(sex);
@@ -107,8 +108,16 @@ Player::setHairColor(Uint16 color)
if (color != mHairColor && mHairStyle > 0)
{
delete mSprites[HAIR_SPRITE];
- mSprites[HAIR_SPRITE] = new AnimatedSprite("graphics/sprites/hairstyle"+toString(mHairStyle)+".xml", color - 1);
+ AnimatedSprite *newHairSprite = new AnimatedSprite(
+ "graphics/sprites/hairstyle" + toString(mHairStyle) + ".xml",
+ color - 1);
+ newHairSprite->setDirection(getSpriteDirection());
+
+ mSprites[HAIR_SPRITE] = newHairSprite;
+
+ setAction(mAction);
}
+
Being::setHairColor(color);
}
@@ -118,8 +127,16 @@ Player::setHairStyle(Uint16 style)
if (style != mHairStyle && mHairColor > 0)
{
delete mSprites[HAIR_SPRITE];
- mSprites[HAIR_SPRITE] = new AnimatedSprite("graphics/sprites/hairstyle"+toString(style)+".xml", mHairColor - 1);
+ AnimatedSprite *newHairSprite = new AnimatedSprite(
+ "graphics/sprites/hairstyle" + toString(style) + ".xml",
+ mHairColor - 1);
+ newHairSprite->setDirection(getSpriteDirection());
+
+ mSprites[HAIR_SPRITE] = newHairSprite;
+
+ setAction(mAction);
}
+
Being::setHairStyle(style);
}
@@ -139,18 +156,24 @@ Player::setVisibleEquipment(Uint8 slot, Uint8 id)
position = TOPCLOTHES_SPRITE;
break;
}
+
+ delete mSprites[position];
+ mSprites[position] = NULL;
+
// id = 0 means unequip
- if (mSprites[position]) {
- delete mSprites[position];
- mSprites[position] = 0;
- }
if (id) {
char stringId[4];
sprintf(stringId, "%03i", id);
- printf("Id: %i %i %s\n", id, slot, stringId);
- mSprites[position] = new AnimatedSprite(
+
+ AnimatedSprite *equipmentSprite = new AnimatedSprite(
"graphics/sprites/item" + toString(stringId) + ".xml", 0);
+ equipmentSprite->setDirection(getSpriteDirection());
+
+ mSprites[position] = equipmentSprite;
+
+ setAction(mAction);
}
+
Being::setVisibleEquipment(slot, id);
}
diff --git a/src/resources/image.h b/src/resources/image.h
index 1f67fcae..78751394 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -24,6 +24,8 @@
#ifndef _TMW_IMAGE_H
#define _TMW_IMAGE_H
+#include "../main.h"
+
#include <SDL.h>
#ifdef USE_OPENGL
#include <SDL_opengl.h>
diff --git a/src/resources/itemmanager.cpp b/src/resources/itemmanager.cpp
index 56ac6354..63c0b036 100644
--- a/src/resources/itemmanager.cpp
+++ b/src/resources/itemmanager.cpp
@@ -30,6 +30,8 @@
#include "../log.h"
+#include "../utils/dtor.h"
+
#define READ_PROP(node, prop, name, target, cast) \
prop = xmlGetProp(node, BAD_CAST name); \
if (prop) { \
@@ -56,14 +58,12 @@ ItemManager::ItemManager()
if (!doc)
{
logger->error("Item Manager: Error while parsing item database (items.xml)!");
- return;
}
xmlNodePtr node = xmlDocGetRootElement(doc);
if (!node || !xmlStrEqual(node->name, BAD_CAST "items"))
{
logger->error("Item Manager: items.xml is not a valid database file!");
- return;
}
for (node = node->xmlChildrenNode; node != NULL; node = node->next)
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index af79480a..382b0797 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -28,7 +28,6 @@
#include "resourcemanager.h"
#include "image.h"
-#include "spriteset.h"
#include "../base64.h"
#include "../log.h"
@@ -220,34 +219,26 @@ MapReader::readMap(xmlNodePtr node, const std::string &path)
void
MapReader::readProperties(xmlNodePtr node, Properties* props)
{
- node = node->xmlChildrenNode;
+ for (node = node->xmlChildrenNode; node; node = node->next) {
+ if (!xmlStrEqual(node->name, BAD_CAST "property"))
+ continue;
- while (node != NULL)
- {
- if (xmlStrEqual(node->name, BAD_CAST "property"))
- {
- // Example: <property name="name" value="value"/>
-
- xmlChar *name = xmlGetProp(node, BAD_CAST "name");
- xmlChar *value = xmlGetProp(node, BAD_CAST "value");
+ // Example: <property name="name" value="value"/>
+ xmlChar *name = xmlGetProp(node, BAD_CAST "name");
+ xmlChar *value = xmlGetProp(node, BAD_CAST "value");
- if (name && value)
- {
- props->setProperty((const char*) name, (const char*) value);
- }
-
- if (name) xmlFree(name);
- if (value) xmlFree(value);
+ if (name && value) {
+ props->setProperty((const char*)name, (const char*)value);
}
- node = node->next;
+ if (name) xmlFree(name);
+ if (value) xmlFree(value);
}
}
void
MapReader::readLayer(xmlNodePtr node, Map *map, int layer)
{
- node = node->xmlChildrenNode;
int h = map->getHeight();
int w = map->getWidth();
int x = 0;
@@ -255,89 +246,86 @@ MapReader::readLayer(xmlNodePtr node, Map *map, int layer)
// Load the tile data. Layers are assumed to be map size, with (0,0) as
// origin.
- while (node != NULL)
- {
- if (xmlStrEqual(node->name, BAD_CAST "data"))
+ for (node = node->xmlChildrenNode; node; node = node->next) {
+ if (!xmlStrEqual(node->name, BAD_CAST "data"))
+ continue;
+
+ xmlChar *encoding = xmlGetProp(node, BAD_CAST "encoding");
+ xmlChar *compression = xmlGetProp(node, BAD_CAST "compression");
+
+ if (encoding && xmlStrEqual(encoding, BAD_CAST "base64"))
{
- xmlChar *encoding = xmlGetProp(node, BAD_CAST "encoding");
- xmlChar *compression = xmlGetProp(node, BAD_CAST "compression");
+ xmlFree(encoding);
- if (encoding && xmlStrEqual(encoding, BAD_CAST "base64"))
- {
- xmlFree(encoding);
+ if (compression) {
+ logger->log("Warning: no layer compression supported!");
+ xmlFree(compression);
+ return;
+ }
- if (compression) {
- logger->log("Warning: no layer compression supported!");
- xmlFree(compression);
- return;
- }
+ // Read base64 encoded map file
+ xmlNodePtr dataChild = node->xmlChildrenNode;
+ if (!dataChild)
+ continue;
- // Read base64 encoded map file
- xmlNodePtr dataChild = node->xmlChildrenNode;
- if (!dataChild) continue;
-
- int len = strlen((const char*)dataChild->content) + 1;
- unsigned char *charData = new unsigned char[len + 1];
- const char *charStart = (const char*)dataChild->content;
- unsigned char *charIndex = charData;
-
- while (*charStart) {
- if (*charStart != ' ' && *charStart != '\t' &&
- *charStart != '\n')
- {
- *charIndex = *charStart;
- charIndex++;
- }
- charStart++;
+ int len = strlen((const char*)dataChild->content) + 1;
+ unsigned char *charData = new unsigned char[len + 1];
+ const char *charStart = (const char*)dataChild->content;
+ unsigned char *charIndex = charData;
+
+ while (*charStart) {
+ if (*charStart != ' ' && *charStart != '\t' &&
+ *charStart != '\n')
+ {
+ *charIndex = *charStart;
+ charIndex++;
}
- *charIndex = '\0';
+ charStart++;
+ }
+ *charIndex = '\0';
- int binLen;
- unsigned char *binData =
- php_base64_decode(charData, strlen((char*)charData),
- &binLen);
+ int binLen;
+ unsigned char *binData =
+ php_base64_decode(charData, strlen((char*)charData),
+ &binLen);
- delete[] charData;
+ delete[] charData;
- if (binData) {
- for (int i = 0; i < binLen - 3; i += 4) {
- int gid = binData[i] |
- binData[i + 1] << 8 |
- binData[i + 2] << 16 |
- binData[i + 3] << 24;
+ if (binData) {
+ for (int i = 0; i < binLen - 3; i += 4) {
+ int gid = binData[i] |
+ binData[i + 1] << 8 |
+ binData[i + 2] << 16 |
+ binData[i + 3] << 24;
- map->setTileWithGid(x, y, layer, gid);
+ map->setTileWithGid(x, y, layer, gid);
- x++;
- if (x == w) {x = 0; y++;}
- }
- free(binData);
+ x++;
+ if (x == w) {x = 0; y++;}
}
+ free(binData);
}
- else {
- // Read plain XML map file
- xmlNodePtr n2 = node->xmlChildrenNode;
-
- while (n2 != NULL)
- {
- if (xmlStrEqual(n2->name, BAD_CAST "tile") && y < h)
- {
- int gid = getProperty(n2, "gid", -1);
- map->setTileWithGid(x, y, layer, gid);
-
- x++;
- if (x == w) {x = 0; y++;}
- }
-
- n2 = n2->next;
+ }
+ else {
+ // Read plain XML map file
+ for (xmlNodePtr n2 = node->xmlChildrenNode; n2; n2 = n2->next) {
+ if (!xmlStrEqual(n2->name, BAD_CAST "tile"))
+ continue;
+
+ int gid = getProperty(n2, "gid", -1);
+ map->setTileWithGid(x, y, layer, gid);
+
+ x++;
+ if (x == w) {
+ x = 0; y++;
+ if (y >= h)
+ break;
}
}
-
- // There can be only one data element
- break;
}
- node = node->next;
+ // There can be only one data element
+ break;
}
}
@@ -356,38 +344,33 @@ MapReader::readTileset(xmlNodePtr node,
int tw = getProperty(node, "tilewidth", map->getTileWidth());
int th = getProperty(node, "tileheight", map->getTileHeight());
- node = node->xmlChildrenNode;
+ for (node = node->xmlChildrenNode; node; node = node->next) {
+ if (!xmlStrEqual(node->name, BAD_CAST "image"))
+ continue;
- while (node != NULL)
- {
- if (xmlStrEqual(node->name, BAD_CAST "image"))
- {
- xmlChar* source = xmlGetProp(node, BAD_CAST "source");
+ xmlChar* source = xmlGetProp(node, BAD_CAST "source");
- if (source)
- {
- std::string sourceStr = std::string((const char*)source);
- sourceStr.erase(0, 3); // Remove "../"
+ if (source)
+ {
+ std::string sourceStr = std::string((const char*)source);
+ sourceStr.erase(0, 3); // Remove "../"
- ResourceManager *resman = ResourceManager::getInstance();
- Image* tilebmp = resman->getImage(sourceStr);
+ ResourceManager *resman = ResourceManager::getInstance();
+ Image* tilebmp = resman->getImage(sourceStr);
- if (tilebmp)
- {
- Tileset *set = new Tileset(tilebmp, tw, th, firstGid);
- tilebmp->decRef();
- xmlFree(source);
- return set;
- }
- else {
- logger->log("Warning: Failed to load tileset (%s)", source);
- }
+ if (tilebmp)
+ {
+ Tileset *set = new Tileset(tilebmp, tw, th, firstGid);
+ tilebmp->decRef();
+ xmlFree(source);
+ return set;
+ }
+ else {
+ logger->log("Warning: Failed to load tileset (%s)", source);
}
-
- break;
}
- node = node->next;
+ break;
}
return NULL;
@@ -396,13 +379,12 @@ MapReader::readTileset(xmlNodePtr node,
int
MapReader::getProperty(xmlNodePtr node, const char* name, int def)
{
+ int &ret = def;
+
xmlChar *prop = xmlGetProp(node, BAD_CAST name);
if (prop) {
- int val = atoi((char*)prop);
+ ret = atoi((char*)prop);
xmlFree(prop);
- return val;
- }
- else {
- return def;
}
+ return ret;
}
diff --git a/src/resources/openglsdlimageloader.cpp b/src/resources/openglsdlimageloader.cpp
index c7ddec74..b3e1601e 100644
--- a/src/resources/openglsdlimageloader.cpp
+++ b/src/resources/openglsdlimageloader.cpp
@@ -21,14 +21,16 @@
* $Id: sdlimageloader.cpp 2121 2006-01-31 02:55:26Z der_doener $
*/
-#ifdef USE_OPENGL
-
#include "openglsdlimageloader.h"
#include <string>
#include "resourcemanager.h"
+#include "../main.h"
+
+#ifdef USE_OPENGL
+
SDL_Surface* OpenGLSDLImageLoader::loadSDLSurface(const std::string& filename)
{
ResourceManager *resman = ResourceManager::getInstance();