summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2013-08-07 22:08:29 +0200
committerErik Schilling <ablu.erikschilling@googlemail.com>2013-08-26 22:56:47 +0200
commitba573fcc38580a01985172b9bc864c97ce855af3 (patch)
treeebcdbcf9a86cd35d5a8ab3bb004faa5c490c16d4 /src
parent7dc001eb32ae5345905e108741984258ee2f1813 (diff)
downloadmanaserv-ba573fcc38580a01985172b9bc864c97ce855af3.tar.gz
manaserv-ba573fcc38580a01985172b9bc864c97ce855af3.tar.bz2
manaserv-ba573fcc38580a01985172b9bc864c97ce855af3.tar.xz
manaserv-ba573fcc38580a01985172b9bc864c97ce855af3.zip
Made cooldowns of abilities scriptable
- Removed hardcoded using of attributes - Simply introduced lua functions to set global and ability cooldowns - Requires database update - Bumps the protocol
Diffstat (limited to 'src')
-rw-r--r--src/account-server/character.cpp7
-rw-r--r--src/account-server/character.h38
-rw-r--r--src/account-server/storage.cpp16
-rw-r--r--src/common/manaserv_protocol.h6
-rw-r--r--src/game-server/abilitycomponent.cpp88
-rw-r--r--src/game-server/abilitycomponent.h28
-rw-r--r--src/game-server/abilitymanager.cpp22
-rw-r--r--src/game-server/abilitymanager.h10
-rw-r--r--src/game-server/character.cpp15
-rw-r--r--src/game-server/character.h27
-rw-r--r--src/game-server/commandhandler.cpp26
-rw-r--r--src/game-server/monster.cpp2
-rw-r--r--src/scripting/lua.cpp103
-rw-r--r--src/serialize/characterdata.h14
-rw-r--r--src/sql/mysql/createTables.sql3
-rw-r--r--src/sql/mysql/updates/update_23_to_24.sql12
-rw-r--r--src/sql/sqlite/createTables.sql3
-rw-r--r--src/sql/sqlite/updates/update_23_to_24.sql34
18 files changed, 166 insertions, 288 deletions
diff --git a/src/account-server/character.cpp b/src/account-server/character.cpp
index 9c371f54..98fe9bd2 100644
--- a/src/account-server/character.cpp
+++ b/src/account-server/character.cpp
@@ -45,10 +45,7 @@ void CharacterData::setAccount(Account *acc)
mAccountLevel = acc->getLevel();
}
-void CharacterData::giveAbility(int id, int currentMana)
+void CharacterData::giveAbility(int id)
{
- if (mAbilities.find(id) == mAbilities.end())
- {
- mAbilities[id] = AbilityValue(currentMana);
- }
+ mAbilities.insert(id);
}
diff --git a/src/account-server/character.h b/src/account-server/character.h
index 1fa0e975..ff29ffe5 100644
--- a/src/account-server/character.h
+++ b/src/account-server/character.h
@@ -23,7 +23,7 @@
#include <string>
#include <vector>
-#include <map>
+#include <set>
#include "common/defines.h"
#include "common/inventorydata.h"
@@ -55,19 +55,6 @@ struct AttributeValue
{ return modified; }
};
-struct AbilityValue
-{
- AbilityValue()
- : currentPoints(0)
- {}
-
- AbilityValue(unsigned currentPoints)
- : currentPoints(currentPoints)
- {}
-
- int currentPoints;
-};
-
struct Status
{
Status()
@@ -82,11 +69,6 @@ struct Status
*/
typedef std::map<unsigned, AttributeValue> AttributeMap;
-/**
- * Stores abilitys by their id.
- */
-typedef std::map<unsigned, AbilityValue> AbilityMap;
-
class CharacterData
{
public:
@@ -196,23 +178,13 @@ class CharacterData
void setKillCount(int monsterId, int kills)
{ mKillCount[monsterId] = kills; }
- /**
- * Get / Set abilitys
- */
- int getAbilitySize() const
- { return mAbilities.size(); }
-
- AbilityMap::const_iterator getAbilityBegin() const
- { return mAbilities.begin(); }
-
- AbilityMap::const_iterator getAbilityEnd() const
- { return mAbilities.end(); }
-
+ const std::set<int> &getAbilities() const
+ { return mAbilities; }
void clearAbilities()
{ mAbilities.clear(); }
- void giveAbility(int id, int currentMana);
+ void giveAbility(int id);
/**
* Gets the Id of the map that the character is on.
@@ -278,7 +250,7 @@ class CharacterData
AttributeMap mAttributes; //!< Attributes.
std::map<int, Status> mStatusEffects; //!< Status Effects
std::map<int, int> mKillCount; //!< Kill Count
- AbilityMap mAbilities;
+ std::set<int> mAbilities;
unsigned short mMapId; //!< Map the being is on.
unsigned char mGender; //!< Gender of the being.
unsigned char mHairStyle; //!< Hair style of the being.
diff --git a/src/account-server/storage.cpp b/src/account-server/storage.cpp
index c2af965b..15f4d9ae 100644
--- a/src/account-server/storage.cpp
+++ b/src/account-server/storage.cpp
@@ -456,7 +456,7 @@ CharacterData *Storage::getCharacterBySQL(Account *owner)
// Load the ability status
s.clear();
s.str("");
- s << "SELECT ability_id, ability_current_points FROM "
+ s << "SELECT ability_id FROM "
<< CHAR_ABILITIES_TBL_NAME
<< " WHERE char_id = " << character->getDatabaseID();
const dal::RecordSet &abilitiesInfo = mDb->execSql(s.str());
@@ -465,8 +465,7 @@ CharacterData *Storage::getCharacterBySQL(Account *owner)
const unsigned nRows = abilitiesInfo.rows();
for (unsigned row = 0; row < nRows; row++)
{
- character->giveAbility(toUint(abilitiesInfo(row, 0)),
- toUint(abilitiesInfo(row, 1)));
+ character->giveAbility(toUint(abilitiesInfo(row, 0)));
}
}
}
@@ -760,18 +759,15 @@ bool Storage::updateCharacter(CharacterData *character)
<< character->getDatabaseID() << "';";
mDb->execSql(deleteSql.str());
// In with the new
- AbilityMap::const_iterator ability_it, ability_it_end;
- for (ability_it = character->getAbilityBegin(),
- ability_it_end = character->getAbilityEnd();
- ability_it != ability_it_end; ++ability_it)
+ std::set<int>::const_iterator ability_it, ability_it_end;
+ for (int abilityId : character->getAbilities())
{
insertSql.str("");
insertSql << "INSERT INTO " << CHAR_ABILITIES_TBL_NAME
- << " (char_id, ability_id, ability_current_points)"
+ << " (char_id, ability_id)"
<< " VALUES ("
<< " '" << character->getDatabaseID() << "',"
- << " '" << ability_it->first << "',"
- << " '" << ability_it->second.currentPoints
+ << " '" << abilityId
<< "');";
mDb->execSql(insertSql.str());
}
diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h
index d3f2c8b4..73ea5932 100644
--- a/src/common/manaserv_protocol.h
+++ b/src/common/manaserv_protocol.h
@@ -29,8 +29,8 @@
namespace ManaServ {
enum {
- PROTOCOL_VERSION = 4,
- SUPPORTED_DB_VERSION = 23
+ PROTOCOL_VERSION = 5,
+ SUPPORTED_DB_VERSION = 24
};
/**
@@ -144,7 +144,7 @@ enum {
GPMSG_BEING_ABILITY_POINT = 0x0282, // W being id, B abilityId, W*2 point
GPMSG_BEING_ABILITY_BEING = 0x0283, // W being id, B abilityId, W target being id
PGMSG_USE_ABILITY_ON_BEING = 0x0292, // B abilityID, W being id
- GPMSG_ABILITY_STATUS = 0x0293, // { B abilityID, D current, D max, D recharge }
+ GPMSG_ABILITY_STATUS = 0x0293, // { B abilityID, D remainingTicks }
PGMSG_USE_ABILITY_ON_POINT = 0x0294, // B abilityID, W*2 position
GPMSG_ABILITY_REMOVED = 0x0295, // B abilityID
GPMSG_ABILITY_COOLDOWN = 0x0296, // W ticks to wait
diff --git a/src/game-server/abilitycomponent.cpp b/src/game-server/abilitycomponent.cpp
index 961617b1..19e832cb 100644
--- a/src/game-server/abilitycomponent.cpp
+++ b/src/game-server/abilitycomponent.cpp
@@ -27,12 +27,10 @@
#include "utils/logger.h"
-AbilityComponent::AbilityComponent(Entity &entity):
+AbilityComponent::AbilityComponent():
mLastUsedAbilityId(0),
mLastTargetBeingId(0)
{
- entity.getComponent<BeingComponent>()->signal_attribute_changed.connect(
- sigc::mem_fun(this, &AbilityComponent::attributeChanged));
}
void AbilityComponent::update(Entity &entity)
@@ -40,23 +38,14 @@ void AbilityComponent::update(Entity &entity)
// Update ability recharge
for (auto &it : mAbilities)
{
- AbilityValue &s = it.second;
- if (s.abilityInfo->rechargeable &&
- s.currentPoints < s.abilityInfo->neededPoints)
- {
- auto *beingComponent = entity.getComponent<BeingComponent>();
- const double rechargeSpeed = beingComponent->getModifiedAttribute(
- s.abilityInfo->rechargeAttribute);
- s.currentPoints += (int)rechargeSpeed;
- if (s.currentPoints >= s.abilityInfo->neededPoints &&
- s.abilityInfo->rechargedCallback.isValid())
- {
- Script *script = ScriptManager::currentState();
- script->prepare(s.abilityInfo->rechargedCallback);
- script->push(&entity);
- script->push(s.abilityInfo->id);
- script->execute(entity.getMap());
- }
+ auto &ability = it.second;
+ if (!ability.recharged && ability.rechargeTimeout.expired()) {
+ ability.recharged = true;
+ Script *script = ScriptManager::currentState();
+ script->prepare(ability.abilityInfo->rechargedCallback);
+ script->push(&entity);
+ script->push(ability.abilityInfo->id);
+ script->execute(entity.getMap());
}
}
@@ -79,7 +68,7 @@ bool AbilityComponent::takeAbility(int id)
bool AbilityComponent::abilityUseCheck(AbilityMap::iterator it)
{
- if (!mCooldown.expired())
+ if (!mGlobalCooldown.expired())
return false;
if (it == mAbilities.end())
@@ -91,13 +80,12 @@ bool AbilityComponent::abilityUseCheck(AbilityMap::iterator it)
//check if the ability is currently recharged
AbilityValue &ability = it->second;
- if (ability.abilityInfo->rechargeable &&
- ability.currentPoints < ability.abilityInfo->neededPoints)
+ if (!ability.recharged)
{
LOG_INFO("Character uses ability " << it->first
<< " which is not recharged. ("
- << ability.currentPoints << "/"
- << ability.abilityInfo->neededPoints << ")");
+ << ability.rechargeTimeout.remaining()
+ << " ticks are missing)");
return false;
}
@@ -125,12 +113,6 @@ bool AbilityComponent::useAbilityOnBeing(Entity &user, int id, Entity *b)
if (ability.abilityInfo->target != AbilityManager::TARGET_BEING)
return false;
- if (ability.abilityInfo->autoconsume) {
- ability.currentPoints = 0;
- signal_ability_changed.emit(id);
- startCooldown(user, ability.abilityInfo);
- }
-
//tell script engine to cast the spell
Script *script = ScriptManager::currentState();
script->prepare(ability.abilityInfo->useCallback);
@@ -163,12 +145,6 @@ bool AbilityComponent::useAbilityOnPoint(Entity &user, int id, int x, int y)
if (ability.abilityInfo->target != AbilityManager::TARGET_POINT)
return false;
- if (ability.abilityInfo->autoconsume) {
- ability.currentPoints = 0;
- signal_ability_changed.emit(id);
- startCooldown(user, ability.abilityInfo);
- }
-
//tell script engine to cast the spell
Script *script = ScriptManager::currentState();
script->prepare(ability.abilityInfo->useCallback);
@@ -207,46 +183,40 @@ bool AbilityComponent::giveAbility(const AbilityManager::AbilityInfo *info,
int currentPoints)
{
bool added = mAbilities.insert(std::pair<int, AbilityValue>(info->id,
- AbilityValue(currentPoints, info))).second;
+ AbilityValue(info))).second;
signal_ability_changed.emit(info->id);
return added;
}
/**
- * Sets new current mana + makes sure that the client will get informed.
+ * Sets cooldown time for this ability
*/
-bool AbilityComponent::setAbilityMana(int id, int mana)
+void AbilityComponent::setAbilityCooldown(int id, int ticks)
{
AbilityMap::iterator it = mAbilities.find(id);
if (it != mAbilities.end())
{
- it->second.currentPoints = mana;
+ it->second.recharged = false;
+ it->second.rechargeTimeout.set(ticks);
signal_ability_changed.emit(id);
- return true;
}
- return false;
}
-void AbilityComponent::startCooldown(
- Entity &entity, const AbilityManager::AbilityInfo *abilityInfo)
+int AbilityComponent::abilityCooldown(int id)
{
- unsigned cooldownAttribute = abilityInfo->cooldownAttribute;
- auto *bc = entity.getComponent<BeingComponent>();
- int cooldown = (int)bc->getModifiedAttribute(cooldownAttribute);
- // Enforce a minimum cooldown of 1 tick to prevent syncing issues
- cooldown = std::max(cooldown, 1);
- mCooldown.set(cooldown);
- signal_cooldown_activated.emit();
+ AbilityMap::iterator it = mAbilities.find(id);
+ if (it != mAbilities.end() && !it->second.recharged)
+ return it->second.rechargeTimeout.remaining();
+
+ return 0;
}
-void AbilityComponent::attributeChanged(Entity *entity, unsigned attr)
+void AbilityComponent::setGlobalCooldown(int ticks)
{
- for (auto &abilityIt : mAbilities)
- {
- // Inform the client about rechargespeed changes
- if (abilityIt.second.abilityInfo->rechargeAttribute == attr)
- signal_ability_changed.emit(abilityIt.first);
- }
+ // Enforce a minimum cooldown of 1 tick to prevent syncing issues
+ ticks = std::max(ticks, 1);
+ mGlobalCooldown.set(ticks);
+ signal_global_cooldown_activated.emit();
}
diff --git a/src/game-server/abilitycomponent.h b/src/game-server/abilitycomponent.h
index 7d3472e0..948d5ed3 100644
--- a/src/game-server/abilitycomponent.h
+++ b/src/game-server/abilitycomponent.h
@@ -31,13 +31,13 @@
struct AbilityValue
{
- AbilityValue(unsigned currentMana,
- const AbilityManager::AbilityInfo *abilityInfo)
- : currentPoints(currentMana)
+ AbilityValue(const AbilityManager::AbilityInfo *abilityInfo)
+ : recharged(false)
, abilityInfo(abilityInfo)
{}
- unsigned currentPoints;
+ bool recharged;
+ Timeout rechargeTimeout;
const AbilityManager::AbilityInfo *abilityInfo;
};
@@ -52,7 +52,7 @@ class AbilityComponent: public Component
public:
static const ComponentType type = CT_Ability;
- AbilityComponent(Entity &entity);
+ AbilityComponent();
void update(Entity &entity);
@@ -68,25 +68,25 @@ public:
const AbilityMap &getAbilities() const;
void clearAbilities();
- bool setAbilityMana(int id, int mana);
+ void setAbilityCooldown(int id, int ticks);
+ int abilityCooldown(int id);
- void startCooldown(Entity &entity,
- const AbilityManager::AbilityInfo *abilityInfo);
- int remainingCooldown() const;
+ void setGlobalCooldown(int ticks);
+ int globalCooldown() const;
sigc::signal<void, int> signal_ability_changed;
sigc::signal<void, int> signal_ability_took;
- sigc::signal<void> signal_cooldown_activated;
+ sigc::signal<void> signal_global_cooldown_activated;
// For informing clients
int getLastUsedAbilityId() const;
const Point &getLastTargetPoint() const;
int getLastTargetBeingId() const;
+
private:
bool abilityUseCheck(AbilityMap::iterator it);
- void attributeChanged(Entity *entity, unsigned attr);
- Timeout mCooldown;
+ Timeout mGlobalCooldown;
AbilityMap mAbilities;
@@ -126,9 +126,9 @@ inline const AbilityMap &AbilityComponent::getAbilities() const
return mAbilities;
}
-inline int AbilityComponent::remainingCooldown() const
+inline int AbilityComponent::globalCooldown() const
{
- return mCooldown.remaining();
+ return mGlobalCooldown.remaining();
}
inline int AbilityComponent::getLastUsedAbilityId() const
diff --git a/src/game-server/abilitymanager.cpp b/src/game-server/abilitymanager.cpp
index 0657c2c2..f6367933 100644
--- a/src/game-server/abilitymanager.cpp
+++ b/src/game-server/abilitymanager.cpp
@@ -96,32 +96,10 @@ void AbilityManager::readAbilityNode(xmlNodePtr abilityNode,
return;
}
- bool rechargeable = XML::getBoolProperty(abilityNode, "rechargeable", true);
- 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)
- {
- LOG_WARN("Invalid ability '" << name
- << "' (rechargable but no needed attribute) in category: "
- << categoryName);
- return;
- }
-
-
AbilityInfo *newInfo = new AbilityManager::AbilityInfo;
newInfo->categoryName = categoryName;
newInfo->name = name;
newInfo->id = id;
- newInfo->rechargeable = rechargeable;
- newInfo->neededPoints = neededMana;
- newInfo->rechargeAttribute = rechargeAttribute;
- newInfo->cooldownAttribute = cooldownAttribute;
- newInfo->autoconsume = autoconsume;
newInfo->target = getTargetByString(XML::getProperty(abilityNode, "target",
std::string()));
diff --git a/src/game-server/abilitymanager.h b/src/game-server/abilitymanager.h
index 9e315b70..ef16c230 100644
--- a/src/game-server/abilitymanager.h
+++ b/src/game-server/abilitymanager.h
@@ -42,22 +42,12 @@ public:
{
AbilityInfo() :
id(0),
- rechargeable(false),
- rechargeAttribute(0),
- cooldownAttribute(0),
- neededPoints(0),
- autoconsume(true),
target(TARGET_BEING)
{}
unsigned id;
std::string name;
std::string categoryName;
- bool rechargeable;
- unsigned rechargeAttribute;
- unsigned cooldownAttribute;
- unsigned neededPoints;
- bool autoconsume;
TargetMode target;
Script::Ref rechargedCallback;
Script::Ref useCallback;
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index a593b58b..48621ef4 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -93,11 +93,11 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg):
actorComponent->setSize(16);
- auto *abilityComponent = new AbilityComponent(entity);
+ auto *abilityComponent = new AbilityComponent();
entity.addComponent(abilityComponent);
abilityComponent->signal_ability_changed.connect(
sigc::mem_fun(this, &CharacterComponent::abilityStatusChanged));
- abilityComponent->signal_cooldown_activated.connect(
+ abilityComponent->signal_global_cooldown_activated.connect(
sigc::mem_fun(this,
&CharacterComponent::abilityCooldownActivated));
@@ -186,8 +186,6 @@ void CharacterComponent::abilityCooldownActivated()
void CharacterComponent::sendAbilityUpdate(Entity &entity)
{
- auto *beingComponent = entity.getComponent<BeingComponent>();
-
auto &abilities = entity.getComponent<AbilityComponent>()->getAbilities();
MessageOut msg(GPMSG_ABILITY_STATUS);
@@ -197,13 +195,8 @@ void CharacterComponent::sendAbilityUpdate(Entity &entity)
if (it == abilities.end())
continue; // got deleted
- const double rechargeSpeed = beingComponent->getModifiedAttribute(
- it->second.abilityInfo->rechargeAttribute);
-
msg.writeInt8(id);
- msg.writeInt32(it->second.currentPoints);
- msg.writeInt32(it->second.abilityInfo->neededPoints);
- msg.writeInt32((int)rechargeSpeed);
+ msg.writeInt32(it->second.rechargeTimeout.remaining());
}
mModifiedAbilities.clear();
@@ -214,7 +207,7 @@ void CharacterComponent::sendAbilityCooldownUpdate(Entity &entity)
{
MessageOut msg(GPMSG_ABILITY_COOLDOWN);
auto *abilityComponent = entity.getComponent<AbilityComponent>();
- msg.writeInt16(abilityComponent->remainingCooldown());
+ msg.writeInt16(abilityComponent->globalCooldown());
gameHandler->sendTo(mClient, msg);
mSendAbilityCooldown = false;
}
diff --git a/src/game-server/character.h b/src/game-server/character.h
index 834f9fe3..860d53e2 100644
--- a/src/game-server/character.h
+++ b/src/game-server/character.h
@@ -89,10 +89,8 @@ public:
void setKillCount(int monsterId, int kills);
void clearAbilities();
- void giveAbility(int id, int mana);
- int getAbilitySize() const;
- AbilityMap::const_iterator getAbilityBegin() const;
- AbilityMap::const_iterator getAbilityEnd() const;
+ void giveAbility(int id);
+ const std::set<int> getAbilities() const;
Possessions &getPossessions() const;
@@ -554,24 +552,21 @@ inline void CharacterData::clearAbilities()
mEntity->getComponent<AbilityComponent>()->clearAbilities();
}
-inline void CharacterData::giveAbility(int id, int mana)
+inline void CharacterData::giveAbility(int id)
{
- mEntity->getComponent<AbilityComponent>()->giveAbility(id, mana);
+ mEntity->getComponent<AbilityComponent>()->giveAbility(id);
}
-inline int CharacterData::getAbilitySize() const
+inline const std::set<int> CharacterData::getAbilities() const
{
- return mEntity->getComponent<AbilityComponent>()->getAbilities().size();
-}
+ // TODO: remove this coping when removing the shared characterdata.h
+ std::set<int> abilities;
-inline AbilityMap::const_iterator CharacterData::getAbilityBegin() const
-{
- return mEntity->getComponent<AbilityComponent>()->getAbilities().begin();
-}
+ for (auto &it : mEntity->getComponent<AbilityComponent>()->getAbilities()) {
+ abilities.insert(it.first);
+ }
-inline AbilityMap::const_iterator CharacterData::getAbilityEnd() const
-{
- return mEntity->getComponent<AbilityComponent>()->getAbilities().end();
+ return abilities;
}
inline Possessions &CharacterData::getPossessions() const
diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp
index 3cdb2f43..a426a144 100644
--- a/src/game-server/commandhandler.cpp
+++ b/src/game-server/commandhandler.cpp
@@ -1639,7 +1639,7 @@ static void handleRechargeAbility(Entity *player, std::string &args)
if (character.empty() || ability.empty())
{
say("Invalid amount of arguments given.", player);
- say("Usage: @rechargeability <character> <ability> [<mana>]", player);
+ say("Usage: @rechargeability <character> <ability>", player);
return;
}
@@ -1669,25 +1669,7 @@ static void handleRechargeAbility(Entity *player, std::string &args)
say("Invalid ability.", player);
return;
}
- int mana;
- if (newMana.empty())
- {
- mana = info->neededPoints;
- }
- else
- {
- if (!utils::isNumeric(newMana))
- {
- say("Invalid mana amount given.", player);
- return;
- }
- mana = utils::stringToInt(newMana);
- }
- if (!other->getComponent<AbilityComponent>()->setAbilityMana(abilityId, mana))
- {
- say("Character does not have ability.", player);
- return;
- }
+ other->getComponent<AbilityComponent>()->setAbilityCooldown(abilityId, 0);
}
static void handleListAbility(Entity *player, std::string &args)
@@ -1720,8 +1702,8 @@ static void handleListAbility(Entity *player, std::string &args)
{
const AbilityValue &info = abilityIt.second;
std::stringstream str;
- str << info.abilityInfo->id << ": " << info.abilityInfo->categoryName << "/"
- << info.abilityInfo->name << " charge: " << info.currentPoints;
+ str << info.abilityInfo->id << ": " << info.abilityInfo->categoryName
+ << "/" << info.abilityInfo->name;
say(str.str(), player);
}
}
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index 30be1201..41a69ecb 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -78,7 +78,7 @@ MonsterComponent::MonsterComponent(Entity &entity, MonsterClass *specy):
beingComponent->setGender(specy->getGender());
beingComponent->setName(specy->getName());
- AbilityComponent *abilityComponent = new AbilityComponent(entity);
+ AbilityComponent *abilityComponent = new AbilityComponent();
entity.addComponent(abilityComponent);
for (auto *abilitiyInfo : specy->getAbilities())
{
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index 13373d81..f22309f7 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -1277,29 +1277,22 @@ static int chr_set_quest(lua_State *s)
}
/** LUA entity:set_ability_mana (being)
- * entity:set_ability_mana(int abilityid, int new_mana)
- * entity:set_ability_mana(string abilityname, int new_mana)
+ * entity:set_ability_cooldown(int abilityid, int ticks)
+ * entity:set_ability_cooldown(string abilityname, int ticks)
**
* Valid only for character entities.
*
- * Sets the mana (recharge status) of the ability to a new value for the
- * character.
+ * Sets the amout of ticks that a ability needs to cooldown.
*
* **Note:** When passing the `abilitynam` as parameter make sure that it is
* formatted in this way: &lt;setname&gt;_&lt;abilityname&gt; (for eg. "Magic_Healingspell").
*/
-static int entity_set_ability_mana(lua_State *s)
+static int entity_set_ability_cooldown(lua_State *s)
{
Entity *c = checkCharacter(s, 1);
auto *abilityInfo = checkAbility(s, 2);
- const int mana = luaL_checkint(s, 3);
- if (!c->getComponent<AbilityComponent>()->setAbilityMana(abilityInfo->id,
- mana))
- {
- luaL_error(s,
- "set_ability_mana called with ability "
- "that is not owned by character.");
- }
+ const int ticks = luaL_checkint(s, 3);
+ c->getComponent<AbilityComponent>()->setAbilityCooldown(abilityInfo->id, ticks);
return 0;
}
@@ -1307,45 +1300,49 @@ static int entity_set_ability_mana(lua_State *s)
* entity:ability_mana(int abilityid)
* entity:ability_mana(string abilityname)
**
- * **Return value:** The mana (recharge status) of the ability that is owned by
- * the character.
+ * **Return value:** The remaining time of the ability cooldown.
*
* **Note:** When passing the `abilityname` as parameter make sure that it is
* formatted in this way: &lt;setname&gt;_&lt;abilityname&gt; (for eg. "Magic_Healingspell").
*/
-static int entity_get_ability_mana(lua_State *s)
+static int entity_get_ability_cooldown(lua_State *s)
{
Entity *c = checkCharacter(s, 1);
auto *abilityComponent = c->getComponent<AbilityComponent>();
auto *abilityInfo = checkAbility(s, 2);
- AbilityMap::iterator it = abilityComponent->findAbility(abilityInfo->id);
- luaL_argcheck(s, it != abilityComponent->getAbilities().end(), 2,
- "character does not have ability");
- lua_pushinteger(s, it->second.currentPoints);
+ lua_pushinteger(s, abilityComponent->abilityCooldown(abilityInfo->id));
return 1;
}
-/** LUA entity:cooldown_ability (being)
- * entity:cooldown_ability(int abilityid)
- * entity:cooldown_ability(string abilityname)
+/** LUA entity:set_global_ability_cooldown (being)
+ * entity:set_global_ability_cooldown(int ticks)
**
- * Starts the cooldown of the passed ability. No other ability will be useable
- * in this time.
- *
- * You do not need to call this if the attribute is set to ''autoconsume''.
+ * Valid only for character entities.
*
- * **Note:** When passing the ''abilityname'' as parameter make sure that it is
- * formatted in this way: <setname>_<abilityname> (for eg. "Magic_Healingspell").
+ * Sets the amount of ticks before any other ability can be used again
*/
-static int entity_cooldown_ability(lua_State *s)
+static int entity_set_global_ability_cooldown(lua_State *s)
{
Entity *c = checkCharacter(s, 1);
- auto *abilityComponent = c->getComponent<AbilityComponent>();
- auto *abilityInfo = checkAbility(s, 2);
- abilityComponent->startCooldown(*c, abilityInfo);
+ const int ticks = luaL_checkint(s, 3);
+ c->getComponent<AbilityComponent>()->setGlobalCooldown(ticks);
return 0;
}
+/** LUA entity:global_ability_cooldown (being)
+ * entity:global_ability_cooldown()
+ **
+ * Valid only for character entities.
+ *
+ * Gets the amount of ticks before any other ability can be used again
+ */
+static int entity_get_global_ability_cooldown(lua_State *s)
+{
+ Entity *c = checkCharacter(s, 1);
+ lua_pushinteger(s, c->getComponent<AbilityComponent>()->globalCooldown());
+ return 1;
+}
+
/** LUA entity:walk (being)
* entity:walk(int pixelX, int pixelY [, int walkSpeed])
**
@@ -2874,37 +2871,6 @@ static int abilityinfo_get_name(lua_State *s)
return 1;
}
-/** LUA abilityinfo:needed_mana (abilityinfo)
- * abilityinfo:needed_mana()
- **
- * ** Return value:** The mana that is needed to use the ability
- *
- * **Note:** See [get_ability_info](scripting.html#get_ability_info) for getting a
- * abilityinfo object.
- */
-static int abilityinfo_get_needed_mana(lua_State *s)
-{
- auto *info = LuaAbilityInfo::check(s, 1);
- lua_pushinteger(s, info->neededPoints);
- return 1;
-}
-
-/** LUA abilityinfo:rechargeable (abilityinfo)
- * abilityinfo:rechargeable()
- **
- * ** Return value:** A boolean value that indicates whether the ability is
- * rechargeable or usuable without recharge.
- *
- * **Note:** See [get_ability_info](scripting.html#get_ability_info) for getting a
- * a abilityinfo object.
- */
-static int abilityinfo_is_rechargeable(lua_State *s)
-{
- auto *info = LuaAbilityInfo::check(s, 1);
- lua_pushboolean(s, info->rechargeable);
- return 1;
-}
-
/** LUA abilityinfo:on_use (abilityinfo)
* abilityinfo:on_use(function callback)
**
@@ -3388,9 +3354,10 @@ LuaScript::LuaScript():
{ "equip_item", entity_equip_item },
{ "unequip_slot", entity_unequip_slot },
{ "unequip_item", entity_unequip_item },
- { "set_ability_mana", entity_set_ability_mana },
- { "ability_mana", entity_get_ability_mana },
- { "cooldown_ability", entity_cooldown_ability },
+ { "set_ability_cooldown", entity_set_ability_cooldown },
+ { "ability_cooldown", entity_get_ability_cooldown },
+ { "set_global_ability_cooldown", entity_set_global_ability_cooldown},
+ { "global_ability_cooldown", entity_get_global_ability_cooldown},
{ "walk", entity_walk },
{ "destination", entity_destination },
{ "look_at", entity_look_at },
@@ -3470,8 +3437,6 @@ LuaScript::LuaScript():
static luaL_Reg const members_AbilityInfo[] = {
{ "name", abilityinfo_get_name },
- { "needed_mana", abilityinfo_get_needed_mana },
- { "rechargeable", abilityinfo_is_rechargeable },
{ "on_use", abilityinfo_on_use },
{ "on_recharged", abilityinfo_on_recharged },
{ "category", abilitiyinfo_get_category },
diff --git a/src/serialize/characterdata.h b/src/serialize/characterdata.h
index 2e4620dc..2fbe256b 100644
--- a/src/serialize/characterdata.h
+++ b/src/serialize/characterdata.h
@@ -76,13 +76,10 @@ void serializeCharacterData(const T &data, MessageOut &msg)
}
// character abilities
- AbilityMap::const_iterator abilitiy_it;
- msg.writeInt16(data.getAbilitySize());
- for (abilitiy_it = data.getAbilityBegin();
- abilitiy_it != data.getAbilityEnd(); abilitiy_it++)
- {
- msg.writeInt32(abilitiy_it->first);
- msg.writeInt32(abilitiy_it->second.currentPoints);
+ const std::set<int> &abilities = data.getAbilities();
+ msg.writeInt16(abilities.size());
+ for (auto &abilityId : abilities) {
+ msg.writeInt32(abilityId);
}
// inventory - must be last because size isn't transmitted
@@ -162,8 +159,7 @@ void deserializeCharacterData(T &data, MessageIn &msg)
for (int i = 0; i < abilitiesSize; i++)
{
const int id = msg.readInt32();
- const int mana = msg.readInt32();
- data.giveAbility(id, mana);
+ data.giveAbility(id);
}
diff --git a/src/sql/mysql/createTables.sql b/src/sql/mysql/createTables.sql
index 50fdae90..fc873712 100644
--- a/src/sql/mysql/createTables.sql
+++ b/src/sql/mysql/createTables.sql
@@ -103,7 +103,6 @@ CREATE TABLE mana_char_abilities
(
`char_id` int(10) unsigned NOT NULL,
`ability_id` int(10) unsigned NOT NULL,
- `ability_current_points` int(10) unsigned NOT NULL,
PRIMARY KEY (`char_id`, `ability_id`),
FOREIGN KEY (`char_id`)
REFERENCES `mana_characters` (`id`)
@@ -421,7 +420,7 @@ AUTO_INCREMENT=0 ;
INSERT INTO mana_world_states VALUES('accountserver_startup',-1,'0', NOW());
INSERT INTO mana_world_states VALUES('accountserver_version',-1,'0', NOW());
-INSERT INTO mana_world_states VALUES('database_version', -1,'23', NOW());
+INSERT INTO mana_world_states VALUES('database_version', -1,'24', NOW());
-- all known transaction codes
diff --git a/src/sql/mysql/updates/update_23_to_24.sql b/src/sql/mysql/updates/update_23_to_24.sql
new file mode 100644
index 00000000..1614bd00
--- /dev/null
+++ b/src/sql/mysql/updates/update_23_to_24.sql
@@ -0,0 +1,12 @@
+START TRANSACTION;
+
+ALTER TABLE mana_char_abilities DROP COLUMN ability_current_points;
+
+-- Update database version.
+UPDATE mana_world_states
+ SET value = '24',
+ moddate = UNIX_TIMESTAMP()
+ WHERE state_name = 'database_version';
+
+COMMIT;
+
diff --git a/src/sql/sqlite/createTables.sql b/src/sql/sqlite/createTables.sql
index 72a70090..9d7d1c2c 100644
--- a/src/sql/sqlite/createTables.sql
+++ b/src/sql/sqlite/createTables.sql
@@ -110,7 +110,6 @@ CREATE TABLE mana_char_abilities
(
char_id INTEGER NOT NULL,
ability_id INTEGER NOT NULL,
- ability_current_points INTEGER NOT NULL,
PRIMARY KEY (char_id, ability_id),
FOREIGN KEY (char_id) REFERENCES mana_characters(id)
);
@@ -409,7 +408,7 @@ AS
INSERT INTO mana_world_states VALUES('accountserver_startup',-1,'0', strftime('%s','now'));
INSERT INTO mana_world_states VALUES('accountserver_version',-1,'0', strftime('%s','now'));
-INSERT INTO mana_world_states VALUES('database_version', -1,'23', strftime('%s','now'));
+INSERT INTO mana_world_states VALUES('database_version', -1,'24', strftime('%s','now'));
-- all known transaction codes
diff --git a/src/sql/sqlite/updates/update_23_to_24.sql b/src/sql/sqlite/updates/update_23_to_24.sql
new file mode 100644
index 00000000..83b129eb
--- /dev/null
+++ b/src/sql/sqlite/updates/update_23_to_24.sql
@@ -0,0 +1,34 @@
+BEGIN;
+
+CREATE TABLE mana_char_abilities_backup
+(
+ char_id INTEGER NOT NULL,
+ ability_id INTEGER NOT NULL,
+ PRIMARY KEY (char_id, ability_id),
+ FOREIGN KEY (char_id) REFERENCES mana_characters(id)
+);
+
+INSERT INTO mana_char_abilities_backup SELECT char_id, ability_id FROM mana_char_abilities;
+
+DROP TABLE mana_char_abilities;
+
+CREATE TABLE mana_char_abilities
+(
+ char_id INTEGER NOT NULL,
+ ability_id INTEGER NOT NULL,
+ PRIMARY KEY (char_id, ability_id),
+ FOREIGN KEY (char_id) REFERENCES mana_characters(id)
+);
+
+INSERT INTO mana_char_abilities SELECT char_id, ability_id FROM mana_char_abilities_backup;
+
+DROP TABLE mana_char_abilities_backup;
+
+-- Update the database version, and set date of update
+UPDATE mana_world_states
+ SET value = '24',
+ moddate = strftime('%s','now')
+ WHERE state_name = 'database_version';
+
+END;
+