summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-04-19 00:37:38 +0200
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-04-19 00:37:38 +0200
commitca1dd6fcaf1dfaef0f18df0b6c114f1baa25d2ce (patch)
treebd33eda8c946436bf844fc157aa5208c7da9b934
parent80e07598a896e73e08e2511f08602e2b6d2e4eb7 (diff)
downloadmanaserv-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.xml9
-rw-r--r--src/game-server/item.cpp24
-rw-r--r--src/game-server/item.h33
-rw-r--r--src/game-server/itemmanager.cpp47
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);
}
}
}