diff options
author | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-04-19 00:37:38 +0200 |
---|---|---|
committer | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-04-19 00:37:38 +0200 |
commit | ca1dd6fcaf1dfaef0f18df0b6c114f1baa25d2ce (patch) | |
tree | bd33eda8c946436bf844fc157aa5208c7da9b934 | |
parent | 80e07598a896e73e08e2511f08602e2b6d2e4eb7 (diff) | |
download | manaserv-ca1dd6fcaf1dfaef0f18df0b6c114f1baa25d2ce.tar.gz manaserv-ca1dd6fcaf1dfaef0f18df0b6c114f1baa25d2ce.tar.bz2 manaserv-ca1dd6fcaf1dfaef0f18df0b6c114f1baa25d2ce.tar.xz manaserv-ca1dd6fcaf1dfaef0f18df0b6c114f1baa25d2ce.zip |
Implemented scriptable effects on item use and dispell.
Reviewed-by: Thorbjorn.
-rw-r--r-- | example/clientdata/items.xml | 9 | ||||
-rw-r--r-- | src/game-server/item.cpp | 24 | ||||
-rw-r--r-- | src/game-server/item.h | 33 | ||||
-rw-r--r-- | src/game-server/itemmanager.cpp | 47 |
4 files changed, 93 insertions, 20 deletions
diff --git a/example/clientdata/items.xml b/example/clientdata/items.xml index 8ab3fd10..ff0b1c5e 100644 --- a/example/clientdata/items.xml +++ b/example/clientdata/items.xml @@ -64,11 +64,14 @@ description="A sugar-free candy." type="usable" hp="5" - script="candy.lua" weight="1" max-per-slot="30" - value="15" - /> + value="15"> + <effect trigger="activation"> + <script src="candy.lua" function="use" /> + <consumes /> + </effect> + </item> <item id="2" max-per-slot="1" name="Regenerative trinket" description="A trinket with refreshing powers." image="usable/usable-regenerative-trinket.png" diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp index 9c73e9dc..980db785 100644 --- a/src/game-server/item.cpp +++ b/src/game-server/item.cpp @@ -57,15 +57,35 @@ void ItemEffectAutoAttack::dispell(Being *itemUser) // TODO } +ItemEffectScript::~ItemEffectScript() +{ + delete mScript; +} + bool ItemEffectScript::apply(Being *itemUser) { - // TODO + if (mScript && !mActivateFunctionName.empty()) + { + mScript->setMap(itemUser->getMap()); + mScript->prepare(mActivateFunctionName); + mScript->push(itemUser); + mScript->push(mItemId); + mScript->execute(); // TODO return depending on script execution success. + return true; + } return false; } void ItemEffectScript::dispell(Being *itemUser) { - // TODO + if (mScript && !mDispellFunctionName.empty()) + { + mScript->setMap(itemUser->getMap()); + mScript->prepare(mDispellFunctionName); + mScript->push(itemUser); + mScript->push(mItemId); + mScript->execute(); + } } bool ItemClass::useTrigger(Being *itemUser, ItemTriggerType trigger) diff --git a/src/game-server/item.h b/src/game-server/item.h index d779e1f0..1c7639c5 100644 --- a/src/game-server/item.h +++ b/src/game-server/item.h @@ -26,6 +26,7 @@ #include "game-server/actor.h" class Being; +class Script; typedef std::list< std::pair< unsigned int, unsigned int> > ItemEquipInfo; typedef std::list< ItemEquipInfo > ItemEquipsInfo; @@ -136,8 +137,24 @@ class ItemEffectConsumes : public ItemEffectInfo class ItemEffectScript : public ItemEffectInfo { public: + ItemEffectScript(int itemId, Script *script, + const std::string& activateFunctionName, + const std::string& dispellFunctionName): + mItemId(0), + mScript(script), + mActivateFunctionName(activateFunctionName), + mDispellFunctionName(dispellFunctionName) + {} + + ~ItemEffectScript(); + bool apply(Being *itemUser); void dispell(Being *itemUser); + private: + int mItemId; + Script *mScript; + std::string mActivateFunctionName; + std::string mDispellFunctionName; }; @@ -147,15 +164,16 @@ class ItemEffectScript : public ItemEffectInfo class ItemClass { public: - ItemClass(int id, unsigned int maxperslot) - : mDatabaseID(id) - , mName("unnamed") - , mSpriteID(0) - , mCost(0) - , mMaxPerSlot(maxperslot) + ItemClass(int id, unsigned int maxperslot): + mDatabaseID(id), + mName("unnamed"), + mSpriteID(0), + mCost(0), + mMaxPerSlot(maxperslot) {} - ~ItemClass() { resetEffects(); } + ~ItemClass() + { resetEffects(); } /** * Returns the name of the item type @@ -210,7 +228,6 @@ class ItemClass */ const ItemEquipsInfo &getItemEquipData() const { return mEquip; } - private: /** * Add an effect to a trigger diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index ab9d511e..d21c791c 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -21,6 +21,7 @@ #include "game-server/itemmanager.h" #include "common/defines.h" +#include "common/resourcemanager.h" #include "game-server/attributemanager.h" #include "game-server/item.h" #include "game-server/skillmanager.h" @@ -387,25 +388,57 @@ void ItemManager::readEffectNode(xmlNodePtr effectNode, ItemClass *item) } else if (xmlStrEqual(subNode->name, BAD_CAST "script")) { + std::string activateFunctionName = XML::getProperty(subNode, + "function", + std::string()); + if (activateFunctionName.empty()) + { + LOG_WARN("Item Manager: Empty function definition " + "for script effect, skipping!"); + continue; + } + std::string src = XML::getProperty(subNode, "src", std::string()); if (src.empty()) { - LOG_WARN("Item Manager: Empty src definition for script effect, skipping!"); + LOG_WARN("Item Manager: Empty src definition for script effect," + " skipping!"); + continue; + } + std::stringstream filename; + filename << "scripts/items/" << src; + if (!ResourceManager::exists(filename.str())) + { + LOG_WARN("Could not find script file \"" << filename.str() + << "\" for item #" << item->mDatabaseID); continue; } - std::string func = XML::getProperty(subNode, "function", std::string()); - if (func.empty()) + + LOG_INFO("Loading item script: " << filename.str()); + Script *script = Script::create("lua"); + if (!script->loadFile(filename.str())) { - LOG_WARN("Item Manager: Empty func definition for script effect, skipping!"); + // Delete the script as it's invalid. + delete script; + + LOG_WARN("Could not load script file \"" << filename.str() + << "\" for item #" << item->mDatabaseID); continue; } + for_each_xml_child_node(scriptSubNode, subNode) { // TODO: Load variables from variable subnodes } - std::string dfunc = XML::getProperty(subNode, "dispell-function", std::string()); - // STUB - item->addEffect(new ItemEffectScript(), triggerTypes.first, triggerTypes.second); + std::string dispellFunctionName = XML::getProperty(subNode, + "dispell-function", + std::string()); + + item->addEffect(new ItemEffectScript(item->mDatabaseID, script, + activateFunctionName, + dispellFunctionName), + triggerTypes.first, + triggerTypes.second); } } } |