summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuck Miller <shadowmil@gmail.com>2009-05-03 17:11:25 -0400
committerChuck Miller <shadowmil@gmail.com>2009-05-03 17:11:25 -0400
commita93a723db62ba2ad445b0fff26be5c51aefcda78 (patch)
tree1d39966d58f3d1c8c948f4719d22146d2373df10
parent19bf50bbff325024c2ed9ad724aeb6acb39bae39 (diff)
downloadmana-a93a723db62ba2ad445b0fff26be5c51aefcda78.tar.gz
mana-a93a723db62ba2ad445b0fff26be5c51aefcda78.tar.bz2
mana-a93a723db62ba2ad445b0fff26be5c51aefcda78.tar.xz
mana-a93a723db62ba2ad445b0fff26be5c51aefcda78.zip
Added rotational particles, and added code to show arrows when a player shoots them.
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/being.cpp17
-rw-r--r--src/localplayer.h2
-rw-r--r--src/particle.cpp7
-rw-r--r--src/particle.h1
-rw-r--r--src/particleemitter.cpp75
-rw-r--r--src/particleemitter.h1
-rw-r--r--src/rotationalparticle.cpp76
-rw-r--r--src/rotationalparticle.h48
-rw-r--r--src/simpleanimation.cpp15
-rw-r--r--src/simpleanimation.h4
12 files changed, 246 insertions, 4 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 65ba4d98..299d75f8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -384,6 +384,8 @@ SET(SRCS
position.cpp
position.h
properties.h
+ rotationalparticle.cpp
+ rotationalparticle.h
serverinfo.h
shopitem.cpp
shopitem.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 21766f34..ad4a0a26 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -337,6 +337,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
position.cpp \
position.h \
properties.h \
+ rotationalparticle.cpp \
+ rotationalparticle.h \
serverinfo.h \
shopitem.cpp \
shopitem.h \
diff --git a/src/being.cpp b/src/being.cpp
index d719635b..fc61fbd9 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -470,8 +470,23 @@ void Being::handleAttack()
void Being::handleAttack(Being *victim, int damage, AttackType type)
#endif
{
- setAction(Being::ATTACK);
+ if (this != player_node)
+ setAction(Being::ATTACK);
#ifdef EATHENA_SUPPORT
+ if (getType() == PLAYER)
+ {
+ if (mEquippedWeapon->getAttackType() == ACTION_ATTACK_BOW)
+ {
+ Particle *p = new Particle(NULL);
+ p->setLifetime(1000);
+ victim->controlParticle(p);
+
+ Particle *p2 = particleEngine->addEffect("graphics/particles/arrow.particle.xml", mPx, mPy);
+ p2->setLifetime(900);
+ p2->setDestination(p, 7, 0);
+ p2->setDieDistance(8);
+ }
+ }
mFrame = 0;
mWalkTime = tick_time;
#endif
diff --git a/src/localplayer.h b/src/localplayer.h
index 55e4e6f6..e67630b2 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -279,7 +279,7 @@ class LocalPlayer : public Player
* @param damage the amount of damage dealt (0 means miss)
* @param type the attack type
*/
- virtual void handleAttack(Being *victim, int damage, AttackType type) {}
+ //virtual void handleAttack(Being *victim, int damage, AttackType type) {}
virtual void handleAttack() {}
/**
diff --git a/src/particle.cpp b/src/particle.cpp
index 78db2a58..42ec84d7 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -31,6 +31,7 @@
#include "map.h"
#include "particle.h"
#include "particleemitter.h"
+#include "rotationalparticle.h"
#include "textparticle.h"
#include "resources/resourcemanager.h"
@@ -222,7 +223,6 @@ bool Particle::update()
p = mChildParticles.erase(p);
}
}
-
if (!mAlive && mChildParticles.empty() && mAutoDelete)
{
return false;
@@ -280,6 +280,11 @@ Particle *Particle::addEffect(const std::string &particleEffectFile,
{
newParticle = new AnimationParticle(mMap, node);
}
+ // Rotational
+ else if ((node = XML::findFirstChildByName(effectChildNode, "rotation")))
+ {
+ newParticle = new RotationalParticle(mMap, node);
+ }
// Image
else if ((node = XML::findFirstChildByName(effectChildNode, "image")))
{
diff --git a/src/particle.h b/src/particle.h
index f3f5571a..52b2dd3c 100644
--- a/src/particle.h
+++ b/src/particle.h
@@ -267,7 +267,6 @@ class Particle : public Sprite
int mFadeIn; /**< Age in game ticks where fading in is finished*/
float mAlpha; /**< Opacity of the graphical representation of the particle */
- private:
// generic properties
bool mAutoDelete; /**< May the particle request its deletion by the parent particle? */
Map *mMap; /**< Map the particle is on. */
diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp
index 25e6ade5..d4a56bfd 100644
--- a/src/particleemitter.cpp
+++ b/src/particleemitter.cpp
@@ -26,6 +26,7 @@
#include "log.h"
#include "particle.h"
#include "particleemitter.h"
+#include "rotationalparticle.h"
#include "resources/image.h"
#include "resources/imageset.h"
@@ -184,6 +185,74 @@ ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target, Map *
ParticleEmitter newEmitter(propertyNode, mParticleTarget, map);
mParticleChildEmitters.push_back(newEmitter);
}
+ else if (xmlStrEqual(propertyNode->name, BAD_CAST "rotation"))
+ {
+ ImageSet *imageset = ResourceManager::getInstance()->getImageSet(
+ XML::getProperty(propertyNode, "imageset", ""),
+ XML::getProperty(propertyNode, "width", 0),
+ XML::getProperty(propertyNode, "height", 0)
+ );
+
+ // Get animation frames
+ for_each_xml_child_node(frameNode, propertyNode)
+ {
+ int delay = XML::getProperty(frameNode, "delay", 0);
+ int offsetX = XML::getProperty(frameNode, "offsetX", 0);
+ int offsetY = XML::getProperty(frameNode, "offsetY", 0);
+ offsetY -= imageset->getHeight() - 32;
+ offsetX -= imageset->getWidth() / 2 - 16;
+
+ if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
+ {
+ int index = XML::getProperty(frameNode, "index", -1);
+
+ if (index < 0)
+ {
+ logger->log("No valid value for 'index'");
+ continue;
+ }
+
+ Image *img = imageset->get(index);
+
+ if (!img)
+ {
+ logger->log("No image at index %d", index);
+ continue;
+ }
+
+ mParticleRotation.addFrame(img, delay, offsetX, offsetY);
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence"))
+ {
+ int start = XML::getProperty(frameNode, "start", -1);
+ int end = XML::getProperty(frameNode, "end", -1);
+
+ if (start < 0 || end < 0)
+ {
+ logger->log("No valid value for 'start' or 'end'");
+ continue;
+ }
+
+ while (end >= start)
+ {
+ Image *img = imageset->get(start);
+
+ if (!img)
+ {
+ logger->log("No image at index %d", start);
+ continue;
+ }
+
+ mParticleRotation.addFrame(img, delay, offsetX, offsetY);
+ start++;
+ }
+ }
+ else if (xmlStrEqual(frameNode->name, BAD_CAST "end"))
+ {
+ mParticleRotation.addTerminator();
+ }
+ } // for frameNode
+ }
else if (xmlStrEqual(propertyNode->name, BAD_CAST "animation"))
{
ImageSet *imageset = ResourceManager::getInstance()->getImageSet(
@@ -285,6 +354,7 @@ ParticleEmitter & ParticleEmitter::operator=(const ParticleEmitter &o)
mOutputPause = o.mOutputPause;
mParticleImage = o.mParticleImage;
mParticleAnimation = o.mParticleAnimation;
+ mParticleRotation = o.mParticleRotation;
mParticleChildEmitters = o.mParticleChildEmitters;
mOutputPauseLeft = 0;
@@ -349,6 +419,11 @@ std::list<Particle *> ParticleEmitter::createParticles(int tick)
{
newParticle = new ImageParticle(mMap, mParticleImage);
}
+ else if (mParticleRotation.getLength() > 0)
+ {
+ Animation *newAnimation = new Animation(mParticleRotation);
+ newParticle = new RotationalParticle(mMap, newAnimation);
+ }
else if (mParticleAnimation.getLength() > 0)
{
Animation *newAnimation = new Animation(mParticleAnimation);
diff --git a/src/particleemitter.h b/src/particleemitter.h
index 67b35ae2..f58430b3 100644
--- a/src/particleemitter.h
+++ b/src/particleemitter.h
@@ -125,6 +125,7 @@ class ParticleEmitter
*/
Image *mParticleImage; /**< Particle image, if used */
Animation mParticleAnimation; /**< Filename of particle animation file */
+ Animation mParticleRotation; /**< Filename of particle rotation file */
ParticleEmitterProp<float> mParticleAlpha; /**< Opacity of the graphical representation of the particles */
/** List of emitters the spawned particles are equipped with */
diff --git a/src/rotationalparticle.cpp b/src/rotationalparticle.cpp
new file mode 100644
index 00000000..2fd7f901
--- /dev/null
+++ b/src/rotationalparticle.cpp
@@ -0,0 +1,76 @@
+/*
+ * The Mana World
+ * Copyright (C) 2006 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "rotationalparticle.h"
+#include "graphics.h"
+#include "simpleanimation.h"
+
+#define PI 3.14159265
+
+RotationalParticle::RotationalParticle(Map *map, Animation *animation):
+ ImageParticle(map, NULL),
+ mAnimation(new SimpleAnimation(animation))
+{
+}
+
+RotationalParticle::RotationalParticle(Map *map, xmlNodePtr animationNode):
+ ImageParticle(map, 0),
+ mAnimation(new SimpleAnimation(animationNode))
+{
+}
+
+RotationalParticle::~RotationalParticle()
+{
+ delete mAnimation;
+ mImage = NULL;
+}
+
+bool RotationalParticle::update()
+{
+ // TODO: cache velocities to avoid spamming atan2()
+
+ float rad = atan2(mVelocity.x, mVelocity.y);
+ if (rad < 0)
+ rad = PI + (PI + rad);
+ int size = mAnimation->getLength();
+ float range = PI / size;
+
+ // Determines which frame the particle should play
+ if (rad < range || rad > ((PI*2) - range))
+ {
+ mAnimation->setFrame(0);
+ }
+ else
+ {
+ for (int c = 1; c < size; c++)
+ {
+ if (((c * (2 * range)) - range) < rad && rad < ((c * (2 * range)) + range))
+ {
+ mAnimation->setFrame(c);
+ break;
+ }
+ }
+ }
+
+ mImage = mAnimation->getCurrentImage();
+
+ return Particle::update();
+}
diff --git a/src/rotationalparticle.h b/src/rotationalparticle.h
new file mode 100644
index 00000000..07c95e9c
--- /dev/null
+++ b/src/rotationalparticle.h
@@ -0,0 +1,48 @@
+/*
+ * The Mana World
+ * Copyright (C) 2006 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ROTATIONAL_PARTICLE_H
+#define _ROTATIONAL_PARTICLE_H
+
+#include <libxml/tree.h>
+
+#include "imageparticle.h"
+
+class Animation;
+class Map;
+class SimpleAnimation;
+
+class RotationalParticle : public ImageParticle
+{
+ public:
+ RotationalParticle(Map *map, Animation *animation);
+
+ RotationalParticle(Map *map, xmlNodePtr animationNode);
+
+ ~RotationalParticle();
+
+ virtual bool update();
+
+ private:
+ SimpleAnimation *mAnimation; /**< Used animation for this particle */
+};
+
+#endif
diff --git a/src/simpleanimation.cpp b/src/simpleanimation.cpp
index 65d8e8e2..7038f446 100644
--- a/src/simpleanimation.cpp
+++ b/src/simpleanimation.cpp
@@ -129,6 +129,16 @@ void SimpleAnimation::reset()
mAnimationPhase = 0;
}
+void SimpleAnimation::setFrame(int frame)
+{
+ if (frame < 0)
+ frame = 0;
+ if (frame >= mAnimation->getLength())
+ frame = mAnimation->getLength() - 1;
+ mAnimationPhase = frame;
+ mCurrentFrame = mAnimation->getFrame(mAnimationPhase);
+}
+
void SimpleAnimation::update(unsigned int timePassed)
{
mAnimationTime += timePassed;
@@ -145,6 +155,11 @@ void SimpleAnimation::update(unsigned int timePassed)
}
}
+int SimpleAnimation::getLength()
+{
+ return mAnimation->getLength();
+}
+
Image *SimpleAnimation::getCurrentImage() const
{
return mCurrentFrame->image;
diff --git a/src/simpleanimation.h b/src/simpleanimation.h
index e48644d4..508810b1 100644
--- a/src/simpleanimation.h
+++ b/src/simpleanimation.h
@@ -48,6 +48,10 @@ class SimpleAnimation
~SimpleAnimation();
+ void setFrame(int frame);
+
+ int getLength();
+
void update(unsigned int timePassed);
bool draw(Graphics* graphics, int posX, int posY) const;