summaryrefslogtreecommitdiffstats
path: root/src/game-server
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2013-04-23 23:36:09 +0200
committerErik Schilling <ablu.erikschilling@googlemail.com>2013-05-08 14:02:51 +0200
commit1758acc8e845524071db8996f3dd5d1935a059e1 (patch)
tree713fef27549712cdb979b096bd82da66a904c672 /src/game-server
parent62f1e23dff18a00066ce9a9df67e058d5e5d7bbd (diff)
downloadmanaserv-1758acc8e845524071db8996f3dd5d1935a059e1.tar.gz
manaserv-1758acc8e845524071db8996f3dd5d1935a059e1.tar.xz
manaserv-1758acc8e845524071db8996f3dd5d1935a059e1.zip
[Abilities] Added support for a global cooldown
Each ability can now define a cooldown that prevents the player from using other abilities for a while. The time of this cooldown can be set to any attribute. The modified value of the attribute is the value of the cooldown in game ticks. The cooldown will be automatically started if the ability has `autoconsume` set to true. Otherwise a script has to call entity:cooldown_ability(ability).
Diffstat (limited to 'src/game-server')
-rw-r--r--src/game-server/abilitycomponent.cpp14
-rw-r--r--src/game-server/abilitycomponent.h14
-rw-r--r--src/game-server/abilitymanager.cpp22
-rw-r--r--src/game-server/abilitymanager.h7
-rw-r--r--src/game-server/character.cpp22
-rw-r--r--src/game-server/character.h4
-rw-r--r--src/game-server/commandhandler.cpp2
7 files changed, 81 insertions, 4 deletions
diff --git a/src/game-server/abilitycomponent.cpp b/src/game-server/abilitycomponent.cpp
index eac5f1c..5b27be1 100644
--- a/src/game-server/abilitycomponent.cpp
+++ b/src/game-server/abilitycomponent.cpp
@@ -77,6 +77,9 @@ bool AbilityComponent::takeAbility(int id)
bool AbilityComponent::abilityUseCheck(AbilityMap::iterator it)
{
+ if (!mCooldown.expired())
+ return false;
+
if (it == mAbilities.end())
{
LOG_INFO("Character uses ability " << it->first
@@ -123,6 +126,7 @@ void AbilityComponent::useAbilityOnBeing(Entity &user, int id, Entity *b)
if (ability.abilityInfo->autoconsume) {
ability.currentPoints = 0;
signal_ability_changed.emit(id);
+ startCooldown(user, ability.abilityInfo);
}
//tell script engine to cast the spell
@@ -151,6 +155,7 @@ void AbilityComponent::useAbilityOnPoint(Entity &user, int id, int x, int y)
if (ability.abilityInfo->autoconsume) {
ability.currentPoints = 0;
signal_ability_changed.emit(id);
+ startCooldown(user, ability.abilityInfo);
}
//tell script engine to cast the spell
@@ -201,6 +206,15 @@ bool AbilityComponent::setAbilityMana(int id, int mana)
return false;
}
+void AbilityComponent::startCooldown(
+ Entity &entity, const AbilityManager::AbilityInfo *abilityInfo)
+{
+ unsigned cooldownAttribute = abilityInfo->cooldownAttribute;
+ auto *bc = entity.getComponent<BeingComponent>();
+ mCooldown.set((int)bc->getModifiedAttribute(cooldownAttribute));
+ signal_cooldown_activated.emit();
+}
+
void AbilityComponent::attributeChanged(Entity *entity, unsigned attr)
{
for (auto &abilityIt : mAbilities)
diff --git a/src/game-server/abilitycomponent.h b/src/game-server/abilitycomponent.h
index ae48e91..c44dcb7 100644
--- a/src/game-server/abilitycomponent.h
+++ b/src/game-server/abilitycomponent.h
@@ -23,6 +23,7 @@
#include "game-server/abilitymanager.h"
#include "game-server/component.h"
+#include "game-server/timeout.h"
#include <sigc++/signal.h>
@@ -65,13 +66,19 @@ public:
bool setAbilityMana(int id, int mana);
+ void startCooldown(Entity &entity,
+ const AbilityManager::AbilityInfo *abilityInfo);
+ int remainingCooldown() const;
+
sigc::signal<void, int> signal_ability_changed;
sigc::signal<void, int> signal_ability_took;
-
+ sigc::signal<void> signal_cooldown_activated;
private:
bool abilityUseCheck(AbilityMap::iterator it);
void attributeChanged(Entity *entity, unsigned attr);
+ Timeout mCooldown;
+
AbilityMap mAbilities;
};
@@ -105,4 +112,9 @@ inline const AbilityMap &AbilityComponent::getAbilities() const
return mAbilities;
}
+inline int AbilityComponent::remainingCooldown() const
+{
+ return mCooldown.remaining();
+}
+
#endif /* ABILITYCOMPONENT_H_ */
diff --git a/src/game-server/abilitymanager.cpp b/src/game-server/abilitymanager.cpp
index eb828e8..0657c2c 100644
--- a/src/game-server/abilitymanager.cpp
+++ b/src/game-server/abilitymanager.cpp
@@ -100,6 +100,8 @@ void AbilityManager::readAbilityNode(xmlNodePtr abilityNode,
int neededMana = XML::getProperty(abilityNode, "needed", 0);
int rechargeAttribute = XML::getProperty(abilityNode,
"rechargeattribute", 0);
+ int cooldownAttribute = XML::getProperty(abilityNode,
+ "cooldownattribute", 0);
bool autoconsume = XML::getBoolProperty(abilityNode, "autoconsume", true);
if (rechargeable && neededMana <= 0)
@@ -118,6 +120,7 @@ void AbilityManager::readAbilityNode(xmlNodePtr abilityNode,
newInfo->rechargeable = rechargeable;
newInfo->neededPoints = neededMana;
newInfo->rechargeAttribute = rechargeAttribute;
+ newInfo->cooldownAttribute = cooldownAttribute;
newInfo->autoconsume = autoconsume;
newInfo->target = getTargetByString(XML::getProperty(abilityNode, "target",
@@ -177,8 +180,25 @@ const std::string AbilityManager::getCategoryName(int id) const
return it != mAbilitiesInfo.end() ? it->second->categoryName : "";
}
-AbilityManager::AbilityInfo *AbilityManager::getAbilityInfo(int id)
+AbilityManager::AbilityInfo *AbilityManager::getAbilityInfo(int id) const
{
AbilitiesInfo::const_iterator it = mAbilitiesInfo.find(id);
return it != mAbilitiesInfo.end() ? it->second : 0;
}
+
+AbilityManager::AbilityInfo *AbilityManager::getAbilityInfo(
+ const std::string &category,
+ const std::string &name) const
+{
+ std::string key = utils::toLower(category) + "_" + utils::toLower(name);
+ return getAbilityInfo(key);
+}
+
+AbilityManager::AbilityInfo *AbilityManager::getAbilityInfo(
+ const std::string &abilityName) const
+{
+ if (mNamedAbilitiesInfo.contains(abilityName))
+ return mNamedAbilitiesInfo.value(abilityName);
+ else
+ return 0;
+}
diff --git a/src/game-server/abilitymanager.h b/src/game-server/abilitymanager.h
index 2d23c48..9e315b7 100644
--- a/src/game-server/abilitymanager.h
+++ b/src/game-server/abilitymanager.h
@@ -44,6 +44,7 @@ public:
id(0),
rechargeable(false),
rechargeAttribute(0),
+ cooldownAttribute(0),
neededPoints(0),
autoconsume(true),
target(TARGET_BEING)
@@ -54,6 +55,7 @@ public:
std::string categoryName;
bool rechargeable;
unsigned rechargeAttribute;
+ unsigned cooldownAttribute;
unsigned neededPoints;
bool autoconsume;
TargetMode target;
@@ -91,7 +93,10 @@ public:
const std::string getAbilityName(int id) const;
const std::string getCategoryName(int id) const;
- AbilityInfo *getAbilityInfo(int id);
+ AbilityInfo *getAbilityInfo(int id) const;
+ AbilityInfo *getAbilityInfo(const std::string &category,
+ const std::string &name) const;
+ AbilityInfo *getAbilityInfo(const std::string &abilityName) const;
void readAbilityCategoryNode(xmlNodePtr node, const std::string &filename);
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index 0fa1e10..3d23e3a 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -82,6 +82,7 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg):
mLevelProgress(0),
mUpdateLevelProgress(false),
mRecalculateLevel(true),
+ mSendAbilityCooldown(false),
mParty(0),
mTransaction(TRANS_NONE),
mTalkNpcId(0),
@@ -127,10 +128,14 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg):
mKnuckleAttackInfo = new AttackInfo(0, knuckleDamage, 7, 3, 0);
combatcomponent->addAttack(mKnuckleAttackInfo);
+
auto *abilityComponent = new AbilityComponent(entity);
entity.addComponent(abilityComponent);
abilityComponent->signal_ability_changed.connect(
sigc::mem_fun(this, &CharacterComponent::abilityStatusChanged));
+ abilityComponent->signal_cooldown_activated.connect(
+ sigc::mem_fun(this,
+ &CharacterComponent::abilityCooldownActivated));
// Get character data.
mDatabaseID = msg.readInt32();
@@ -170,6 +175,9 @@ void CharacterComponent::update(Entity &entity)
if (!mModifiedAbilities.empty())
sendAbilityUpdate(entity);
+
+ if (mSendAbilityCooldown)
+ sendAbilityCooldownUpdate(entity);
}
void CharacterComponent::characterDied(Entity *being)
@@ -214,6 +222,11 @@ void CharacterComponent::abilityStatusChanged(int id)
mModifiedAbilities.insert(id);
}
+void CharacterComponent::abilityCooldownActivated()
+{
+ mSendAbilityCooldown = true;
+}
+
void CharacterComponent::sendAbilityUpdate(Entity &entity)
{
auto *beingComponent = entity.getComponent<BeingComponent>();
@@ -240,6 +253,15 @@ void CharacterComponent::sendAbilityUpdate(Entity &entity)
gameHandler->sendTo(mClient, msg);
}
+void CharacterComponent::sendAbilityCooldownUpdate(Entity &entity)
+{
+ MessageOut msg(GPMSG_ABILITY_COOLDOWN);
+ auto *abilityComponent = entity.getComponent<AbilityComponent>();
+ msg.writeInt16(abilityComponent->remainingCooldown());
+ gameHandler->sendTo(mClient, msg);
+ mSendAbilityCooldown = false;
+}
+
void CharacterComponent::cancelTransaction()
{
TransactionType t = mTransaction;
diff --git a/src/game-server/character.h b/src/game-server/character.h
index a67436c..78d27ec 100644
--- a/src/game-server/character.h
+++ b/src/game-server/character.h
@@ -429,12 +429,15 @@ class CharacterComponent : public Component
void recalculateLevel(Entity &entity);
void abilityStatusChanged(int id);
+ void abilityCooldownActivated();
/**
* Informs the client about his characters abilities charge status
*/
void sendAbilityUpdate(Entity &entity);
+ void sendAbilityCooldownUpdate(Entity &entity);
+
enum TransactionType
{ TRANS_NONE, TRANS_TRADE, TRANS_BUYSELL };
@@ -468,6 +471,7 @@ class CharacterComponent : public Component
int mCorrectionPoints; /**< Unused attribute correction points */
bool mUpdateLevelProgress; /**< Flag raised when percent to next level changed */
bool mRecalculateLevel; /**< Flag raised when the character level might have increased */
+ bool mSendAbilityCooldown;
unsigned char mAccountLevel; /**< Account level of the user. */
int mParty; /**< Party id of the character */
TransactionType mTransaction; /**< Trade/buy/sell action the character is involved in. */
diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp
index 3e74835..e54b9ea 100644
--- a/src/game-server/commandhandler.cpp
+++ b/src/game-server/commandhandler.cpp
@@ -1710,7 +1710,7 @@ static void handleRechargeAbility(Entity *player, std::string &args)
else
abilityId = abilityManager->getId(ability);
- AbilityManager::AbilityInfo *info =
+ const AbilityManager::AbilityInfo *info =
abilityManager->getAbilityInfo(abilityId);
if (!info)