summaryrefslogtreecommitdiff
path: root/src/game-server
diff options
context:
space:
mode:
Diffstat (limited to 'src/game-server')
-rw-r--r--src/game-server/item.cpp20
-rw-r--r--src/game-server/item.h31
-rw-r--r--src/game-server/itemmanager.cpp51
-rw-r--r--src/game-server/monster.cpp34
-rw-r--r--src/game-server/monster.h27
-rw-r--r--src/game-server/monstermanager.cpp5
-rw-r--r--src/game-server/statuseffect.cpp17
-rw-r--r--src/game-server/statuseffect.h8
-rw-r--r--src/game-server/statusmanager.cpp31
-rw-r--r--src/game-server/statusmanager.h5
10 files changed, 139 insertions, 90 deletions
diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp
index 979a1bc3..888c90ad 100644
--- a/src/game-server/item.cpp
+++ b/src/game-server/item.cpp
@@ -64,13 +64,17 @@ ItemEffectScript::~ItemEffectScript()
bool ItemEffectScript::apply(Being *itemUser)
{
- if (!mActivateFunctionName.empty())
+ if (mActivateEventName.empty())
+ return false;
+
+ Script::Ref function = mItemClass->getEventCallback(mActivateEventName);
+ if (function.isValid())
{
Script *script = ScriptManager::currentState();
script->setMap(itemUser->getMap());
- script->prepare(mActivateFunctionName);
+ script->prepare(function);
script->push(itemUser);
- script->push(mItemId);
+ script->push(mItemClass->getDatabaseID());
script->execute(); // TODO return depending on script execution success.
return true;
}
@@ -79,13 +83,17 @@ bool ItemEffectScript::apply(Being *itemUser)
void ItemEffectScript::dispell(Being *itemUser)
{
- if (!mDispellFunctionName.empty())
+ if (mDispellEventName.empty())
+ return;
+
+ Script::Ref function = mItemClass->getEventCallback(mDispellEventName);
+ if (function.isValid())
{
Script *script = ScriptManager::currentState();
script->setMap(itemUser->getMap());
- script->prepare(mDispellFunctionName);
+ script->prepare(function);
script->push(itemUser);
- script->push(mItemId);
+ script->push(mItemClass->getDatabaseID());
script->execute();
}
}
diff --git a/src/game-server/item.h b/src/game-server/item.h
index 8cd3ce64..2677589f 100644
--- a/src/game-server/item.h
+++ b/src/game-server/item.h
@@ -24,8 +24,10 @@
#include <vector>
#include "game-server/actor.h"
+#include "scripting/script.h"
class Being;
+class ItemClass;
// Indicates the equip slot "cost" to equip an item.
struct ItemEquipRequirement {
@@ -143,12 +145,12 @@ class ItemEffectConsumes : public ItemEffectInfo
class ItemEffectScript : public ItemEffectInfo
{
public:
- ItemEffectScript(int itemId,
- const std::string& activateFunctionName,
- const std::string& dispellFunctionName):
- mItemId(itemId),
- mActivateFunctionName(activateFunctionName),
- mDispellFunctionName(dispellFunctionName)
+ ItemEffectScript(ItemClass *itemClass,
+ const std::string &activateEventName,
+ const std::string &dispellEventName):
+ mItemClass(itemClass),
+ mActivateEventName(activateEventName),
+ mDispellEventName(dispellEventName)
{}
~ItemEffectScript();
@@ -157,9 +159,9 @@ class ItemEffectScript : public ItemEffectInfo
void dispell(Being *itemUser);
private:
- int mItemId;
- std::string mActivateFunctionName;
- std::string mDispellFunctionName;
+ ItemClass *mItemClass;
+ std::string mActivateEventName;
+ std::string mDispellEventName;
};
@@ -234,6 +236,12 @@ class ItemClass
const ItemEquipRequirement &getItemEquipRequirement() const
{ return mEquipReq; }
+ void setEventCallback(const std::string &event, Script *script)
+ { script->assignCallback(mEventCallbacks[event]); }
+
+ Script::Ref getEventCallback(const std::string &event) const
+ { return mEventCallbacks.value(event); }
+
private:
/**
* Add an effect to a trigger
@@ -282,6 +290,11 @@ class ItemClass
*/
ItemEquipRequirement mEquipReq;
+ /**
+ * Named event callbacks. Can be used in custom item effects.
+ */
+ utils::NameMap<Script::Ref> mEventCallbacks;
+
friend class ItemManager;
};
diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp
index b334760a..8c74680e 100644
--- a/src/game-server/itemmanager.cpp
+++ b/src/game-server/itemmanager.cpp
@@ -404,50 +404,25 @@ void ItemManager::readEffectNode(xmlNodePtr effectNode, ItemClass *item)
{
item->addEffect(new ItemEffectConsumes, triggerTypes.first);
}
- else if (xmlStrEqual(subNode->name, BAD_CAST "script"))
+ else if (xmlStrEqual(subNode->name, BAD_CAST "scriptevent"))
{
- 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!");
- 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;
- }
-
- LOG_INFO("Loading item script: " << filename.str());
- Script *script = ScriptManager::currentState();
- if (!script->loadFile(filename.str()))
+ std::string activateEventName = XML::getProperty(subNode,
+ "activate",
+ std::string());
+ if (activateEventName.empty())
{
- LOG_WARN("Could not load script file \"" << filename.str()
- << "\" for item #" << item->mDatabaseID);
+ LOG_WARN("Item Manager: Empty name for 'activate' item script "
+ "event, skipping effect!");
continue;
}
- std::string dispellFunctionName = XML::getProperty(subNode,
- "dispell-function",
- std::string());
+ std::string dispellEventName = XML::getProperty(subNode,
+ "dispell",
+ std::string());
- item->addEffect(new ItemEffectScript(item->mDatabaseID,
- activateFunctionName,
- dispellFunctionName),
+ item->addEffect(new ItemEffectScript(item,
+ activateEventName,
+ dispellEventName),
triggerTypes.first,
triggerTypes.second);
}
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index 21eeea7c..b82f4638 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -28,7 +28,6 @@
#include "game-server/item.h"
#include "game-server/mapcomposite.h"
#include "game-server/state.h"
-#include "scripting/script.h"
#include "scripting/scriptmanager.h"
#include "utils/logger.h"
#include "utils/speedconv.h"
@@ -140,16 +139,20 @@ void Monster::perform()
int hit = performAttack(mTarget, dmg);
- if (! mCurrentAttack->scriptFunction.empty()
+ if (! mCurrentAttack->scriptEvent.empty()
&& hit > -1)
{
- Script *script = ScriptManager::currentState();
- script->setMap(getMap());
- script->prepare(mCurrentAttack->scriptFunction);
- script->push(this);
- script->push(mTarget);
- script->push(hit);
- script->execute();
+ Script::Ref function = mSpecy->getEventCallback(mCurrentAttack->scriptEvent);
+ if (function.isValid())
+ {
+ Script *script = ScriptManager::currentState();
+ script->setMap(getMap());
+ script->prepare(function);
+ script->push(this);
+ script->push(mTarget);
+ script->push(hit);
+ script->execute();
+ }
}
}
}
@@ -180,11 +183,14 @@ void Monster::update()
return;
}
- Script *script = ScriptManager::currentState();
- script->setMap(getMap());
- script->prepare("update_monster");
- script->push(this);
- script->execute();
+ if (mSpecy->getUpdateCallback().isValid())
+ {
+ Script *script = ScriptManager::currentState();
+ script->setMap(getMap());
+ script->prepare(mSpecy->getUpdateCallback());
+ script->push(this);
+ script->execute();
+ }
// Cancel the rest when we are currently performing an attack
if (isTimerRunning(T_M_ATTACK_TIME))
diff --git a/src/game-server/monster.h b/src/game-server/monster.h
index 37bbe355..5ccabfa9 100644
--- a/src/game-server/monster.h
+++ b/src/game-server/monster.h
@@ -28,6 +28,8 @@
#include "game-server/being.h"
#include "game-server/eventlistener.h"
#include "common/defines.h"
+#include "scripting/script.h"
+#include "utils/string.h"
class ItemClass;
class Script;
@@ -57,7 +59,7 @@ struct MonsterAttack
int preDelay;
int aftDelay;
int range;
- std::string scriptFunction;
+ std::string scriptEvent;
};
typedef std::vector< MonsterAttack *> MonsterAttacks;
@@ -197,6 +199,18 @@ class MonsterClass
/** Returns script filename */
const std::string &getScript() const { return mScript; }
+ void setUpdateCallback(Script *script)
+ { script->assignCallback(mUpdateCallback); }
+
+ void setEventCallback(const std::string &event, Script *script)
+ { script->assignCallback(mEventCallbacks[event]); }
+
+ Script::Ref getUpdateCallback() const
+ { return mUpdateCallback; }
+
+ Script::Ref getEventCallback(const std::string &event) const
+ { return mEventCallbacks.value(event); }
+
private:
unsigned short mId;
std::string mName;
@@ -217,6 +231,17 @@ class MonsterClass
MonsterAttacks mAttacks;
std::string mScript;
+ /**
+ * A reference to the script function that is called each update.
+ */
+ Script::Ref mUpdateCallback;
+
+ /**
+ * Named event callbacks. Currently only used for custom attack
+ * callbacks.
+ */
+ utils::NameMap<Script::Ref> mEventCallbacks;
+
friend class MonsterManager;
friend class Monster;
};
diff --git a/src/game-server/monstermanager.cpp b/src/game-server/monstermanager.cpp
index bebb74a3..7612ddc1 100644
--- a/src/game-server/monstermanager.cpp
+++ b/src/game-server/monstermanager.cpp
@@ -243,9 +243,8 @@ void MonsterManager::initialize()
att->preDelay = XML::getProperty(subnode, "pre-delay", 1);
att->aftDelay = XML::getProperty(subnode, "aft-delay", 0);
att->range = XML::getProperty(subnode, "range", 0);
- att->scriptFunction = XML::getProperty(subnode,
- "script-function",
- std::string());
+ att->scriptEvent = XML::getProperty(subnode, "script-event",
+ std::string());
std::string sElement = XML::getProperty(subnode,
"element", "neutral");
att->element = elementFromString(sElement);
diff --git a/src/game-server/statuseffect.cpp b/src/game-server/statuseffect.cpp
index 32e0d621..c101bc02 100644
--- a/src/game-server/statuseffect.cpp
+++ b/src/game-server/statuseffect.cpp
@@ -20,9 +20,8 @@
#include "game-server/statuseffect.h"
-#include "scripting/script.h"
-#include "scripting/scriptmanager.h"
#include "game-server/being.h"
+#include "scripting/scriptmanager.h"
StatusEffect::StatusEffect(int id):
mId(id)
@@ -35,13 +34,13 @@ StatusEffect::~StatusEffect()
void StatusEffect::tick(Being *target, int count)
{
- if (!mTickFunction.empty())
+ if (mTickCallback.isValid())
{
- Script *script = ScriptManager::currentState();
- script->setMap(target->getMap());
- script->prepare(mTickFunction);
- script->push(target);
- script->push(count);
- script->execute();
+ Script *s = ScriptManager::currentState();
+ s->setMap(target->getMap());
+ s->prepare(mTickCallback);
+ s->push(target);
+ s->push(count);
+ s->execute();
}
}
diff --git a/src/game-server/statuseffect.h b/src/game-server/statuseffect.h
index 2b7a36f8..7da5fdf9 100644
--- a/src/game-server/statuseffect.h
+++ b/src/game-server/statuseffect.h
@@ -21,7 +21,7 @@
#ifndef STATUSEFFECT_H
#define STATUSEFFECT_H
-#include <string>
+#include "scripting/script.h"
class Being;
@@ -36,12 +36,12 @@ class StatusEffect
int getId() const
{ return mId; }
- void setTickFunction(const std::string &tickFunction)
- { mTickFunction = tickFunction; }
+ void setTickCallback(Script *script)
+ { script->assignCallback(mTickCallback); }
private:
int mId;
- std::string mTickFunction;
+ Script::Ref mTickCallback;
};
#endif
diff --git a/src/game-server/statusmanager.cpp b/src/game-server/statusmanager.cpp
index 15203d65..7769ef0f 100644
--- a/src/game-server/statusmanager.cpp
+++ b/src/game-server/statusmanager.cpp
@@ -33,6 +33,7 @@
typedef std::map< int, StatusEffect * > StatusEffectsMap;
static StatusEffectsMap statusEffects;
+static utils::NameMap<StatusEffect*> statusEffectsByName;
static std::string statusReferenceFile;
void StatusManager::initialize(const std::string &file)
@@ -59,7 +60,7 @@ void StatusManager::reload()
if (!xmlStrEqual(node->name, BAD_CAST "status-effect"))
continue;
- int id = XML::getProperty(node, "id", 0);
+ const int id = XML::getProperty(node, "id", 0);
if (id < 1)
{
LOG_WARN("Status Manager: The status ID: " << id << " in "
@@ -68,9 +69,24 @@ void StatusManager::reload()
continue;
}
+ StatusEffect *statusEffect = new StatusEffect(id);
+
+ const std::string name = XML::getProperty(node, "name",
+ std::string());
+ if (!name.empty())
+ {
+ if (statusEffectsByName.contains(name))
+ {
+ LOG_WARN("StatusManager: name not unique for status effect "
+ << id);
+ }
+ else
+ {
+ statusEffectsByName.insert(name, statusEffect);
+ }
+ }
+
std::string scriptFile = XML::getProperty(node, "script", std::string());
- std::string tickFunction = XML::getProperty(node, "tick-function",
- std::string());
//TODO: Get these modifiers
/*
modifiers.setAttributeValue(BASE_ATTR_PHY_ATK_MIN, XML::getProperty(node, "attack-min", 0));
@@ -84,8 +100,6 @@ void StatusManager::reload()
modifiers.setAttributeValue(CHAR_ATTR_INTELLIGENCE, XML::getProperty(node, "intelligence", 0));
modifiers.setAttributeValue(CHAR_ATTR_WILLPOWER, XML::getProperty(node, "willpower", 0));
*/
- StatusEffect *statusEffect = new StatusEffect(id);
- statusEffect->setTickFunction(tickFunction);
if (!scriptFile.empty())
{
std::stringstream filename;
@@ -112,11 +126,16 @@ void StatusManager::deinitialize()
delete i->second;
}
statusEffects.clear();
+ statusEffectsByName.clear();
}
StatusEffect *StatusManager::getStatus(int statusId)
{
StatusEffectsMap::const_iterator i = statusEffects.find(statusId);
- return i != statusEffects.end() ? i->second : NULL;
+ return i != statusEffects.end() ? i->second : 0;
}
+StatusEffect *StatusManager::getStatusByName(const std::string &name)
+{
+ return statusEffectsByName.value(name);
+}
diff --git a/src/game-server/statusmanager.h b/src/game-server/statusmanager.h
index fc09adb5..8ab321d1 100644
--- a/src/game-server/statusmanager.h
+++ b/src/game-server/statusmanager.h
@@ -46,6 +46,11 @@ namespace StatusManager
* Gets the status having the given ID.
*/
StatusEffect *getStatus(int statusId);
+
+ /**
+ * Gets the status having the given name.
+ */
+ StatusEffect *getStatusByName(const std::string &name);
}
#endif // STATUSMANAGER_H