summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/defaults.cpp1
-rw-r--r--src/effectmanager.cpp71
-rw-r--r--src/effectmanager.h18
-rw-r--r--src/game.cpp4
-rw-r--r--src/gui/windows/skilldialog.cpp21
-rw-r--r--src/gui/windows/skilldialog.h5
-rw-r--r--src/net/eathena/beingrecv.cpp6
-rw-r--r--src/particle/particletimer.h39
10 files changed, 157 insertions, 10 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bc5b60a3a..24ea0e3fa 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1045,6 +1045,7 @@ SET(SRCS
particle/particleinfo.h
particle/particlelist.cpp
particle/particlelist.h
+ particle/particletimer.h
particle/particlevector.cpp
particle/particlevector.h
party.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index dcf9009d2..9e7d0a6fe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1057,6 +1057,7 @@ manaplus_SOURCES += main.cpp \
particle/particleinfo.h \
particle/particlelist.cpp \
particle/particlelist.h \
+ particle/particletimer.h \
particle/particlevector.cpp \
particle/particlevector.h \
party.cpp \
diff --git a/src/defaults.cpp b/src/defaults.cpp
index 91a092dbe..0c11be8ac 100644
--- a/src/defaults.cpp
+++ b/src/defaults.cpp
@@ -519,6 +519,7 @@ DefaultsData* getPathsDefaults()
AddDEF("skillRemoveEffectId", -1);
AddDEF("skillCastingSrcEffectId", -1);
AddDEF("skillCastingDstEffectId", -1);
+ AddDEF("skillCastingGroundEffectId", -1);
AddDEF("skillHitEffectId", -1);
AddDEF("skillMissEffectId", -1);
diff --git a/src/effectmanager.cpp b/src/effectmanager.cpp
index e88dc0a74..3a76f3e6d 100644
--- a/src/effectmanager.cpp
+++ b/src/effectmanager.cpp
@@ -37,7 +37,8 @@
EffectManager *effectManager = nullptr;
EffectManager::EffectManager() :
- mEffects()
+ mEffects(),
+ mTimers()
{
logger->log1("Effects are now loading");
loadXmlFile(paths.getStringValue("effectsFile"));
@@ -80,7 +81,8 @@ EffectManager::~EffectManager()
{
}
-bool EffectManager::triggerDirection(const int id, Being *const being,
+bool EffectManager::triggerDirection(const int id,
+ Being *const being,
const SpriteDirection::Type &direction)
{
int rotation;
@@ -110,7 +112,8 @@ bool EffectManager::triggerDirection(const int id, Being *const being,
return trigger(id, being, rotation);
}
-bool EffectManager::trigger(const int id, Being *const being,
+bool EffectManager::trigger(const int id,
+ Being *const being,
const int rotation)
{
if (!being || !particleEngine)
@@ -141,7 +144,8 @@ bool EffectManager::trigger(const int id, Being *const being,
return rValue;
}
-Particle *EffectManager::triggerReturn(const int id, Being *const being,
+Particle *EffectManager::triggerReturn(const int id,
+ Being *const being,
const int rotation)
{
if (!being || !particleEngine)
@@ -169,7 +173,9 @@ Particle *EffectManager::triggerReturn(const int id, Being *const being,
return rValue;
}
-bool EffectManager::trigger(const int id, const int x, const int y,
+bool EffectManager::trigger(const int id,
+ const int x, const int y,
+ const int endTime,
const int rotation)
{
if (!particleEngine)
@@ -183,7 +189,13 @@ bool EffectManager::trigger(const int id, const int x, const int y,
{
rValue = true;
if (!effect.gfx.empty())
- particleEngine->addEffect(effect.gfx, x, y, rotation);
+ {
+ Particle *const particle = particleEngine->addEffect(effect.gfx,
+ x, y,
+ rotation);
+ if (particle)
+ mTimers.push_back(ParticleTimer(particle, endTime));
+ }
if (!effect.sfx.empty())
soundManager.playSfx(effect.sfx);
// TODO add sprite effect to position
@@ -203,3 +215,50 @@ void EffectManager::triggerDefault(int effectId,
return;
trigger(effectId, being);
}
+
+void EffectManager::triggerDefault(int effectId,
+ const int x,
+ const int y,
+ const int endTime,
+ const int defaultEffectId)
+{
+ if (effectId == -1)
+ effectId = defaultEffectId;
+ if (effectId == -1)
+ return;
+ trigger(effectId, x, y, endTime);
+}
+
+void EffectManager::logic()
+{
+ const int time = cur_time;
+ bool found(true);
+ while (found)
+ {
+ found = false;
+ FOR_EACH (std::list<ParticleTimer>::iterator, it, mTimers)
+ {
+ const ParticleTimer &timer = *it;
+ if (timer.endTime < time)
+ {
+ found = true;
+ Particle *const particle = timer.particle;
+ if (particle)
+ particle->kill();
+ mTimers.erase(it);
+ break;
+ }
+ }
+ }
+}
+
+void EffectManager::clear()
+{
+ FOR_EACH (std::list<ParticleTimer>::iterator, it, mTimers)
+ {
+ Particle *const particle = (*it).particle;
+ if (particle)
+ particle->kill();
+ }
+ mTimers.clear();
+}
diff --git a/src/effectmanager.h b/src/effectmanager.h
index 0e81ffa44..16425908a 100644
--- a/src/effectmanager.h
+++ b/src/effectmanager.h
@@ -23,10 +23,13 @@
#ifndef EFFECTMANAGER_H
#define EFFECTMANAGER_H
+#include "particle/particletimer.h"
+
#include "resources/effectdescription.h"
#include "resources/spritedirection.h"
#include <vector>
+#include <list>
#include "localconsts.h"
@@ -60,15 +63,28 @@ class EffectManager final
* Triggers a effect with the id, at
* the specified x and y coordinate.
*/
- bool trigger(const int id, const int x, const int y,
+ bool trigger(const int id,
+ const int x, const int y,
+ const int endTime,
const int rotation = 0);
void triggerDefault(int effectId,
Being *const being,
const int defaultEffectId);
+ void triggerDefault(int effectId,
+ const int x,
+ const int y,
+ const int endTime,
+ const int defaultEffectId);
+
+ void logic();
+
+ void clear();
+
private:
std::vector<EffectDescription> mEffects;
+ std::list<ParticleTimer> mTimers;
};
extern EffectManager *effectManager;
diff --git a/src/game.cpp b/src/game.cpp
index 9fe4c2508..776dd8621 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -439,6 +439,8 @@ Game::~Game()
delete2(actorManager)
if (client->getState() != STATE_CHANGE_MAP)
delete2(localPlayer)
+ if (effectManager)
+ effectManager->clear();
delete2(effectManager)
delete2(particleEngine)
delete2(viewport)
@@ -622,6 +624,8 @@ void Game::slowLogic()
config.writeUpdated();
serverConfig.writeUpdated();
}
+ if (effectManager)
+ effectManager->logic();
}
if (mainGraphics->getOpenGL())
diff --git a/src/gui/windows/skilldialog.cpp b/src/gui/windows/skilldialog.cpp
index bf317b8cd..091c6c1d9 100644
--- a/src/gui/windows/skilldialog.cpp
+++ b/src/gui/windows/skilldialog.cpp
@@ -649,7 +649,8 @@ void SkillDialog::playCastingSrcEffect(const int id, Being *const being) const
paths.getIntValue("skillCastingSrcEffectId"));
}
-void SkillDialog::playCastingDstEffect(const int id, Being *const being) const
+void SkillDialog::playCastingDstEffect(const int id,
+ Being *const being) const
{
if (!effectManager)
return;
@@ -661,6 +662,24 @@ void SkillDialog::playCastingDstEffect(const int id, Being *const being) const
paths.getIntValue("skillCastingDstEffectId"));
}
+
+void SkillDialog::playCastingDstTileEffect(const int id,
+ const int x,
+ const int y,
+ const int delay) const
+{
+ if (!effectManager)
+ return;
+ SkillInfo *const info = getSkill(id);
+ if (!info)
+ return;
+ effectManager->triggerDefault(info->castingDstEffectId,
+ x * 32,
+ y * 32,
+ cur_time + delay / 1000, // end time in seconds
+ paths.getIntValue("skillCastingGroundEffectId"));
+}
+
void SkillDialog::useSkill(const SkillInfo *const info,
const AutoTarget autoTarget)
{
diff --git a/src/gui/windows/skilldialog.h b/src/gui/windows/skilldialog.h
index 8f085ee22..1e5740f58 100644
--- a/src/gui/windows/skilldialog.h
+++ b/src/gui/windows/skilldialog.h
@@ -130,6 +130,11 @@ class SkillDialog final : public Window,
void playCastingDstEffect(const int id,
Being *const being) const;
+ void playCastingDstTileEffect(const int id,
+ const int x,
+ const int y,
+ const int delay) const;
+
void slowLogic();
void removeSkill(const int id);
diff --git a/src/net/eathena/beingrecv.cpp b/src/net/eathena/beingrecv.cpp
index a85d9b3ee..a18af6b11 100644
--- a/src/net/eathena/beingrecv.cpp
+++ b/src/net/eathena/beingrecv.cpp
@@ -766,7 +766,7 @@ void BeingRecv::processSkillCasting(Net::MessageIn &msg)
const int dstY = msg.readInt16("dst y");
const int skillId = msg.readInt16("skill id");
msg.readInt32("property"); // can be used to trigger effect
- msg.readInt32("cast time");
+ const int castTime = msg.readInt32("cast time");
msg.readInt8("dispossable");
if (!effectManager)
@@ -786,7 +786,9 @@ void BeingRecv::processSkillCasting(Net::MessageIn &msg)
}
else if (dstX != 0 || dstY != 0)
{ // being to position
- UNIMPLIMENTEDPACKET;
+ skillDialog->playCastingDstTileEffect(skillId,
+ dstX, dstY,
+ castTime);
}
}
diff --git a/src/particle/particletimer.h b/src/particle/particletimer.h
new file mode 100644
index 000000000..ffcde3b8d
--- /dev/null
+++ b/src/particle/particletimer.h
@@ -0,0 +1,39 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2015 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PARTICLE_PARTICLETIMER_H
+#define PARTICLE_PARTICLETIMER_H
+
+class Particle;
+
+struct ParticleTimer final
+{
+ ParticleTimer(Particle *const particle0,
+ const int endTime0) :
+ particle(particle0),
+ endTime(endTime0)
+ {
+ }
+
+ Particle *particle;
+ int endTime;
+};
+
+#endif // PARTICLE_PARTICLETIMER_H