summaryrefslogtreecommitdiffstats
path: root/src/game-server
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2013-05-08 00:06:32 +0200
committerErik Schilling <ablu.erikschilling@googlemail.com>2013-05-11 23:31:14 +0200
commitf6765ffda1e0db5006aaebc359b2634837fe70bd (patch)
tree9d79efdcd21bf008d296cfd6b73d03e9870fc0ba /src/game-server
parentcec65058123f710643290c13b7f2b0512b878381 (diff)
downloadmanaserv-f6765ffda1e0db5006aaebc359b2634837fe70bd.tar.gz
manaserv-f6765ffda1e0db5006aaebc359b2634837fe70bd.tar.xz
manaserv-f6765ffda1e0db5006aaebc359b2634837fe70bd.zip
[Abilities] Added abilities to monsters
Monsters can now either receive abilities at lifetime via scripts, or via the <ability> node in the monsters node.
Diffstat (limited to 'src/game-server')
-rw-r--r--src/game-server/abilitycomponent.cpp35
-rw-r--r--src/game-server/abilitycomponent.h6
-rw-r--r--src/game-server/monster.cpp7
-rw-r--r--src/game-server/monster.h19
-rw-r--r--src/game-server/monstermanager.cpp44
5 files changed, 95 insertions, 16 deletions
diff --git a/src/game-server/abilitycomponent.cpp b/src/game-server/abilitycomponent.cpp
index 60c9b86..961617b 100644
--- a/src/game-server/abilitycomponent.cpp
+++ b/src/game-server/abilitycomponent.cpp
@@ -84,7 +84,7 @@ bool AbilityComponent::abilityUseCheck(AbilityMap::iterator it)
if (it == mAbilities.end())
{
- LOG_INFO("Character uses ability " << it->first
+ LOG_INFO("Entity uses ability " << it->first
<< " without authorization.");
return false;
}
@@ -115,15 +115,15 @@ bool AbilityComponent::abilityUseCheck(AbilityMap::iterator it)
* makes the character perform a ability on a being
* when it is allowed to do so
*/
-void AbilityComponent::useAbilityOnBeing(Entity &user, int id, Entity *b)
+bool AbilityComponent::useAbilityOnBeing(Entity &user, int id, Entity *b)
{
AbilityMap::iterator it = mAbilities.find(id);
if (!abilityUseCheck(it))
- return;
+ return false;
AbilityValue &ability = it->second;
if (ability.abilityInfo->target != AbilityManager::TARGET_BEING)
- return;
+ return false;
if (ability.abilityInfo->autoconsume) {
ability.currentPoints = 0;
@@ -146,21 +146,22 @@ void AbilityComponent::useAbilityOnBeing(Entity &user, int id, Entity *b)
mLastTargetBeingId = 0;
user.getComponent<ActorComponent>()->raiseUpdateFlags(
UPDATEFLAG_ABILITY_ON_BEING);
+ return true;
}
/**
* makes the character perform a ability on a map point
* when it is allowed to do so
*/
-void AbilityComponent::useAbilityOnPoint(Entity &user, int id, int x, int y)
+bool AbilityComponent::useAbilityOnPoint(Entity &user, int id, int x, int y)
{
AbilityMap::iterator it = mAbilities.find(id);
if (!abilityUseCheck(it))
- return;
+ return false;
AbilityValue &ability = it->second;
if (ability.abilityInfo->target != AbilityManager::TARGET_POINT)
- return;
+ return false;
if (ability.abilityInfo->autoconsume) {
ability.currentPoints = 0;
@@ -181,6 +182,7 @@ void AbilityComponent::useAbilityOnPoint(Entity &user, int id, int x, int y)
mLastTargetPoint = Point(x, y);
user.getComponent<ActorComponent>()->raiseUpdateFlags(
UPDATEFLAG_ABILITY_ON_POINT);
+ return true;
}
/**
@@ -190,22 +192,27 @@ bool AbilityComponent::giveAbility(int id, int currentPoints)
{
if (mAbilities.find(id) == mAbilities.end())
{
- const AbilityManager::AbilityInfo *abilityInfo =
- abilityManager->getAbilityInfo(id);
+ auto *abilityInfo = abilityManager->getAbilityInfo(id);
if (!abilityInfo)
{
LOG_ERROR("Tried to give not existing ability id " << id << ".");
return false;
}
- mAbilities.insert(std::pair<int, AbilityValue>(
- id, AbilityValue(currentPoints, abilityInfo)));
-
- signal_ability_changed.emit(id);
- return true;
+ return giveAbility(abilityInfo, currentPoints);
}
return false;
}
+bool AbilityComponent::giveAbility(const AbilityManager::AbilityInfo *info,
+ int currentPoints)
+{
+ bool added = mAbilities.insert(std::pair<int, AbilityValue>(info->id,
+ AbilityValue(currentPoints, info))).second;
+
+ signal_ability_changed.emit(info->id);
+ return added;
+}
+
/**
* Sets new current mana + makes sure that the client will get informed.
*/
diff --git a/src/game-server/abilitycomponent.h b/src/game-server/abilitycomponent.h
index def3e00..7d3472e 100644
--- a/src/game-server/abilitycomponent.h
+++ b/src/game-server/abilitycomponent.h
@@ -56,10 +56,12 @@ public:
void update(Entity &entity);
- void useAbilityOnBeing(Entity &user, int id, Entity *b);
- void useAbilityOnPoint(Entity &user, int id, int x, int y);
+ bool useAbilityOnBeing(Entity &user, int id, Entity *b);
+ bool useAbilityOnPoint(Entity &user, int id, int x, int y);
bool giveAbility(int id, int currentMana = 0);
+ bool giveAbility(const AbilityManager::AbilityInfo *info,
+ int currentMana = 0);
bool hasAbility(int id) const;
bool takeAbility(int id);
AbilityMap::iterator findAbility(int id);
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index e0feed9..45a99d8 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -86,6 +86,13 @@ MonsterComponent::MonsterComponent(Entity &entity, MonsterClass *specy):
beingComponent->setGender(specy->getGender());
+ AbilityComponent *abilityComponent = new AbilityComponent(entity);
+ entity.addComponent(abilityComponent);
+ for (auto *abilitiyInfo : specy->getAbilities())
+ {
+ abilityComponent->giveAbility(abilitiyInfo);
+ }
+
beingComponent->signal_died.connect(sigc::mem_fun(this,
&MonsterComponent::monsterDied));
}
diff --git a/src/game-server/monster.h b/src/game-server/monster.h
index 4949d4c..9854a7a 100644
--- a/src/game-server/monster.h
+++ b/src/game-server/monster.h
@@ -21,9 +21,13 @@
#ifndef MONSTER_H
#define MONSTER_H
+#include "game-server/abilitymanager.h"
#include "game-server/being.h"
+
#include "common/defines.h"
+
#include "scripting/script.h"
+
#include "utils/string.h"
#include <map>
@@ -182,6 +186,9 @@ class MonsterClass
double getVulnerability(Element element) const;
+ void addAbility(AbilityManager::AbilityInfo *info);
+ const std::set<AbilityManager::AbilityInfo *> &getAbilities() const;
+
void setUpdateCallback(Script *script)
{ script->assignCallback(mUpdateCallback); }
@@ -201,6 +208,7 @@ class MonsterClass
MonsterDrops mDrops;
std::map<int, double> mAttributes; /**< Base attributes of the monster. */
+ std::set<AbilityManager::AbilityInfo *> mAbilities;
float mSpeed; /**< The monster class speed in tiles per second */
int mSize;
int mExp;
@@ -308,4 +316,15 @@ class MonsterComponent : public Component
Timeout mDecayTimeout;
};
+inline void MonsterClass::addAbility(AbilityManager::AbilityInfo *info)
+{
+ mAbilities.insert(info);
+}
+
+inline const std::set<AbilityManager::AbilityInfo *>
+&MonsterClass::getAbilities() const
+{
+ return mAbilities;
+}
+
#endif // MONSTER_H
diff --git a/src/game-server/monstermanager.cpp b/src/game-server/monstermanager.cpp
index df8c690..19e196e 100644
--- a/src/game-server/monstermanager.cpp
+++ b/src/game-server/monstermanager.cpp
@@ -216,6 +216,50 @@ void MonsterManager::readMonsterNode(xmlNodePtr node, const std::string &filenam
}
}
+ else if (xmlStrEqual(subnode->name, BAD_CAST "attribute"))
+ {
+ const int id = XML::getProperty(subnode, "id", 0);
+ auto *attributeInfo = attributeManager->getAttributeInfo(id);
+
+ if (!attributeInfo)
+ {
+ LOG_WARN(filename
+ << ": Invalid attribute id " << id
+ << " for monster Id: " << id
+ << ". Skipping!");
+ continue;
+ }
+
+ const double value = XML::getFloatProperty(subnode, "value", 0.0);
+
+ monster->setAttribute(id, value);
+ }
+ else if (xmlStrEqual(subnode->name, BAD_CAST "ability"))
+ {
+ const std::string idText = XML::getProperty(subnode, "id",
+ std::string());
+ AbilityManager::AbilityInfo *info = 0;
+ if (utils::isNumeric(idText))
+ {
+ const int id = utils::stringToInt(idText);
+ info = abilityManager->getAbilityInfo(id);
+ }
+ else
+ {
+ info = abilityManager->getAbilityInfo(idText);
+ }
+
+ if (!info)
+ {
+ LOG_WARN(filename
+ << ": Invalid ability id " << idText
+ << " for monster id: " << id
+ << " Skipping!");
+ continue;
+ }
+
+ monster->addAbility(info);
+ }
else if (xmlStrEqual(subnode->name, BAD_CAST "exp"))
{
xmlChar *exp = subnode->xmlChildrenNode->content;