diff options
author | Erik Schilling <ablu.erikschilling@googlemail.com> | 2013-08-07 22:08:29 +0200 |
---|---|---|
committer | Erik Schilling <ablu.erikschilling@googlemail.com> | 2013-08-26 22:56:47 +0200 |
commit | ba573fcc38580a01985172b9bc864c97ce855af3 (patch) | |
tree | ebcdbcf9a86cd35d5a8ab3bb004faa5c490c16d4 /src | |
parent | 7dc001eb32ae5345905e108741984258ee2f1813 (diff) | |
download | manaserv-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.cpp | 7 | ||||
-rw-r--r-- | src/account-server/character.h | 38 | ||||
-rw-r--r-- | src/account-server/storage.cpp | 16 | ||||
-rw-r--r-- | src/common/manaserv_protocol.h | 6 | ||||
-rw-r--r-- | src/game-server/abilitycomponent.cpp | 88 | ||||
-rw-r--r-- | src/game-server/abilitycomponent.h | 28 | ||||
-rw-r--r-- | src/game-server/abilitymanager.cpp | 22 | ||||
-rw-r--r-- | src/game-server/abilitymanager.h | 10 | ||||
-rw-r--r-- | src/game-server/character.cpp | 15 | ||||
-rw-r--r-- | src/game-server/character.h | 27 | ||||
-rw-r--r-- | src/game-server/commandhandler.cpp | 26 | ||||
-rw-r--r-- | src/game-server/monster.cpp | 2 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 103 | ||||
-rw-r--r-- | src/serialize/characterdata.h | 14 | ||||
-rw-r--r-- | src/sql/mysql/createTables.sql | 3 | ||||
-rw-r--r-- | src/sql/mysql/updates/update_23_to_24.sql | 12 | ||||
-rw-r--r-- | src/sql/sqlite/createTables.sql | 3 | ||||
-rw-r--r-- | src/sql/sqlite/updates/update_23_to_24.sql | 34 |
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: <setname>_<abilityname> (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: <setname>_<abilityname> (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; + |